在Linux中,我有一个共享库somelib.so
,可以选择对其他几个共享库,例如dep1
和dep2
进行编译。现在,我正在编写一个使用somelib
的客户端应用程序,但是如果somelib
是用dep1
和dep2
编译的,我现在不提前,直到得到一个链接器错误。
是否有使用CMake找出答案的方法?我需要类似的东西
IF somelib DEPEND ON dep1 THEN...
答案 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 page,CMAKE_MODULE_LINKER_FLAGS和CMAKE_SHARED_LINKER_FLAGS。如果您要构建可执行文件,您可能还对CMAKE_EXE_LINKER_FLAGS感兴趣。