在QMake中设置RPATH顺序

时间:2014-12-09 16:54:05

标签: linux qt qmake rpath

我有一个Linux Qt程序。我希望在可执行文件目录中优先使用(动态)Qt库(如果存在),否则使用系统的Qt库。 RPATH救援。

我将此行添加到 qmake 的.pro文件中:

QMAKE_LFLAGS    += '-Wl,-rpath,\'\$$ORIGIN\''

readelf 查看生成的可执行文件,我看到了:

0x000000000000000f (RPATH)              Library rpath: [$ORIGIN:/usr/local/Trolltech/Qt-5.2.0/lib]
0x000000000000001d (RUNPATH)            Library runpath: [$ORIGIN:/usr/local/Trolltech/Qt-5.2.0/lib]

似乎没错,但是 ldd 显示它使用系统版本:

libQt5Core.so.5 => /usr/local/Trolltech/Qt-5.2.0/lib/libQt5Core.so.5 (0x00007f2d2fe09000)

如果我手动编辑qmake的生成的Makefile来交换两个rpath的顺序,那么$ ORIGIN出现在/ usr / local / ...之后,我得到正确的行为:

0x000000000000000f (RPATH)              Library rpath: [/usr/local/Trolltech/Qt-5.2.0/lib:$ORIGIN]
0x000000000000001d (RUNPATH)            Library runpath: [/usr/local/Trolltech/Qt-5.2.0/lib:$ORIGIN]

libQt5Core.so.5 => ./libQt5Core.so.5 (0x00007fb92aba9000)

我的问题在于 qmake 如何构建最终的LFLAGS变量。我无法弄清楚如何在系统库之后添加($ ORIGIN)。有什么想法吗?

4 个答案:

答案 0 :(得分:12)

您可以将以下内容添加到.pro文件中,以强制动态链接器在运行时在Linux中查找与Qt应用程序相同的目录:

unix:{
    # suppress the default RPATH if you wish
    QMAKE_LFLAGS_RPATH=
    # add your own with quoting gyrations to make sure $ORIGIN gets to the command line unexpanded
    QMAKE_LFLAGS += "-Wl,-rpath,\'\$$ORIGIN\'"
}

如果要查看可执行路径的子目录,可以使用:

QMAKE_LFLAGS += "-Wl,-rpath,\'\$$ORIGIN/libs\'"

请注意,您的应用程序目录中应该具有完全相同名称的.so文件。例如,您应该将libQt5Core.so.5.2.0复制到名称为libQt5Core.so.5的应用程序目录中。现在ldd显示了应用程序的目录。

您还可以在应用程序目录中使用libQt5Core.so.5.2.0及其名称为libQt5Core.so.5的链接。

答案 1 :(得分:1)

就我的研究而言,你只能在QMake的列表开头添加RPATH。

但是,如果您使用的是Linux并且可以安装chrpath,那么您可以解决这个问题。

在.pro文件末尾添加此块

# Add spacing since chrpath cannot expand RPATH length
QMAKE_RPATHDIR = \
    /XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY1\
    /XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY2\
    /XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY3\
    /XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY4
QMAKE_POST_LINK += 'chrpath -r \'/my/qt/installation:\$$ORIGIN\' $$OUT_PWD/mybinaryname;'

答案 2 :(得分:0)

我对发生的事情进行了一些猜测,但这是基于了解ld的一些奇怪行为。

检查是否存在将在处理RUNPATH变量之前生效的LD_LIBRARY_PATH变量。由于RPATHRUNPATH都存在,LD_LIBRARY_PATH规则生效,因此如果已设置,则取消设置。

其次,我永远不会期待看到:

libQt5Core.so.5 => ./libQt5Core.so.5 (0x00007fb92aba9000)

ldd的输出中,我总会看到$ORIGIN扩展到二进制文件的目录(也许你缩短了它?),所以我原以为:

libQt5Core.so.5 => /path/to/bin/./libQt5Core.so.5 (0x00007fb92aba9000)

这意味着LD_LIBRARY_PATH展开.:/usr/local/Trolltech/Qt-5.2.0/lib听起来像是{{1}},这听起来像是你发生了环境覆盖。

答案 3 :(得分:0)

qmake会始终将QMAKE_RPATHDIR附加在QT_INSTALL_LIBS文件中内部定义的$(QT_DIR)/mkspecs/features/qt.prf

170:    relative_qt_rpath:!isEmpty(QMAKE_REL_RPATH_BASE):contains(INSTALLS, target):\
173:        QMAKE_RPATHDIR += $$relative_path($$[QT_INSTALL_LIBS], $$qtRelativeRPathBase())
175:        QMAKE_RPATHDIR += $$[QT_INSTALL_LIBS/dev]
179:!isEmpty(QMAKE_LFLAGS_RPATHLINK):!contains(QT_CONFIG, static) {
189:    QMAKE_RPATHLINKDIR *= $$unique(rpaths)

为避免您的应用程序使用系统路径中的QT ,请注释掉上面的行QMAKE_RPATHDIR并添加QMAKE_RPATHDIR=$ORIGIN到{ {1}}文件。