【问题标题】:boost libraries built with relative paths使用相对路径构建的 boost 库
【发布时间】:2016-10-10 13:07:10
【问题描述】:

我在 QNX 6.5.0 中构建了 boost 1.57.0。没有构建错误。但是一些库链接到 libboost_system.so 指定相对路径。我保存了编译日志。这是 boost_thread 的链接步骤:

"QCC_gpp"   -o "bin.v2/libs/thread/build/qcc/release/threading-multi/libboost_thread.so.1.57.0"  -shared "bin.v2/libs/thread/build/qcc/release/threading-multi/pthread/thread.o" "bin.v2/libs/thread/build/qcc/release/threading-multi/pthread/once.o" "bin.v2/libs/thread/build/qcc/release/threading-multi/future.o" "bin.v2/libs/system/build/qcc/release/threading-multi/libboost_system.so.1.57.0"    -lm 

所以,当我运行ldd libboost_thread.so 时,它找不到 libboost_system。我认为 libboost_thread 应该与-lboost_system 选项相关联。但我不知道该怎么做。

谢谢。

编辑:我无法构建任何与 boost_thread 链接的程序。因为, boost_thread 在 bin.v2/libs/system/build/qcc/release/threading-multi 文件夹中搜索 boost_system。但是 boost_thread 和 boost_system 都在库搜索文件夹中。 (用LD_LIBRARY_PATH定义)

【问题讨论】:

标签: boost linkage


【解决方案1】:

如果您运行objdump -p libboost_thread.so,您会发现 libboost_system.so 的 NEEDED 条目包含一个(相对)路径。根据 ELF 规范,NEEDED 条目应该只包含所需库的名称,因此链接器或 QCC 中似乎存在错误。

因为如果这样,系统将无法在运行时找到该文件,除非当前目录与发生链接时的目录相同。

最简单的解决方法是静态链接到 libboost_thread.a。

我自己使用的另一种解决方法是创建一个围绕 QCC 的包装器,它可以转换命令行,以便将依赖项作为 -Wl,-L <path> -Wl,-l <name> 而不是 <path>/lib<name>.so 给出这也需要更改 Boost 构建系统,所以它不会将版本号附加到库文件名的末尾。

【讨论】:

  • 只是一个旧答案的注释...... ELF specification 在这里没有被违反。该错误在 Boost.Build 中;请参阅下面的答案。
【解决方案2】:

正如 Nicklas Angare 所写,问题在于 NEEDED 条目包含构建时的相对路径,而它应该只包含 .so 文件的名称。

发生这种情况是因为提供给链接器的共享库没有 SONAME,而 发生是因为没有为链接器提供 -h 选项。

来自ld documentation

-h 名称
-soname=名称
创建 ELF 共享对象时,将内部 DT_SONAME 字段设置为指定名称。当可执行文件与具有 DT_SONAME 字段的共享对象链接时,当可执行文件运行时,动态链接器将尝试加载由 DT_SONAME 字段指定的共享对象,而不是使用链接器提供的文件名。

为什么链接器没有获得 qcc 构建的 -h 选项?这似乎是一个长期被忽视的 Boost 错误(请参阅Boost.org ticketgithub issue

如上述链接中所建议的,解决方案是从tools/build/v2/tools/qcc.jam 中删除$(HAVE_SONAME)

【讨论】:

    【解决方案3】:

    我认为你应该从暂存区拿走图书馆。

    我通常有类似的东西:

    -L /home/.../boost/stage/lib/ -lboost_system
    

    当然用你的 boost 目录替换 /home/.../boost


    稍微相关:使用上述配置,您需要确保正确版本的库位于加载程序库路径(LD_LIBRARY_PATH,ldconfig)上。

    如果您想要一个可以在构建它的系统上“直接运行”的开发构建,您可以将库路径直接烘焙到目标二进制文件中:

    -Wl,-rpath -Wl,/home/.../boost/stage/lib/:/usr/lib/x86_64-linux-gnu
    

    【讨论】:

    • 在 /usr/local/lib 中安装了库后,我也尝试了 ldd。结果是一样的。
    • @QQ 我看不出你的评论与我的回答有什么关系。
    猜你喜欢
    • 2013-04-18
    • 1970-01-01
    • 1970-01-01
    • 2017-05-14
    • 1970-01-01
    • 2018-06-15
    • 2012-09-05
    • 2012-04-27
    • 2018-02-24
    相关资源
    最近更新 更多