qmake: fix lookup of .prl files for libs specified by full filename
under windows, libraries can have a numeric suffix derived from VERSION, and (under MinGW) a unix-like "lib" prefix - neither of which .prl files have. therefore, we had to make the back-mapping from the library to the .prl file reverse-engineer the original TARGET's name. we verify whether we actually got the right file by comparing the target specified inside the .prl file with what we started from. this fixes linking of transitive deps of static deps. the alternative of changing the .prl naming pattern to avoid the back-mapping was discarded, as a) it would be backwards incompatible and b) it would break project-internal -lfoo references to versioned libs. Change-Id: Ia9b899fe6a5700fee528bd1dacf130caf083cdd6 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io>
This commit is contained in:
parent
dcb3a13fa0
commit
7a33f49e15
@ -878,23 +878,35 @@ MakefileGenerator::init()
|
||||
bool
|
||||
MakefileGenerator::processPrlFile(QString &file, bool baseOnly)
|
||||
{
|
||||
bool try_replace_file = false;
|
||||
QString f = fileFixify(file, FileFixifyBackwards);
|
||||
QString meta_file;
|
||||
if (!baseOnly && f.endsWith(Option::prl_ext)) {
|
||||
meta_file = QMakeMetaInfo::checkLib(f);
|
||||
try_replace_file = true;
|
||||
} else {
|
||||
meta_file = QMakeMetaInfo::checkLib(f + Option::prl_ext);
|
||||
if (!meta_file.isEmpty()) {
|
||||
try_replace_file = true;
|
||||
} else if (!baseOnly) {
|
||||
int off = qMax(f.lastIndexOf('/'), f.lastIndexOf('\\')) + 1;
|
||||
int ext = f.midRef(off).lastIndexOf('.');
|
||||
if (ext != -1)
|
||||
meta_file = QMakeMetaInfo::checkLib(f.leftRef(off + ext) + Option::prl_ext);
|
||||
}
|
||||
// Explicitly given full .prl name
|
||||
if (!baseOnly && f.endsWith(Option::prl_ext))
|
||||
return processPrlFileCore(file, QStringRef(), f);
|
||||
// Explicitly given or derived (from -l) base name
|
||||
if (processPrlFileCore(file, QStringRef(), f + Option::prl_ext))
|
||||
return true;
|
||||
if (!baseOnly) {
|
||||
// Explicitly given full library name
|
||||
int off = qMax(f.lastIndexOf('/'), f.lastIndexOf('\\')) + 1;
|
||||
int ext = f.midRef(off).lastIndexOf('.');
|
||||
if (ext != -1)
|
||||
return processPrlFileBase(file, f.midRef(off), f.leftRef(off + ext), off);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
MakefileGenerator::processPrlFileBase(QString &origFile, const QStringRef &origName,
|
||||
const QStringRef &fixedBase, int slashOff)
|
||||
{
|
||||
return processPrlFileCore(origFile, origName, fixedBase + Option::prl_ext);
|
||||
}
|
||||
|
||||
bool
|
||||
MakefileGenerator::processPrlFileCore(QString &origFile, const QStringRef &origName,
|
||||
const QString &fixedFile)
|
||||
{
|
||||
const QString meta_file = QMakeMetaInfo::checkLib(fixedFile);
|
||||
if (meta_file.isEmpty())
|
||||
return false;
|
||||
QMakeMetaInfo libinfo(project);
|
||||
@ -907,29 +919,37 @@ MakefileGenerator::processPrlFile(QString &file, bool baseOnly)
|
||||
debug_msg(2, "Ignored meta file %s", meta_file.toLatin1().constData());
|
||||
return false;
|
||||
}
|
||||
ProString tgt = libinfo.first("QMAKE_PRL_TARGET");
|
||||
if (tgt.isEmpty()) {
|
||||
fprintf(stderr, "Error: %s does not define QMAKE_PRL_TARGET\n",
|
||||
meta_file.toLatin1().constData());
|
||||
return false;
|
||||
}
|
||||
if (!tgt.contains('.') && !libinfo.values("QMAKE_PRL_CONFIG").contains("lib_bundle")) {
|
||||
fprintf(stderr, "Error: %s defines QMAKE_PRL_TARGET without extension\n",
|
||||
meta_file.toLatin1().constData());
|
||||
return false;
|
||||
}
|
||||
if (origName.isEmpty()) {
|
||||
// We got a .prl file as input, replace it with an actual library.
|
||||
int off = qMax(origFile.lastIndexOf('/'), origFile.lastIndexOf('\\')) + 1;
|
||||
debug_msg(1, " Replacing library reference %s with %s",
|
||||
origFile.mid(off).toLatin1().constData(),
|
||||
tgt.toQString().toLatin1().constData());
|
||||
origFile.replace(off, 1000, tgt.toQString());
|
||||
} else if (tgt != origName) {
|
||||
// We got an actual library as input, and found the wrong .prl for it.
|
||||
debug_msg(2, "Mismatched meta file %s (want %s, got %s)",
|
||||
meta_file.toLatin1().constData(),
|
||||
origName.toLatin1().constData(), tgt.toLatin1().constData());
|
||||
return false;
|
||||
}
|
||||
project->values("QMAKE_CURRENT_PRL_LIBS") = libinfo.values("QMAKE_PRL_LIBS");
|
||||
ProStringList &defs = project->values("DEFINES");
|
||||
const ProStringList &prl_defs = project->values("PRL_EXPORT_DEFINES");
|
||||
for (const ProString &def : libinfo.values("QMAKE_PRL_DEFINES"))
|
||||
if (!defs.contains(def) && prl_defs.contains(def))
|
||||
defs.append(def);
|
||||
if (try_replace_file) {
|
||||
ProString tgt = libinfo.first("QMAKE_PRL_TARGET");
|
||||
if (tgt.isEmpty()) {
|
||||
fprintf(stderr, "Error: %s does not define QMAKE_PRL_TARGET\n",
|
||||
meta_file.toLatin1().constData());
|
||||
} else if (!tgt.contains('.')
|
||||
&& !libinfo.values("QMAKE_PRL_CONFIG").contains("lib_bundle")) {
|
||||
fprintf(stderr, "Error: %s defines QMAKE_PRL_TARGET without extension\n",
|
||||
meta_file.toLatin1().constData());
|
||||
} else {
|
||||
int off = qMax(file.lastIndexOf('/'), file.lastIndexOf('\\')) + 1;
|
||||
debug_msg(1, " Replacing library reference %s with %s",
|
||||
file.mid(off).toLatin1().constData(),
|
||||
tgt.toQString().toLatin1().constData());
|
||||
file.replace(off, 1000, tgt.toQString());
|
||||
}
|
||||
}
|
||||
QString mf = fileFixify(meta_file);
|
||||
if (!project->values("QMAKE_PRL_INTERNAL_FILES").contains(mf))
|
||||
project->values("QMAKE_PRL_INTERNAL_FILES").append(mf);
|
||||
|
@ -246,6 +246,11 @@ protected:
|
||||
|
||||
QString installMetaFile(const ProKey &replace_rule, const QString &src, const QString &dst);
|
||||
|
||||
virtual bool processPrlFileBase(QString &origFile, const QStringRef &origName,
|
||||
const QStringRef &fixedBase, int slashOff);
|
||||
bool processPrlFileCore(QString &origFile, const QStringRef &origName,
|
||||
const QString &fixedFile);
|
||||
|
||||
public:
|
||||
MakefileGenerator();
|
||||
virtual ~MakefileGenerator();
|
||||
|
@ -73,6 +73,19 @@ MingwMakefileGenerator::parseLibFlag(const ProString &flag, ProString *arg)
|
||||
return MakefileGenerator::parseLibFlag(flag, arg);
|
||||
}
|
||||
|
||||
bool MingwMakefileGenerator::processPrlFileBase(QString &origFile, const QStringRef &origName,
|
||||
const QStringRef &fixedBase, int slashOff)
|
||||
{
|
||||
if (origName.startsWith("lib")) {
|
||||
QString newFixedBase = fixedBase.left(slashOff) + fixedBase.mid(slashOff + 3);
|
||||
if (Win32MakefileGenerator::processPrlFileBase(origFile, origName,
|
||||
QStringRef(&newFixedBase), slashOff)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return Win32MakefileGenerator::processPrlFileBase(origFile, origName, fixedBase, slashOff);
|
||||
}
|
||||
|
||||
bool MingwMakefileGenerator::writeMakefile(QTextStream &t)
|
||||
{
|
||||
writeHeader(t);
|
||||
|
@ -42,6 +42,8 @@ protected:
|
||||
using MakefileGenerator::escapeDependencyPath;
|
||||
virtual QString escapeDependencyPath(const QString &path) const;
|
||||
virtual ProString fixLibFlag(const ProString &lib);
|
||||
virtual bool processPrlFileBase(QString &origFile, const QStringRef &origName,
|
||||
const QStringRef &fixedBase, int slashOff);
|
||||
virtual QString getManifestFileForRcFile() const;
|
||||
bool writeMakefile(QTextStream &);
|
||||
void init();
|
||||
|
@ -163,6 +163,23 @@ Win32MakefileGenerator::findLibraries(bool linkPrl, bool mergeLflags)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Win32MakefileGenerator::processPrlFileBase(QString &origFile, const QStringRef &origName,
|
||||
const QStringRef &fixedBase, int slashOff)
|
||||
{
|
||||
if (MakefileGenerator::processPrlFileBase(origFile, origName, fixedBase, slashOff))
|
||||
return true;
|
||||
for (int off = fixedBase.length(); off > slashOff; off--) {
|
||||
if (!fixedBase.at(off - 1).isDigit()) {
|
||||
if (off != fixedBase.length()) {
|
||||
return MakefileGenerator::processPrlFileBase(
|
||||
origFile, origName, fixedBase.left(off), slashOff);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Win32MakefileGenerator::processVars()
|
||||
{
|
||||
if (project->first("TEMPLATE").endsWith("aux"))
|
||||
|
@ -58,6 +58,8 @@ protected:
|
||||
|
||||
virtual LibFlagType parseLibFlag(const ProString &flag, ProString *arg);
|
||||
virtual ProString fixLibFlag(const ProString &lib);
|
||||
virtual bool processPrlFileBase(QString &origFile, const QStringRef &origName,
|
||||
const QStringRef &fixedBase, int slashOff);
|
||||
|
||||
void processVars();
|
||||
void fixTargetExt();
|
||||
|
Loading…
x
Reference in New Issue
Block a user