CMake:从ExternalProject链接共享C对象生成具有相对路径的二进制文件,而不是绝对

前端之家收集整理的这篇文章主要介绍了CMake:从ExternalProject链接共享C对象生成具有相对路径的二进制文件,而不是绝对前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
问题:我正在CMake中构建一个外部项目.该项目有一个Makefile,最终生成一个共享对象.我想链接并在我的超级项目中安装这个对象,就像它是项目中的一个库一样.问题是,ExternalProject lib通过相对路径链接到我的应用程序和库,而不是从CMake放置的任何目录运行时导致问题的绝对路径.

我有created a sample SSCCE example project来演示我的整体设置.如果需要,请随意仔细阅读和编译(git clone https://github.com/calebwherry/cmake-SO-question-main –recursive&& cd cmake-SO-question-main&& mkdir build& & cd build&& cmake ..&& make&& cd src / app / testApp&& ldd testApp).

每当我在可执行文件和libs上运行ldd时,我得到如下输出

linux-vdso.so.1 =>  (0x00007fff8b5a2000)
    libTestLib.so => /home/jwherry3/repos/cmake-superprj-main-test/build/src/lib/TestLib/libTestLib.so (0x00007f592da57000)
    ../../lib/libExtLib.so (0x00007f592d855000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f592d539000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f592d2b7000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f592d0a0000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f592cd14000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f592dc5a000)

我已尝试过处理RPATHS的各种事情,但无法将ExtLib链接到正确的位置.项目本地的lib(libTestLib.so)链接得很好.

我还尝试设置LD_LIBRARY_PATH以覆盖运行应用程序时的相对路径,但即使我这样做,它仍然找不到库.我想因为它是相对的,它不遵循正常的链接顺序?结果是二进制文件不会运行,除非我在它所在的目录中.

我觉得在使用ExternalProject创建依赖项时,我正在做一些非常愚蠢的事情,这是我的问题,但我已经打了3天,并没有想出任何东西.

系统设置:Debian Wheezy 64位,CMake 3.0.2,g -4.9.2.

解决方法

花了一段时间,但我终于在CMake Users listserv的帮助下得到了答案,特别是@ brad-king.

主要问题是我没有在我的外部项目中正确编译我的共享对象.布拉德回答我的问题:

Thanks for the complete/simple example. The problem is that
the libExtLib.so file built by the external project does not
have DT_SONAME set by the linker. When a linker is given a
path to a shared library file that has no soname then the path
is copied into the DT_NEEDED field of the consumer since it
has no soname to use for that.

There are two solutions:

  1. Make sure DT_SONAME gets set properly by the external build system.

  2. Tell CMake that the imported library file has no soname:

    set_property(TARGET ExtLib PROPERTY IMPORTED_NO_SONAME 1)

    CMake will then link it via -lExtLib and the linker will not
    store the path to the file in DT_NEEDED but only the file name.

Either of these should resolve the issue. Number 1 is cleaner.

由于我可以控制外部库中的Make文件,因此我通过编译共享对象选择了更清洁的第一个解决方案,如下所示:

$(SHARED_TARGET):$(OBJECTS)
$(CXX)$(CXXFLAGS)$(OBJECTS)-o $@ $(LDFLAGS)-Wl,-soname,$@

我已经修改了我的原始示例并使其更加简单:https://github.com/calebwherry/cmake-SO-question-main.我将把它作为参考,以便日后在这篇文章中绊倒的人.

附:

还有另一个次优解决方案.如果我没有完成上述任何操作,我可以给target_link_library指向我链接的库的完整路径,而不是使用导入的库目标.我在回购中的CMake文件中注意到了这一点并对其进行了评论.不是一个好的解决方案,但确实以另一种方式解决了问

原文链接:https://www.f2er.com/c/119142.html

猜你在找的C&C++相关文章