编写CMakeLists.txt以将目标与次要依赖关系静态链接的正确方法是什么?

时间:2017-07-06 21:45:57

标签: c++ linux gcc cmake static-linking

首先,我认为问题标题大部分是准确的,但如果我没有正确询问,请告诉我如何改变它。

我有一个我想要使用的可执行文件,特别是audiowaveform。 readme.md上有关于如何动态构建动态的很好的说明。 但是,我的部署要求我静态链接目标,以避免在使用前安装依赖项。我该如何做到这一点?

根据readelf的说法,audiowaveform取决于几个方面:

$ readelf -d ~/Desktop/audiowaveform

Dynamic section at offset 0x4dd78 contains 35 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libsndfile.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libgd.so.3]
 0x0000000000000001 (NEEDED)             Shared library: [libmad.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libid3tag.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libboost_program_options.so.1.58.0]
 0x0000000000000001 (NEEDED)             Shared library: [libboost_filesystem.so.1.58.0]
 0x0000000000000001 (NEEDED)             Shared library: [libboost_regex.so.1.58.0]
 0x0000000000000001 (NEEDED)             Shared library: [libboost_system.so.1.58.0]
 0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]

大。所有这些都包含在带有find_package(x)的CMakeLists.txt中,依此类推。唯一没有明确包含的库是libstdc ++,libm,libgcc_s和libc,我猜是特殊的标准库并且可以自动使用? (我也很喜欢这里的清晰度,虽然这不是我的问题。)

由于我想要一个静态链接的输出,因此我可以直接修改CMakeLists.txt来查找这些库的静态版本,方法是在SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a")语句之上添加find_package()之类的内容。

问题是,这些库本身具有许多动态依赖性。如果我只是这样做,那些辅助依赖关系是未解决的,并且链接器会扼杀一堆/usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib/libid3tag.a(util.o): In function 'id3_util_compress': (.text+0x2a9): undefined reference to 'compress2',依此类推,等等几天。

我想我知道如何使用ldd按顺序查找整个依赖项列表:

$ ldd ~/Desktop/audiowaveform
    linux-vdso.so.1 =>  (0x00007ffcd057f000)
    libsndfile.so.1 => /usr/lib/x86_64-linux-gnu/libsndfile.so.1 (0x00007f748288d000)
    libgd.so.3 => /usr/lib/x86_64-linux-gnu/libgd.so.3 (0x00007f7482621000)
    libmad.so.0 => /usr/lib/x86_64-linux-gnu/libmad.so.0 (0x00007f7482401000)
    libid3tag.so.0 => /usr/lib/libid3tag.so.0 (0x00007f74821e8000)
    libboost_program_options.so.1.58.0 => /usr/lib/x86_64-linux-gnu/libboost_program_options.so.1.58.0 (0x00007f7481f6a000)
    libboost_filesystem.so.1.58.0 => /usr/lib/x86_64-linux-gnu/libboost_filesystem.so.1.58.0 (0x00007f7481d51000)
    libboost_regex.so.1.58.0 => /usr/lib/x86_64-linux-gnu/libboost_regex.so.1.58.0 (0x00007f7481a49000)
    libboost_system.so.1.58.0 => /usr/lib/x86_64-linux-gnu/libboost_system.so.1.58.0 (0x00007f7481845000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f74814c2000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f74811b9000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f7480fa3000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7480bd9000)
    libFLAC.so.8 => /usr/lib/x86_64-linux-gnu/libFLAC.so.8 (0x00007f7480964000)
    libvorbisenc.so.2 => /usr/lib/x86_64-linux-gnu/libvorbisenc.so.2 (0x00007f74806bb000)
    libjpeg.so.8 => /usr/lib/x86_64-linux-gnu/libjpeg.so.8 (0x00007f7480461000)
    libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f7480247000)
    libpng12.so.0 => /lib/x86_64-linux-gnu/libpng12.so.0 (0x00007f7480022000)
    libfreetype.so.6 => /usr/lib/x86_64-linux-gnu/libfreetype.so.6 (0x00007f747fd77000)
    libfontconfig.so.1 => /usr/lib/x86_64-linux-gnu/libfontconfig.so.1 (0x00007f747fb34000)
    libXpm.so.4 => /usr/lib/x86_64-linux-gnu/libXpm.so.4 (0x00007f747f922000)
    libvpx.so.3 => /usr/lib/x86_64-linux-gnu/libvpx.so.3 (0x00007f747f4fd000)
    libtiff.so.5 => /usr/lib/x86_64-linux-gnu/libtiff.so.5 (0x00007f747f289000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f747f06c000)
    libicui18n.so.55 => /usr/lib/x86_64-linux-gnu/libicui18n.so.55 (0x00007f747ec09000)
    libicuuc.so.55 => /usr/lib/x86_64-linux-gnu/libicuuc.so.55 (0x00007f747e875000)
    /lib64/ld-linux-x86-64.so.2 (0x00005567e9b26000)
    libogg.so.0 => /usr/lib/x86_64-linux-gnu/libogg.so.0 (0x00007f747e66b000)
    libvorbis.so.0 => /usr/lib/x86_64-linux-gnu/libvorbis.so.0 (0x00007f747e43f000)
    libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007f747e215000)
    libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007f747dedb000)
    liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007f747dcb9000)
    libjbig.so.0 => /usr/lib/x86_64-linux-gnu/libjbig.so.0 (0x00007f747daab000)
    libicudata.so.55 => /usr/lib/x86_64-linux-gnu/libicudata.so.55 (0x00007f747bff3000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f747bdef000)
    libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f747bbcc000)
    libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007f747b9c8000)
    libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f747b7c2000)

我相信,如果我手动将整个依赖列表写入CMakeLists.txt,那么编写FindX.cmake模块,将满足所有二级,三级等依赖项。但肯定必须有更快的方式;一个自动满足指定静态库的二级依赖关系,对吧?

在将目标与CMake静态链接时,满足整个依赖关系树的最佳方法是什么?

0 个答案:

没有答案