support relative paths in QMAKE_RPATHDIR

... and make use of it in qt.prf.

[ChangeLog][qmake][Unix] Added support for relative paths in
QMAKE_RPATHDIR.

Note that this technically breaks backwards compatibility, as relative
paths were previously silently resolved against $$_PRO_FILE_PWD_. This
was not documented and seems rather useless, so i'm not worried.

Change-Id: I855042a8962ab34ad4617899a5b9825af0087f8a
Reviewed-by: Joerg Bornemann <joerg.bornemann@theqtcompany.com>
Reviewed-by: Jake Petroules <jake.petroules@theqtcompany.com>
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
This commit is contained in:
Oswald Buddenhagen 2015-09-29 20:06:05 +02:00
parent bf92993829
commit 2d8801a962
5 changed files with 46 additions and 10 deletions

View File

@ -10,6 +10,9 @@ QMAKE_CFLAGS_THREAD += -D_REENTRANT
QMAKE_CXXFLAGS_THREAD += $$QMAKE_CFLAGS_THREAD QMAKE_CXXFLAGS_THREAD += $$QMAKE_CFLAGS_THREAD
QMAKE_LFLAGS_GCSECTIONS = -Wl,--gc-sections QMAKE_LFLAGS_GCSECTIONS = -Wl,--gc-sections
QMAKE_LFLAGS_REL_RPATH = -Wl,-z,origin
QMAKE_REL_RPATH_BASE = $ORIGIN
QMAKE_INCDIR = QMAKE_INCDIR =
QMAKE_LIBDIR = QMAKE_LIBDIR =
QMAKE_INCDIR_X11 = QMAKE_INCDIR_X11 =

View File

@ -22,6 +22,9 @@ QMAKE_FIX_RPATH = install_name_tool -id
QMAKE_LFLAGS_RPATH = -Wl,-rpath, QMAKE_LFLAGS_RPATH = -Wl,-rpath,
QMAKE_LFLAGS_GCSECTIONS = -Wl,-dead_strip QMAKE_LFLAGS_GCSECTIONS = -Wl,-dead_strip
QMAKE_LFLAGS_REL_RPATH =
QMAKE_REL_RPATH_BASE = @loader_path
QMAKE_LIBS_DYNLOAD = QMAKE_LIBS_DYNLOAD =
QMAKE_LIBS_OPENGL = -framework OpenGL -framework AGL QMAKE_LIBS_OPENGL = -framework OpenGL -framework AGL
QMAKE_LIBS_THREAD = QMAKE_LIBS_THREAD =

View File

@ -167,17 +167,11 @@ qt_module_deps = $$resolve_depends(qt_module_deps, "QT.")
} else { } else {
binpath = $$target.path binpath = $$target.path
} }
rpath = @loader_path
} else { } else {
QMAKE_LFLAGS += -Wl,-z,origin
binpath = $$target.path binpath = $$target.path
rpath = $ORIGIN
} }
# NOT the /dev property, as INSTALLS use host paths # NOT the /dev property, as INSTALLS use host paths
relpath = $$relative_path($$[QT_INSTALL_LIBS], $$binpath) QMAKE_RPATHDIR += $$relative_path($$[QT_INSTALL_LIBS], $$binpath)
!equals(relpath, .): \
rpath = $$rpath/$$relpath
QMAKE_RPATHDIR += $$rpath
} else { } else {
QMAKE_RPATHDIR += $$[QT_INSTALL_LIBS/dev] QMAKE_RPATHDIR += $$[QT_INSTALL_LIBS/dev]
} }

View File

@ -1845,6 +1845,22 @@
The value of this variable is typically handled by The value of this variable is typically handled by
qmake or \l{#QMAKESPEC}{qmake.conf} and rarely needs to be modified. qmake or \l{#QMAKESPEC}{qmake.conf} and rarely needs to be modified.
\section1 QMAKE_LFLAGS_REL_RPATH
Specifies the linker flags needed to enable relative paths in
\l{QMAKE_RPATHDIR}.
The value of this variable is typically handled by
qmake or \l{#QMAKESPEC}{qmake.conf} and rarely needs to be modified.
\section1 QMAKE_REL_RPATH_BASE
Specifies the string the dynamic linker understands to be the
location of the referring executable or library.
The value of this variable is typically handled by
qmake or \l{#QMAKESPEC}{qmake.conf} and rarely needs to be modified.
\section1 QMAKE_LFLAGS_RPATHLINK \section1 QMAKE_LFLAGS_RPATHLINK
Specifies the linker flags needed to use the values from Specifies the linker flags needed to use the values from
@ -2095,6 +2111,13 @@
executable at link time so that the paths will be preferentially executable at link time so that the paths will be preferentially
searched at runtime. searched at runtime.
When relative paths are specified, qmake will mangle them into a form
understood by the dynamic linker to be relative to the location of
the referring executable or library.
This is supported only by some platforms (currently Linux and
Darwin-based ones) and is detectable by checking whether
\l{QMAKE_REL_RPATH_BASE} is set.
\section1 QMAKE_RPATHLINKDIR \section1 QMAKE_RPATHLINKDIR
Specifies a list of library paths for the static linker to search for implicit Specifies a list of library paths for the static linker to search for implicit

View File

@ -125,10 +125,23 @@ UnixMakefileGenerator::init()
const ProStringList &rpathdirs = project->values("QMAKE_RPATHDIR"); const ProStringList &rpathdirs = project->values("QMAKE_RPATHDIR");
for (int i = 0; i < rpathdirs.size(); ++i) { for (int i = 0; i < rpathdirs.size(); ++i) {
QString rpathdir = rpathdirs[i].toQString(); QString rpathdir = rpathdirs[i].toQString();
if (rpathdir.length() > 1 && rpathdir.at(0) == '$' && rpathdir.at(1) != '(') if (rpathdir.length() > 1 && rpathdir.at(0) == '$' && rpathdir.at(1) != '(') {
rpathdir.replace(0, 1, "\\$$"); // Escape from make and the shell rpathdir.replace(0, 1, "\\$$"); // Escape from make and the shell
else if (!rpathdir.startsWith('@')) } else if (!rpathdir.startsWith('@') && fileInfo(rpathdir).isRelative()) {
rpathdir = QFileInfo(rpathdir).absoluteFilePath(); QString rpathbase = project->first("QMAKE_REL_RPATH_BASE").toQString();
if (rpathbase.isEmpty()) {
fprintf(stderr, "Error: This platform does not support relative paths in QMAKE_RPATHDIR (%s)\n",
rpathdir.toLatin1().constData());
continue;
}
if (rpathbase.startsWith('$'))
rpathbase.replace(0, 1, "\\$$"); // Escape from make and the shell
if (rpathdir == ".")
rpathdir = rpathbase;
else
rpathdir.prepend(rpathbase + '/');
project->values("QMAKE_LFLAGS").insertUnique(project->values("QMAKE_LFLAGS_REL_RPATH"));
}
project->values("QMAKE_LFLAGS") += var("QMAKE_LFLAGS_RPATH") + escapeFilePath(rpathdir); project->values("QMAKE_LFLAGS") += var("QMAKE_LFLAGS_RPATH") + escapeFilePath(rpathdir);
} }
} }