📄 metamakefile.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 "metamakefile.h"#include "qregexp.h"#include "qdir.h"#include "qdebug.h"#include "makefile.h"#include "project.h"#include "cachekeys.h"#define BUILDSMETATYPE 1#define SUBDIRSMETATYPE 2MetaMakefileGenerator::~MetaMakefileGenerator(){ if(own_project) delete project;}class BuildsMetaMakefileGenerator : public MetaMakefileGenerator{ bool init_flag;private: struct Build { QString name, build; MakefileGenerator *makefile; }; QList<Build *> makefiles; void clearBuilds(); MakefileGenerator *processBuild(const QString &);public: BuildsMetaMakefileGenerator(QMakeProject *p, const QString &n, bool op) : MetaMakefileGenerator(p, n, op), init_flag(false) { } virtual ~BuildsMetaMakefileGenerator() { clearBuilds(); } virtual bool init(); virtual int type() const { return BUILDSMETATYPE; } virtual bool write(const QString &);};voidBuildsMetaMakefileGenerator::clearBuilds(){ for(int i = 0; i < makefiles.count(); i++) { Build *build = makefiles[i]; if(QMakeProject *p = build->makefile->projectFile()) { if(p != project) delete p; } delete build->makefile; delete build; } makefiles.clear();}boolBuildsMetaMakefileGenerator::init(){ if(init_flag) return false; init_flag = true; const QStringList &builds = project->variables()["BUILDS"]; bool use_single_build = builds.isEmpty(); if(builds.count() > 1 && Option::output.fileName() == "-") { use_single_build = true; warn_msg(WarnLogic, "Cannot direct to stdout when using multiple BUILDS."); } else if(0 && !use_single_build && project->first("TEMPLATE") == "subdirs") { use_single_build = true; warn_msg(WarnLogic, "Cannot specify multiple builds with TEMPLATE subdirs."); } if(!use_single_build) { for(int i = 0; i < builds.count(); i++) { QString build = builds[i]; MakefileGenerator *makefile = processBuild(build); if(!makefile) return false; if(!makefile->supportsMetaBuild()) { warn_msg(WarnLogic, "QMAKESPEC does not support multiple BUILDS."); clearBuilds(); use_single_build = true; break; } else { Build *b = new Build; b->name = name; if(builds.count() != 1) b->build += build; b->makefile = makefile; makefiles += b; } } } if(use_single_build) { Build *build = new Build; build->name = name; build->makefile = createMakefileGenerator(project, false); makefiles += build; } return true;}boolBuildsMetaMakefileGenerator::write(const QString &oldpwd){ Build *glue = 0; if(!makefiles.isEmpty() && !makefiles.first()->build.isNull()) { glue = new Build; glue->name = name; glue->makefile = createMakefileGenerator(project, true); makefiles += glue; } bool ret = true; const QString &output_name = Option::output.fileName(); for(int i = 0; ret && i < makefiles.count(); i++) { Option::output.setFileName(output_name); Build *build = makefiles[i]; bool using_stdout = false; if(build->makefile && (Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) && (!build->makefile->supportsMergedBuilds() || (build->makefile->supportsMergedBuilds() && (!glue || build == glue)))) { //open output if(!(Option::output.isOpen())) { if(Option::output.fileName() == "-") { Option::output.setFileName(""); Option::output_dir = qmake_getpwd(); Option::output.open(stdout, QIODevice::WriteOnly | QIODevice::Text); using_stdout = true; } else { if(Option::output.fileName().isEmpty() && Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE) Option::output.setFileName(project->first("QMAKE_MAKEFILE")); Option::output_dir = oldpwd; QString build_name = build->name; if(!build->build.isEmpty()) { if(!build_name.isEmpty()) build_name += "."; build_name += build->build; } if(!build->makefile->openOutput(Option::output, build_name)) { fprintf(stderr, "Failure to open file: %s\n", Option::output.fileName().isEmpty() ? "(stdout)" : Option::output.fileName().toLatin1().constData()); return false; } } } } else { using_stdout = true; //kind of.. } if(!build->makefile) { ret = false; } else if(build == glue) { ret = build->makefile->writeProjectMakefile(); } else { ret = build->makefile->write(); if (glue && glue->makefile->supportsMergedBuilds()) ret = glue->makefile->mergeBuildProject(build->makefile); } if(!using_stdout) { Option::output.close(); if(!ret) Option::output.remove(); } // debugging if(Option::debug_level) { QMap<QString, QStringList> &vars = project->variables(); for(QMap<QString, QStringList>::Iterator it = vars.begin(); it != vars.end(); ++it) { if(!it.key().startsWith(".") && !it.value().isEmpty()) debug_msg(1, "%s === %s", it.key().toLatin1().constData(), it.value().join(" :: ").toLatin1().constData()); } } } return ret;}MakefileGenerator*BuildsMetaMakefileGenerator::processBuild(const QString &build){ if(project) { debug_msg(1, "Meta Generator: Parsing '%s' for build [%s].", project->projectFile().toLatin1().constData(),build.toLatin1().constData()); //initialize the base QMap<QString, QStringList> basevars; if(!project->isEmpty(build + ".CONFIG")) basevars["CONFIG"] += project->values(build + ".CONFIG"); basevars["CONFIG"] += build; basevars["CONFIG"] += "build_pass"; basevars["BUILD_PASS"] = QStringList(build); QStringList buildname = project->values(build + ".name"); basevars["BUILD_NAME"] = (buildname.isEmpty() ? QStringList(build) : buildname); //create project QMakeProject *build_proj = new QMakeProject(project->properties(), basevars); //all the user configs must be set again afterwards (for .pro tests and for .prf tests) const QStringList old_after_user_config = Option::after_user_configs; const QStringList old_user_config = Option::user_configs; Option::after_user_configs += basevars["CONFIG"];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -