summaryrefslogtreecommitdiffstats
path: root/qmake
diff options
context:
space:
mode:
Diffstat (limited to 'qmake')
-rw-r--r--qmake/Makefile.unix8
-rw-r--r--qmake/Makefile.win324
-rw-r--r--qmake/doc/qmake.qdocconf2
-rw-r--r--qmake/doc/snippets/code/doc_src_qmake-manual.pro4
-rw-r--r--qmake/doc/snippets/qmake/scopes.pro18
-rw-r--r--qmake/doc/src/qmake-manual.qdoc56
-rw-r--r--qmake/generators/mac/pbuilder_pbx.cpp29
-rw-r--r--qmake/generators/makefile.cpp31
-rw-r--r--qmake/generators/makefile.h4
-rw-r--r--qmake/generators/unix/unixmake.cpp21
-rw-r--r--qmake/generators/unix/unixmake.h2
-rw-r--r--qmake/generators/unix/unixmake2.cpp100
-rw-r--r--qmake/generators/win32/mingw_make.cpp24
-rw-r--r--qmake/generators/win32/msvc_objectmodel.cpp36
-rw-r--r--qmake/generators/win32/msvc_vcproj.cpp15
-rw-r--r--qmake/generators/win32/msvc_vcproj.h2
-rw-r--r--qmake/main.cpp2
-rw-r--r--qmake/qmake.pro5
18 files changed, 228 insertions, 135 deletions
diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix
index 2e4958dcd7..4024231b70 100644
--- a/qmake/Makefile.unix
+++ b/qmake/Makefile.unix
@@ -24,7 +24,8 @@ QOBJS = \
qfile.o qfiledevice.o qfileinfo.o qfilesystemengine.o \
qfilesystementry.o qfsfileengine.o qfsfileengine_iterator.o \
qiodevice.o qsettings.o qtemporaryfile.o qtextstream.o \
- qcborvalue.o qjsoncbor.o qjsonarray.o qjsondocument.o qjsonobject.o qjsonparser.o qjsonvalue.o \
+ qcborstreamwriter.o qcborvalue.o \
+ qjsoncbor.o qjsonarray.o qjsondocument.o qjsonobject.o qjsonparser.o qjsonvalue.o \
qmetatype.o qsystemerror.o qvariant.o \
quuid.o \
qarraydata.o qbitarray.o qbytearray.o qbytearraylist.o qbytearraymatcher.o \
@@ -96,6 +97,7 @@ DEPEND_SRC = \
$(SOURCE_PATH)/src/corelib/kernel/qsystemerror.cpp \
$(SOURCE_PATH)/src/corelib/kernel/qvariant.cpp \
$(SOURCE_PATH)/src/corelib/plugin/quuid.cpp \
+ $(SOURCE_PATH)/src/corelib/serialization/qcborstreamwriter.cpp \
$(SOURCE_PATH)/src/corelib/serialization/qcborvalue.cpp \
$(SOURCE_PATH)/src/corelib/serialization/qdatastream.cpp \
$(SOURCE_PATH)/src/corelib/serialization/qjsonarray.cpp \
@@ -135,6 +137,7 @@ DEPEND_SRC = \
CPPFLAGS = -g $(EXTRA_CPPFLAGS) \
-I$(QMKSRC) -I$(QMKLIBSRC) -I$(QMKGENSRC) \
+ -I$(SOURCE_PATH)/src/3rdparty/tinycbor/src \
-I$(QMKGENSRC)/unix -I$(QMKGENSRC)/win32 -I$(QMKGENSRC)/mac \
-I$(INC_PATH) -I$(INC_PATH)/QtCore \
-I$(INC_PATH)/QtCore/$(QT_VERSION) -I$(INC_PATH)/QtCore/$(QT_VERSION)/QtCore \
@@ -463,6 +466,9 @@ qsystemlibrary.o: $(SOURCE_PATH)/src/corelib/plugin/qsystemlibrary.cpp
qdatastream.o: $(SOURCE_PATH)/src/corelib/serialization/qdatastream.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
+qcborstreamwriter.o: $(SOURCE_PATH)/src/corelib/serialization/qcborstreamwriter.cpp
+ $(CXX) -c -o $@ $(CXXFLAGS) $<
+
qcborvalue.o: $(SOURCE_PATH)/src/corelib/serialization/qcborvalue.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32
index 1c2692d143..6f27b735d4 100644
--- a/qmake/Makefile.win32
+++ b/qmake/Makefile.win32
@@ -13,7 +13,7 @@ QMKSRC = $(SOURCE_PATH)\qmake
!if "$(QMAKESPEC)" == "win32-icc"
CXX = icl
LINKER = xilink
-CFLAGS_EXTRA = /Zc:forScope /Qstd=c++11 /O3
+CFLAGS_EXTRA = /Zc:forScope /Qstd=c++11
!elseif "$(QMAKESPEC)" == "win32-clang-msvc"
CXX = clang-cl
LINKER = lld-link
@@ -31,6 +31,7 @@ CFLAGS_BARE = -c -Fo./ -Fdqmake.pdb \
-W2 -nologo -O2 \
$(CFLAGS_EXTRA) \
-I$(QMKSRC) -I$(QMKSRC)\library -I$(QMKSRC)\generators -I$(QMKSRC)\generators\unix -I$(QMKSRC)\generators\win32 -I$(QMKSRC)\generators\mac \
+ -I$(SOURCE_PATH)/src/3rdparty/tinycbor/src \
-I$(INC_PATH) -I$(INC_PATH)\QtCore -I$(INC_PATH)\QtCore\$(QT_VERSION) -I$(INC_PATH)\QtCore\$(QT_VERSION)\QtCore \
-I$(BUILD_PATH)\src\corelib\global \
-I$(SOURCE_PATH)\mkspecs\$(QMAKESPEC) \
@@ -117,6 +118,7 @@ QTOBJS= \
qxmlutils.obj \
qnumeric.obj \
qlogging.obj \
+ qcborstreamwriter.obj \
qcborvalue.obj \
qjsoncbor.obj \
qjsondocument.obj \
diff --git a/qmake/doc/qmake.qdocconf b/qmake/doc/qmake.qdocconf
index cf8f911372..9e1ad2f807 100644
--- a/qmake/doc/qmake.qdocconf
+++ b/qmake/doc/qmake.qdocconf
@@ -47,7 +47,7 @@ depends += \
qtnetwork \
qtopengl \
qtprintsupport \
- qtqml \
+ qtqml qtqmltest \
qtquick \
qtquickcontrols \
qtquickdialogs \
diff --git a/qmake/doc/snippets/code/doc_src_qmake-manual.pro b/qmake/doc/snippets/code/doc_src_qmake-manual.pro
index 8ba0aa0713..d36d926b66 100644
--- a/qmake/doc/snippets/code/doc_src_qmake-manual.pro
+++ b/qmake/doc/snippets/code/doc_src_qmake-manual.pro
@@ -303,7 +303,9 @@ SUBDIRS = kernel \
#! [51]
-CONFIG += ordered
+SUBDIRS += my_executable my_library tests doc
+my_executable.depends = my_library
+tests.depends = my_executable
#! [51]
diff --git a/qmake/doc/snippets/qmake/scopes.pro b/qmake/doc/snippets/qmake/scopes.pro
index 63b9b3aa55..6721937755 100644
--- a/qmake/doc/snippets/qmake/scopes.pro
+++ b/qmake/doc/snippets/qmake/scopes.pro
@@ -40,3 +40,21 @@ win32|macx {
HEADERS += debugging.h
}
#! [4]
+
+#! [5]
+if(win32|macos):CONFIG(debug, debug|release) {
+ # Do something on Windows and macOS,
+ # but only for the debug configuration.
+}
+win32|if(macos:CONFIG(debug, debug|release)) {
+ # Do something on Windows (regardless of debug or release)
+ # and on macOS (only for debug).
+}
+#! [5]
+
+#! [6]
+win32-* {
+ # Matches every mkspec starting with "win32-"
+ SOURCES += win32_specific.cpp
+}
+#! [6]
diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc
index ed7fe60fdc..cd8129a539 100644
--- a/qmake/doc/src/qmake-manual.qdoc
+++ b/qmake/doc/src/qmake-manual.qdoc
@@ -936,7 +936,9 @@
file.
\row \li ordered \li When using the \c subdirs template, this option
specifies that the directories listed should be processed in the
- order in which they are given.
+ order in which they are given. \note The use of this option is discouraged.
+ Specify dependencies as described in the \l{#SUBDIRS}{SUBDIRS}
+ variable documentation.
\row \li precompile_header \li Enables support for the use of
\l{Using Precompiled Headers}{precompiled headers} in projects.
\row \li precompile_header_c (MSVC only) \li Enables support for the use of
@@ -1329,7 +1331,7 @@
\li Value
\li Description
\row
- \li no_check_exists
+ \li no_check_exist
\li If not set, qmake looks to see if the files to install actually
exist. If these files don't exist, qmake doesn’t create the
install rule. Use this config value if you need to install
@@ -1577,6 +1579,12 @@
\l{CONFIG}{CONFIG += lrelease} will be installed to. Does not have any
effect if \l{CONFIG}{CONFIG += embed_translations} is set.
+ \target QML_IMPORT_PATH
+ \section1 QML_IMPORT_PATH
+
+ This variable is only used by \l{Qt Creator Manual}{Qt Creator}.
+ See \l{Qt Creator: Using QML Modules with Plugins} for details.
+
\target QMAKE_systemvariable
\section1 QMAKE
@@ -2724,21 +2732,35 @@
\snippet code/doc_src_qmake-manual.pro 50
- If you need to ensure that the subdirectories are built in the order in
- which they are specified, update the \l{#CONFIG}{CONFIG} variable to
- include the \c ordered option:
+ If you need to ensure that the subdirectories are built in a particular
+ order, use the \c .depends modifier on the relevant \c SUBDIRS elements.
+
+ For example:
\snippet code/doc_src_qmake-manual.pro 51
- It is possible to modify this default behavior of \c SUBDIRS by giving
- additional modifiers to \c SUBDIRS elements. Supported modifiers are:
+ The configuration above ensures that \c{my_library} is built before
+ \c{my_executable} and that \c{my_executable} is built before \c{tests}.
+ However, \c{doc} can be built in parallel with the other subdirectories,
+ thus speeding up the build process.
+
+ \note Multiple dependencies can be listed and they will all be built before
+ the target that depends on them.
+
+ \note Using \l{#CONFIG}{CONFIG += ordered} is discouraged as it can slow down
+ multi-core builds. Unlike the example shown above, all builds will happen
+ sequentially even if they don't have dependencies.
+
+ Beside defining the build order, it is possible to modify the default behavior
+ of \c SUBDIRS by giving additional modifiers to \c SUBDIRS elements.
+ Supported modifiers are:
\table
\header \li Modifier \li Effect
\row \li .subdir \li Use the specified subdirectory instead of \c SUBDIRS value.
\row \li .file \li Specify the subproject \c pro file explicitly. Cannot be
used in conjunction with \c .subdir modifier.
- \row \li .depends \li This subproject depends on specified subproject.
+ \row \li .depends \li This subproject depends on specified subproject(s).
\row \li .makefile \li The makefile of subproject.
Available only on platforms that use makefiles.
\row \li .target \li Base string used for makefile targets related to this
@@ -4412,6 +4434,20 @@
\snippet qmake/scopes.pro 4
+ If you need to mix both operators, you can use the \c if function to specify
+ operator precedence.
+
+ \snippet qmake/scopes.pro 5
+
+ The condition accepts the wildcard character to match a family of \c{CONFIG}
+ values or mkspec names.
+
+ \snippet qmake/scopes.pro 6
+
+ \note Historically, checking the mkspec name with wildcards like above was
+ qmake's way to check for the platform. Nowadays, we recommend to use values
+ that are defined by the mkspec in the \c QMAKE_PLATFORM variable.
+
You can also provide alternative declarations to those within a scope by
using an \c else scope. Each \c else scope is processed if the conditions
for the preceding scopes are false.
@@ -5407,8 +5443,8 @@
\li The exit code of the test will be ignored during \c{make check}.
\endtable
- Testcases will often be written with \l{QTest} or \l{TestCase}, but
- that is not a requirement to make use of \c{CONFIG+=testcase} and \c{make check}.
+ Test cases will often be written with \l{QTest} or \c{TestCase}, but
+ it is not a requirement to make use of \c{CONFIG+=testcase} and \c{make check}.
The only primary requirement is that the test program exit with a zero exit code
on success, and a non-zero exit code on failure.
diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp
index 24e69444c9..c2f6df7787 100644
--- a/qmake/generators/mac/pbuilder_pbx.cpp
+++ b/qmake/generators/mac/pbuilder_pbx.cpp
@@ -1629,17 +1629,24 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
}
}
- // The symroot is marked by xcodebuild as excluded from Time Machine
- // backups, as it's a temporary build dir, so we don't want it to be
- // the same as the possibe in-source dir, as that would leave out
- // sources from being backed up.
- t << "\t\t\t\t" << writeSettings("SYMROOT",
- Option::output_dir + Option::dir_sep + ".xcode") << ";\n";
-
- // The configuration build dir however is not treated as excluded,
- // so we can safely point it to the root output dir.
- t << "\t\t\t\t" << writeSettings("CONFIGURATION_BUILD_DIR",
- Option::output_dir + Option::dir_sep + "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)") << ";\n";
+ if (Option::output_dir != qmake_getpwd()) {
+ // The SYMROOT is marked by Xcode as excluded from Time Machine
+ // backups, as it's a temporary build dir, but that's fine when
+ // we are shadow building.
+ t << "\t\t\t\t" << writeSettings("SYMROOT", "$(PROJECT_DIR)") << ";\n";
+ } else {
+ // For in-source builds we don't want to exclude the sources
+ // from being backed up, so we point SYMROOT to a temporary
+ // build directory.
+ t << "\t\t\t\t" << writeSettings("SYMROOT", ".xcode") << ";\n";
+
+ // Then we set the configuration build dir instead, so that the
+ // final build artifacts end up in the place Qt Creator expects.
+ // The disadvantage of using this over SYMROOT is that Xcode will
+ // fail to archive projects that override this variable.
+ t << "\t\t\t\t" << writeSettings("CONFIGURATION_BUILD_DIR",
+ "$(PROJECT_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)") << ";\n";
+ }
if (!project->isEmpty("DESTDIR")) {
ProString dir = project->first("DESTDIR");
diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp
index c5868adf27..7e471f126c 100644
--- a/qmake/generators/makefile.cpp
+++ b/qmake/generators/makefile.cpp
@@ -1520,7 +1520,7 @@ MakefileGenerator::createObjectList(const ProStringList &sources)
if (!noIO()) {
// Ensure that the final output directory of each object exists
QString outRelativePath = fileFixify(dir, FileFixifyBackwards);
- if (!mkdir(outRelativePath))
+ if (!outRelativePath.isEmpty() && !mkdir(outRelativePath))
warn_msg(WarnLogic, "Cannot create directory '%s'", outRelativePath.toLatin1().constData());
}
} else {
@@ -1857,10 +1857,13 @@ void MakefileGenerator::callExtraCompilerDependCommand(const ProString &extraCom
const QString &tmp_out,
bool dep_lines,
QStringList *deps,
- bool existingDepsOnly)
+ bool existingDepsOnly,
+ bool checkCommandAvailability)
{
char buff[256];
QString dep_cmd = replaceExtraCompilerVariables(tmp_dep_cmd, inpf, tmp_out, LocalShell);
+ if (checkCommandAvailability && !canExecute(dep_cmd))
+ return;
dep_cmd = dep_cd_cmd + fixEnvVariables(dep_cmd);
if (FILE *proc = QT_POPEN(dep_cmd.toLatin1().constData(), QT_POPEN_READ)) {
QByteArray depData;
@@ -3455,4 +3458,28 @@ ProKey MakefileGenerator::fullTargetVariable() const
return "TARGET";
}
+void MakefileGenerator::createResponseFile(const QString &fileName, const ProStringList &objList)
+{
+ QString filePath = Option::output_dir + QDir::separator() + fileName;
+ QFile file(filePath);
+ if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
+ QTextStream t(&file);
+ for (ProStringList::ConstIterator it = objList.constBegin(); it != objList.constEnd(); ++it) {
+ QString path = (*it).toQString();
+ // In response files, whitespace and special characters are
+ // escaped with a backslash; backslashes themselves can either
+ // be escaped into double backslashes, or, as this is a list of
+ // path names, converted to forward slashes.
+ path.replace(QLatin1Char('\\'), QLatin1String("/"))
+ .replace(QLatin1Char(' '), QLatin1String("\\ "))
+ .replace(QLatin1Char('\t'), QLatin1String("\\\t"))
+ .replace(QLatin1Char('"'), QLatin1String("\\\""))
+ .replace(QLatin1Char('\''), QLatin1String("\\'"));
+ t << path << Qt::endl;
+ }
+ t.flush();
+ file.close();
+ }
+}
+
QT_END_NAMESPACE
diff --git a/qmake/generators/makefile.h b/qmake/generators/makefile.h
index 18c27a4385..ab970c966f 100644
--- a/qmake/generators/makefile.h
+++ b/qmake/generators/makefile.h
@@ -87,7 +87,8 @@ protected:
void callExtraCompilerDependCommand(const ProString &extraCompiler, const QString &dep_cd_cmd,
const QString &tmp_dep_cmd, const QString &inpf,
const QString &tmp_out, bool dep_lines, QStringList *deps,
- bool existingDepsOnly);
+ bool existingDepsOnly,
+ bool checkCommandAvailability = false);
void writeExtraCompilerTargets(QTextStream &t);
void writeExtraCompilerVariables(QTextStream &t);
bool writeDummyMakefile(QTextStream &t);
@@ -257,6 +258,7 @@ protected:
const QStringRef &fixedBase, int slashOff);
bool processPrlFileCore(QString &origFile, const QStringRef &origName,
const QString &fixedFile);
+ void createResponseFile(const QString &fileName, const ProStringList &objList);
public:
QMakeProject *projectFile() const;
diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp
index e56e8c41b6..f7bd6dc663 100644
--- a/qmake/generators/unix/unixmake.cpp
+++ b/qmake/generators/unix/unixmake.cpp
@@ -208,15 +208,15 @@ UnixMakefileGenerator::init()
escapeFilePath(pchBaseName + language + headerSuffix));
const ProStringList pchArchs = project->values("QMAKE_PCH_ARCHS");
for (const ProString &arch : pchArchs) {
- QString suffix = headerSuffix;
- suffix.replace(QLatin1String("${QMAKE_PCH_ARCH}"), arch.toQString());
+ QString file = pchBaseName + language + headerSuffix;
+ file.replace(QLatin1String("${QMAKE_PCH_ARCH}"), arch.toQString());
if (project->isActiveConfig("clang_pch_style")
- && (suffix.endsWith(QLatin1String(".pch"))
- || suffix.endsWith(QLatin1String(".gch")))) {
- suffix.chop(4); // must omit header suffix for -include to recognize the PCH
+ && (file.endsWith(QLatin1String(".pch"))
+ || file.endsWith(QLatin1String(".gch")))) {
+ file.chop(4); // must omit header suffix for -include to recognize the PCH
}
pchFlags.replace(QLatin1String("${QMAKE_PCH_OUTPUT_") + arch + QLatin1Char('}'),
- escapeFilePath(pchBaseName + language + suffix));
+ escapeFilePath(file));
}
}
}
@@ -363,10 +363,11 @@ QStringList
if (pchArchs.isEmpty())
pchArchs << ProString(); // normal single-arch PCH
for (const ProString &arch : qAsConst(pchArchs)) {
- QString suffix = header_suffix;
- if (!arch.isEmpty())
- suffix.replace(QLatin1String("${QMAKE_PCH_ARCH}"), arch.toQString());
- QString precompiledHeader = header_prefix + language + suffix;
+ QString precompiledHeader = header_prefix + language + header_suffix;
+ if (!arch.isEmpty()) {
+ precompiledHeader.replace(QLatin1String("${QMAKE_PCH_ARCH}"),
+ arch.toQString());
+ }
if (!ret.contains(precompiledHeader))
ret += precompiledHeader;
}
diff --git a/qmake/generators/unix/unixmake.h b/qmake/generators/unix/unixmake.h
index 79b161f6da..28302b4f15 100644
--- a/qmake/generators/unix/unixmake.h
+++ b/qmake/generators/unix/unixmake.h
@@ -58,7 +58,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);
private:
void init2();
ProStringList libdirToFlags(const ProKey &key);
diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp
index a87fbe0fc3..4a6a42c7d2 100644
--- a/qmake/generators/unix/unixmake2.cpp
+++ b/qmake/generators/unix/unixmake2.cpp
@@ -246,38 +246,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;
- if(do_incremental) {
- const ProStringList &objs = project->values("OBJECTS");
- const ProStringList &incrs = project->values("QMAKE_INCREMENTAL");
- ProStringList incrs_out;
- t << "OBJECTS = ";
- for (ProStringList::ConstIterator objit = objs.begin(); objit != objs.end(); ++objit) {
- bool increment = false;
- for (ProStringList::ConstIterator incrit = incrs.begin(); incrit != incrs.end(); ++incrit) {
- if ((*objit).toQString().indexOf(QRegExp((*incrit).toQString(), Qt::CaseSensitive,
- QRegExp::Wildcard)) != -1) {
- increment = true;
- incrs_out.append((*objit));
- break;
- }
- }
- if(!increment)
- t << "\\\n\t\t" << (*objit);
- }
- if(incrs_out.count() == objs.count()) { //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()) {
- t << Qt::endl;
- } else {
- src_incremental = true;
- t << Qt::endl;
- t << "INCREMENTAL_OBJECTS = "
- << escapeFilePaths(incrs_out).join(QString(" \\\n\t\t")) << Qt::endl;
- }
- } else {
- // Used all over the place in both deps and commands.
- t << "OBJECTS = " << valList(escapeDependencyPaths(project->values("OBJECTS"))) << Qt::endl;
- }
+ auto objectParts = writeObjectsPart(t, do_incremental);
+ src_incremental = objectParts.first;
if(do_incremental && !src_incremental)
do_incremental = false;
t << "DIST = " << valList(fileFixify(project->values("DISTFILES").toQStringList())) << " "
@@ -513,7 +483,8 @@ 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) $(OBJECTS) $(OBJCOMP) $(LIBS)";
+ t << "$(LINK) $(LFLAGS) " << var("QMAKE_LINK_O_FLAG") << "$(TARGET) "
+ << objectParts.second << " $(OBJCOMP) $(LIBS)";
if (!project->isEmpty("QMAKE_POST_LINK"))
t << "\n\t" << var("QMAKE_POST_LINK");
}
@@ -1046,10 +1017,10 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
if (pchArchs.isEmpty())
pchArchs << ProString(); // normal single-arch PCH
for (const ProString &arch : qAsConst(pchArchs)) {
- auto suffix = header_suffix.toQString();
+ QString file = precomph_out_dir + header_prefix + language + header_suffix;
if (!arch.isEmpty())
- suffix.replace(QStringLiteral("${QMAKE_PCH_ARCH}"), arch.toQString());
- precomp_files += precomph_out_dir + header_prefix + language + suffix;
+ file.replace(QStringLiteral("${QMAKE_PCH_ARCH}"), arch.toQString());
+ precomp_files += file;
}
}
}
@@ -1169,7 +1140,10 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
t << "\n\techo \"// Automatically generated, do not modify\" > " << sourceFile_f
<< "\n\trm -f " << escapeFilePath(pchArchOutput);
} else {
- t << "\n\t" << mkdir_p_asstring(pchOutputDir);
+ QString outDir = pchOutputDir;
+ if (!arch.isEmpty())
+ outDir.replace(QStringLiteral("${QMAKE_PCH_ARCH}"), arch.toQString());
+ t << "\n\t" << mkdir_p_asstring(outDir);
}
auto pchArchFlags = pchFlags;
@@ -1545,4 +1519,56 @@ UnixMakefileGenerator::writeLibtoolFile()
"libdir='" << Option::fixPathToTargetOS(install_dir.toQString(), false) << "'\n";
}
+std::pair<bool, QString> UnixMakefileGenerator::writeObjectsPart(QTextStream &t, bool do_incremental)
+{
+ bool src_incremental = false;
+ QString objectsLinkLine;
+ const ProStringList &objs = project->values("OBJECTS");
+ if (do_incremental) {
+ const ProStringList &incrs = project->values("QMAKE_INCREMENTAL");
+ ProStringList incrs_out;
+ t << "OBJECTS = ";
+ for (ProStringList::ConstIterator objit = objs.begin(); objit != objs.end(); ++objit) {
+ bool increment = false;
+ for (ProStringList::ConstIterator incrit = incrs.begin(); incrit != incrs.end(); ++incrit) {
+ if ((*objit).toQString().indexOf(QRegExp((*incrit).toQString(), Qt::CaseSensitive,
+ QRegExp::Wildcard)) != -1) {
+ increment = true;
+ incrs_out.append((*objit));
+ break;
+ }
+ }
+ if (!increment)
+ t << "\\\n\t\t" << (*objit);
+ }
+ if (incrs_out.count() == objs.count()) { //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()) {
+ t << Qt::endl;
+ } else {
+ src_incremental = true;
+ t << Qt::endl;
+ t << "INCREMENTAL_OBJECTS = "
+ << 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 {
+ QString ld_response_file = fileVar("OBJECTS_DIR");
+ ld_response_file += var("QMAKE_LINK_OBJECT_SCRIPT") + "." + var("TARGET");
+ if (!var("BUILD_NAME").isEmpty())
+ ld_response_file += "." + var("BUILD_NAME");
+ if (!var("MAKEFILE").isEmpty())
+ ld_response_file += "." + var("MAKEFILE");
+ createResponseFile(ld_response_file, objs);
+ objectsLinkLine = "@" + escapeFilePath(ld_response_file);
+ }
+ t << "OBJECTS = " << valList(escapeDependencyPaths(objs)) << Qt::endl;
+ }
+ return std::make_pair(src_incremental, objectsLinkLine);
+}
+
QT_END_NAMESPACE
diff --git a/qmake/generators/win32/mingw_make.cpp b/qmake/generators/win32/mingw_make.cpp
index 878291fae9..096b041056 100644
--- a/qmake/generators/win32/mingw_make.cpp
+++ b/qmake/generators/win32/mingw_make.cpp
@@ -115,30 +115,6 @@ QString MingwMakefileGenerator::installRoot() const
return QStringLiteral("$(INSTALL_ROOT:@msyshack@%=%)");
}
-static void createResponseFile(const QString &fileName, const ProStringList &objList)
-{
- QString filePath = Option::output_dir + QDir::separator() + fileName;
- QFile file(filePath);
- if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
- QTextStream t(&file);
- for (ProStringList::ConstIterator it = objList.constBegin(); it != objList.constEnd(); ++it) {
- QString path = (*it).toQString();
- // In response files, whitespace and special characters are
- // escaped with a backslash; backslashes themselves can either
- // be escaped into double backslashes, or, as this is a list of
- // path names, converted to forward slashes.
- path.replace(QLatin1Char('\\'), QLatin1String("/"))
- .replace(QLatin1Char(' '), QLatin1String("\\ "))
- .replace(QLatin1Char('\t'), QLatin1String("\\\t"))
- .replace(QLatin1Char('"'), QLatin1String("\\\""))
- .replace(QLatin1Char('\''), QLatin1String("\\'"));
- t << path << Qt::endl;
- }
- t.flush();
- file.close();
- }
-}
-
void MingwMakefileGenerator::writeMingwParts(QTextStream &t)
{
writeStandardParts(t);
diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp
index 5396eba72e..2b39a4baaa 100644
--- a/qmake/generators/win32/msvc_objectmodel.cpp
+++ b/qmake/generators/win32/msvc_objectmodel.cpp
@@ -2351,33 +2351,15 @@ bool VCFilter::addExtraCompiler(const VCFilterFile &info)
if (!tmp_dep.isEmpty())
deps = tmp_dep;
if (!tmp_dep_cmd.isEmpty()) {
- // Execute dependency command, and add every line as a dep
- char buff[256];
- QString dep_cmd = Project->replaceExtraCompilerVariables(
- tmp_dep_cmd, inFile, out, MakefileGenerator::LocalShell);
- if(Project->canExecute(dep_cmd)) {
- dep_cmd.prepend(QLatin1String("cd ")
- + IoUtils::shellQuote(Option::fixPathToLocalOS(Option::output_dir, false))
- + QLatin1String(" && "));
- if (FILE *proc = QT_POPEN(dep_cmd.toLatin1().constData(), QT_POPEN_READ)) {
- QString indeps;
- while(!feof(proc)) {
- int read_in = (int)fread(buff, 1, 255, proc);
- if(!read_in)
- break;
- indeps += QByteArray(buff, read_in);
- }
- QT_PCLOSE(proc);
- if(!indeps.isEmpty()) {
- QStringList extradeps = indeps.split(QLatin1Char('\n'));
- for (int i = 0; i < extradeps.count(); ++i) {
- QString dd = extradeps.at(i).simplified();
- if (!dd.isEmpty())
- deps += Project->fileFixify(dd, MakefileGenerator::FileFixifyFromOutdir);
- }
- }
- }
- }
+ const QString dep_cd_cmd = QLatin1String("cd ")
+ + IoUtils::shellQuote(Option::fixPathToLocalOS(Option::output_dir, false))
+ + QLatin1String(" && ");
+ Project->callExtraCompilerDependCommand(extraCompilerName, dep_cd_cmd, tmp_dep_cmd,
+ inFile, out,
+ true, // dep_lines
+ &deps,
+ configs.contains("dep_existing_only"),
+ true /* checkCommandAvailability */);
}
for (int i = 0; i < deps.count(); ++i)
deps[i] = Option::fixPathToTargetOS(
diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp
index e45beca459..867b14faea 100644
--- a/qmake/generators/win32/msvc_vcproj.cpp
+++ b/qmake/generators/win32/msvc_vcproj.cpp
@@ -1247,10 +1247,10 @@ void VcprojGenerator::initDeploymentTool()
+ "|" + targetPath
+ "|0;";
if (!qpaPluginDeployed) {
- QChar debugInfixChar;
+ QString debugInfix;
bool foundGuid = dllName.contains(QLatin1String("Guid"));
if (foundGuid)
- debugInfixChar = QLatin1Char('d');
+ debugInfix = QLatin1Char('d');
if (foundGuid || dllName.contains(QLatin1String("Gui"))) {
QFileInfo info2;
@@ -1258,13 +1258,14 @@ void VcprojGenerator::initDeploymentTool()
QString absoluteDllFilePath = dllPath.toQString();
if (!absoluteDllFilePath.endsWith(QLatin1Char('/')))
absoluteDllFilePath += QLatin1Char('/');
- absoluteDllFilePath += QLatin1String("../plugins/platforms/qwindows") + debugInfixChar + QLatin1String(".dll");
+ absoluteDllFilePath += QLatin1String("../plugins/platforms/qwindows")
+ + debugInfix + QLatin1String(".dll");
info2 = QFileInfo(absoluteDllFilePath);
if (info2.exists())
break;
}
if (info2.exists()) {
- conf.deployment.AdditionalFiles += QLatin1String("qwindows") + debugInfixChar + QLatin1String(".dll")
+ conf.deployment.AdditionalFiles += QLatin1String("qwindows") + debugInfix + QLatin1String(".dll")
+ QLatin1Char('|') + QDir::toNativeSeparators(info2.absolutePath())
+ QLatin1Char('|') + targetPath + QLatin1String("\\platforms")
+ QLatin1String("|0;");
@@ -1581,12 +1582,14 @@ void VcprojGenerator::initExtraCompilerOutputs()
if (!outputVar.isEmpty() && otherFilters.contains(outputVar))
continue;
- QString tmp_out = project->first(outputs.first().toKey()).toQString();
+ QString tmp_out;
+ if (!outputs.isEmpty())
+ tmp_out = project->first(outputs.first().toKey()).toQString();
if (project->values(ProKey(*it + ".CONFIG")).indexOf("combine") != -1) {
// Combined output, only one file result
extraCompile.addFile(Option::fixPathToTargetOS(
replaceExtraCompilerVariables(tmp_out, QString(), QString(), NoShell), false));
- } else {
+ } 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) {
diff --git a/qmake/generators/win32/msvc_vcproj.h b/qmake/generators/win32/msvc_vcproj.h
index 8f38252274..c565b709d2 100644
--- a/qmake/generators/win32/msvc_vcproj.h
+++ b/qmake/generators/win32/msvc_vcproj.h
@@ -69,6 +69,8 @@ public:
bool pchIsCFile = false;
VCProjectWriter *projectWriter;
+ using Win32MakefileGenerator::callExtraCompilerDependCommand;
+
protected:
virtual VCProjectWriter *createProjectWriter();
bool doDepends() const override { return false; } // Never necessary
diff --git a/qmake/main.cpp b/qmake/main.cpp
index 7a2532eb0e..c0e6088d80 100644
--- a/qmake/main.cpp
+++ b/qmake/main.cpp
@@ -154,7 +154,7 @@ static int doSed(int argc, char **argv)
FILE *f;
if (!strcmp(inFile, "-")) {
f = stdin;
- } else if (!(f = fopen(inFile, "r"))) {
+ } else if (!(f = fopen(inFile, "rb"))) {
perror(inFile);
return 1;
}
diff --git a/qmake/qmake.pro b/qmake/qmake.pro
index 42c727b33e..745ee9b6af 100644
--- a/qmake/qmake.pro
+++ b/qmake/qmake.pro
@@ -31,7 +31,8 @@ INCLUDEPATH += \
generators \
generators/unix \
generators/win32 \
- generators/mac
+ generators/mac \
+ ../src/3rdparty/tinycbor/src
SOURCES += \
main.cpp \
@@ -116,6 +117,7 @@ SOURCES += \
qbytearray.cpp \
qbytearraymatcher.cpp \
qcalendar.cpp \
+ qcborstreamwriter.cpp \
qcborvalue.cpp \
qcryptographichash.cpp \
qdatetime.cpp \
@@ -175,6 +177,7 @@ HEADERS += \
qcalendar.h \
qcalendarbackend_p.h \
qcalendarmath_p.h \
+ qcborstreamwriter.h \
qcborvalue.h \
qcborvalue_p.h \
qchar.h \