📄 makefile.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the qmake application of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "makefile.h"#include "option.h"#include "cachekeys.h"#include "meta.h"#include <qdir.h>#include <qfile.h>#include <qtextstream.h>#include <qregexp.h>#include <qhash.h>#include <qdebug.h>#include <qbuffer.h>#include <qsettings.h>#include <qdatetime.h>#if defined(Q_OS_UNIX)#include <unistd.h>#else#include <io.h>#endif#include <qdebug.h>#include <stdio.h>#include <stdlib.h>#include <time.h>#include <fcntl.h>#include <sys/types.h>#include <sys/stat.h>// Well, Windows doesn't have this, so here's the macro#ifndef S_ISDIR# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)#endifbool MakefileGenerator::canExecute(const QStringList &cmdline, int *a) const{ int argv0 = -1; for(int i = 0; i < cmdline.count(); ++i) { if(!cmdline.at(i).contains('=')) { argv0 = i; break; } } if(a) *a = argv0; if(argv0 != -1) { const QString c = Option::fixPathToLocalOS(cmdline.at(argv0), true); if(exists(c)) return true; } return false;}QString MakefileGenerator::mkdir_p_asstring(const QString &dir, bool escape) const{ QString ret = "@$(CHK_DIR_EXISTS) "; if(escape) ret += escapeFilePath(dir); else ret += dir; ret += " "; if(isWindowsShell()) ret += "$(MKDIR)"; else ret += "|| $(MKDIR)"; ret += " "; if(escape) ret += escapeFilePath(dir); else ret += dir; ret += " "; return ret;}bool MakefileGenerator::mkdir(const QString &in_path) const{ QString path = Option::fixPathToLocalOS(in_path); if(QFile::exists(path)) return true; QDir d; if(path.startsWith(QDir::separator())) { d.cd(QString(QDir::separator())); path = path.right(path.length() - 1); } bool ret = true;#ifdef Q_OS_WIN bool driveExists = true; if(!QDir::isRelativePath(path)) { if(QFile::exists(path.left(3))) { d.cd(path.left(3)); path = path.right(path.length() - 3); } else { warn_msg(WarnLogic, "Cannot access drive '%s' (%s)", path.left(3).toLatin1().data(), path.toLatin1().data()); driveExists = false; } } if(driveExists)#endif { QStringList subs = path.split(QDir::separator()); for(QStringList::Iterator subit = subs.begin(); subit != subs.end(); ++subit) { if(!d.cd(*subit)) { d.mkdir((*subit)); if(d.exists((*subit))) { d.cd((*subit)); } else { ret = false; break; } } } } return ret;}// ** base makefile generatorMakefileGenerator::MakefileGenerator() : init_opath_already(false), init_already(false), no_io(false), project(0){}voidMakefileGenerator::verifyCompilers(){ QMap<QString, QStringList> &v = project->variables(); QStringList &quc = v["QMAKE_EXTRA_COMPILERS"]; for(int i = 0; i < quc.size(); ) { bool error = false; QString comp = quc.at(i); if(v[comp + ".output"].isEmpty()) { if(!v[comp + ".output_function"].isEmpty()) { v[comp + ".output"].append("${QMAKE_FUNC_FILE_IN_" + v[comp + ".output_function"].first() + "}"); } else { error = true; warn_msg(WarnLogic, "Compiler: %s: No output file specified", comp.toLatin1().constData()); } } else if(v[comp + ".input"].isEmpty()) { error = true; warn_msg(WarnLogic, "Compiler: %s: No input variable specified", comp.toLatin1().constData()); } if(error) quc.removeAt(i); else ++i; }}voidMakefileGenerator::initOutPaths(){ if(init_opath_already) return; verifyCompilers(); init_opath_already = true; QMap<QString, QStringList> &v = project->variables(); //for shadow builds if(!v.contains("QMAKE_ABSOLUTE_SOURCE_PATH")) { if(Option::mkfile::do_cache && !Option::mkfile::cachefile.isEmpty() && v.contains("QMAKE_ABSOLUTE_SOURCE_ROOT")) { QString root = v["QMAKE_ABSOLUTE_SOURCE_ROOT"].first(); root = Option::fixPathToTargetOS(root); if(!root.isEmpty()) { QFileInfo fi = fileInfo(Option::mkfile::cachefile); if(!fi.makeAbsolute()) { QString cache_r = fi.path(), pwd = Option::output_dir; if(pwd.startsWith(cache_r) && !pwd.startsWith(root)) { pwd = Option::fixPathToTargetOS(root + pwd.mid(cache_r.length())); if(exists(pwd)) v.insert("QMAKE_ABSOLUTE_SOURCE_PATH", QStringList(pwd)); } } } } } if(!v["QMAKE_ABSOLUTE_SOURCE_PATH"].isEmpty()) { QString &asp = v["QMAKE_ABSOLUTE_SOURCE_PATH"].first(); asp = Option::fixPathToTargetOS(asp); if(asp.isEmpty() || asp == Option::output_dir) //if they're the same, why bother? v["QMAKE_ABSOLUTE_SOURCE_PATH"].clear(); } QString currentDir = qmake_getpwd(); //just to go back to //some builtin directories if(project->isEmpty("PRECOMPILED_DIR") && !project->isEmpty("OBJECTS_DIR")) v["PRECOMPILED_DIR"] = v["OBJECTS_DIR"]; QString dirs[] = { QString("OBJECTS_DIR"), QString("DESTDIR"), QString("QMAKE_PKGCONFIG_DESTDIR"), QString("SUBLIBS_DIR"), QString("DLLDESTDIR"), QString("QMAKE_LIBTOOL_DESTDIR"), QString("PRECOMPILED_DIR"), QString() }; for(int x = 0; !dirs[x].isEmpty(); x++) { if(v[dirs[x]].isEmpty()) continue; const QString orig_path = v[dirs[x]].first(); QString &pathRef = v[dirs[x]].first(); pathRef = fileFixify(pathRef, Option::output_dir, Option::output_dir);#ifdef Q_OS_WIN // We don't want to add a separator for DLLDESTDIR on Windows (###why?) if(!(dirs[x] == "DLLDESTDIR"))#endif { if(pathRef.right(Option::dir_sep.length()) != Option::dir_sep) pathRef += Option::dir_sep; } if(noIO()) continue; QString path = project->first(dirs[x]); //not to be changed any further path = fileFixify(path, currentDir, Option::output_dir); debug_msg(3, "Fixed output_dir %s (%s) into %s", dirs[x].toLatin1().constData(), orig_path.toLatin1().constData(), path.toLatin1().constData()); if(!mkdir(path)) warn_msg(WarnLogic, "%s: Cannot access directory '%s'", dirs[x].toLatin1().constData(), path.toLatin1().constData()); } //out paths from the extra compilers const QStringList &quc = project->values("QMAKE_EXTRA_COMPILERS"); for(QStringList::ConstIterator it = quc.begin(); it != quc.end(); ++it) { QString tmp_out = project->values((*it) + ".output").first(); if(tmp_out.isEmpty()) continue; const QStringList &tmp = project->values((*it) + ".input"); for(QStringList::ConstIterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { QStringList &inputs = project->values((*it2)); for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { (*input) = fileFixify((*input), Option::output_dir, Option::output_dir); QString path = unescapeFilePath(replaceExtraCompilerVariables(tmp_out, (*input), QString())); path = Option::fixPathToTargetOS(path); int slash = path.lastIndexOf(Option::dir_sep); if(slash != -1) { path = path.left(slash); if(path != "." && !mkdir(fileFixify(path, qmake_getpwd(), Option::output_dir))) warn_msg(WarnLogic, "%s: Cannot access directory '%s'", (*it).toLatin1().constData(), path.toLatin1().constData()); } } } } if(!v["DESTDIR"].isEmpty()) { QDir d(v["DESTDIR"].first()); if(Option::fixPathToLocalOS(d.absolutePath()) == Option::fixPathToLocalOS(Option::output_dir)) v.remove("DESTDIR"); } QDir::current().cd(currentDir);}QMakeProject*MakefileGenerator::projectFile() const{ return project;}voidMakefileGenerator::setProjectFile(QMakeProject *p){ if(project) return; project = p; init(); usePlatformDir(); findLibraries(); if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE && project->isActiveConfig("link_prl")) //load up prl's' processPrlFiles();}QStringListMakefileGenerator::findFilesInVPATH(QStringList l, uchar flags, const QString &vpath_var){ QStringList vpath; QMap<QString, QStringList> &v = project->variables(); for(int val_it = 0; val_it < l.count(); ) { bool remove_file = false; QString &val = l[val_it]; if(!val.isEmpty()) { QString file = fixEnvVariables(val); if(!(flags & VPATH_NoFixify))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -