fix -rpath-link handling for non-installed prefix builds
authorOswald Buddenhagen <oswald.buddenhagen@nokia.com>
Wed, 8 Aug 2012 19:38:35 +0000 (21:38 +0200)
committerQt by Nokia <qt-info@nokia.com>
Sat, 11 Aug 2012 08:40:16 +0000 (10:40 +0200)
forwarding module pris get rpath_link{,_private} fields, which are
used accordingly by qtAddModule().

Change-Id: I0abc2dc8b1e8744dbf7f439aa7fed9ae159c2c74
Reviewed-by: Joerg Bornemann <joerg.bornemann@nokia.com>
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@nokia.com>
mkspecs/features/qt_functions.prf
mkspecs/features/qt_module_fwdpri.prf
mkspecs/features/qt_tool.prf

index 06389fa..8daa2c4 100644 (file)
@@ -85,13 +85,7 @@ defineTest(qtAddModule) {
     }
 
     isEmpty(LINKAGE) {
-       !isEmpty(MODULE_LIBS) {
-           LINKAGE = -L$$MODULE_LIBS
-           !isEqual(MODULE_LIBS, $$[QT_INSTALL_LIBS]) {
-               # Make sure we can link to uninstalled libraries
-               unix:!mac:QMAKE_LFLAGS *= "-Wl,-rpath-link,$$MODULE_LIBS"
-           }
-       }
+       !isEmpty(MODULE_LIBS): LINKAGE = -L$$MODULE_LIBS
        lib =
        if(!debug_and_release|build_pass):CONFIG(debug, debug|release) {
            win32: lib = -l$${MODULE_NAME}$${QT_LIBINFIX}d
@@ -99,6 +93,15 @@ defineTest(qtAddModule) {
        }
        isEmpty(lib): lib = -l$${MODULE_NAME}$${QT_LIBINFIX}
        LINKAGE += $$lib
+
+       # Make sure we can link to uninstalled libraries
+       unix:!mac:!isEmpty(QT.$${1}.libs) { # Use unmodified path, so /usr/lib also works
+            for(rpl, QT.$${1}.rpath_link): \
+                QMAKE_LFLAGS *= -Wl,-rpath-link,$$rpl
+            !auto_use_privates:!isEqual(2, UsePrivate): \
+                for(rpl, QT.$${1}.rpath_link_private): \
+                    QMAKE_LFLAGS *= -Wl,-rpath-link,$$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.
index 2fd833d..0f7c7c4 100644 (file)
 
     MODULE_FWD_PRI = $$mod_qmake_base/mkspecs/modules/qt_$${MODULE}.pri
 
+    # -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_BASE = $$MODULE_BASE_DIR" \
@@ -21,6 +62,8 @@
         "QT_MODULE_IMPORT_BASE = $$mod_component_base/imports" \
         "QT_MODULE_LIB_BASE = $$mod_component_base/lib" \
         "QT_MODULE_PLUGIN_BASE = $$mod_component_base/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)
index f1555de..5e05f93 100644 (file)
@@ -40,6 +40,8 @@ INSTALLS += target
     !isEmpty(deps) {
         for(dep, deps) {
             deppath += $$shell_path($$eval(QT.$${dep}.libs))
+            for(rpath, QT.$${dep}.rpath_link): \
+                deppath += $$shell_path($$rpath)
         }
         deppath = $$unique(deppath)
         equals(QMAKE_DIR_SEP, /) {