diff options
Diffstat (limited to 'qmake/generators')
29 files changed, 771 insertions, 1244 deletions
diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index c1c9336c92..d0d560aca9 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "pbuilder_pbx.h" #include "option.h" @@ -112,7 +87,7 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t) for(int pb_subdir = 0; pb_subdir < pb_subdirs.size(); ++pb_subdir) { ProjectBuilderSubDirs *pb = pb_subdirs[pb_subdir]; const ProStringList &subdirs = pb->project->values("SUBDIRS"); - for(int subdir = 0; subdir < subdirs.count(); subdir++) { + for(int subdir = 0; subdir < subdirs.size(); subdir++) { ProString tmpk = subdirs[subdir]; const ProKey fkey(tmpk + ".file"); if (!pb->project->isEmpty(fkey)) { @@ -354,7 +329,7 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t) t << "\t\t\tprojectReferences = (\n"; { const ProStringList &qmake_subdirs = project->values("QMAKE_PBX_SUBDIRS"); - for(int i = 0; i < qmake_subdirs.count(); i++) { + for(int i = 0; i < qmake_subdirs.size(); i++) { const ProString &subdir = qmake_subdirs[i]; t << "\t\t\t\t{\n" << "\t\t\t\t\t" << writeSettings("ProductGroup", keyFor(subdir + "_PRODUCTGROUP")) << ";\n" @@ -454,17 +429,17 @@ ProjectBuilderSources::files(QMakeProject *project) const static QString xcodeFiletypeForFilename(const QString &filename) { - for (const QString &ext : qAsConst(Option::cpp_ext)) { + for (const QString &ext : std::as_const(Option::cpp_ext)) { if (filename.endsWith(ext)) return QStringLiteral("sourcecode.cpp.cpp"); } - for (const QString &ext : qAsConst(Option::c_ext)) { + for (const QString &ext : std::as_const(Option::c_ext)) { if (filename.endsWith(ext)) return QStringLiteral("sourcecode.c.c"); } - for (const QString &ext : qAsConst(Option::h_ext)) { + for (const QString &ext : std::as_const(Option::h_ext)) { if (filename.endsWith(ext)) return "sourcecode.c.h"; } @@ -549,14 +524,14 @@ bool ProjectBuilderMakefileGenerator::replaceLibrarySuffix(const QString &lib_fi warn_msg(WarnLogic, "Failed to find expected suffix '%s' for library '%s'.", qPrintable(librarySuffix), qPrintable(library)); } else { - library.replace(pos, librarySuffix.length(), suffixSetting); + library.replace(pos, librarySuffix.size(), suffixSetting); if (name.endsWith(librarySuffix)) - name.chop(librarySuffix.length()); + name.chop(librarySuffix.size()); } } else { int pos = library.lastIndexOf(name); if (pos != -1) - library.insert(pos + name.length(), suffixSetting); + library.insert(pos + name.size(), suffixSetting); } } } @@ -683,7 +658,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) const QStringList &files = fileFixify(sources.at(source).files(project), FileFixifyFromOutdir | FileFixifyAbsolute); - for(int f = 0; f < files.count(); ++f) { + for(int f = 0; f < files.size(); ++f) { QString file = files[f]; if(!sources.at(source).compilerName().isNull() && !verifyExtraCompiler(sources.at(source).compilerName(), file)) @@ -873,6 +848,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t" << writeSettings("shellScript", "make -C " + IoUtils::shellQuoteUnix(Option::output_dir) + " -f " + IoUtils::shellQuoteUnix(mkfile)) << ";\n" << "\t\t\t" << writeSettings("showEnvVarsInLog", "0") << ";\n" + << "\t\t\t" << writeSettings("alwaysOutOfDate", "1") << ";\n" << "\t\t};\n"; } @@ -897,7 +873,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", nullptr }; for (int i = 0; libs[i]; i++) { tmp = project->values(libs[i]); - for(int x = 0; x < tmp.count();) { + for(int x = 0; x < tmp.size();) { bool libSuffixReplaced = false; bool remove = false; QString library, name; @@ -936,7 +912,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) if(opt.size() > 2) { r = opt.mid(2).toQString(); } else { - if(x == tmp.count()-1) + if(x == tmp.size()-1) break; r = tmp[++x].toQString(); } @@ -945,12 +921,12 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) frameworkdirs.append(r); } } else if(opt == "-framework") { - if(x == tmp.count()-1) + if(x == tmp.size()-1) break; const ProString &framework = tmp[x+1]; ProStringList fdirs = frameworkdirs; fdirs << "/System/Library/Frameworks/" << "/Library/Frameworks/"; - for(int fdir = 0; fdir < fdirs.count(); fdir++) { + for(int fdir = 0; fdir < fdirs.size(); fdir++) { if(exists(fdirs[fdir] + QDir::separator() + framework + ".framework")) { remove = true; library = fdirs[fdir] + Option::dir_sep + framework + ".framework"; @@ -979,7 +955,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) const int slsh = library.lastIndexOf(Option::dir_sep); if(name.isEmpty()) { if(slsh != -1) - name = library.right(library.length() - slsh - 1); + name = library.right(library.size() - slsh - 1); } if(slsh != -1) { const QString path = QFileInfo(library.left(slsh)).absoluteFilePath(); @@ -1032,12 +1008,12 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) mkt << "SUBLIBS= "; // ### This is missing the parametrization found in unixmake2.cpp tmp = project->values("SUBLIBS"); - for(int i = 0; i < tmp.count(); i++) + for(int i = 0; i < tmp.size(); i++) t << escapeFilePath("tmp/lib" + tmp[i] + ".a") << ' '; t << Qt::endl << Qt::endl; mkt << "sublibs: $(SUBLIBS)\n\n"; tmp = project->values("SUBLIBS"); - for(int i = 0; i < tmp.count(); i++) + for(int i = 0; i < tmp.size(); i++) t << escapeFilePath("tmp/lib" + tmp[i] + ".a") + ":\n\t" << var(ProKey("MAKELIB" + tmp[i])) << Qt::endl << Qt::endl; mkt.flush(); @@ -1172,7 +1148,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) //all bundle data const ProStringList &bundle_data = project->values("QMAKE_BUNDLE_DATA"); - for(int i = 0; i < bundle_data.count(); i++) { + for(int i = 0; i < bundle_data.size(); i++) { ProStringList bundle_files; ProString path = project->first(ProKey(bundle_data[i] + ".path")); const bool isEmbeddedFramework = ((!osx && path == QLatin1String("Frameworks")) @@ -1182,7 +1158,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) //all files const ProStringList &files = project->values(ProKey(bundle_data[i] + ".files")); - for(int file = 0; file < files.count(); file++) { + for(int file = 0; file < files.size(); file++) { QString fn = fileFixify(files[file].toQString(), FileFixifyAbsolute); QString name = fn.split(Option::dir_sep).back(); QString file_ref_key = keyFor("QMAKE_PBX_BUNDLE_DATA_FILE_REF." + bundle_data[i] + "-" + fn); @@ -1205,13 +1181,13 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) if (copyBundleResources && ((!osx && path.isEmpty()) || (osx && path == QLatin1String("Contents/Resources")))) { - for (const ProString &s : qAsConst(bundle_files)) + for (const ProString &s : std::as_const(bundle_files)) bundle_resources_files << s; } else if (copyBundleResources && isEmbeddedFramework) { - for (const ProString &s : qAsConst(bundle_files)) + for (const ProString &s : std::as_const(bundle_files)) embedded_frameworks << s; } else if (copyBundleResources && isEmbeddedPlugin) { - for (const ProString &s : qAsConst(bundle_files)) { + for (const ProString &s : std::as_const(bundle_files)) { ProString subpath = (path == pluginsPrefix) ? ProString() : path.mid(pluginsPrefix.size() + 1); embedded_plugins[subpath] << s; } @@ -1708,7 +1684,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) t << "\t\t\t\t" << writeSettings("CODE_SIGN_IDENTITY", project->first("QMAKE_XCODE_CODE_SIGN_IDENTITY")) << ";\n"; tmp = project->values("QMAKE_PBX_VARS"); - for (int i = 0; i < tmp.count(); i++) { + for (int i = 0; i < tmp.size(); i++) { QString var = tmp[i].toQString(), val = QString::fromLocal8Bit(qgetenv(var.toLatin1().constData())); if (val.isEmpty() && var == "TB") val = "/usr/bin/"; @@ -1912,7 +1888,7 @@ ProStringList ProjectBuilderMakefileGenerator::fixListForOutput(const ProStringList &l) { ProStringList ret; - for(int i = 0; i < l.count(); i++) + for(int i = 0; i < l.size(); i++) ret += fixForOutput(l[i].toQString()); return ret; } @@ -1994,14 +1970,14 @@ ProjectBuilderMakefileGenerator::pbxbuild() static QString quotedStringLiteral(const QString &value) { QString result; - const int len = value.length(); + const int len = value.size(); result.reserve(int(len * 1.1) + 2); result += QLatin1Char('"'); // Escape for (int i = 0; i < len; ++i) { - QChar character = value.at(i);; + QChar character = value.at(i); ushort code = character.unicode(); switch (code) { case '\\': @@ -2073,4 +2049,10 @@ ProjectBuilderMakefileGenerator::writeSettings(const QString &var, const ProStri return ret; } +bool +ProjectBuilderMakefileGenerator::inhibitMakeDirOutPath(const ProKey &path) const +{ + return path == "OBJECTS_DIR"; +} + QT_END_NAMESPACE diff --git a/qmake/generators/mac/pbuilder_pbx.h b/qmake/generators/mac/pbuilder_pbx.h index 9b85764caa..681544971a 100644 --- a/qmake/generators/mac/pbuilder_pbx.h +++ b/qmake/generators/mac/pbuilder_pbx.h @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef PBUILDER_PBX_H #define PBUILDER_PBX_H @@ -66,6 +41,7 @@ public: protected: bool doPrecompiledHeaders() const override { return false; } bool doDepends() const override { return writingUnixMakefileGenerator && UnixMakefileGenerator::doDepends(); } + bool inhibitMakeDirOutPath(const ProKey &path) const override; }; QT_END_NAMESPACE diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 41525c5778..482ef2e269 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "makefile.h" #include "option.h" @@ -41,6 +16,7 @@ #include <qdebug.h> #include <qbuffer.h> #include <qdatetime.h> +#include <qtversion.h> #if defined(Q_OS_UNIX) #include <unistd.h> @@ -63,7 +39,7 @@ using namespace QMakeInternal; bool MakefileGenerator::canExecute(const QStringList &cmdline, int *a) const { int argv0 = -1; - for(int i = 0; i < cmdline.count(); ++i) { + for(int i = 0; i < cmdline.size(); ++i) { if(!cmdline.at(i).contains('=')) { argv0 = i; break; @@ -137,7 +113,7 @@ MakefileGenerator::initOutPaths() if(!fi.makeAbsolute()) { QString cache_r = fi.path(), pwd = Option::output_dir; if(pwd.startsWith(cache_r) && !pwd.startsWith(root)) { - pwd = root + pwd.mid(cache_r.length()); + pwd = root + pwd.mid(cache_r.size()); if(exists(pwd)) v.insert("QMAKE_ABSOLUTE_SOURCE_PATH", ProStringList(pwd)); } @@ -173,6 +149,9 @@ MakefileGenerator::initOutPaths() if (noIO() || (project->first("TEMPLATE") == "subdirs")) continue; + if (inhibitMakeDirOutPath(dkey)) + continue; + QString path = project->first(dkey).toQString(); //not to be changed any further path = fileFixify(path, FileFixifyBackwards); debug_msg(3, "Fixed output_dir %s (%s) into %s", dirs[x], @@ -216,6 +195,18 @@ MakefileGenerator::initOutPaths() } } +/* + * For the given directory path, return true if MakefileGenerator::initOutPaths() should inhibit the + * creation of the directory. Overload this in subclasses. + */ +bool +MakefileGenerator::inhibitMakeDirOutPath(const ProKey &path) const +{ + Q_UNUSED(path); + return false; +} + + QMakeProject *MakefileGenerator::projectFile() const { @@ -247,7 +238,7 @@ MakefileGenerator::findFilesInVPATH(ProStringList l, uchar flags, const QString { ProStringList vpath; const ProValueMap &v = project->variables(); - for(int val_it = 0; val_it < l.count(); ) { + for(int val_it = 0; val_it < l.size(); ) { bool remove_file = false; ProString &val = l[val_it]; if(!val.isEmpty()) { @@ -297,23 +288,23 @@ MakefileGenerator::findFilesInVPATH(ProStringList l, uchar flags, const QString real_dir = dir; if(!(flags & VPATH_NoFixify)) real_dir = fileFixify(real_dir, FileFixifyBackwards) + '/'; - regex.remove(0, dir.length()); + regex.remove(0, dir.size()); } if(real_dir.isEmpty() || exists(real_dir)) { QStringList files = QDir(real_dir).entryList(QStringList(regex), QDir::NoDotAndDotDot | QDir::AllEntries); if(files.isEmpty()) { - debug_msg(1, "%s:%d Failure to find %s in vpath (%s)", - __FILE__, __LINE__, val.toLatin1().constData(), + debug_msg(1, "makefile.cpp:%d Failure to find %s in vpath (%s)", + __LINE__, val.toLatin1().constData(), vpath.join(QString("::")).toLatin1().constData()); - if(flags & VPATH_RemoveMissingFiles) + if (flags & VPATH_RemoveMissingFiles) remove_file = true; - else if(flags & VPATH_WarnMissingFiles) + if (flags & VPATH_WarnMissingFiles) warn_msg(WarnLogic, "Failure to find: %s", val.toLatin1().constData()); } else { l.removeAt(val_it); QString a; - for(int i = (int)files.count()-1; i >= 0; i--) { + for(int i = (int)files.size()-1; i >= 0; i--) { a = real_dir + files[i]; if(!(flags & VPATH_NoFixify)) a = fileFixify(a); @@ -321,12 +312,12 @@ MakefileGenerator::findFilesInVPATH(ProStringList l, uchar flags, const QString } } } else { - debug_msg(1, "%s:%d Cannot match %s%s, as %s does not exist.", - __FILE__, __LINE__, real_dir.toLatin1().constData(), + debug_msg(1, "makefile.cpp:%d Cannot match %s%s, as %s does not exist.", + __LINE__, real_dir.toLatin1().constData(), regex.toLatin1().constData(), real_dir.toLatin1().constData()); - if(flags & VPATH_RemoveMissingFiles) + if (flags & VPATH_RemoveMissingFiles) remove_file = true; - else if(flags & VPATH_WarnMissingFiles) + if (flags & VPATH_WarnMissingFiles) warn_msg(WarnLogic, "Failure to find: %s", val.toLatin1().constData()); } } @@ -347,9 +338,14 @@ MakefileGenerator::initCompiler(const MakefileGenerator::Compiler &comp) // find all the relevant file inputs if(!init_compiler_already.contains(comp.variable_in)) { init_compiler_already.insert(comp.variable_in, true); - if(!noIO()) - l = findFilesInVPATH(l, (comp.flags & Compiler::CompilerRemoveNoExist) ? - VPATH_RemoveMissingFiles : VPATH_WarnMissingFiles, "VPATH_" + comp.variable_in); + if(!noIO()) { + uchar flags = 0; + if (comp.flags & Compiler::CompilerRemoveNoExist) + flags |= VPATH_RemoveMissingFiles; + if (comp.flags & Compiler::CompilerWarnNoExist) + flags |= VPATH_WarnMissingFiles; + l = findFilesInVPATH(l, flags, "VPATH_" + comp.variable_in); + } } } @@ -477,12 +473,12 @@ MakefileGenerator::init() continue; } const ProStringList &tinn = v[innkey], &toutn = v[outnkey]; - if (tinn.length() != 1) { + if (tinn.size() != 1) { warn_msg(WarnLogic, "Substitute '%s.input' does not have exactly one value", sub.toLatin1().constData()); continue; } - if (toutn.length() != 1) { + if (toutn.size() != 1) { warn_msg(WarnLogic, "Substitute '%s.output' does not have exactly one value", sub.toLatin1().constData()); continue; @@ -500,7 +496,7 @@ MakefileGenerator::init() inn.toLatin1().constData()); continue; } - outn = fileFixify(inn.left(inn.length() - 3), FileFixifyBackwards); + outn = fileFixify(inn.left(inn.size() - 3), FileFixifyBackwards); } const ProKey confign(sub + ".CONFIG"); @@ -521,7 +517,7 @@ MakefileGenerator::init() QString line = QString::fromLatin1(in.readLine()); if (line.startsWith("!!IF ")) { if (state.isEmpty() || state.top() == IN_CONDITION) { - QString test = line.mid(5, line.length()-(5+1)); + QString test = line.mid(5, line.size()-(5+1)); if (project->test(test, inn, count)) state.push(IN_CONDITION); else @@ -534,7 +530,7 @@ MakefileGenerator::init() warn_msg(WarnLogic, "(%s:%d): Unexpected else condition", in.fileName().toLatin1().constData(), count); } else if (state.top() == PENDING_CONDITION) { - QString test = line.mid(7, line.length()-(7+1)); + QString test = line.mid(7, line.size()-(7+1)); if (project->test(test, inn, count)) { state.pop(); state.push(IN_CONDITION); @@ -622,6 +618,10 @@ MakefileGenerator::init() const ProStringList &config = v[ProKey(*it + ".CONFIG")]; if (config.indexOf("ignore_no_exist") != -1) compiler.flags |= Compiler::CompilerRemoveNoExist; + else + compiler.flags |= Compiler::CompilerWarnNoExist; + if (config.indexOf("remove_no_exist") != -1) + compiler.flags |= Compiler::CompilerRemoveNoExist; if (config.indexOf("no_dependencies") != -1) compiler.flags |= Compiler::CompilerNoCheckDeps; if (config.indexOf("add_inputs_as_makefile_deps") != -1) @@ -643,12 +643,12 @@ MakefileGenerator::init() } { //do the path fixifying ProStringList paths; - for(x = 0; x < compilers.count(); ++x) { + for(x = 0; x < compilers.size(); ++x) { if(!paths.contains(compilers.at(x).variable_in)) paths << compilers.at(x).variable_in; } paths << "INCLUDEPATH" << "QMAKE_INTERNAL_INCLUDED_FILES" << "PRECOMPILED_HEADER"; - for(int y = 0; y < paths.count(); y++) { + for(int y = 0; y < paths.size(); y++) { ProStringList &l = v[paths[y].toKey()]; for (ProStringList::Iterator it = l.begin(); it != l.end(); ++it) { if((*it).isEmpty()) @@ -662,7 +662,7 @@ MakefileGenerator::init() if(noIO() || !doDepends() || project->isActiveConfig("GNUmake")) QMakeSourceFileInfo::setDependencyMode(QMakeSourceFileInfo::NonRecursive); - for(x = 0; x < compilers.count(); ++x) + for(x = 0; x < compilers.size(); ++x) initCompiler(compilers.at(x)); //merge actual compiler outputs into their variable_out. This is done last so that @@ -773,7 +773,7 @@ MakefileGenerator::init() incDirs.join(QString(" :: ")).toLatin1().constData()); //add to dependency engine - for(x = 0; x < compilers.count(); ++x) { + for(x = 0; x < compilers.size(); ++x) { const MakefileGenerator::Compiler &comp = compilers.at(x); if(!(comp.flags & Compiler::CompilerNoCheckDeps)) { const ProKey ikey(comp.variable_in); @@ -829,14 +829,14 @@ MakefileGenerator::init() QString dir, regex = Option::normalizePath(dep); if (regex.lastIndexOf('/') != -1) { dir = regex.left(regex.lastIndexOf('/') + 1); - regex.remove(0, dir.length()); + regex.remove(0, dir.size()); } QStringList files = QDir(dir).entryList(QStringList(regex)); if(files.isEmpty()) { warn_msg(WarnLogic, "Dependency for [%s]: Not found %s", (*file_it).toLatin1().constData(), dep.toLatin1().constData()); } else { - for(int i = 0; i < files.count(); i++) + for(int i = 0; i < files.size(); i++) out_deps.append(dir + files[i]); } } @@ -1040,7 +1040,7 @@ MakefileGenerator::writeProjectMakefile() //install t << "install: "; - for (SubTarget *s : qAsConst(targets)) + for (SubTarget *s : std::as_const(targets)) t << s->target << '-'; t << "install " << Qt::endl; @@ -1182,7 +1182,7 @@ QString MakefileGenerator::filePrefixRoot(const QString &root, const QString &path) { QString ret(path); - if(path.length() > 2 && path[1] == ':') //c:\foo + if(path.size() > 2 && path[1] == ':') //c:\foo ret.insert(2, root); else ret.prepend(root); @@ -1258,14 +1258,14 @@ MakefileGenerator::writeInstalls(QTextStream &t, bool noBuild) qPrintable(wild), qPrintable((*it).toQString()), qPrintable(base_path)); } else { - QString dir_sfx = dirstr.mid(base_path.length()); + QString dir_sfx = dirstr.mid(base_path.size()); dst_dir += dir_sfx; if (!dir_sfx.isEmpty() && !made_dirs.contains(dir_sfx)) { made_dirs.insert(dir_sfx); QString tmp_dst = fileFixify(dst_dir, FileFixifyAbsolute, false); tmp_dst.chop(1); inst << mkdir_p_asstring(filePrefixRoot(root, tmp_dst)); - for (int i = dst.length(); i < dst_dir.length(); i++) { + for (int i = dst.size(); i < dst_dir.size(); i++) { if (dst_dir.at(i) == Option::dir_sep) { QString subd = dst_dir.left(i); if (!removed_dirs.contains(subd)) { @@ -1325,7 +1325,7 @@ MakefileGenerator::writeInstalls(QTextStream &t, bool noBuild) inst << cmd; uninst.append(rm_dir_contents + " " + escapeFilePath(filePrefixRoot(root, fileFixify(dst_dir + filestr, FileFixifyAbsolute, false)))); } - for(int x = 0; x < files.count(); x++) { + for(int x = 0; x < files.size(); x++) { QString file = files[x]; uninst.append(rm_dir_contents + " " + escapeFilePath(filePrefixRoot(root, fileFixify(dst_dir + file, FileFixifyAbsolute, false)))); QFileInfo fi(fileInfo(dirstr + file)); @@ -1625,7 +1625,7 @@ MakefileGenerator::replaceExtraCompilerVariables( QFileInfo fi(fileInfo(Option::normalizePath(in.at(i)))); QString ext; // Ensure complementarity with QMAKE_FILE_BASE - int baseLen = fi.completeBaseName().length(); + int baseLen = fi.completeBaseName().size(); if(baseLen == 0) ext = fi.fileName(); else @@ -1691,7 +1691,7 @@ MakefileGenerator::replaceExtraCompilerVariables( fullVal = val.join(' '); } ret.replace(match.capturedStart(), match.capturedLength(), fullVal); - rep += fullVal.length(); + rep += fullVal.size(); } else { rep = match.capturedEnd(); } @@ -1892,7 +1892,7 @@ void MakefileGenerator::callExtraCompilerDependCommand(const ProString &extraCom return; QDir outDir(Option::output_dir); QStringList dep_cmd_deps = splitDeps(indeps, dep_lines); - for (int i = 0; i < dep_cmd_deps.count(); ++i) { + for (int i = 0; i < dep_cmd_deps.size(); ++i) { QString &file = dep_cmd_deps[i]; const QString absFile = outDir.absoluteFilePath(file); if (absFile == file) { @@ -1970,7 +1970,7 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) if (raw_clean.isEmpty()) raw_clean << tmp_out; QString tmp_clean; - for (const QString &rc : qAsConst(raw_clean)) + for (const QString &rc : std::as_const(raw_clean)) tmp_clean += ' ' + escapeFilePath(Option::fixPathToTargetOS(rc)); QString tmp_clean_cmds = project->values(ProKey(*it + ".clean_commands")).join(' '); if(!tmp_inputs.isEmpty()) @@ -1995,7 +1995,7 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) for (ProStringList::ConstIterator input = tmp_inputs.cbegin(); input != tmp_inputs.cend(); ++input) { QString tinp = (*input).toQString(); QString out = replaceExtraCompilerVariables(tmp_out, tinp, QString(), NoShell); - for (const QString &rc : qAsConst(raw_clean)) { + for (const QString &rc : std::as_const(raw_clean)) { dels << ' ' + escapeFilePath(fileFixify( replaceExtraCompilerVariables(rc, tinp, out, NoShell), FileFixifyFromOutdir)); @@ -2006,9 +2006,9 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) } else { QString files; const int commandlineLimit = 2047; // NT limit, expanded - for (const QString &file : qAsConst(dels)) { - if(del_statement.length() + files.length() + - qMax(fixEnvVariables(file).length(), file.length()) > commandlineLimit) { + for (const QString &file : std::as_const(dels)) { + if(del_statement.size() + files.size() + + qMax(fixEnvVariables(file).size(), file.size()) > commandlineLimit) { cleans.append(files); files.clear(); } @@ -2228,6 +2228,7 @@ MakefileGenerator::writeDummyMakefile(QTextStream &t) << "@echo \"Skipped.\"\n\n"; writeMakeQmake(t); t << "FORCE:\n\n"; + suppressBuiltinRules(t); return true; } @@ -2242,6 +2243,7 @@ MakefileGenerator::writeMakefile(QTextStream &t) writeInstalls(t); t << "FORCE:\n\n"; + suppressBuiltinRules(t); return true; } @@ -2270,11 +2272,11 @@ QString MakefileGenerator::buildArgs(bool withExtra) { QString ret; - for (const QString &arg : qAsConst(Option::globals->qmake_args)) + for (const QString &arg : std::as_const(Option::globals->qmake_args)) ret += " " + shellQuote(arg); if (withExtra && !Option::globals->qmake_extra_args.isEmpty()) { ret += " --"; - for (const QString &arg : qAsConst(Option::globals->qmake_extra_args)) + for (const QString &arg : std::as_const(Option::globals->qmake_extra_args)) ret += " " + shellQuote(arg); } return ret; @@ -2389,7 +2391,7 @@ MakefileGenerator::findSubDirsSubTargets() const if(new_slsh != -1) basename = basename.mid(new_slsh+1); if(st->profile != basename + Option::pro_ext) - st->makefile += "." + st->profile.left(st->profile.length() - Option::pro_ext.length()); + st->makefile += "." + st->profile.left(st->profile.size() - Option::pro_ext.size()); } } const ProKey dkey(fixedSubdir + ".depends"); @@ -2528,7 +2530,7 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT if(!out_directory.isEmpty() && !out_directory.endsWith(Option::dir_sep)) out_directory += Option::dir_sep; if(!abs_source_path.isEmpty() && out_directory.startsWith(abs_source_path)) - out_directory = Option::output_dir + out_directory.mid(abs_source_path.length()); + out_directory = Option::output_dir + out_directory.mid(abs_source_path.size()); QString out_directory_cdin = out_directory.isEmpty() ? QString("\n\t") : "\n\tcd " + escapeFilePath(out_directory) + " && "; @@ -2541,7 +2543,7 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT out = subtarget->makefile; in = escapeFilePath(fileFixify(in_directory + subtarget->profile, FileFixifyAbsolute)); if(out.startsWith(in_directory)) - out = out.mid(in_directory.length()); + out = out.mid(in_directory.size()); out = escapeFilePath(out); t << subtarget->target << "-qmake_all: "; if (flags & SubTargetOrdered) { @@ -2706,7 +2708,7 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT if(!out_directory.isEmpty() && !out_directory.endsWith(Option::dir_sep)) out_directory += Option::dir_sep; if(!abs_source_path.isEmpty() && out_directory.startsWith(abs_source_path)) - out_directory = Option::output_dir + out_directory.mid(abs_source_path.length()); + out_directory = Option::output_dir + out_directory.mid(abs_source_path.size()); if(!recurse.contains(subtarget->name)) continue; @@ -2721,7 +2723,7 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT out = subtarget->makefile; in = escapeFilePath(fileFixify(in_directory + subtarget->profile, FileFixifyAbsolute)); if (out.startsWith(in_directory)) - out = out.mid(in_directory.length()); + out = out.mid(in_directory.size()); out = escapeFilePath(out); } @@ -2763,6 +2765,13 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT writeInstalls(t, true); } t << "FORCE:\n\n"; + suppressBuiltinRules(t); +} + +void +MakefileGenerator::suppressBuiltinRules(QTextStream &t) const +{ + t << ".SUFFIXES:\n\n"; } void @@ -2811,7 +2820,7 @@ MakefileGenerator::writeMakeQmake(QTextStream &t, bool noDummyQmakeAll) QFileInfo MakefileGenerator::fileInfo(QString file) const { - static QHash<FileInfoCacheKey, QFileInfo> *cache = nullptr; + Q_CONSTINIT static QHash<FileInfoCacheKey, QFileInfo> *cache = nullptr; static QFileInfo noInfo = QFileInfo(); if(!cache) { cache = new QHash<FileInfoCacheKey, QFileInfo>; @@ -2850,7 +2859,7 @@ MakefileGenerator::fixLibFlags(const ProKey &var) const ProStringList &in = project->values(var); ProStringList ret; - ret.reserve(in.length()); + ret.reserve(in.size()); for (const ProString &v : in) ret << fixLibFlag(v); return ret; @@ -3016,7 +3025,7 @@ MakefileGenerator::fileFixify(const QString &file, FileFixifyTypes fix, bool can if(ret == match_dir) { ret = ""; } else if(ret.startsWith(match_dir + Option::dir_sep)) { - ret = ret.mid(match_dir.length() + Option::dir_sep.length()); + ret = ret.mid(match_dir.size() + Option::dir_sep.size()); } else { //figure out the depth int depth = 4; @@ -3038,7 +3047,7 @@ MakefileGenerator::fileFixify(const QString &file, FileFixifyTypes fix, bool can break; if(ret.startsWith(match_dir + Option::dir_sep)) { //concat - int remlen = ret.length() - (match_dir.length() + 1); + int remlen = ret.size() - (match_dir.size() + 1); if(remlen < 0) remlen = 0; ret = ret.right(remlen); @@ -3112,12 +3121,12 @@ MakefileGenerator::findFileForDep(const QMakeLocalFileName &dep, const QMakeLoca QList<QMakeLocalFileName> depdirs = QMakeSourceFileInfo::dependencyPaths(); depdirs.prepend(fileInfo(file.real()).absoluteDir().path()); QString pwd = qmake_getpwd(); - if(pwd.at(pwd.length()-1) != '/') + if(pwd.at(pwd.size()-1) != '/') pwd += '/'; - for(int i = 0; i < depdirs.count(); i++) { + for(int i = 0; i < depdirs.size(); i++) { QString dir = depdirs.at(i).real(); if(!QDir::isRelativePath(dir) && dir.startsWith(pwd)) - dir = dir.mid(pwd.length()); + dir = dir.mid(pwd.size()); if(QDir::isRelativePath(dir)) { if(!dir.endsWith(Option::dir_sep)) dir += Option::dir_sep; @@ -3233,7 +3242,7 @@ MakefileGenerator::pkgConfigFileName(bool fixify) ret = project->first("TARGET").toQString(); int slsh = ret.lastIndexOf(Option::dir_sep); if (slsh != -1) - ret = ret.right(ret.length() - slsh - 1); + ret = ret.right(ret.size() - slsh - 1); if (ret.startsWith("lib")) ret = ret.mid(3); int dot = ret.indexOf('.'); @@ -3477,20 +3486,26 @@ ProKey MakefileGenerator::fullTargetVariable() const return "TARGET"; } +/* + * Create a response file and return its file name. + */ QString MakefileGenerator::createResponseFile( const QString &baseName, const ProStringList &objList, - const QString &prefix) + const QString &prefix) const { - QString fileName = baseName + '.' + fileVar("QMAKE_ORIG_TARGET"); + QString fileName = baseName + '.' + var("QMAKE_ORIG_TARGET"); if (!var("BUILD_NAME").isEmpty()) fileName += '.' + var("BUILD_NAME"); if (!var("MAKEFILE").isEmpty()) fileName += '.' + var("MAKEFILE"); QString filePath = Option::output_dir + QDir::separator() + fileName; QFile file(filePath); - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) - return QString(); + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { + fprintf(stderr, "Error: Cannot open response file '%s' for writing.\n", + qPrintable(filePath)); + exit(1); + } QTextStream t(&file); for (ProStringList::ConstIterator it = objList.constBegin(); it != objList.constEnd(); ++it) { QString path = (*it).toQString(); @@ -3510,4 +3525,46 @@ QString MakefileGenerator::createResponseFile( return fileName; } +/* + * If the threshold for response files are overstepped, create a response file for the linker + * command line. + */ +MakefileGenerator::LinkerResponseFileInfo MakefileGenerator::maybeCreateLinkerResponseFile() const +{ + bool useLinkObjectMax = false; + bool ok; + int threshold = project->first("QMAKE_RESPONSEFILE_THRESHOLD").toInt(&ok); + if (!ok) { + threshold = project->first("QMAKE_LINK_OBJECT_MAX").toInt(&ok); + if (ok) + useLinkObjectMax = true; + } + if (!ok) + return {}; + + ProStringList linkerInputs = project->values("OBJECTS"); + if (useLinkObjectMax) { + // When using QMAKE_LINK_OBJECT_MAX, the number of object files (regardless of their path + // length) decides whether to use a response file. This is far from being a useful + // heuristic but let's keep this behavior for backwards compatibility. + if (linkerInputs.size() < threshold) + return {}; + } else { + // When using QMAKE_REPONSEFILE_THRESHOLD, try to determine the command line length of the + // inputs. + linkerInputs += project->values("LIBS"); + int totalLength = std::accumulate(linkerInputs.cbegin(), linkerInputs.cend(), 0, + [](int total, const ProString &input) { + return total + input.size() + 1; + }); + if (totalLength < threshold) + return {}; + } + + return { + createResponseFile(fileVar("OBJECTS_DIR") + var("QMAKE_LINK_OBJECT_SCRIPT"), linkerInputs), + useLinkObjectMax + }; +} + QT_END_NAMESPACE diff --git a/qmake/generators/makefile.h b/qmake/generators/makefile.h index 720599fd96..6ab4ad505d 100644 --- a/qmake/generators/makefile.h +++ b/qmake/generators/makefile.h @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef MAKEFILE_H #define MAKEFILE_H @@ -121,6 +96,7 @@ protected: void writeSubTargetCall(QTextStream &t, const QString &in_directory, const QString &in, const QString &out_directory, const QString &out, const QString &out_directory_cdin, const QString &makefilein); + virtual void suppressBuiltinRules(QTextStream &t) const; virtual void writeSubMakeCall(QTextStream &t, const QString &outDirectory_cdin, const QString &makeFileIn); virtual void writeSubTargets(QTextStream &t, QList<SubTarget*> subtargets, int flags); @@ -160,6 +136,7 @@ protected: void verifyCompilers(); virtual void init(); void initOutPaths(); + virtual bool inhibitMakeDirOutPath(const ProKey &path) const; struct Compiler { QString variable_in; @@ -168,7 +145,8 @@ protected: CompilerBuiltin = 0x01, CompilerNoCheckDeps = 0x02, CompilerRemoveNoExist = 0x04, - CompilerAddInputsAsMakefileDeps = 0x08 + CompilerWarnNoExist = 0x08, + CompilerAddInputsAsMakefileDeps = 0x10 }; uint flags, type; }; @@ -265,7 +243,17 @@ protected: const QString &fixedFile); QString createResponseFile(const QString &baseName, const ProStringList &objList, - const QString &prefix = QString()); + const QString &prefix = QString()) const; + + struct LinkerResponseFileInfo + { + QString filePath; + bool onlyObjects; + + bool isValid() const { return !filePath.isEmpty(); } + }; + + LinkerResponseFileInfo maybeCreateLinkerResponseFile() const; public: QMakeProject *projectFile() const; diff --git a/qmake/generators/makefiledeps.cpp b/qmake/generators/makefiledeps.cpp index f1b1e4b216..8e8d42cc96 100644 --- a/qmake/generators/makefiledeps.cpp +++ b/qmake/generators/makefiledeps.cpp @@ -1,34 +1,10 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2016 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "makefiledeps.h" #include "option.h" +#include <qfile.h> #include <qdir.h> #include <qdatetime.h> #include <qfileinfo.h> @@ -40,16 +16,8 @@ # 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> #include <limits.h> -#if defined(_MSC_VER) && _MSC_VER >= 1400 -#include <share.h> -#endif QT_BEGIN_NAMESPACE @@ -196,7 +164,7 @@ void QMakeSourceFileInfo::setDependencyPaths(const QList<QMakeLocalFileName> &l) { // Ensure that depdirs does not contain the same paths several times, to minimize the stats QList<QMakeLocalFileName> ll; - for (int i = 0; i < l.count(); ++i) { + for (int i = 0; i < l.size(); ++i) { if (!ll.contains(l.at(i))) ll.append(l.at(i)); } @@ -397,13 +365,21 @@ static bool matchWhileUnsplitting(const char *buffer, int buffer_len, int start, return true; } -/* Advance from an opening quote at buffer[offset] to the matching close quote. */ +/* Advance from an opening quote at buffer[offset] to the matching close quote. + If an apostrophe turns out to be a digit-separator in a numeric literal, + rather than the start of a character literal, treat it as both the open and + the close quote of the "string" that isn't there. +*/ static int scanPastString(char *buffer, int buffer_len, int offset, int *lines) { // http://en.cppreference.com/w/cpp/language/string_literal // It might be a C++11 raw string. bool israw = false; - if (buffer[offset] == '"' && offset > 0) { + + Q_ASSERT(offset < buffer_len); + if (offset <= 0) { + // skip, neither of these special cases applies here + } else if (buffer[offset] == '"') { int explore = offset - 1; bool prefix = false; // One of L, U, u or u8 may appear before R bool saw8 = false; // Partial scan of u8 @@ -447,6 +423,19 @@ static int scanPastString(char *buffer, int buffer_len, int offset, int *lines) && (isalnum(buffer[explore]) || buffer[explore] == '_')) { israw = false; } + + } else { + // Is this apostrophe a digit separator rather than the start of a + // character literal ? If so, there was no string to scan past, so + // treat the apostrophe as both open and close. + Q_ASSERT(buffer[offset] == '\'' && offset > 0); + // Wrap std::isdigit() to package the casting to unsigned char. + const auto isDigit = [](unsigned char c) { return std::isdigit(c); }; + if (isDigit(buffer[offset - 1]) && offset + 1 < buffer_len && isDigit(buffer[offset + 1])) { + // One exception: u8'0' is a perfectly good character literal. + if (offset < 2 || buffer[offset - 1] != '8' || buffer[offset - 2] != 'u') + return offset; + } } if (israw) { @@ -515,28 +504,17 @@ bool QMakeSourceFileInfo::findDeps(SourceFile *file) const QMakeLocalFileName sourceFile = fixPathForFile(file->file, true); - struct stat fst; char *buffer = nullptr; int buffer_len = 0; { - int fd; -#if defined(_MSC_VER) && _MSC_VER >= 1400 - if (_sopen_s(&fd, sourceFile.local().toLatin1().constData(), - _O_RDONLY, _SH_DENYNO, _S_IREAD) != 0) - fd = -1; -#else - fd = open(sourceFile.local().toLatin1().constData(), O_RDONLY); -#endif - if (fd == -1 || fstat(fd, &fst) || S_ISDIR(fst.st_mode)) { - if (fd != -1) - QT_CLOSE(fd); + QFile f(sourceFile.local()); + if (!f.open(QIODevice::ReadOnly)) return false; - } - buffer = getBuffer(fst.st_size); + const qint64 fs = f.size(); + buffer = getBuffer(fs); for(int have_read = 0; - (have_read = QT_READ(fd, buffer + buffer_len, fst.st_size - buffer_len)); + (have_read = f.read(buffer + buffer_len, fs - buffer_len)); buffer_len += have_read) ; - QT_CLOSE(fd); } if(!buffer) return false; @@ -831,7 +809,7 @@ bool QMakeSourceFileInfo::findDeps(SourceFile *file) } } if(!exists) { //path lookup - for (const QMakeLocalFileName &depdir : qAsConst(depdirs)) { + for (const QMakeLocalFileName &depdir : std::as_const(depdirs)) { QMakeLocalFileName f(depdir.real() + Option::dir_sep + lfn.real()); QFileInfo fi(findFileInfo(f)); if(fi.exists() && !fi.isDir()) { @@ -901,32 +879,37 @@ bool QMakeSourceFileInfo::findMocs(SourceFile *file) int buffer_len = 0; char *buffer = nullptr; { - struct stat fst; - int fd; -#if defined(_MSC_VER) && _MSC_VER >= 1400 - if (_sopen_s(&fd, fixPathForFile(file->file, true).local().toLocal8Bit().constData(), - _O_RDONLY, _SH_DENYNO, _S_IREAD) != 0) - fd = -1; -#else - fd = open(fixPathForFile(file->file, true).local().toLocal8Bit().constData(), O_RDONLY); -#endif - if (fd == -1 || fstat(fd, &fst) || S_ISDIR(fst.st_mode)) { - if (fd != -1) - QT_CLOSE(fd); + QFile f(fixPathForFile(file->file, true).local()); + if (!f.open(QIODevice::ReadOnly)) return false; //shouldn't happen - } - buffer = getBuffer(fst.st_size); - while (int have_read = QT_READ(fd, buffer + buffer_len, fst.st_size - buffer_len)) + const qint64 fs = f.size(); + buffer = getBuffer(fs); + while (int have_read = f.read(buffer + buffer_len, fs - buffer_len)) buffer_len += have_read; - - QT_CLOSE(fd); } debug_msg(2, "findMocs: %s", file->file.local().toLatin1().constData()); int line_count = 1; - // [0] for Q_OBJECT, [1] for Q_GADGET, [2] for Q_NAMESPACE, [3] for Q_NAMESPACE_EXPORT - bool ignore[4] = { false, false, false, false }; + enum Keywords { + Q_OBJECT_Keyword, + Q_GADGET_Keyword, + Q_GADGET_EXPORT_Keyword, + Q_NAMESPACE_Keyword, + Q_NAMESPACE_EXPORT_Keyword, + + NumKeywords + }; + static const char keywords[][19] = { + "Q_OBJECT", + "Q_GADGET", + "Q_GADGET_EXPORT", + "Q_NAMESPACE", + "Q_NAMESPACE_EXPORT", + }; + static_assert(std::size(keywords) == NumKeywords); + bool ignore[NumKeywords] = {}; /* qmake ignore Q_GADGET */ + /* qmake ignore Q_GADGET_EXPORT */ /* qmake ignore Q_OBJECT */ /* qmake ignore Q_NAMESPACE */ /* qmake ignore Q_NAMESPACE_EXPORT */ @@ -950,30 +933,26 @@ bool QMakeSourceFileInfo::findMocs(SourceFile *file) x = SKIP_BSNL(y + 1); for (; x < buffer_len; x = SKIP_BSNL(x + 1)) { if (buffer[x] == 't' || buffer[x] == 'q') { // ignore - if(buffer_len >= (x + 20) && - !strncmp(buffer + x + 1, "make ignore Q_OBJECT", 20)) { - debug_msg(2, "Mocgen: %s:%d Found \"qmake ignore Q_OBJECT\"", - file->file.real().toLatin1().constData(), line_count); - x += 20; - ignore[0] = true; - } else if(buffer_len >= (x + 20) && - !strncmp(buffer + x + 1, "make ignore Q_GADGET", 20)) { - debug_msg(2, "Mocgen: %s:%d Found \"qmake ignore Q_GADGET\"", - file->file.real().toLatin1().constData(), line_count); - x += 20; - ignore[1] = true; - } else if (buffer_len >= (x + 23) && - !strncmp(buffer + x + 1, "make ignore Q_NAMESPACE", 23)) { - debug_msg(2, "Mocgen: %s:%d Found \"qmake ignore Q_NAMESPACE\"", - file->file.real().toLatin1().constData(), line_count); - x += 23; - ignore[2] = true; - } else if (buffer_len >= (x + 30) && - !strncmp(buffer + x + 1, "make ignore Q_NAMESPACE_EXPORT", 30)) { - debug_msg(2, "Mocgen: %s:%d Found \"qmake ignore Q_NAMESPACE_EXPORT\"", - file->file.real().toLatin1().constData(), line_count); - x += 30; - ignore[3] = true; + const char tag[] = "make ignore "; + const auto starts_with = [](const char *haystack, const char *needle) { + return strncmp(haystack, needle, strlen(needle)) == 0; + }; + const auto is_ignore = [&](const char *keyword) { + return buffer_len >= int(x + strlen(tag) + strlen(keyword)) && + starts_with(buffer + x + 1, tag) && + starts_with(buffer + x + 1 + strlen(tag), keyword); + }; + int interest = 0; + for (const char *keyword : keywords) { + if (is_ignore(keyword)){ + debug_msg(2, "Mocgen: %s:%d Found \"q%s%s\"", + file->file.real().toLatin1().constData(), line_count, + tag, keyword); + x += static_cast<int>(strlen(tag)); + x += static_cast<int>(strlen(keyword)); + ignore[interest] = true; + } + ++interest; } } else if (buffer[x] == '*') { extralines = 0; @@ -1001,16 +980,15 @@ bool QMakeSourceFileInfo::findMocs(SourceFile *file) int morelines = 0; int y = skipEscapedLineEnds(buffer, buffer_len, x + 1, &morelines); if (buffer[y] == 'Q') { - static const char interesting[][19] = { "Q_OBJECT", "Q_GADGET", "Q_NAMESPACE", "Q_NAMESPACE_EXPORT" }; - for (int interest = 0; interest < 4; ++interest) { + for (int interest = 0; interest < NumKeywords; ++interest) { if (ignore[interest]) continue; int matchlen = 0, extralines = 0; - size_t needle_len = strlen(interesting[interest]); + size_t needle_len = strlen(keywords[interest]); Q_ASSERT(needle_len <= INT_MAX); if (matchWhileUnsplitting(buffer, buffer_len, y, - interesting[interest], + keywords[interest], static_cast<int>(needle_len), &matchlen, &extralines) && y + matchlen < buffer_len diff --git a/qmake/generators/makefiledeps.h b/qmake/generators/makefiledeps.h index 31587371ef..c7743d7eb5 100644 --- a/qmake/generators/makefiledeps.h +++ b/qmake/generators/makefiledeps.h @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef MAKEFILEDEPS_H #define MAKEFILEDEPS_H diff --git a/qmake/generators/metamakefile.cpp b/qmake/generators/metamakefile.cpp index 8ba941c213..79443a1d4b 100644 --- a/qmake/generators/metamakefile.cpp +++ b/qmake/generators/metamakefile.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "metamakefile.h" #include "qdir.h" @@ -77,7 +52,7 @@ public: void BuildsMetaMakefileGenerator::clearBuilds() { - for(int i = 0; i < makefiles.count(); i++) { + for(int i = 0; i < makefiles.size(); i++) { Build *build = makefiles[i]; if(QMakeProject *p = build->makefile->projectFile()) { if(p != project) @@ -98,12 +73,12 @@ BuildsMetaMakefileGenerator::init() const ProStringList &builds = project->values("BUILDS"); bool use_single_build = builds.isEmpty(); - if(builds.count() > 1 && Option::output.fileName() == "-") { + if(builds.size() > 1 && Option::output.fileName() == "-") { use_single_build = true; warn_msg(WarnLogic, "Cannot direct to stdout when using multiple BUILDS."); } if(!use_single_build) { - for(int i = 0; i < builds.count(); i++) { + for(int i = 0; i < builds.size(); i++) { ProString build = builds[i]; MakefileGenerator *makefile = processBuild(build); if(!makefile) @@ -116,7 +91,7 @@ BuildsMetaMakefileGenerator::init() } else { Build *b = new Build; b->name = name; - if(builds.count() != 1) + if(builds.size() != 1) b->build = build.toQString(); b->makefile = makefile; makefiles += b; @@ -151,7 +126,7 @@ BuildsMetaMakefileGenerator::write() bool ret = true; const QString &output_name = Option::output.fileName(); - for(int i = 0; ret && i < makefiles.count(); i++) { + for(int i = 0; ret && i < makefiles.size(); i++) { Option::output.setFileName(output_name); Build *build = makefiles[i]; @@ -165,7 +140,10 @@ BuildsMetaMakefileGenerator::write() if(Option::output.fileName() == "-") { Option::output.setFileName(""); Option::output_dir = qmake_getpwd(); - Option::output.open(stdout, QIODevice::WriteOnly | QIODevice::Text); + if (!Option::output.open(stdout, QIODevice::WriteOnly | QIODevice::Text)) { + fprintf(stderr, "Failure to open stdout\n"); + return false; + } using_stdout = true; } else { if(Option::output.fileName().isEmpty() && @@ -248,7 +226,7 @@ void BuildsMetaMakefileGenerator::accumulateVariableFromBuilds(const ProKey &nam void BuildsMetaMakefileGenerator::checkForConflictingTargets() const { - if (makefiles.count() < 3) { + if (makefiles.size() < 3) { // Checking for conflicts only makes sense if we have more than one BUILD, // and the last entry in makefiles is the "glue" Build. return; @@ -259,7 +237,7 @@ void BuildsMetaMakefileGenerator::checkForConflictingTargets() const } using TargetInfo = std::pair<Build *, ProString>; QList<TargetInfo> targets; - const int last = makefiles.count() - 1; + const int last = makefiles.size() - 1; targets.resize(last); for (int i = 0; i < last; ++i) { Build *b = makefiles.at(i); @@ -326,7 +304,7 @@ SubdirsMetaMakefileGenerator::init() if(!thispwd.endsWith('/')) thispwd += '/'; const ProStringList &subdirs = project->values("SUBDIRS"); - static int recurseDepth = -1; + Q_CONSTINIT static int recurseDepth = -1; ++recurseDepth; for(int i = 0; i < subdirs.size(); ++i) { Subdir *sub = new Subdir; @@ -349,7 +327,7 @@ SubdirsMetaMakefileGenerator::init() if(!subdir.isRelative()) { //we can try to make it relative QString subdir_path = subdir.filePath(); if(subdir_path.startsWith(thispwd)) - subdir = QFileInfo(subdir_path.mid(thispwd.length())); + subdir = QFileInfo(subdir_path.mid(thispwd.size())); } //handle sub project @@ -416,12 +394,12 @@ SubdirsMetaMakefileGenerator::write() const QString &pwd = qmake_getpwd(); const QString &output_dir = Option::output_dir; const QString &output_name = Option::output.fileName(); - for(int i = 0; ret && i < subs.count(); i++) { + for(int i = 0; ret && i < subs.size(); i++) { const Subdir *sub = subs.at(i); qmake_setpwd(sub->input_dir); Option::output_dir = QFileInfo(sub->output_dir).absoluteFilePath(); Option::output.setFileName(sub->output_file); - if(i != subs.count()-1) { + if(i != subs.size()-1) { for (int ind = 0; ind < sub->indent; ++ind) printf(" "); printf("Writing %s\n", QDir::cleanPath(Option::output_dir+"/"+ @@ -439,7 +417,7 @@ SubdirsMetaMakefileGenerator::write() SubdirsMetaMakefileGenerator::~SubdirsMetaMakefileGenerator() { - for(int i = 0; i < subs.count(); i++) + for(int i = 0; i < subs.size(); i++) delete subs[i]; subs.clear(); } diff --git a/qmake/generators/metamakefile.h b/qmake/generators/metamakefile.h index 9337130143..6ce00a851e 100644 --- a/qmake/generators/metamakefile.h +++ b/qmake/generators/metamakefile.h @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef METAMAKEFILE_H #define METAMAKEFILE_H diff --git a/qmake/generators/projectgenerator.cpp b/qmake/generators/projectgenerator.cpp index 4e1b32fb69..96d7b26370 100644 --- a/qmake/generators/projectgenerator.cpp +++ b/qmake/generators/projectgenerator.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "projectgenerator.h" #include "option.h" @@ -79,7 +54,7 @@ ProjectGenerator::init() dirs.prepend(qmake_getpwd()); } - for(int i = 0; i < dirs.count(); ++i) { + for(int i = 0; i < dirs.size(); ++i) { QString dir, regex, pd = dirs.at(i); bool add_depend = false; if(exists(pd)) { @@ -91,7 +66,7 @@ ProjectGenerator::init() dir += Option::dir_sep; if (Option::recursive) { QStringList files = QDir(dir).entryList(QDir::Files); - for (int i = 0; i < files.count(); i++) + for (int i = 0; i < files.size(); i++) dirs.append(dir + files[i] + QDir::separator() + builtin_regex); } regex = builtin_regex; @@ -112,16 +87,16 @@ ProjectGenerator::init() int s = regex.lastIndexOf(Option::dir_sep); if(s != -1) { dir = regex.left(s+1); - regex = regex.right(regex.length() - (s+1)); + regex = regex.right(regex.size() - (s+1)); } const QDir d(dir); if (Option::recursive) { QStringList entries = d.entryList(QDir::Dirs | QDir::NoDotAndDotDot); - for (int i = 0; i < entries.count(); i++) + for (int i = 0; i < entries.size(); i++) dirs.append(dir + entries[i] + QDir::separator() + regex); } QStringList files = d.entryList(QDir::nameFiltersFromString(regex)); - for(int i = 0; i < (int)files.count(); i++) { + for(int i = 0; i < (int)files.size(); i++) { QString file = d.absoluteFilePath(files[i]); if (addFile(file)) { add_depend = true; @@ -141,7 +116,7 @@ ProjectGenerator::init() if(Option::projfile::do_pwd) knownDirs.prepend("."); const QString out_file = fileFixify(Option::output.fileName()); - for(int i = 0; i < knownDirs.count(); ++i) { + for(int i = 0; i < knownDirs.size(); ++i) { QString pd = knownDirs.at(i); if(exists(pd)) { QString newdir = pd; @@ -154,7 +129,7 @@ ProjectGenerator::init() subdirs.append(newdir); } else { QStringList profiles = QDir(newdir).entryList(QStringList("*" + Option::pro_ext), QDir::Files); - for(int i = 0; i < (int)profiles.count(); i++) { + for(int i = 0; i < (int)profiles.size(); i++) { QString nd = newdir; if(nd == ".") nd = ""; @@ -168,7 +143,7 @@ ProjectGenerator::init() } if (Option::recursive) { QStringList dirs = QDir(newdir).entryList(QDir::Dirs | QDir::NoDotAndDotDot); - for(int i = 0; i < (int)dirs.count(); i++) { + for(int i = 0; i < (int)dirs.size(); i++) { QString nd = fileFixify(newdir + QDir::separator() + dirs[i]); if (!knownDirs.contains(nd, Qt::CaseInsensitive)) knownDirs.append(nd); @@ -180,12 +155,12 @@ ProjectGenerator::init() int s = regx.lastIndexOf(Option::dir_sep); if(s != -1) { dir = regx.left(s+1); - regx = regx.right(regx.length() - (s+1)); + regx = regx.right(regx.size() - (s+1)); } QStringList files = QDir(dir).entryList(QDir::nameFiltersFromString(regx), QDir::Dirs | QDir::NoDotAndDotDot); ProStringList &subdirs = v["SUBDIRS"]; - for(int i = 0; i < (int)files.count(); i++) { + for(int i = 0; i < (int)files.size(); i++) { QString newdir(dir + files[i]); QFileInfo fi(fileInfo(newdir)); { @@ -195,7 +170,7 @@ ProjectGenerator::init() subdirs.append(newdir); } else { QStringList profiles = QDir(newdir).entryList(QStringList("*" + Option::pro_ext), QDir::Files); - for(int i = 0; i < (int)profiles.count(); i++) { + for(int i = 0; i < (int)profiles.size(); i++) { QString nd = newdir + QDir::separator() + files[i]; fileFixify(nd); if(files[i] != "." && files[i] != ".." && !subdirs.contains(nd, Qt::CaseInsensitive)) { @@ -256,7 +231,7 @@ ProjectGenerator::init() } if(!h_ext.isEmpty()) { for(int cppit = 0; cppit < Option::cpp_ext.size(); ++cppit) { - QString src(dep.left(dep.length() - h_ext.length()) + + QString src(dep.left(dep.size() - h_ext.size()) + Option::cpp_ext.at(cppit)); if(exists(src)) { ProStringList &srcl = v["SOURCES"]; @@ -346,7 +321,7 @@ ProjectGenerator::writeMakefile(QTextStream &t) "# Please consult the documentation of the deprecated API in order to know\n" "# how to port your code away from it.\n" "# You can also select to disable deprecated APIs only up to a certain version of Qt.\n" - "#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0\n\n"; + "#DEFINES += QT_DISABLE_DEPRECATED_UP_TO=0x060000 # disables all APIs deprecated in Qt 6.0.0 and earlier\n\n"; t << "# Input" << "\n"; t << getWritableVar("HEADERS") @@ -383,7 +358,7 @@ ProjectGenerator::addFile(QString file) int s = file.lastIndexOf(Option::dir_sep); if(s != -1) dir = file.left(s+1); - if(file.mid(dir.length(), Option::h_moc_mod.length()) == Option::h_moc_mod) + if(file.mid(dir.size(), Option::h_moc_mod.size()) == Option::h_moc_mod) return false; ProKey where; @@ -453,9 +428,9 @@ ProjectGenerator::getWritableVar(const char *vk, bool) else ret = v + " += "; QString join = vals.join(' '); - if(ret.length() + join.length() > 80) { + if(ret.size() + join.size() > 80) { QString spaces; - for(int i = 0; i < ret.length(); i++) + for(int i = 0; i < ret.size(); i++) spaces += " "; join = vals.join(" \\\n" + spaces); } diff --git a/qmake/generators/projectgenerator.h b/qmake/generators/projectgenerator.h index 374bad98c7..d1f5228140 100644 --- a/qmake/generators/projectgenerator.h +++ b/qmake/generators/projectgenerator.h @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef PROJECTGENERATOR_H #define PROJECTGENERATOR_H diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp index 07f8d861dc..c6771e7ab9 100644 --- a/qmake/generators/unix/unixmake.cpp +++ b/qmake/generators/unix/unixmake.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "unixmake.h" #include "option.h" @@ -39,7 +14,7 @@ QT_BEGIN_NAMESPACE ProStringList UnixMakefileGenerator::libdirToFlags(const ProKey &key) { ProStringList results; - for (const auto &libdir : qAsConst(project->values(key))) { + for (const auto &libdir : std::as_const(project->values(key))) { if (!project->isEmpty("QMAKE_LFLAGS_RPATH") && project->isActiveConfig("rpath_libdirs")) project->values("QMAKE_LFLAGS") += var("QMAKE_LFLAGS_RPATH") + libdir; results.append("-L" + escapeFilePath(libdir)); @@ -73,7 +48,7 @@ UnixMakefileGenerator::init() for (const ProString &iif : project->values("QMAKE_INTERNAL_INCLUDED_FILES")) { if (iif == project->cacheFile()) continue; - if (iif.startsWith(sroot) && iif.at(sroot.length()) == QLatin1Char('/')) + if (iif.startsWith(sroot) && iif.at(sroot.size()) == QLatin1Char('/')) project->values("DISTFILES") += fileFixify(iif.toQString(), FileFixifyRelative); } @@ -126,7 +101,7 @@ UnixMakefileGenerator::init() const ProStringList &rpathdirs = project->values("QMAKE_RPATHDIR"); for (int i = 0; i < rpathdirs.size(); ++i) { QString rpathdir = rpathdirs[i].toQString(); - if (rpathdir.length() > 1 && rpathdir.at(0) == '$' && rpathdir.at(1) != '(') { + if (rpathdir.size() > 1 && rpathdir.at(0) == '$' && rpathdir.at(1) != '(') { rpathdir.replace(0, 1, "\\$$"); // Escape from make and the shell } else if (!rpathdir.startsWith('@') && fileInfo(rpathdir).isRelative()) { QString rpathbase = project->first("QMAKE_REL_RPATH_BASE").toQString(); @@ -266,7 +241,6 @@ UnixMakefileGenerator::init() if(project->isEmpty("QMAKE_BUNDLE_LOCATION")) project->values("QMAKE_BUNDLE_LOCATION").append("Contents/MacOS"); project->values("QMAKE_PKGINFO").append(project->first("DESTDIR") + bundle + "/Contents/PkgInfo"); - project->values("QMAKE_BUNDLE_RESOURCE_FILE").append(project->first("DESTDIR") + bundle + "/Contents/Resources/empty.lproj"); } else if(project->first("TEMPLATE") == "lib" && !project->isActiveConfig("staticlib") && ((!project->isActiveConfig("plugin") && project->isActiveConfig("lib_bundle")) || (project->isActiveConfig("plugin") && project->isActiveConfig("plugin_bundle")))) { @@ -324,7 +298,7 @@ QStringList ProStringList pchArchs = project->values("QMAKE_PCH_ARCHS"); if (pchArchs.isEmpty()) pchArchs << ProString(); // normal single-arch PCH - for (const ProString &arch : qAsConst(pchArchs)) { + for (const ProString &arch : std::as_const(pchArchs)) { auto pfx = header_prefix; if (!arch.isEmpty()) pfx.replace(QLatin1String("${QMAKE_PCH_ARCH}"), arch.toQString()); @@ -362,7 +336,7 @@ QStringList ProStringList pchArchs = project->values("QMAKE_PCH_ARCHS"); if (pchArchs.isEmpty()) pchArchs << ProString(); // normal single-arch PCH - for (const ProString &arch : qAsConst(pchArchs)) { + for (const ProString &arch : std::as_const(pchArchs)) { QString precompiledHeader = header_prefix + language + header_suffix; if (!arch.isEmpty()) { precompiledHeader.replace(QLatin1String("${QMAKE_PCH_ARCH}"), @@ -417,7 +391,7 @@ UnixMakefileGenerator::findLibraries(bool linkPrl, bool mergeLflags) libdirs.insert(libidx++, f); } else if(opt.startsWith("-l")) { QString lib = opt.mid(2); - for (const QMakeLocalFileName &libdir : qAsConst(libdirs)) { + for (const QMakeLocalFileName &libdir : std::as_const(libdirs)) { QString libBase = libdir.local() + '/' + project->first("QMAKE_PREFIX_SHLIB") + lib; if (linkPrl && processPrlFile(libBase, true)) @@ -443,7 +417,7 @@ UnixMakefileGenerator::findLibraries(bool linkPrl, bool mergeLflags) frameworkName.truncate(suffixPosition); opt.remove(suffixMarker); // Apply suffix by removing marker } - for (const QMakeLocalFileName &dir : qAsConst(frameworkdirs)) { + for (const QMakeLocalFileName &dir : std::as_const(frameworkdirs)) { auto processPrlIfFound = [&](QString directory) { QString suffixedPrl = directory + opt; if (processPrlFile(suffixedPrl, true)) @@ -461,7 +435,7 @@ UnixMakefileGenerator::findLibraries(bool linkPrl, bool mergeLflags) break; } } else { - if (opt.length() == 10) + if (opt.size() == 10) ++it; // Skip } @@ -714,7 +688,7 @@ UnixMakefileGenerator::defaultInstall(const QString &t) QString link = Option::fixPathToTargetOS(destdir + links[i], false); int lslash = link.lastIndexOf(Option::dir_sep); if(lslash != -1) - link = link.right(link.length() - (lslash + 1)); + link = link.right(link.size() - (lslash + 1)); QString dst_link = escapeFilePath( filePrefixRoot(root, fileFixify(targetdir + link, FileFixifyAbsolute))); ret += "\n\t-$(SYMLINK) $(TARGET) " + dst_link; diff --git a/qmake/generators/unix/unixmake.h b/qmake/generators/unix/unixmake.h index 1f32e4341f..92f118a143 100644 --- a/qmake/generators/unix/unixmake.h +++ b/qmake/generators/unix/unixmake.h @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef UNIXMAKE_H #define UNIXMAKE_H @@ -58,7 +33,7 @@ protected: void writeSubTargets(QTextStream &t, QList<SubTarget*> subtargets, int flags) override; void writeMakeParts(QTextStream &); bool writeMakefile(QTextStream &) override; - std::pair<bool, QString> writeObjectsPart(QTextStream &, bool do_incremental); + bool writeObjectsPart(QTextStream &, bool do_incremental); private: void init2(); ProStringList libdirToFlags(const ProKey &key); diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index 190f5e355a..96036eba70 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -1,31 +1,6 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2016 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "unixmake.h" #include "option.h" @@ -35,8 +10,12 @@ #include <qfile.h> #include <qdir.h> #include <qdebug.h> +#include <qtversion.h> #include <time.h> +#include <tuple> +#include <utility> + QT_BEGIN_NAMESPACE void @@ -126,11 +105,11 @@ UnixMakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator:: if (!out_directory.isEmpty() && !out_directory.endsWith(Option::dir_sep)) out_directory += Option::dir_sep; if (!abs_source_path.isEmpty() && out_directory.startsWith(abs_source_path)) - out_directory = Option::output_dir + out_directory.mid(abs_source_path.length()); + out_directory = Option::output_dir + out_directory.mid(abs_source_path.size()); QString dist_directory = out_directory; if (dist_directory.endsWith(Option::dir_sep)) - dist_directory.chop(Option::dir_sep.length()); + dist_directory.chop(Option::dir_sep.size()); if (!dist_directory.startsWith(Option::dir_sep)) dist_directory.prepend(Option::dir_sep); @@ -142,7 +121,7 @@ UnixMakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator:: QString out = subtarget->makefile; QString in = escapeFilePath(fileFixify(in_directory + subtarget->profile, FileFixifyAbsolute)); if (out.startsWith(in_directory)) - out.remove(0, in_directory.length()); + out.remove(0, in_directory.size()); t << subtarget->target << "-distdir: FORCE"; writeSubTargetCall(t, in_directory, in, out_directory, escapeFilePath(out), @@ -241,8 +220,8 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "####### Files\n\n"; // This is used by the dist target. t << "SOURCES = " << fileVarList("SOURCES") << ' ' << fileVarList("GENERATED_SOURCES") << Qt::endl; - auto objectParts = writeObjectsPart(t, do_incremental); - src_incremental = objectParts.first; + + src_incremental = writeObjectsPart(t, do_incremental); if(do_incremental && !src_incremental) do_incremental = false; t << "DIST = " << valList(fileFixify(project->values("DISTFILES").toQStringList())) << " " @@ -324,7 +303,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) for(QStringList::Iterator cit = Option::c_ext.begin(); cit != Option::c_ext.end(); ++cit) { if((*it).endsWith((*cit))) { - d_file = (*it).left((*it).length() - (*cit).length()).toQString(); + d_file = (*it).left((*it).length() - (*cit).size()).toQString(); break; } } @@ -332,7 +311,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) { if((*it).endsWith((*cppit))) { - d_file = (*it).left((*it).length() - (*cppit).length()).toQString(); + d_file = (*it).left((*it).length() - (*cppit).size()).toQString(); break; } } @@ -392,6 +371,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) } } } + LinkerResponseFileInfo linkerResponseFile = maybeCreateLinkerResponseFile(); QString deps = escapeDependencyPath(fileFixify(Option::output.fileName())); QString allDeps; if (!project->values("QMAKE_APP_FLAG").isEmpty() || project->first("TEMPLATE") == "aux") { @@ -408,7 +388,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) //incremental target QString incr_target = var("TARGET") + "_incremental"; if(incr_target.indexOf(Option::dir_sep) != -1) - incr_target = incr_target.right(incr_target.length() - + incr_target = incr_target.right(incr_target.size() - (incr_target.lastIndexOf(Option::dir_sep) + 1)); QString incr_deps, incr_objs; if(project->first("QMAKE_INCREMENTAL_STYLE") == "ld") { @@ -478,8 +458,13 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << mkdir_p_asstring(destdir) << "\n\t"; if (!project->isEmpty("QMAKE_PRE_LINK")) t << var("QMAKE_PRE_LINK") << "\n\t"; - t << "$(LINK) $(LFLAGS) " << var("QMAKE_LINK_O_FLAG") << "$(TARGET) " - << objectParts.second << " $(OBJCOMP) $(LIBS)"; + t << "$(LINK) $(LFLAGS) " << var("QMAKE_LINK_O_FLAG") << "$(TARGET) "; + if (!linkerResponseFile.isValid()) + t << " $(OBJECTS) $(OBJCOMP) $(LIBS)"; + else if (linkerResponseFile.onlyObjects) + t << " @" << linkerResponseFile.filePath << " $(OBJCOMP) $(LIBS)"; + else + t << " $(OBJCOMP) @" << linkerResponseFile.filePath; if (!project->isEmpty("QMAKE_POST_LINK")) t << "\n\t" << var("QMAKE_POST_LINK"); } @@ -504,7 +489,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) QString incr_target = var("QMAKE_ORIG_TARGET").replace( QRegularExpression("\\." + s_ext), "").replace(QRegularExpression("^lib"), "") + "_incremental"; if(incr_target.indexOf(Option::dir_sep) != -1) - incr_target = incr_target.right(incr_target.length() - + incr_target = incr_target.right(incr_target.size() - (incr_target.lastIndexOf(Option::dir_sep) + 1)); if(project->first("QMAKE_INCREMENTAL_STYLE") == "ld") { @@ -554,7 +539,10 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) << incr_deps << " $(SUBLIBS) " << target_deps << ' ' << depVar("POST_TARGETDEPS"); } else { ProStringList &cmd = project->values("QMAKE_LINK_SHLIB_CMD"); - cmd[0] = cmd.at(0).toQString().replace(QLatin1String("$(OBJECTS)"), objectParts.second); + if (linkerResponseFile.isValid()) { + cmd[0] = cmd.at(0).toQString().replace(QLatin1String("$(OBJECTS)"), + "@" + linkerResponseFile.filePath); + } t << destdir_d << depVar("TARGET") << ": " << depVar("PRE_TARGETDEPS") << " $(OBJECTS) $(SUBLIBS) $(OBJCOMP) " << target_deps << ' ' << depVar("POST_TARGETDEPS"); @@ -816,18 +804,19 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) QString icon = fileFixify(var("ICON")); t << "@$(DEL_FILE) " << info_plist_out << "\n\t" - << "@sed "; - for (const ProString &arg : qAsConst(commonSedArgs)) + << "@plutil -convert xml1 -o - " << info_plist << " | " + << "sed "; + for (const ProString &arg : std::as_const(commonSedArgs)) t << arg; const QString iconName = icon.section(Option::dir_sep, -1); t << "-e \"s,@ICON@," << iconName << ",g\" " << "-e \"s,\\$${ASSETCATALOG_COMPILER_APPICON_NAME}," << iconName << ",g\" " << "-e \"s,@EXECUTABLE@," << app_bundle_name << ",g\" " << "-e \"s,@LIBRARY@," << plugin_bundle_name << ",g\" " - << "-e \"s,\\$${EXECUTABLE_NAME}," << (app_bundle_name.isEmpty() ? app_bundle_name : plugin_bundle_name) << ",g\" " + << "-e \"s,\\$${EXECUTABLE_NAME}," << (!app_bundle_name.isEmpty() ? app_bundle_name : plugin_bundle_name) << ",g\" " << "-e \"s,@TYPEINFO@,"<< typeInfo << ",g\" " << "-e \"s,\\$${QMAKE_PKGINFO_TYPEINFO},"<< typeInfo << ",g\" " - << "" << info_plist << " >" << info_plist_out << Qt::endl; + << ">" << info_plist_out << Qt::endl; //copy the icon if (!project->isEmpty("ICON")) { QString dir = bundle_dir + "Contents/Resources/"; @@ -848,21 +837,22 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if (!isShallowBundle) symlinks[bundle_dir + "Resources"] = "Versions/Current/Resources"; t << "@$(DEL_FILE) " << info_plist_out << "\n\t" - << "@sed "; - for (const ProString &arg : qAsConst(commonSedArgs)) + << "@plutil -convert xml1 -o - " << info_plist << " | " + << "sed "; + for (const ProString &arg : std::as_const(commonSedArgs)) t << arg; t << "-e \"s,@LIBRARY@," << lib_bundle_name << ",g\" " << "-e \"s,\\$${EXECUTABLE_NAME}," << lib_bundle_name << ",g\" " << "-e \"s,@TYPEINFO@," << typeInfo << ",g\" " << "-e \"s,\\$${QMAKE_PKGINFO_TYPEINFO}," << typeInfo << ",g\" " - << "" << info_plist << " >" << info_plist_out << Qt::endl; + << ">" << info_plist_out << Qt::endl; } break; } // project->isActiveConfig("no_plist") //copy other data if(!project->isEmpty("QMAKE_BUNDLE_DATA")) { const ProStringList &bundle_data = project->values("QMAKE_BUNDLE_DATA"); - for(int i = 0; i < bundle_data.count(); i++) { + for(int i = 0; i < bundle_data.size(); i++) { const ProStringList &files = project->values(ProKey(bundle_data[i] + ".files")); QString path = bundle_dir; const ProKey pkey(bundle_data[i] + ".path"); @@ -882,7 +872,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) } path += project->first(pkey).toQString(); path = Option::fixPathToTargetOS(path); - for(int file = 0; file < files.count(); file++) { + for(int file = 0; file < files.size(); file++) { QString fn = files.at(file).toQString(); QString src = fileFixify(fn, FileFixifyAbsolute); if (!QFile::exists(src)) @@ -989,7 +979,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) ProStringList pchArchs = project->values("QMAKE_PCH_ARCHS"); if (pchArchs.isEmpty()) pchArchs << ProString(); // normal single-arch PCH - for (const ProString &arch : qAsConst(pchArchs)) { + for (const ProString &arch : std::as_const(pchArchs)) { ProString pchOutput; if (!project->isEmpty("PRECOMPILED_DIR")) pchOutput = project->first("PRECOMPILED_DIR"); @@ -1020,7 +1010,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) ProStringList pchArchs = project->values("QMAKE_PCH_ARCHS"); if (pchArchs.isEmpty()) pchArchs << ProString(); // normal single-arch PCH - for (const ProString &arch : qAsConst(pchArchs)) { + for (const ProString &arch : std::as_const(pchArchs)) { QString file = precomph_out_dir + header_prefix + language + header_suffix; if (!arch.isEmpty()) file.replace(QStringLiteral("${QMAKE_PCH_ARCH}"), arch.toQString()); @@ -1118,7 +1108,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) } pchFlags.replace(QLatin1String("${QMAKE_PCH_INPUT}"), escapeFilePath(pchInput)) .replace(QLatin1String("${QMAKE_PCH_OUTPUT_BASE}"), escapeFilePath(pchBaseName.toQString())); - for (const ProString &arch : qAsConst(pchArchs)) { + for (const ProString &arch : std::as_const(pchArchs)) { auto pchArchOutput = pchOutput.toQString(); if (!arch.isEmpty()) pchArchOutput.replace(QStringLiteral("${QMAKE_PCH_ARCH}"), arch.toQString()); @@ -1407,7 +1397,7 @@ UnixMakefileGenerator::libtoolFileName(bool fixify) QString ret = var("TARGET"); int slsh = ret.lastIndexOf(Option::dir_sep); if(slsh != -1) - ret = ret.right(ret.length() - slsh - 1); + ret = ret.right(ret.size() - slsh - 1); int dot = ret.indexOf('.'); if(dot != -1) ret = ret.left(dot); @@ -1422,6 +1412,25 @@ UnixMakefileGenerator::libtoolFileName(bool fixify) return ret; } +static std::pair<ProStringList, ProStringList> +splitFrameworksAndLibs(const ProStringList &linkArgs) +{ + std::pair<ProStringList, ProStringList> result; + bool frameworkArg = false; + for (auto arg : linkArgs) { + if (frameworkArg) { + frameworkArg = false; + result.second += arg; + } else if (arg == "-framework") { + frameworkArg = true; + result.second += arg; + } else { + result.first += arg; + } + } + return result; +} + void UnixMakefileGenerator::writeLibtoolFile() { @@ -1458,7 +1467,7 @@ UnixMakefileGenerator::writeLibtoolFile() mkdir(fileInfo(fname).path()); int slsh = lname.lastIndexOf(Option::dir_sep); if(slsh != -1) - lname = lname.right(lname.length() - slsh - 1); + lname = lname.right(lname.size() - slsh - 1); QFile ft(fname); if(!ft.open(QIODevice::WriteOnly)) return; @@ -1488,7 +1497,7 @@ UnixMakefileGenerator::writeLibtoolFile() t << "'\n\n"; t << "# The name of the static archive.\n" - << "old_library='" << escapeFilePath(lname.left(lname.length()-Option::libtool_ext.length())) + << "old_library='" << escapeFilePath(lname.left(lname.size()-Option::libtool_ext.size())) << ".a'\n\n"; t << "# Libraries that this one depends upon.\n"; @@ -1496,7 +1505,13 @@ UnixMakefileGenerator::writeLibtoolFile() ProStringList libs; for (auto var : libVars) libs += fixLibFlags(var); + ProStringList frameworks; + std::tie(libs, frameworks) = splitFrameworksAndLibs(libs); t << "dependency_libs='" << fixDependencyLibs(libs).join(' ') << "'\n\n"; + if (!frameworks.isEmpty()) { + t << "# Frameworks that this library depends upon.\n"; + t << "inherited_linker_flags='" << frameworks.join(' ') << "'\n\n"; + } t << "# Version information for " << lname << "\n"; int maj = project->first("VER_MAJ").toInt(); @@ -1522,7 +1537,7 @@ UnixMakefileGenerator::writeLibtoolFile() "libdir='" << Option::fixPathToTargetOS(install_dir.toQString(), false) << "'\n"; } -std::pair<bool, QString> UnixMakefileGenerator::writeObjectsPart(QTextStream &t, bool do_incremental) +bool UnixMakefileGenerator::writeObjectsPart(QTextStream &t, bool do_incremental) { bool src_incremental = false; QString objectsLinkLine; @@ -1545,9 +1560,9 @@ std::pair<bool, QString> UnixMakefileGenerator::writeObjectsPart(QTextStream &t, if (!increment) t << "\\\n\t\t" << (*objit); } - if (incrs_out.count() == objs.count()) { //we just switched places, no real incrementals to be done! + if (incrs_out.size() == objs.size()) { //we just switched places, no real incrementals to be done! t << escapeFilePaths(incrs_out).join(QString(" \\\n\t\t")) << Qt::endl; - } else if (!incrs_out.count()) { + } else if (!incrs_out.size()) { t << Qt::endl; } else { src_incremental = true; @@ -1556,18 +1571,9 @@ std::pair<bool, QString> UnixMakefileGenerator::writeObjectsPart(QTextStream &t, << escapeFilePaths(incrs_out).join(QString(" \\\n\t\t")) << Qt::endl; } } else { - const ProString &objMax = project->first("QMAKE_LINK_OBJECT_MAX"); - // Used all over the place in both deps and commands. - if (objMax.isEmpty() || project->values("OBJECTS").count() < objMax.toInt()) { - objectsLinkLine = "$(OBJECTS)"; - } else { - const QString ld_response_file = createResponseFile( - fileVar("OBJECTS_DIR") + var("QMAKE_LINK_OBJECT_SCRIPT"), objs); - objectsLinkLine = "@" + escapeFilePath(ld_response_file); - } t << "OBJECTS = " << valList(escapeDependencyPaths(objs)) << Qt::endl; } - return std::make_pair(src_incremental, objectsLinkLine); + return src_incremental; } QT_END_NAMESPACE diff --git a/qmake/generators/win32/mingw_make.cpp b/qmake/generators/win32/mingw_make.cpp index 823b799eb2..7f798a2cc6 100644 --- a/qmake/generators/win32/mingw_make.cpp +++ b/qmake/generators/win32/mingw_make.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "mingw_make.h" #include "option.h" @@ -216,7 +191,7 @@ void MingwMakefileGenerator::writeIncPart(QTextStream &t) return; } } - for (const ProString &incit: qAsConst(incs)) { + for (const ProString &incit: std::as_const(incs)) { QString inc = incit.toQString(); inc.replace(QRegularExpression("\\\\$"), ""); inc.replace('\\', '/'); @@ -242,21 +217,18 @@ void MingwMakefileGenerator::writeLibsPart(QTextStream &t) void MingwMakefileGenerator::writeObjectsPart(QTextStream &t) { - const ProString &objmax = project->first("QMAKE_LINK_OBJECT_MAX"); - if (objmax.isEmpty() || project->values("OBJECTS").count() < objmax.toInt()) { + linkerResponseFile = maybeCreateLinkerResponseFile(); + if (!linkerResponseFile.isValid()) { objectsLinkLine = "$(OBJECTS)"; } else if (project->isActiveConfig("staticlib") && project->first("TEMPLATE") == "lib") { // QMAKE_LIB is used for win32, including mingw, whereas QMAKE_AR is used on Unix. QString ar_cmd = var("QMAKE_LIB"); if (ar_cmd.isEmpty()) ar_cmd = "ar -rc"; - const QString ar_response_file = - createResponseFile(var("QMAKE_LINK_OBJECT_SCRIPT"), project->values("OBJECTS")); - objectsLinkLine = ar_cmd + ' ' + var("DEST_TARGET") + " @" + escapeFilePath(ar_response_file); + objectsLinkLine = ar_cmd + ' ' + var("DEST_TARGET") + " @" + + escapeFilePath(linkerResponseFile.filePath); } else { - const QString ld_response_file = - createResponseFile(var("QMAKE_LINK_OBJECT_SCRIPT"), project->values("OBJECTS")); - objectsLinkLine = "@" + escapeFilePath(ld_response_file); + objectsLinkLine = "@" + escapeFilePath(linkerResponseFile.filePath); } Win32MakefileGenerator::writeObjectsPart(t); } @@ -278,13 +250,16 @@ void MingwMakefileGenerator::writeBuildRulesPart(QTextStream &t) if(project->isActiveConfig("staticlib") && project->first("TEMPLATE") == "lib") { t << "\n\t-$(DEL_FILE) $(DESTDIR_TARGET) 2>" << var("QMAKE_SHELL_NULL_DEVICE"); const ProString &objmax = project->first("QMAKE_LINK_OBJECT_MAX"); - if (objmax.isEmpty() || project->values("OBJECTS").count() < objmax.toInt()) { + if (objmax.isEmpty() || project->values("OBJECTS").size() < objmax.toInt()) { t << "\n\t$(LIB) $(DESTDIR_TARGET) " << objectsLinkLine << " " ; } else { t << "\n\t" << objectsLinkLine << " " ; } } else { - t << "\n\t$(LINKER) $(LFLAGS) " << var("QMAKE_LINK_O_FLAG") << "$(DESTDIR_TARGET) " << objectsLinkLine << " $(LIBS)"; + t << "\n\t$(LINKER) $(LFLAGS) " << var("QMAKE_LINK_O_FLAG") << "$(DESTDIR_TARGET) " + << objectsLinkLine; + if (!linkerResponseFile.isValid() || linkerResponseFile.onlyObjects) + t << " $(LIBS)"; } if(!project->isEmpty("QMAKE_POST_LINK")) t << "\n\t" <<var("QMAKE_POST_LINK"); @@ -298,7 +273,7 @@ void MingwMakefileGenerator::writeRcFilePart(QTextStream &t) ProStringList rcIncPaths = project->values("RC_INCLUDEPATH"); rcIncPaths.prepend(fileInfo(rc_file).path()); QString incPathStr; - for (int i = 0; i < rcIncPaths.count(); ++i) { + for (int i = 0; i < rcIncPaths.size(); ++i) { const ProString &path = rcIncPaths.at(i); if (path.isEmpty()) continue; diff --git a/qmake/generators/win32/mingw_make.h b/qmake/generators/win32/mingw_make.h index 6c1f0086cc..8b919f97e7 100644 --- a/qmake/generators/win32/mingw_make.h +++ b/qmake/generators/win32/mingw_make.h @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef MINGW_MAKE_H #define MINGW_MAKE_H @@ -59,6 +34,7 @@ private: LibFlagType parseLibFlag(const ProString &flag, ProString *arg) override; QString objectsLinkLine; + LinkerResponseFileInfo linkerResponseFile; }; QT_END_NAMESPACE diff --git a/qmake/generators/win32/msbuild_objectmodel.cpp b/qmake/generators/win32/msbuild_objectmodel.cpp index b5b8a14a9e..9bbeed36ff 100644 --- a/qmake/generators/win32/msbuild_objectmodel.cpp +++ b/qmake/generators/win32/msbuild_objectmodel.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "msbuild_objectmodel.h" @@ -35,6 +10,7 @@ #include <qstringlist.h> #include <qfileinfo.h> #include <qregularexpression.h> +#include <qvarlengtharray.h> QT_BEGIN_NAMESPACE @@ -144,6 +120,7 @@ const char _IntermediateDirectory[] = "IntermediateDirectory"; const char _KeyContainer[] = "KeyContainer"; const char _KeyFile[] = "KeyFile"; const char _LanguageStandard[] = "LanguageStandard"; +const char _LanguageStandard_C[] = "LanguageStandard_C"; const char _LargeAddressAware[] = "LargeAddressAware"; const char _LinkDLL[] = "LinkDLL"; const char _LinkErrorReporting[] = "LinkErrorReporting"; @@ -306,7 +283,7 @@ static QString commandLinesForOutput(QStringList commands) // As we want every sub-command to be error-checked (as is done by makefile-based // backends), we insert the checks ourselves, using the undocumented jump target. static QString errchk = QStringLiteral("if errorlevel 1 goto VCEnd"); - for (int i = commands.count() - 2; i >= 0; --i) { + for (int i = commands.size() - 2; i >= 0; --i) { if (!commands.at(i).startsWith("rem", Qt::CaseInsensitive)) commands.insert(i + 1, errchk); } @@ -324,7 +301,7 @@ static QStringList unquote(const QStringList &values) { QStringList result; result.reserve(values.size()); - for (int i = 0; i < values.count(); ++i) + for (int i = 0; i < values.size(); ++i) result << unquote(values.at(i)); return result; } @@ -535,7 +512,10 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProjectSingleConfig &tool) QFile filterFile; filterFile.setFileName(Option::output.fileName().append(".filters")); - filterFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate); + if (!filterFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) { + warn_msg(WarnLogic, "Generator: cannot open output filter file"); + return; + } QTextStream ts(&filterFile); XmlOutput xmlFilter(ts, XmlOutput::NoConversion); @@ -567,7 +547,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProjectSingleConfig &tool) [] (const VCFilter &filter) { return filter.Name; }); tempProj.ExtraCompilers.removeDuplicates(); - for (int x = 0; x < tempProj.ExtraCompilers.count(); ++x) + for (int x = 0; x < tempProj.ExtraCompilers.size(); ++x) addFilters(tempProj, xmlFilter, tempProj.ExtraCompilers.at(x)); xmlFilter << closetag(); @@ -582,7 +562,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProjectSingleConfig &tool) outputFilter(tempProj, xml, xmlFilter, "Deployment Files"); outputFilter(tempProj, xml, xmlFilter, "Distribution Files"); - for (int x = 0; x < tempProj.ExtraCompilers.count(); ++x) { + for (int x = 0; x < tempProj.ExtraCompilers.size(); ++x) { outputFilter(tempProj, xml, xmlFilter, tempProj.ExtraCompilers.at(x)); } @@ -597,7 +577,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProjectSingleConfig &tool) void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) { - if (tool.SingleProjects.count() == 0) { + if (tool.SingleProjects.size() == 0) { warn_msg(WarnLogic, "Generator: .NET: no single project in merge project, no output"); return; } @@ -612,7 +592,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) << tag("ItemGroup") << attrTag("Label", "ProjectConfigurations"); - for (int i = 0; i < tool.SingleProjects.count(); ++i) { + for (int i = 0; i < tool.SingleProjects.size(); ++i) { xml << tag("ProjectConfiguration") << attrTag("Include" , tool.SingleProjects.at(i).Configuration.Name) << tagValue("Configuration", tool.SingleProjects.at(i).Configuration.ConfigurationName) @@ -636,7 +616,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) // config part. xml << import("Project", "$(VCTargetsPath)\\Microsoft.Cpp.Default.props"); - for (int i = 0; i < tool.SingleProjects.count(); ++i) + for (int i = 0; i < tool.SingleProjects.size(); ++i) write(xml, tool.SingleProjects.at(i).Configuration); xml << import("Project", "$(VCTargetsPath)\\Microsoft.Cpp.props"); @@ -646,7 +626,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) << closetag(); // PropertySheets - for (int i = 0; i < tool.SingleProjects.count(); ++i) { + for (int i = 0; i < tool.SingleProjects.size(); ++i) { xml << tag("ImportGroup") << attrTag("Condition", generateCondition(tool.SingleProjects.at(i).Configuration)) << attrTag("Label", "PropertySheets"); @@ -664,7 +644,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) << closetag(); xml << tag("PropertyGroup"); - for (int i = 0; i < tool.SingleProjects.count(); ++i) { + for (int i = 0; i < tool.SingleProjects.size(); ++i) { const VCConfiguration &config = tool.SingleProjects.at(i).Configuration; const QString condition = generateCondition(config); @@ -731,7 +711,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) } xml << closetag(); - for (int i = 0; i < tool.SingleProjects.count(); ++i) { + for (int i = 0; i < tool.SingleProjects.size(); ++i) { const VCConfiguration &config = tool.SingleProjects.at(i).Configuration; xml << tag("ItemDefinitionGroup") @@ -774,7 +754,10 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) // The file filters are added in a separate file for MSBUILD. QFile filterFile; filterFile.setFileName(Option::output.fileName().append(".filters")); - filterFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate); + if (!filterFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) { + warn_msg(WarnLogic, "Cannot open output filter file"); + return; + } QTextStream ts(&filterFile); XmlOutput xmlFilter(ts, XmlOutput::NoConversion); @@ -797,7 +780,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) addFilters(tool, xmlFilter, "Deployment Files"); addFilters(tool, xmlFilter, "Distribution Files"); - for (int x = 0; x < tool.ExtraCompilers.count(); ++x) + for (int x = 0; x < tool.ExtraCompilers.size(); ++x) addFilters(tool, xmlFilter, tool.ExtraCompilers.at(x)); xmlFilter << closetag(); @@ -811,7 +794,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) outputFilter(tool, xml, xmlFilter, "Resource Files"); outputFilter(tool, xml, xmlFilter, "Deployment Files"); outputFilter(tool, xml, xmlFilter, "Distribution Files"); - for (int x = 0; x < tool.ExtraCompilers.count(); ++x) { + for (int x = 0; x < tool.ExtraCompilers.size(); ++x) { outputFilter(tool, xml, xmlFilter, tool.ExtraCompilers.at(x)); } outputFilter(tool, xml, xmlFilter, "Root Files"); @@ -1087,6 +1070,8 @@ static inline QString toString(optLinkTimeCodeGenType option) break; case optLTCGEnabled: return "UseLinkTimeCodeGeneration"; + case optLTCGIncremental: + return "UseFastLinkTimeCodeGeneration"; case optLTCGInstrument: return "PGInstrument"; case optLTCGOptimize: @@ -1120,6 +1105,8 @@ static inline QString toString(triState genDebugInfo, linkerDebugOption option) case _True: if (option == linkerDebugOptionFastLink) return "DebugFastLink"; + else if (option == linkerDebugOptionFull) + return "DebugFull"; return "true"; } return QString(); @@ -1440,6 +1427,7 @@ void VCXProjectWriter::write(XmlOutput &xml, const VCCLCompilerTool &tool) << attrTagT(_MinimalRebuild, tool.MinimalRebuild) << attrTagT(_MultiProcessorCompilation, tool.MultiProcessorCompilation) << attrTagS(_LanguageStandard, tool.LanguageStandard) + << attrTagS(_LanguageStandard_C, tool.LanguageStandard_C) << attrTagS(_ObjectFileName, tool.ObjectFile) << attrTagT(_OmitDefaultLibName, tool.OmitDefaultLibName) << attrTagT(_OmitFramePointers, tool.OmitFramePointers) @@ -1755,7 +1743,7 @@ void VCXProjectWriter::addFilters(VCProject &project, XmlOutput &xmlFilter, cons { bool added = false; - for (int i = 0; i < project.SingleProjects.count(); ++i) { + for (int i = 0; i < project.SingleProjects.size(); ++i) { const VCFilter filter = project.SingleProjects.at(i).filterByName(filtername); if(!filter.Files.isEmpty() && !added) { xmlFilter << tag("Filter") @@ -1777,10 +1765,10 @@ void VCXProjectWriter::outputFilter(VCProject &project, XmlOutput &xml, XmlOutpu else root.reset(new XTreeNode); - for (int i = 0; i < project.SingleProjects.count(); ++i) { + for (int i = 0; i < project.SingleProjects.size(); ++i) { const VCFilter filter = project.SingleProjects.at(i).filterByName(filtername); // Merge all files in this filter to root tree - for (int x = 0; x < filter.Files.count(); ++x) + for (int x = 0; x < filter.Files.size(); ++x) root->addElement(filter.Files.at(x)); } @@ -1807,8 +1795,8 @@ void VCXProjectWriter::outputFileConfigs(VCProject &project, XmlOutput &xml, Xml // We need to check if the file has any custom build step. // If there is one then it has to be included with "CustomBuild Include" bool hasCustomBuildStep = false; - QVarLengthArray<OutputFilterData> data(project.SingleProjects.count()); - for (int i = 0; i < project.SingleProjects.count(); ++i) { + QVarLengthArray<OutputFilterData> data(project.SingleProjects.size()); + for (int i = 0; i < project.SingleProjects.size(); ++i) { data[i].filter = project.SingleProjects.at(i).filterByName(cleanFilterName); if (!data[i].filter.Config) // only if the filter is not empty continue; @@ -1830,7 +1818,7 @@ void VCXProjectWriter::outputFileConfigs(VCProject &project, XmlOutput &xml, Xml } bool fileAdded = false; - for (int i = 0; i < project.SingleProjects.count(); ++i) { + for (int i = 0; i < project.SingleProjects.size(); ++i) { OutputFilterData *d = &data[i]; if (!d->filter.Config) // only if the filter is not empty continue; diff --git a/qmake/generators/win32/msbuild_objectmodel.h b/qmake/generators/win32/msbuild_objectmodel.h index ce5711f2da..3d96a030e9 100644 --- a/qmake/generators/win32/msbuild_objectmodel.h +++ b/qmake/generators/win32/msbuild_objectmodel.h @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef MSBUILD_OBJECTMODEL_H #define MSBUILD_OBJECTMODEL_H diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index cf58ead2e9..b5df617927 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -1,37 +1,12 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "msvc_nmake.h" #include "option.h" #include <qregularexpression.h> #include <qdir.h> -#include <qdiriterator.h> +#include <qdirlisting.h> #include <qset.h> #include <time.h> @@ -174,6 +149,10 @@ QString NmakeMakefileGenerator::var(const ProKey &value) const return MakefileGenerator::var(value); } +void NmakeMakefileGenerator::suppressBuiltinRules(QTextStream &) const +{ +} + void NmakeMakefileGenerator::init() { /* this should probably not be here, but I'm using it to wrap the .t files */ @@ -285,9 +264,9 @@ QStringList NmakeMakefileGenerator::sourceFilesForImplicitRulesFilter() { QStringList filter; const QChar wildcard = QLatin1Char('*'); - for (const QString &ext : qAsConst(Option::c_ext)) + for (const QString &ext : std::as_const(Option::c_ext)) filter << wildcard + ext; - for (const QString &ext : qAsConst(Option::cpp_ext)) + for (const QString &ext : std::as_const(Option::cpp_ext)) filter << wildcard + ext; return filter; } @@ -311,7 +290,7 @@ void NmakeMakefileGenerator::writeImplicitRulesPart(QTextStream &t) for (int y = 0; directories[y]; y++) { QString dirTemp = project->first(directories[y]).toQString(); if (dirTemp.endsWith("\\")) - dirTemp.truncate(dirTemp.length()-1); + dirTemp.truncate(dirTemp.size()-1); if(!dirTemp.isEmpty()) source_directories.insert(dirTemp); } @@ -335,17 +314,15 @@ void NmakeMakefileGenerator::writeImplicitRulesPart(QTextStream &t) const QStringList sourceFilesFilter = sourceFilesForImplicitRulesFilter(); QStringList fixifiedSourceDirs = fileFixify(QList<QString>(source_directories.constBegin(), source_directories.constEnd()), FileFixifyAbsolute); fixifiedSourceDirs.removeDuplicates(); - for (const QString &sourceDir : qAsConst(fixifiedSourceDirs)) { - QDirIterator dit(sourceDir, sourceFilesFilter, QDir::Files | QDir::NoDotAndDotDot); - while (dit.hasNext()) { - dit.next(); - const QFileInfo fi = dit.fileInfo(); - QString &duplicate = fileNames[fi.completeBaseName()]; + constexpr auto filters = QDir::Files | QDir::NoDotAndDotDot; + for (const QString &sourceDir : std::as_const(fixifiedSourceDirs)) { + for (const auto &dirEntry : QDirListing(sourceDir, sourceFilesFilter, filters)) { + QString &duplicate = fileNames[dirEntry.completeBaseName()]; if (duplicate.isNull()) { - duplicate = fi.filePath(); + duplicate = dirEntry.filePath(); } else { warn_msg(WarnLogic, "%s conflicts with %s", qPrintable(duplicate), - qPrintable(fi.filePath())); + qPrintable(dirEntry.filePath())); duplicatesFound = true; } } @@ -361,7 +338,7 @@ void NmakeMakefileGenerator::writeImplicitRulesPart(QTextStream &t) project->variables().remove("QMAKE_RUN_CXX"); project->variables().remove("QMAKE_RUN_CC"); - for (const QString &sourceDir : qAsConst(source_directories)) { + for (const QString &sourceDir : std::as_const(source_directories)) { if (sourceDir.isEmpty()) continue; QString objDir = var("OBJECTS_DIR"); diff --git a/qmake/generators/win32/msvc_nmake.h b/qmake/generators/win32/msvc_nmake.h index 3064f06521..8839a24c65 100644 --- a/qmake/generators/win32/msvc_nmake.h +++ b/qmake/generators/win32/msvc_nmake.h @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef MSVC_NMAKE_H #define MSVC_NMAKE_H @@ -52,6 +27,7 @@ protected: QString defaultInstall(const QString &t) override; QStringList &findDependencies(const QString &file) override; QString var(const ProKey &value) const override; + void suppressBuiltinRules(QTextStream &t) const override; QString precompH, precompObj, precompPch; QString precompObjC, precompPchC; bool usePCH = false; diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp index cf4e2445b1..6517e5c451 100644 --- a/qmake/generators/win32/msvc_objectmodel.cpp +++ b/qmake/generators/win32/msvc_objectmodel.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "msvc_objectmodel.h" #include "msvc_vcproj.h" @@ -40,36 +15,42 @@ using namespace QMakeInternal; QT_BEGIN_NAMESPACE -static DotNET vsVersionFromString(const char *versionString) +DotNET vsVersionFromString(const ProString &versionString) { - struct VSVersionMapping - { - const char *str; - DotNET version; - }; - static VSVersionMapping mapping[] = { - { "7.0", NET2002 }, - { "7.1", NET2003 }, - { "8.0", NET2005 }, - { "9.0", NET2008 }, - { "10.0", NET2010 }, - { "11.0", NET2012 }, - { "12.0", NET2013 }, - { "14.0", NET2015 }, - { "15.0", NET2017 }, - { "16.0", NET2019 } - }; - DotNET result = NETUnknown; - for (const auto entry : mapping) { - if (strcmp(entry.str, versionString) == 0) - return entry.version; + int idx = versionString.indexOf(QLatin1Char('.')); + if (idx == -1) + return NETUnknown; + + QStringView versionView = versionString.toQStringView(); + int versionMajor = versionView.left(idx).toInt(); + int versionMinor = versionView.mid(idx + 1).toInt(); + + if (versionMajor == 17) + return NET2022; + if (versionMajor == 16) + return NET2019; + if (versionMajor == 15) + return NET2017; + if (versionMajor == 14) + return NET2015; + if (versionMajor == 12) + return NET2013; + if (versionMajor == 11) + return NET2012; + if (versionMajor == 10) + return NET2010; + if (versionMajor == 9) + return NET2008; + if (versionMajor == 8) + return NET2005; + if (versionMajor == 7) { + if (versionMinor == 0) + return NET2002; + if (versionMinor == 1) + return NET2003; } - return result; -} -DotNET vsVersionFromString(const ProString &versionString) -{ - return vsVersionFromString(versionString.toLatin1().constData()); + return NETUnknown; } // XML Tags --------------------------------------------------------- @@ -330,14 +311,12 @@ static QString vcCommandSeparator() // of the custom commands into it, and putting an "if errorlevel goto" statement behind it. // As we want every sub-command to be error-checked (as is done by makefile-based // backends), we insert the checks ourselves, using the undocumented jump target. - static QString cmdSep = - QLatin1String("
if errorlevel 1 goto VCReportError
"); - return cmdSep; + return QStringLiteral("
if errorlevel 1 goto VCReportError
"); } static void unknownOptionWarning(const char *tool, const char *option) { - static bool firstCall = true; + Q_CONSTINIT static bool firstCall = true; warn_msg(WarnLogic, "Could not parse %s option '%s'; added to AdditionalOptions.", tool, option); if (firstCall) { firstCall = false; @@ -404,7 +383,7 @@ VCCLCompilerTool::VCCLCompilerTool() CompileForArchitecture(archUnknown), InterworkCalls(unset), EnablePREfast(unset), - DisplayFullPaths(unset), + DisplayFullPaths(_False), MultiProcessorCompilation(unset), GenerateXMLDocumentationFiles(unset), CreateHotpatchableImage(unset) @@ -883,7 +862,7 @@ bool VCCLCompilerTool::parseOption(const char* option) } break; } - // Fallthrough + [[fallthrough]]; default: found = false; break; } @@ -1147,12 +1126,40 @@ bool VCCLCompilerTool::parseOption(const char* option) ShowIncludes = _True; break; } - if (strlen(option) > 8 && second == 't' && third == 'd') { - const QString version = option + 8; - static const QStringList knownVersions = { "14", "17", "latest" }; - if (knownVersions.contains(version)) { - LanguageStandard = "stdcpp" + version; - break; + if (strlen(option) > 7 && second == 't' && third == 'd' && fourth == ':') { + static const QRegularExpression rex("(c(?:\\+\\+)?)(.+)"); + auto m = rex.match(option + 5); + if (m.hasMatch()) { + QString *var = nullptr; + const QStringList *knownVersions = nullptr; + QString valuePrefix; + auto lang = m.capturedView(1); + auto version = m.capturedView(2); + if (lang == QStringLiteral("c++")) { + // Turn /std:c++17 into <LanguageStandard>stdcpp17</LanguageStandard> + static const QStringList knownCxxVersions = { + "14", + "17", + "20", + "latest" + }; + var = &LanguageStandard; + knownVersions = &knownCxxVersions; + valuePrefix = "stdcpp"; + } else if (lang == QStringLiteral("c")) { + // Turn /std:c17 into <LanguageStandard_C>stdc17</LanguageStandard_C> + static const QStringList knownCVersions = { + "11", + "17" + }; + var = &LanguageStandard_C; + knownVersions = &knownCVersions; + valuePrefix = "stdc"; + } + if (var && knownVersions->contains(version)) { + *var = valuePrefix + version; + break; + } } } found = false; break; @@ -1470,10 +1477,23 @@ bool VCLinkerTool::parseOption(const char* option) }else EnableUAC = _True; break; - case 0x3389797: // /DEBUG[:FASTLINK] - GenerateDebugInformation = _True; - if (config->CompilerVersion >= NET2015 && strcmp(option + 7, "FASTLINK") == 0) - DebugInfoOption = linkerDebugOptionFastLink; + case 0x3389797: // /DEBUG[:{FASTLINK|FULL|NONE}] + DebugInfoOption = linkerDebugOptionEnabled; + if (config->CompilerVersion >= NET2015 && *(option + 6) == ':') { + const char *str = option + 7; + if (qstricmp(str, "fastlink") == 0) + DebugInfoOption = linkerDebugOptionFastLink; + else if (qstricmp(str, "full") == 0) + DebugInfoOption = linkerDebugOptionFull; + else if (qstricmp(str, "none") == 0) + DebugInfoOption = linkerDebugOptionNone; + else + AdditionalOptions += option; + } + if (DebugInfoOption == linkerDebugOptionNone) + GenerateDebugInformation = _False; + else + GenerateDebugInformation = _True; break; case 0x0033896: // /DEF:filename ModuleDefinitionFile = option+5; @@ -1520,7 +1540,7 @@ bool VCLinkerTool::parseOption(const char* option) { QStringList both = QString(option+6).split(","); HeapReserveSize = both[0].toLongLong(); - if(both.count() == 2) + if(both.size() == 2) HeapCommitSize = both[1].toLongLong(); } break; @@ -1560,24 +1580,28 @@ bool VCLinkerTool::parseOption(const char* option) case 0x0d745c8: // /LIBPATH:dir AdditionalLibraryDirectories += option+9; break; - case 0x0341877: // /LTCG[:NOSTATUS|:STATUS] - config->WholeProgramOptimization = _True; - if (config->CompilerVersion >= NET2005) { - LinkTimeCodeGeneration = optLTCGEnabled; - if(*(option+5) == ':') { - const char* str = option+6; - if (*str == 'S') - ShowProgress = linkProgressAll; - else if (qstricmp(str, "pginstrument") == 0) - LinkTimeCodeGeneration = optLTCGInstrument; - else if (qstricmp(str, "pgoptimize") == 0) - LinkTimeCodeGeneration = optLTCGOptimize; - else if (qstricmp(str, "pgupdate") == 0) - LinkTimeCodeGeneration = optLTCGUpdate; - } - } else { - AdditionalOptions.append(option); + case 0x0341877: // /LTCG[:{INCREMENTAL|NOSTATUS|STATUS|OFF}] + // /LTCG:{PGINSTRUMENT|PGOPTIMIZE|PGUPDATE} + LinkTimeCodeGeneration = optLTCGEnabled; + if (*(option + 5) == ':') { + const char* str = option + 6; + if (qstricmp(str, "status") == 0) + ShowProgress = linkProgressAll; + else if (qstricmp(str, "off") == 0) + LinkTimeCodeGeneration = optLTCGDefault; + else if (qstricmp(str, "incremental") == 0) + LinkTimeCodeGeneration = optLTCGIncremental; + else if (qstricmp(str, "pginstrument") == 0) + LinkTimeCodeGeneration = optLTCGInstrument; + else if (qstricmp(str, "pgoptimize") == 0) + LinkTimeCodeGeneration = optLTCGOptimize; + else if (qstricmp(str, "pgupdate") == 0) + LinkTimeCodeGeneration = optLTCGUpdate; + else + AdditionalOptions.append(option); } + if (LinkTimeCodeGeneration != optLTCGDefault) + config->WholeProgramOptimization = _True; break; case 0x379ED25: case 0x157cf65: // /MACHINE:{AM33|ARM|CEE|IA64|X86|M32R|MIPS|MIPS16|MIPSFPU|MIPSFPU16|MIPSR41XX|PPC|SH3|SH4|SH5|THUMB|TRICORE} @@ -1705,7 +1729,7 @@ bool VCLinkerTool::parseOption(const char* option) { QStringList both = QString(option+7).split(","); StackReserveSize = both[0].toLongLong(); - if(both.count() == 2) + if(both.size() == 2) StackCommitSize = both[1].toLongLong(); } break; @@ -2208,13 +2232,13 @@ void VCFilter::addFile(const VCFilterFile& fileInfo) void VCFilter::addFiles(const QStringList& fileList) { - for (int i = 0; i < fileList.count(); ++i) + for (int i = 0; i < fileList.size(); ++i) addFile(fileList.at(i)); } void VCFilter::addFiles(const ProStringList& fileList) { - for (int i = 0; i < fileList.count(); ++i) + for (int i = 0; i < fileList.size(); ++i) addFile(fileList.at(i).toQString()); } @@ -2248,7 +2272,7 @@ void VCFilter::modifyPCHstage(QString str) lines << "* WARNING: All changes made in this file will be lost."; lines << "--------------------------------------------------------------------*/"; lines << "#include \"" + Project->precompHFilename + "\""; - for (const QString &line : qAsConst(lines)) + for (const QString &line : std::as_const(lines)) CustomBuildTool.CommandLine += "echo " + line + ">>" + toFile; return; } @@ -2281,7 +2305,7 @@ void VCFilter::modifyPCHstage(QString str) VCFilterFile VCFilter::findFile(const QString &filePath, bool *found) const { - for (int i = 0; i < Files.count(); ++i) { + for (int i = 0; i < Files.size(); ++i) { const VCFilterFile &f = Files.at(i); if (f.file == filePath) { *found = true; @@ -2307,7 +2331,7 @@ bool VCFilter::addExtraCompiler(const VCFilterFile &info) hasBuiltIn = Project->hasBuiltinCompiler(objectMappedFile); // Remove the fake file suffix we've added initially to generate correct command lines. - inFile.chop(Project->customBuildToolFilterFileSuffix.length()); + inFile.chop(Project->customBuildToolFilterFileSuffix.size()); // qDebug("*** Extra compiler file has object mapped file '%s' => '%s'", qPrintable(inFile), qPrintable(objectMappedFile.join(' '))); } @@ -2319,7 +2343,7 @@ bool VCFilter::addExtraCompiler(const VCFilterFile &info) CustomBuildTool.ToolPath.clear(); CustomBuildTool.ToolName = QLatin1String(_VCCustomBuildTool); - for (int x = 0; x < extraCompilers.count(); ++x) { + for (int x = 0; x < extraCompilers.size(); ++x) { const QString &extraCompilerName = extraCompilers.at(x); if (!Project->verifyExtraCompiler(extraCompilerName, inFile) && !hasBuiltIn) @@ -2364,7 +2388,7 @@ bool VCFilter::addExtraCompiler(const VCFilterFile &info) configs.contains("dep_existing_only"), true /* checkCommandAvailability */); } - for (int i = 0; i < deps.count(); ++i) + for (int i = 0; i < deps.size(); ++i) deps[i] = Option::fixPathToTargetOS( Project->replaceExtraCompilerVariables( deps.at(i), inFile, out, MakefileGenerator::NoShell), @@ -2373,9 +2397,9 @@ bool VCFilter::addExtraCompiler(const VCFilterFile &info) if (combined) { // Add dependencies for each file const ProStringList &tmp_in = Project->project->values(ProKey(extraCompilerName + ".input")); - for (int a = 0; a < tmp_in.count(); ++a) { + for (int a = 0; a < tmp_in.size(); ++a) { const ProStringList &files = Project->project->values(tmp_in.at(a).toKey()); - for (int b = 0; b < files.count(); ++b) { + for (int b = 0; b < files.size(); ++b) { QString file = files.at(b).toQString(); deps += Project->findDependencies(file); inputs += Option::fixPathToTargetOS(file, false); @@ -2405,10 +2429,11 @@ bool VCFilter::addExtraCompiler(const VCFilterFile &info) cmd_name = cmd.left(space); else cmd_name = cmd; + cmd_name = cmd_name.trimmed(); } // Fixify paths - for (int i = 0; i < deps.count(); ++i) + for (int i = 0; i < deps.size(); ++i) deps[i] = Option::fixPathToTargetOS(deps[i], false); @@ -2426,7 +2451,7 @@ bool VCFilter::addExtraCompiler(const VCFilterFile &info) deps += CustomBuildTool.AdditionalDependencies; // Make sure that all deps are only once QStringList uniqDeps; - for (int c = 0; c < deps.count(); ++c) { + for (int c = 0; c < deps.size(); ++c) { QString aDep = deps.at(c); if (!aDep.isEmpty()) uniqDeps << aDep; @@ -2437,7 +2462,7 @@ bool VCFilter::addExtraCompiler(const VCFilterFile &info) // Ensure that none of the output files are also dependencies. Or else, the custom buildstep // will be rebuild every time, even if nothing has changed. - for (const QString &output : qAsConst(CustomBuildTool.Outputs)) + for (const QString &output : std::as_const(CustomBuildTool.Outputs)) CustomBuildTool.AdditionalDependencies.removeAll(output); useCustomBuildTool = !CustomBuildTool.CommandLine.isEmpty(); @@ -2472,7 +2497,7 @@ const VCFilter &VCProjectSingleConfig::filterByName(const QString &name) const const VCFilter &VCProjectSingleConfig::filterForExtraCompiler(const QString &compilerName) const { - for (int i = 0; i < ExtraCompilersFiles.count(); ++i) + for (int i = 0; i < ExtraCompilersFiles.size(); ++i) if (ExtraCompilersFiles.at(i).Name == compilerName) return ExtraCompilersFiles.at(i); @@ -2552,7 +2577,7 @@ void VCProjectWriter::write(XmlOutput &xml, VCProjectSingleConfig &tool) outputFilter(tempProj, xml, "Distribution Files"); QSet<QString> extraCompilersInProject; - for (int i = 0; i < tool.ExtraCompilersFiles.count(); ++i) { + for (int i = 0; i < tool.ExtraCompilersFiles.size(); ++i) { const QString &compilerName = tool.ExtraCompilersFiles.at(i).Name; if (!extraCompilersInProject.contains(compilerName)) { extraCompilersInProject += compilerName; @@ -2560,7 +2585,7 @@ void VCProjectWriter::write(XmlOutput &xml, VCProjectSingleConfig &tool) } } - for (int x = 0; x < tempProj.ExtraCompilers.count(); ++x) { + for (int x = 0; x < tempProj.ExtraCompilers.size(); ++x) { outputFilter(tempProj, xml, tempProj.ExtraCompilers.at(x)); } outputFilter(tempProj, xml, "Root Files"); @@ -2571,7 +2596,7 @@ void VCProjectWriter::write(XmlOutput &xml, VCProjectSingleConfig &tool) void VCProjectWriter::write(XmlOutput &xml, VCProject &tool) { - if (tool.SingleProjects.count() == 0) { + if (tool.SingleProjects.size() == 0) { warn_msg(WarnLogic, "Generator: .NET: no single project in merge project, no output"); return; } @@ -2591,7 +2616,7 @@ void VCProjectWriter::write(XmlOutput &xml, VCProject &tool) << closetag(_Platforms) << tag(_Configurations); // Output each configuration - for (int i = 0; i < tool.SingleProjects.count(); ++i) + for (int i = 0; i < tool.SingleProjects.size(); ++i) write(xml, tool.SingleProjects.at(i).Configuration); xml << closetag(_Configurations) << tag(q_Files); @@ -2604,7 +2629,7 @@ void VCProjectWriter::write(XmlOutput &xml, VCProject &tool) outputFilter(tool, xml, "Resource Files"); outputFilter(tool, xml, "Deployment Files"); outputFilter(tool, xml, "Distribution Files"); - for (int x = 0; x < tool.ExtraCompilers.count(); ++x) { + for (int x = 0; x < tool.ExtraCompilers.size(); ++x) { outputFilter(tool, xml, tool.ExtraCompilers.at(x)); } outputFilter(tool, xml, "Root Files"); @@ -2906,7 +2931,7 @@ void VCProjectWriter::write(XmlOutput &xml, const VCConfiguration &tool) void VCProjectWriter::write(XmlOutput &xml, VCFilter &tool) { - if(!tool.Files.count()) + if(!tool.Files.size()) return; if (!tool.Name.isEmpty()) { @@ -2916,7 +2941,7 @@ void VCProjectWriter::write(XmlOutput &xml, VCFilter &tool) << attrS(_UniqueIdentifier, tool.Guid) << attrT(_ParseFiles, tool.ParseFiles); } - for (int i = 0; i < tool.Files.count(); ++i) { + for (int i = 0; i < tool.Files.size(); ++i) { const VCFilterFile &info = tool.Files.at(i); xml << tag(q_File) << attrS(_RelativePath, Option::fixPathToTargetOS(info.file)) @@ -2940,11 +2965,11 @@ void VCProjectWriter::outputFilter(VCProject &project, XmlOutput &xml, const QSt QString name, extfilter, guid; triState parse = unset; - for (int i = 0; i < project.SingleProjects.count(); ++i) { + for (int i = 0; i < project.SingleProjects.size(); ++i) { const VCFilter filter = project.SingleProjects.at(i).filterByName(filtername); // Merge all files in this filter to root tree - for (int x = 0; x < filter.Files.count(); ++x) + for (int x = 0; x < filter.Files.size(); ++x) root->addElement(filter.Files.at(x)); // Save filter setting from first filter. Next filters @@ -2979,7 +3004,7 @@ void VCProjectWriter::outputFileConfigs(VCProject &project, XmlOutput &xml, cons { xml << tag(q_File) << attrS(_RelativePath, Option::fixPathToTargetOS(info.file)); - for (int i = 0; i < project.SingleProjects.count(); ++i) { + for (int i = 0; i < project.SingleProjects.size(); ++i) { VCFilter filter = project.SingleProjects.at(i).filterByName(filtername); if (filter.Config) // only if the filter is not empty outputFileConfig(filter, xml, info.file); diff --git a/qmake/generators/win32/msvc_objectmodel.h b/qmake/generators/win32/msvc_objectmodel.h index 84f76ce224..190d6c727f 100644 --- a/qmake/generators/win32/msvc_objectmodel.h +++ b/qmake/generators/win32/msvc_objectmodel.h @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef MSVC_OBJECTMODEL_H #define MSVC_OBJECTMODEL_H @@ -53,7 +28,8 @@ enum DotNET { NET2013 = 0xc0, NET2015 = 0xd0, NET2017 = 0xe0, - NET2019 + NET2019, + NET2022 }; DotNET vsVersionFromString(const ProString &versionString); @@ -282,7 +258,9 @@ enum inlineExpansionOption { }; enum linkerDebugOption { linkerDebugOptionNone, - linkerDebugOptionFastLink + linkerDebugOptionEnabled, // represents /DEBUG without further options + linkerDebugOptionFastLink, + linkerDebugOptionFull }; enum linkIncrementalType { linkIncrementalDefault, @@ -355,6 +333,7 @@ enum optWin98Type { enum optLinkTimeCodeGenType { optLTCGDefault, optLTCGEnabled, + optLTCGIncremental, optLTCGInstrument, optLTCGOptimize, optLTCGUpdate @@ -527,6 +506,7 @@ public: inlineExpansionOption InlineFunctionExpansion; triState KeepComments; QString LanguageStandard; + QString LanguageStandard_C; triState MinimalRebuild; QString ObjectFile; triState OmitDefaultLibName; diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index ce4ce5769a..2192535867 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "msvc_vcproj.h" #include "option.h" @@ -33,16 +8,20 @@ #include <ioutils.h> #include <qdir.h> -#include <qdiriterator.h> +#include <qdirlisting.h> #include <qcryptographichash.h> #include <qhash.h> #include <quuid.h> +#include <qregularexpression.h> #include <stdlib.h> +#include <tuple> +#include <utility> //#define DEBUG_SOLUTION_GEN using namespace QMakeInternal; +using namespace Qt::StringLiterals; QT_BEGIN_NAMESPACE // Filter GUIDs (Do NOT change these!) ------------------------------ @@ -75,6 +54,8 @@ const char _slnHeader141[] = "Microsoft Visual Studio Solution File, Format "\n# Visual Studio 15"; const char _slnHeader142[] = "Microsoft Visual Studio Solution File, Format Version 12.00" "\n# Visual Studio Version 16"; +const char _slnHeader143[] = "Microsoft Visual Studio Solution File, Format Version 12.00" + "\n# Visual Studio Version 17"; // The following UUID _may_ change for later servicepacks... // If so we need to search through the registry at // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\7.0\Projects @@ -161,24 +142,24 @@ bool VcprojGenerator::writeProjectMakefile() // Generate project file if(project->first("TEMPLATE") == "vcapp" || project->first("TEMPLATE") == "vclib") { - if (!mergedProjects.count()) { + if (!mergedProjects.size()) { warn_msg(WarnLogic, "Generator: MSVC.NET: no single configuration created, cannot output project!"); return false; } debug_msg(1, "Generator: MSVC.NET: Writing project file"); VCProject mergedProject; - for (int i = 0; i < mergedProjects.count(); ++i) { + for (int i = 0; i < mergedProjects.size(); ++i) { VCProjectSingleConfig *singleProject = &(mergedProjects.at(i)->vcProject); mergedProject.SingleProjects += *singleProject; - for (int j = 0; j < singleProject->ExtraCompilersFiles.count(); ++j) { + for (int j = 0; j < singleProject->ExtraCompilersFiles.size(); ++j) { const QString &compilerName = singleProject->ExtraCompilersFiles.at(j).Name; if (!mergedProject.ExtraCompilers.contains(compilerName)) mergedProject.ExtraCompilers += compilerName; } } - if(mergedProjects.count() > 1 && + if(mergedProjects.size() > 1 && mergedProjects.at(0)->vcProject.Name == mergedProjects.at(1)->vcProject.Name) mergedProjects.at(0)->writePrlFile(); @@ -296,21 +277,7 @@ QString VcprojGenerator::retrievePlatformToolSet() const if (!envVar.isEmpty()) return envVar; - switch (vcProject.Configuration.CompilerVersion) - { - case NET2012: - return QStringLiteral("v110"); - case NET2013: - return QStringLiteral("v120"); - case NET2015: - return QStringLiteral("v140"); - case NET2017: - return QStringLiteral("v141"); - case NET2019: - return QStringLiteral("v142"); - default: - return QString(); - } + return u"v"_s + project->first("MSVC_TOOLSET_VER"); } bool VcprojGenerator::isStandardSuffix(const QString &suffix) const @@ -382,7 +349,7 @@ ProStringList VcprojGenerator::collectDependencies(QMakeProject *proj, QHash<QSt collectedSubdirs.append(qMakePair(tmpdir.toQString(), proj->values(ProKey(tmp_proj_subdirs.at(x) + ".depends")))); projLookup.insert(tmp_proj_subdirs.at(x).toQString(), tmpdir.toQString()); } - for (const auto &subdir : qAsConst(collectedSubdirs)) { + for (const auto &subdir : std::as_const(collectedSubdirs)) { QString profile = subdir.first; QFileInfo fi(fileInfo(Option::normalizePath(profile))); if (fi.exists()) { @@ -451,7 +418,7 @@ ProStringList VcprojGenerator::collectDependencies(QMakeProject *proj, QHash<QSt newDep->uuid = tmp_proj.isEmpty("QMAKE_UUID") ? getProjectUUID(Option::fixPathToLocalOS(vcprojDir + QDir::separator() + vcproj)).toString().toUpper(): tmp_proj.first("QMAKE_UUID").toQString(); // We want to store it as the .lib name. if (newDep->target.endsWith(".dll")) - newDep->target = newDep->target.left(newDep->target.length()-3) + "lib"; + newDep->target = newDep->target.left(newDep->target.size()-3) + "lib"; projGuids.insert(newDep->projectName, newDep->target); if (tmpList.size()) { @@ -535,6 +502,9 @@ void VcprojGenerator::writeSubDirs(QTextStream &t) } switch (vcProject.Configuration.CompilerVersion) { + case NET2022: + t << _slnHeader143; + break; case NET2019: t << _slnHeader142; break; @@ -664,10 +634,10 @@ void VcprojGenerator::writeSubDirs(QTextStream &t) bool VcprojGenerator::hasBuiltinCompiler(const QString &file) { // Source files - for (int i = 0; i < Option::cpp_ext.count(); ++i) + for (int i = 0; i < Option::cpp_ext.size(); ++i) if (file.endsWith(Option::cpp_ext.at(i))) return true; - for (int i = 0; i < Option::c_ext.count(); ++i) + for (int i = 0; i < Option::c_ext.size(); ++i) if (file.endsWith(Option::c_ext.at(i))) return true; if (file.endsWith(".rc") @@ -797,41 +767,70 @@ void VcprojGenerator::init() if (autogenPrecompSource) { precompSource = precompH + (pchIsCFile - ? (Option::c_ext.count() ? Option::c_ext.at(0) : QLatin1String(".c")) - : (Option::cpp_ext.count() ? Option::cpp_ext.at(0) : QLatin1String(".cpp"))); + ? (Option::c_ext.size() ? Option::c_ext.at(0) : QLatin1String(".c")) + : (Option::cpp_ext.size() ? Option::cpp_ext.at(0) : QLatin1String(".cpp"))); project->values("GENERATED_SOURCES") += precompSource; } else if (!precompSource.isEmpty()) { project->values("SOURCES") += precompSource; } } - // Add all input files for a custom compiler into a map for uniqueness, - // unless the compiler is configure as a combined stage, then use the first one + // Helper function to create a fake file foo.cbt for the project view. + // + // This prevents VS from complaining about a circular dependency from "foo -> foo". + // + // The .cbt file is added as "source" of the Custom Build Tool. This means, in the project + // view, this is the file the Custom Build Tool property page is attached to. + // + // This function returns a pair with + // - the fully resolved output file path + // - the file path of the .cbt file + auto addExtraCompilerSourceWithCustomBuildToolFakeFile + = [this](const QString &compilerOutput, const ProString &extraCompiler, + const QStringList &inputs) -> std::pair<QString, QString> + { + QString realOut = replaceExtraCompilerVariables(compilerOutput, inputs, {}, NoShell); + QString out = realOut + customBuildToolFilterFileSuffix; + createCustomBuildToolFakeFile(out, realOut); + out = Option::fixPathToTargetOS(out, false); + extraCompilerSources[out] += extraCompiler.toQString(); + return { realOut, out }; + }; + + // Add all input files for a custom compiler into a map for uniqueness. + // + // Use .cbt files for the following cases: + // - CONFIG += combine + // - the input has a built-in compiler (e.g. C++ source file) for (const ProString &quc : project->values("QMAKE_EXTRA_COMPILERS")) { const ProStringList &invar = project->values(ProKey(quc + ".input")); const QString compiler_out = project->first(ProKey(quc + ".output")).toQString(); - for (ProStringList::ConstIterator iit = invar.constBegin(); iit != invar.constEnd(); ++iit) { - ProStringList fileList = project->values((*iit).toKey()); - if (!fileList.isEmpty()) { - if (project->values(ProKey(quc + ".CONFIG")).indexOf("combine") != -1) - fileList.erase(fileList.begin() + 1, fileList.end()); - for (ProStringList::ConstIterator fit = fileList.constBegin(); fit != fileList.constEnd(); ++fit) { - QString file = (*fit).toQString(); - if (verifyExtraCompiler(quc, file)) { - if (!hasBuiltinCompiler(file)) { - extraCompilerSources[file] += quc.toQString(); - } else { - // Create a fake file foo.moc.cbt for the project view. - // This prevents VS from complaining about a circular - // dependency from foo.moc -> foo.moc. - QString realOut = replaceExtraCompilerVariables( - compiler_out, file, QString(), NoShell); - QString out = realOut + customBuildToolFilterFileSuffix; - createCustomBuildToolFakeFile(out, realOut); - out = Option::fixPathToTargetOS(out, false); - extraCompilerSources[out] += quc.toQString(); - extraCompilerOutputs[out] = file; - } + + QStringList inputFiles; + for (auto it = invar.begin(); it != invar.end(); ++it) + inputFiles += project->values(it->toKey()).toQStringList(); + + if (project->values(ProKey(quc + ".CONFIG")).contains("combine")) { + // Handle "CONFIG += combine" extra compilers. + QString realOut; + QString out; + std::tie(realOut, out) + = addExtraCompilerSourceWithCustomBuildToolFakeFile(compiler_out, quc, inputFiles); + if (hasBuiltinCompiler(realOut)) + extraCompilerOutputs[out] = realOut; + } else { + // Handle regular 1-to-1 extra compilers. + for (const QString &file : inputFiles) { + if (verifyExtraCompiler(quc, file)) { + if (!hasBuiltinCompiler(file)) { + extraCompilerSources[file] += quc.toQString(); + } else { + QString out; + std::tie(std::ignore, out) + = addExtraCompilerSourceWithCustomBuildToolFakeFile(compiler_out, + quc, + QStringList(file)); + extraCompilerOutputs[out] = file; } } } @@ -842,7 +841,7 @@ void VcprojGenerator::init() for (auto it = extraCompilerSources.cbegin(), end = extraCompilerSources.cend(); it != end; ++it) qDebug("Extracompilers for %s are (%s)", it.key().toLatin1().constData(), it.value().join(", ").toLatin1().constData()); for (auto it = extraCompilerOutputs.cbegin(), end = extraCompilerOutputs.cend(); it != end; ++it) - qDebug("Object mapping for %s is (%s)", it.key().toLatin1().constData(), it.value().join(", ").toLatin1().constData()); + qDebug("Object mapping for %s is (%s)", qPrintable(it.key()), qPrintable(it.value())); qDebug(""); #endif } @@ -883,6 +882,9 @@ void VcprojGenerator::initProject() // Own elements ----------------------------- vcProject.Name = project->first("QMAKE_ORIG_TARGET").toQString(); switch (vcProject.Configuration.CompilerVersion) { + case NET2022: + vcProject.Version = "17.00"; + break; case NET2019: vcProject.Version = "16.00"; break; @@ -1034,6 +1036,20 @@ void VcprojGenerator::initConfiguration() initPreLinkEventTools(); } +// Filter from the given QMAKE_CFLAGS the options that are relevant +// for the vcxproj-global VCCLCompilerTool. +static ProStringList relevantCFlags(const ProStringList &flags) +{ + ProStringList result; + static const QRegularExpression rex("^[/-]std:"); + for (const ProString &flag : flags) { + if (rex.match(flag.toQString()).hasMatch()) { + result.append(flag); + } + } + return result; +} + void VcprojGenerator::initCompilerTool() { QString placement = project->first("OBJECTS_DIR").toQString(); @@ -1056,6 +1072,7 @@ void VcprojGenerator::initCompilerTool() conf.compiler.ForcedIncludeFiles = project->values("PRECOMPILED_HEADER").toQStringList(); } + conf.compiler.parseOptions(relevantCFlags(project->values("QMAKE_CFLAGS"))); conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS")); if (project->isActiveConfig("windows")) @@ -1196,7 +1213,7 @@ void VcprojGenerator::initDeploymentTool() continue; // We want to deploy .dlls not .libs if (dllName.endsWith(QLatin1String(".lib"))) - dllName.replace(dllName.length() - 3, 3, QLatin1String("dll")); + dllName.replace(dllName.size() - 3, 3, QLatin1String("dll")); // Use only the file name and check in Qt's install path and LIBPATHs to check for existence dllName.remove(0, dllName.lastIndexOf(QLatin1Char('/')) + 1); QFileInfo info; @@ -1276,18 +1293,16 @@ void VcprojGenerator::initDeploymentTool() } int pathSize = searchPath.size(); - QDirIterator iterator(searchPath, QStringList() << nameFilter - , QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks - , QDirIterator::Subdirectories); + constexpr auto filters = QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks; + using F = QDirListing::IteratorFlag; + QDirListing dirList(searchPath, QStringList{nameFilter}, filters, F::Recursive); // foreach dirIterator-entry in d - while(iterator.hasNext()) { - iterator.next(); - - QString absoluteItemPath = Option::fixPathToTargetOS(QFileInfo(iterator.filePath()).absolutePath()); + for (const auto &dirEntry : dirList) { + const QString absoluteItemPath = Option::fixPathToTargetOS(dirEntry.absolutePath()); // Identify if it is just another subdir int diffSize = absoluteItemPath.size() - pathSize; // write out rules - conf.deployment.AdditionalFiles += iterator.fileName() + conf.deployment.AdditionalFiles += dirEntry.fileName() + "|" + absoluteItemPath + "|" + itemDevicePath + (diffSize ? (absoluteItemPath.right(diffSize)) : QLatin1String("")) + "|0;"; @@ -1529,13 +1544,14 @@ void VcprojGenerator::initExtraCompilerOutputs() if (!outputs.isEmpty()) tmp_out = outputs.first().toQString(); if (project->values(ProKey(*it + ".CONFIG")).indexOf("combine") != -1) { - // Combined output, only one file result + // Combined output, only one file result. Use .cbt file. extraCompile.addFile(Option::fixPathToTargetOS( - replaceExtraCompilerVariables(tmp_out, QString(), QString(), NoShell), false)); + replaceExtraCompilerVariables(tmp_out + customBuildToolFilterFileSuffix, + QString(), QString(), NoShell), false)); } else if (!inputVars.isEmpty()) { // One output file per input const ProStringList &tmp_in = project->values(inputVars.first().toKey()); - for (int i = 0; i < tmp_in.count(); ++i) { + for (int i = 0; i < tmp_in.size(); ++i) { const QString &filename = tmp_in.at(i).toQString(); if (extraCompilerSources.contains(filename) && !otherFiltersContain(filename)) extraCompile.addFile(Option::fixPathToTargetOS( @@ -1550,7 +1566,7 @@ void VcprojGenerator::initExtraCompilerOutputs() for (const ProString &inputVar : inputVars) { if (!otherFilters.contains(inputVar)) { const ProStringList &tmp_in = project->values(inputVar.toKey()); - for (int i = 0; i < tmp_in.count(); ++i) { + for (int i = 0; i < tmp_in.size(); ++i) { const QString &filename = tmp_in.at(i).toQString(); if (extraCompilerSources.contains(filename) && !otherFiltersContain(filename)) extraCompile.addFile(Option::fixPathToTargetOS( diff --git a/qmake/generators/win32/msvc_vcproj.h b/qmake/generators/win32/msvc_vcproj.h index c565b709d2..aa4cc53c70 100644 --- a/qmake/generators/win32/msvc_vcproj.h +++ b/qmake/generators/win32/msvc_vcproj.h @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef MSVC_VCPROJ_H #define MSVC_VCPROJ_H diff --git a/qmake/generators/win32/msvc_vcxproj.cpp b/qmake/generators/win32/msvc_vcxproj.cpp index ccbbf8cbac..1b5541bb16 100644 --- a/qmake/generators/win32/msvc_vcxproj.cpp +++ b/qmake/generators/win32/msvc_vcxproj.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "msvc_vcxproj.h" #include "msbuild_objectmodel.h" diff --git a/qmake/generators/win32/msvc_vcxproj.h b/qmake/generators/win32/msvc_vcxproj.h index 7e02b6c32f..05e5a4c9da 100644 --- a/qmake/generators/win32/msvc_vcxproj.h +++ b/qmake/generators/win32/msvc_vcxproj.h @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef MSVC_VCXPROJ_H #define MSVC_VCXPROJ_H diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp index 422919b872..c8317389f5 100644 --- a/qmake/generators/win32/winmakefile.cpp +++ b/qmake/generators/win32/winmakefile.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "winmakefile.h" #include "option.h" @@ -199,9 +174,9 @@ bool Win32MakefileGenerator::processPrlFileBase(QString &origFile, QStringView o { if (MakefileGenerator::processPrlFileBase(origFile, origName, fixedBase, slashOff)) return true; - for (int off = fixedBase.length(); off > slashOff; off--) { + for (int off = fixedBase.size(); off > slashOff; off--) { if (!fixedBase.at(off - 1).isDigit()) { - if (off != fixedBase.length()) { + if (off != fixedBase.size()) { return MakefileGenerator::processPrlFileBase( origFile, origName, fixedBase.left(off), slashOff); } @@ -504,8 +479,8 @@ void Win32MakefileGenerator::writeCleanParts(QTextStream &t) const int commandlineLimit = 2047; // NT limit, expanded for (ProStringList::ConstIterator it = list.begin(); it != list.end(); ++it) { file = ' ' + escapeFilePath(Option::fixPathToTargetOS((*it).toQString())); - if(del_statement.length() + files.length() + - qMax(fixEnvVariables(file).length(), file.length()) > commandlineLimit) { + if(del_statement.size() + files.size() + + qMax(fixEnvVariables(file).size(), file.size()) > commandlineLimit) { t << "\n\t" << del_statement << files; files.clear(); } @@ -533,8 +508,8 @@ void Win32MakefileGenerator::writeCleanParts(QTextStream &t) const int commandlineLimit = 2047; // NT limit, expanded for (ProStringList::ConstIterator it = list.begin(); it != list.end(); ++it) { file = " " + escapeFilePath(Option::fixPathToTargetOS((*it).toQString())); - if(del_statement.length() + files.length() + - qMax(fixEnvVariables(file).length(), file.length()) > commandlineLimit) { + if(del_statement.size() + files.size() + + qMax(fixEnvVariables(file).size(), file.size()) > commandlineLimit) { t << "\n\t" << del_statement << files; files.clear(); } @@ -711,7 +686,7 @@ void Win32MakefileGenerator::writeRcFilePart(QTextStream &t) const ProStringList rcIncPaths = project->values("RC_INCLUDEPATH"); QString incPathStr; - for (int i = 0; i < rcIncPaths.count(); ++i) { + for (int i = 0; i < rcIncPaths.size(); ++i) { const ProString &path = rcIncPaths.at(i); if (path.isEmpty()) continue; @@ -774,7 +749,7 @@ QString Win32MakefileGenerator::defaultInstall(const QString &t) QString dst_prl = Option::fixPathToTargetOS(project->first("QMAKE_INTERNAL_PRL_FILE").toQString()); int slsh = dst_prl.lastIndexOf(Option::dir_sep); if(slsh != -1) - dst_prl = dst_prl.right(dst_prl.length() - slsh - 1); + dst_prl = dst_prl.right(dst_prl.size() - slsh - 1); dst_prl = filePrefixRoot(root, targetdir + dst_prl); if (!ret.isEmpty()) ret += "\n\t"; diff --git a/qmake/generators/win32/winmakefile.h b/qmake/generators/win32/winmakefile.h index 180bd0fde8..bdab01b488 100644 --- a/qmake/generators/win32/winmakefile.h +++ b/qmake/generators/win32/winmakefile.h @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef WINMAKEFILE_H #define WINMAKEFILE_H diff --git a/qmake/generators/xmloutput.cpp b/qmake/generators/xmloutput.cpp index c43f8d810b..be64176f33 100644 --- a/qmake/generators/xmloutput.cpp +++ b/qmake/generators/xmloutput.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "xmloutput.h" @@ -103,7 +78,7 @@ void XmlOutput::decreaseIndent() QString XmlOutput::doConversion(const QString &text) { - if (!text.count()) + if (!text.size()) return QString(); else if (conversion == NoConversion) return text; @@ -112,10 +87,10 @@ QString XmlOutput::doConversion(const QString &text) if (conversion == XMLConversion) { // this is a way to escape characters that shouldn't be converted - for (int i=0; i<text.count(); ++i) { + for (int i=0; i<text.size(); ++i) { const QChar c = text.at(i); if (c == QLatin1Char('&')) { - if ( (i + 7) < text.count() && + if ( (i + 7) < text.size() && text.at(i + 1) == QLatin1Char('#') && text.at(i + 2) == QLatin1Char('x') && text.at(i + 7) == QLatin1Char(';') ) { @@ -184,9 +159,9 @@ XmlOutput& XmlOutput::operator<<(const xml_output& o) addRaw(QString("\n%1<Import %2=\"%3\" />").arg(currentIndent).arg(o.xo_text).arg(o.xo_value)); break; case tCloseTag: - if (o.xo_value.count()) + if (o.xo_value.size()) closeAll(); - else if (o.xo_text.count()) + else if (o.xo_text.size()) closeTo(o.xo_text); else closeTag(); @@ -201,7 +176,7 @@ XmlOutput& XmlOutput::operator<<(const xml_output& o) { // Special case to be able to close tag in normal // way ("</tag>", not "/>") without using addRaw().. - if (!o.xo_text.count()) { + if (!o.xo_text.size()) { closeOpen(); break; } @@ -230,14 +205,14 @@ XmlOutput& XmlOutput::operator<<(const xml_output& o) // Output functions ---------------------------------------------------------- void XmlOutput::newTag(const QString &tag) { - Q_ASSERT_X(tag.count(), "XmlOutput", "Cannot open an empty tag"); + Q_ASSERT_X(tag.size(), "XmlOutput", "Cannot open an empty tag"); newTagOpen(tag); closeOpen(); } void XmlOutput::newTagOpen(const QString &tag) { - Q_ASSERT_X(tag.count(), "XmlOutput", "Cannot open an empty tag"); + Q_ASSERT_X(tag.size(), "XmlOutput", "Cannot open an empty tag"); closeOpen(); if (format == NewLine) @@ -265,9 +240,9 @@ void XmlOutput::closeTag() { switch(currentState) { case Bare: - if (tagStack.count()) + if (tagStack.size()) //warn_msg(WarnLogic, "<Root>: Cannot close tag in Bare state, %d tags on stack", tagStack.count()); - qDebug("<Root>: Cannot close tag in Bare state, %d tags on stack", int(tagStack.count())); + qDebug("<Root>: Cannot close tag in Bare state, %d tags on stack", int(tagStack.size())); else //warn_msg(WarnLogic, "<Root>: Cannot close tag, no tags on stack"); qDebug("<Root>: Cannot close tag, no tags on stack"); @@ -296,7 +271,7 @@ void XmlOutput::closeTo(const QString &tag) qDebug("<%s>: Cannot close to tag <%s>, not on stack", tagStack.last().toLatin1().constData(), tag.toLatin1().constData()); return; } - int left = tagStack.count(); + int left = tagStack.size(); while (left-- && cont) { cont = tagStack.last().compare(tag) != 0; closeTag(); @@ -305,7 +280,7 @@ void XmlOutput::closeTo(const QString &tag) void XmlOutput::closeAll() { - if (!tagStack.count()) + if (!tagStack.size()) return; closeTo(QString()); } @@ -340,7 +315,7 @@ void XmlOutput::addAttribute(const QString &attribute, const QString &value) case Tag: //warn_msg(WarnLogic, "<%s>: Cannot add attribute since tags not open", tagStack.last().toLatin1().constData()); qDebug("<%s>: Cannot add attribute (%s) since tag's not open", - (tagStack.count() ? tagStack.last().toLatin1().constData() : "Root"), + (tagStack.size() ? tagStack.last().toLatin1().constData() : "Root"), attribute.toLatin1().constData()); return; case Attribute: @@ -358,7 +333,7 @@ void XmlOutput::addAttributeTag(const QString &attribute, const QString &value) case Tag: //warn_msg(WarnLogic, "<%s>: Cannot add attribute since tags not open", tagStack.last().toLatin1().constData()); qDebug("<%s>: Cannot add attribute (%s) since tag's not open", - (tagStack.count() ? tagStack.last().toLatin1().constData() : "Root"), + (tagStack.size() ? tagStack.last().toLatin1().constData() : "Root"), attribute.toLatin1().constData()); return; case Attribute: diff --git a/qmake/generators/xmloutput.h b/qmake/generators/xmloutput.h index d16634ee3b..44f80ac7e4 100644 --- a/qmake/generators/xmloutput.h +++ b/qmake/generators/xmloutput.h @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #ifndef XMLOUTPUT_H #define XMLOUTPUT_H |