【发布时间】:2020-07-30 00:17:59
【问题描述】:
我有两个 C++ 模块:A 和 B,其中 B 链接到一组静态库 lib*.a(我在这里使用 * 表示一组库文件)和 A链接到B。
我有 B 的 CMakeLists.txt:
add_library(B STATIC B.cpp)
target_include_directories(B PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} "/path/to/headers/directory/for/lib*.a")
link_directories("Path/to/directory/contains/lib*.a")
target_link_libraries(B PRIVATE lib*)
和A 的 CMakeLists.txt:
add_library(A STATIC A.cpp)
target_include_directories(A PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} "/path/to/headers/for/libB.a") # compiler outputs libB.a when target name is B
link_directories("Path/to/directory/contains/libB.a")
target_link_libraries(A PRIVATE B)
一切正常,直到我尝试将A 设为共享库,然后我从链接器收到错误消息cannot find -l*。我相信原因是当我将A设置为共享时,编译器会查找共享库,但不可用。
我不明白的事情:
- B 已经是静态库了,为什么链接器需要 lib*?
- 当我将
A设置为共享时,为什么编译器会查找共享库?我认为即使是共享的A也可以链接到静态库
我确实想指出,在A.cpp 中,我在顶部有#include B.hh,而B.hh 还包括lib*.a 的标题,这就是我有target_include_directories(B PUBLIC...) 的原因
【问题讨论】:
-
target_include_directories/path/to/headers/for/lib*.a如何是一个目录?为什么A与libB链接而不与B链接?link_directories("Path/to/libB.a")为什么? -
@KamilCuk 我更新了我的帖子。请看一下。关于 libB,编译器会自动将 lib 前缀附加到库名称中。所以如果你使用
libB,cmake 会寻找libB,如果你使用B,cmake 仍然会寻找libB -
A 的 CMakeLists.txt 中的
link_directories没有理由。A 的 CMakeLists.txt 中的target_include_directories也是错误的。当 A 为STATIC时,它会创建一个存档文件。当您将 A 设为共享库时,它需要链接到 B 和所有lib*,因为这就是共享库的工作方式。创建 B 时,它不包含来自lib*的任何内容,它只是 B 的任何来源的目标文件的存档。因此,涉及 B 的任何链接步骤也需要链接到lib*档案;假设您使用了正确的文件名。 -
@fdk1342 你的回答对解释我在这里遇到的情况很有意义,但它似乎与stackoverflow.com/questions/63163471/… 冲突,你能解释一下吗?谢谢!
-
请不要在描述您的代码或错误消息时使用
lib*.a之类的东西。相反,请使用确切名称、路径等。您希望每个人都能理解这些“通配符”是什么类型的库,并且您希望减少“不需要的”(如您所想的)信息。但实际上你的整个描述是相当模糊,为了理解问题,我们需要猜测这种“globbing”背后的原因。这种猜测很难:对这种通配符的不同解释会极大地改变你的问题。请准备好minimal reproducible example,并发布确切代码和错误消息。