fix lack of rpath-link when using modules from final location

if the libraries are in a non-standard location, but no rpath is used,
rpath-link is needed. this is often the case for non-prefix builds
(which have no forwarding pris any more).

as we cannot store absolute paths in the final pris, we need to store the
module names, and resolve them only at use time.

Change-Id: I1538b5d531611c76a2d7058a3b2ff683bdcbe427
Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
This commit is contained in:
Oswald Buddenhagen 2013-02-01 17:30:31 +01:00 committed by The Qt Project
parent 8705480587
commit 4c34b418b8
3 changed files with 24 additions and 53 deletions

View File

@ -67,6 +67,7 @@ qtAddModules(QT_PRIVATE, LIBS_PRIVATE)
message("Running this project against other versions of the Qt modules may crash at any arbitrary point.")
message("This is not a bug, but a result of using Qt internals. You have been warned!")
}
qtAddRpathLink($$QT $$QT_PRIVATE)
wince*:static:gui {
QTLIB += qmenu_wce.res

View File

@ -121,15 +121,6 @@ defineTest(qtAddModule) {
contains(MODULE_CONFIG, staticlib): \
PRE_TARGETDEPS *= $$MODULE_LIBS/$${QMAKE_PREFIX_STATICLIB}$${lib}.$${QMAKE_EXTENSION_STATICLIB}
# Make sure we can link to uninstalled libraries
!isEmpty(MODULE_LIBS) {
for(rpl, QT.$${1}.rpath_link): \
QMAKE_RPATHLINKDIR *= $$rpl
!auto_use_privates:!isEqual(2, UsePrivate): \
for(rpl, QT.$${1}.rpath_link_private): \
QMAKE_RPATHLINKDIR *= $$rpl
}
}
# Only link to this module if a libs directory is set, else this is just a module
# to give access to sources or include files, and not for linking.
@ -190,6 +181,24 @@ defineTest(qtAddModules) {
export(using_privates)
}
defineTest(qtAddRpathLink) {
# -rpath-link is used by the linker to find dependencies of dynamic
# libraries which were NOT specified on the command line.
# This means that paths of direct dependencies (QT & QT_PRIVATE)
# don't need to appear here. However, their private dependencies'
# paths OTOH need to be put there.
pubqt = $$replace(1, -private$, )
pubdep = $$resolve_depends(pubqt, "QT.")
privdep = $$resolve_depends(pubqt, "QT.", ".depends" ".private_depends" ".run_depends")
privdep -= $$pubdep
rpaths =
for(dep, privdep): \
rpaths += $$eval(QT.$${dep}.libs)
QMAKE_RPATHLINKDIR *= $$unique(rpaths)
QMAKE_RPATHLINKDIR -= $$QMAKE_RPATHDIR # -rpath implies -rpath-link
export(QMAKE_RPATHLINKDIR)
}
# variable, default
defineTest(qtPrepareTool) {
$$1 = $$eval(QT_TOOL.$${2}.command)

View File

@ -29,6 +29,10 @@ else: \
} else {
module_privdep =
}
!isEmpty(QT_PRIVATE): \
module_rundep = "QT.$${MODULE}.run_depends = $$unique($$list($$replace(QT_PRIVATE, -private$, )))"
else: \
module_rundep =
static: \
module_build_type = "QT.$${MODULE}.module_config = staticlib"
else:mac:contains(QT_CONFIG, qt_framework): \
@ -62,6 +66,7 @@ else: \
"QT.$${MODULE}.qml = \$\$QT_MODULE_QML_BASE" \
"QT.$${MODULE}.depends =$$join(MODULE_DEPENDS, " ", " ")" \
$$module_privdep \
$$module_rundep \
$$module_build_type \
$$module_config \
"QT.$${MODULE}.DEFINES = $$MODULE_DEFINES" \ # assume sufficient quoting
@ -72,48 +77,6 @@ else: \
prefix_build {
# -rpath-link is used by the linker to find depedencies of dynamic
# libraries which were NOT specified on the command line.
# This means that .libs of each module's regular .depends (QT) don't
# need to be put there, as they appear on the linker line anyway.
# A module's QT_PRIVATE's .libs OTOH need to be put there.
# .depends_private (QT_FOR_PRIVATE) is somewhat special: if the privates
# are used, the libraries are explicitly linked. If not, their locations
# need to be put into -rpath-link. As QT_FOR_PRIVATE cannot in turn
# contain privates, they always end up in -rpath-link of dependant
# modules.
# For simplicity of use, each module's rpath list has all dependencies
# transitively resolved already.
pubqt = $$MODULE_DEPENDS $$QT_FOR_PRIVATE
pubdep = $$resolve_depends(pubqt, "QT.")
privqt = $$replace(QT_PRIVATE, -private$, )
privdep = $$resolve_depends(privqt, "QT.")
rpaths =
alldep = $$pubdep $$privdep
for(dep, alldep) { # Inherit link-rpaths from all our dependencies
rpaths += $$eval(QT.$${dep}.rpath_link) $$eval(QT.$${dep}.rpath_link_private)
}
privdep -= $$pubdep
for(dep, privdep): \ # Add our private dependencies' lib paths as new link-rpaths
rpaths += $$eval(QT.$${dep}.libs)
!isEmpty(rpaths) {
rpaths = $$unique(rpaths)
module_rpathlink = "QT.$${MODULE}.rpath_link = $$val_escape(rpaths)"
} else {
module_rpathlink =
}
rpaths_priv =
xtradep = $$resolve_depends(QT_FOR_PRIVATE, "QT.")
for(dep, xtradep): \ # Add our private API's dependencies' lib paths as new link-rpaths
rpaths_priv += $$eval(QT.$${dep}.libs)
rpaths_priv = $$unique(rpaths_priv)
rpaths_priv -= $$rpaths
!isEmpty(rpaths_priv) {
module_rpathlink_priv = "QT.$${MODULE}.rpath_link_private = $$val_escape(rpaths_priv)"
} else {
module_rpathlink_priv =
}
# Create a forwarding module .pri file
MODULE_FWD_PRI_CONT = \
"QT_MODULE_BIN_BASE = $$MODULE_BASE_OUTDIR/bin" \
@ -123,8 +86,6 @@ else: \
"QT_MODULE_LIB_BASE = $$MODULE_BASE_OUTDIR/lib" \
"QT_MODULE_LIBEXEC_BASE = $$MODULE_BASE_OUTDIR/libexec" \
"QT_MODULE_PLUGIN_BASE = $$MODULE_BASE_OUTDIR/plugins" \
$$module_rpathlink \
$$module_rpathlink_priv \
"include($$MODULE_PRI)"
write_file($$MODULE_FWD_PRI, MODULE_FWD_PRI_CONT)|error("Aborting.")
touch($$MODULE_FWD_PRI, $$MODULE_PRI)