在CMake中有条件地找到共享库的依赖项

时间:2019-01-20 12:25:35

标签: linux cmake dependencies shared-libraries

在Linux中,我有一个共享库somelib.so,可以选择对其他几个共享库,例如dep1dep2进行编译。现在,我正在编写一个使用somelib的客户端应用程序,但是如果somelib是用dep1dep2编译的,我现在不提前,直到得到一个链接器错误。

是否有使用CMake找出答案的方法?我需要类似的东西

IF somelib DEPEND ON dep1 THEN...

1 个答案:

答案 0 :(得分:2)

  

...使用somelib的客户端应用程序,但是我现在不提前   如果somelib是用dep1和dep2编译的...我需要类似的东西

IF somelib DEPEND ON dep1 THEN...

我相信在Linux上,解决方法是使用LD链接器选项-Wl,--exclude-libs,ALL-Wl,--as-needed

始终包括-ldep1-ldep2作为库选项。然后在不需要时使用-Wl,--as-needed排除库。

如果我没记错的话,对于数学库-lm来说,这种技巧可以追溯到20或30年左右。有时,数学符号包含在glibc中,而其他时候它们包含在-lm中。因此,您始终针对-lm进行链接,并允许链接程序使用-lm丢弃-Wl,--as-needed库。

实际上,ld(1) man page表示在使用技巧时会推入并弹出状态:

  

此选项的一个目标是pkg-config的规范。   与--libs选项一起使用时,所有可能需要的库   被列出,然后可能一直与之关联。它是   最好返回如下内容:

 -Wl,--push-state,--as-needed -libone -libtwo -Wl,--pop-state

-Wl,--exclude-libs,ALL是阻止您从-ldep1-ldep2重新导出符号的一种选择。如果未使用库,则您不需要-Wl,--exclude-libs,ALL

我相信在构建somelib.so时,静态库和共享对象的两个CMake设置是:

set(OUR_LINKER_FLAGS "-Wl,--exclude-libs,ALL -Wl,--as-needed -ldep1 -ldep2")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${OUR_LINKER_FLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${OUR_LINKER_FLAGS}")

另请参阅CMake文档中的ld(1) man pageCMAKE_MODULE_LINKER_FLAGSCMAKE_SHARED_LINKER_FLAGS。如果您要构建可执行文件,您可能还对CMAKE_EXE_LINKER_FLAGS感兴趣。