qmake: Fix building with lld with mingw makefiles

lld for coff/mingw doesn't support linker scripts, which qmake used
for passing larger numbers of input file names to the linker.

Instead of using a fullblown linker script for this, just use a plain
response file, which both lld and binutils ld support.

Change-Id: I3aace7902fa6ca861a0a9fe67feaa236e7ea417b
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io>
This commit is contained in:
Martin Storsjö 2018-10-09 13:51:46 +03:00
parent 8d2deea49c
commit d92c25b1b4

View File

@ -131,22 +131,25 @@ QString MingwMakefileGenerator::installRoot() const
return QStringLiteral("$(INSTALL_ROOT:@msyshack@%=%)"); return QStringLiteral("$(INSTALL_ROOT:@msyshack@%=%)");
} }
void createLdObjectScriptFile(const QString &fileName, const ProStringList &objList) void createLdResponseFile(const QString &fileName, const ProStringList &objList)
{ {
QString filePath = Option::output_dir + QDir::separator() + fileName; QString filePath = Option::output_dir + QDir::separator() + fileName;
QFile file(filePath); QFile file(filePath);
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) { if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QTextStream t(&file); QTextStream t(&file);
t << "INPUT(\n";
for (ProStringList::ConstIterator it = objList.constBegin(); it != objList.constEnd(); ++it) { for (ProStringList::ConstIterator it = objList.constBegin(); it != objList.constEnd(); ++it) {
QString path = (*it).toQString(); QString path = (*it).toQString();
// ### quoting? // In response files, whitespace and special characters are
if (QDir::isRelativePath(path)) // escaped with a backslash; backslashes themselves can either
t << "./" << path << endl; // be escaped into double backslashes, or, as this is a list of
else // path names, converted to forward slashes.
t << path << endl; path.replace(QLatin1Char('\\'), QLatin1String("/"))
.replace(QLatin1Char(' '), QLatin1String("\\ "))
.replace(QLatin1Char('\t'), QLatin1String("\\\t"))
.replace(QLatin1Char('"'), QLatin1String("\\\""))
.replace(QLatin1Char('\''), QLatin1String("\\'"));
t << path << endl;
} }
t << ");\n";
t.flush(); t.flush();
file.close(); file.close();
} }
@ -307,14 +310,13 @@ void MingwMakefileGenerator::writeObjectsPart(QTextStream &t)
createArObjectScriptFile(ar_script_file, var("DEST_TARGET"), project->values("OBJECTS")); createArObjectScriptFile(ar_script_file, var("DEST_TARGET"), project->values("OBJECTS"));
objectsLinkLine = ar_cmd + " -M < " + escapeFilePath(ar_script_file); objectsLinkLine = ar_cmd + " -M < " + escapeFilePath(ar_script_file);
} else { } else {
QString ld_script_file = var("QMAKE_LINK_OBJECT_SCRIPT") + "." + var("TARGET"); QString ld_response_file = var("QMAKE_LINK_OBJECT_SCRIPT") + "." + var("TARGET");
if (!var("BUILD_NAME").isEmpty()) { if (!var("BUILD_NAME").isEmpty())
ld_script_file += "." + var("BUILD_NAME"); ld_response_file += "." + var("BUILD_NAME");
}
if (!var("MAKEFILE").isEmpty()) if (!var("MAKEFILE").isEmpty())
ld_script_file += "." + var("MAKEFILE"); ld_response_file += "." + var("MAKEFILE");
createLdObjectScriptFile(ld_script_file, project->values("OBJECTS")); createLdResponseFile(ld_response_file, project->values("OBJECTS"));
objectsLinkLine = escapeFilePath(ld_script_file); objectsLinkLine = "@" + escapeFilePath(ld_response_file);
} }
Win32MakefileGenerator::writeObjectsPart(t); Win32MakefileGenerator::writeObjectsPart(t);
} }