diff options
author | Joerg Bornemann <joerg.bornemann@qt.io> | 2022-02-17 17:57:16 +0100 |
---|---|---|
committer | Joerg Bornemann <joerg.bornemann@qt.io> | 2022-02-21 12:37:19 +0100 |
commit | 1d3b190425e9e47fa8f263b99d89f407fb5dda8b (patch) | |
tree | 1620228a38b902901d915cc4ba9fc73726752883 /qmake/generators/win32 | |
parent | 5731b83445d890c5316c16cd3a16cd2f5bca2fbd (diff) |
qmake: Fix overlong command lines for static Qt builds on Windows
Linker response files for the MinGW and Unix makefile generators are
controlled by the variable QMAKE_LINK_OBJECT_MAX. This variable holds a
number. If the number of object files passed to the linker exceeds this
number, a linker response file containing object file paths is created.
This heuristic is extremely imprecise. It doesn't take into account the
length of object file names nor the length of $$OBJECTS_DIR.
Also, when using a static Qt, a big part of the linker command line are
libraries. A relatively small example can fail to link with "The
command line is too long" on Windows, even with the object files being
in a response file.
The MinGW makefile generator already reads the variable
QMAKE_RESPONSEFILE_THRESHOLD for compiler response files. Re-use this
variable for the linker response file of the Unix and MinGW makefile
generators.
If QMAKE_RESPONSEFILE_THRESHOLD is set, use it to determine whether to
create a response file. QMAKE_LINK_OBJECT_MAX is then ignored. The
response file contains objects and libraries.
If QMAKE_RESPONSEFILE_THRESHOLD is not set, use QMAKE_LINK_OBJECT_MAX to
determine whether to create a response file. The response file contains
only object files.
QMAKE_LINK_OBJECT_SCRIPT is used in both cases to specify a common base
name of all linker response files.
Pick-to: 6.2 6.3
Task-number: QTBUG-100559
Change-Id: I3c78354fa5ebb1a86438ec804679e0ee776c3f49
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Kai Koehne <kai.koehne@qt.io>
Diffstat (limited to 'qmake/generators/win32')
-rw-r--r-- | qmake/generators/win32/mingw_make.cpp | 18 | ||||
-rw-r--r-- | qmake/generators/win32/mingw_make.h | 1 |
2 files changed, 10 insertions, 9 deletions
diff --git a/qmake/generators/win32/mingw_make.cpp b/qmake/generators/win32/mingw_make.cpp index 823b799eb2..59fcb34ad8 100644 --- a/qmake/generators/win32/mingw_make.cpp +++ b/qmake/generators/win32/mingw_make.cpp @@ -242,21 +242,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); } @@ -284,7 +281,10 @@ void MingwMakefileGenerator::writeBuildRulesPart(QTextStream &t) 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"); diff --git a/qmake/generators/win32/mingw_make.h b/qmake/generators/win32/mingw_make.h index 6c1f0086cc..645a73c374 100644 --- a/qmake/generators/win32/mingw_make.h +++ b/qmake/generators/win32/mingw_make.h @@ -59,6 +59,7 @@ private: LibFlagType parseLibFlag(const ProString &flag, ProString *arg) override; QString objectsLinkLine; + LinkerResponseFileInfo linkerResponseFile; }; QT_END_NAMESPACE |