【问题标题】:Generate in CMake header-only library that "stores" its dependency on boost filesystem在 CMake 仅标头库中生成,该库“存储”其对 boost 文件系统的依赖
【发布时间】:2023-03-04 02:32:01
【问题描述】:

我想在 cmake 中从 header.h 生成一个仅标头库,这取决于 libboost_system。 我可以毫无问题地编译库:

find_package(Boost COMPONENTS
        system filesystem
        REQUIRED)
include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
add_library(mylib header.h)
target_link_libraries(mylib PUBLIC ${Boost_LIBRARIES})
set_target_properties(mylib PROPERTIES LINKER_LANGUAGE CXX)

但是当我链接到其他地方的 mylib 时,找不到带有 ld 错误的 boost 库。

失败是有道理的,但我不知道如何在 CMake 中解决它。 如何“存储”对 mylib 的 boost 依赖?这样我就不用担心在其他外部项目中找到 boost 库了?

编辑:我正在使用 cmake 3.2

更新:mylib 是一个共享库(.so),当我在其他项目中使用它时,链接器无法找到 boost 库:

target_link_libraries(newproject.exe ${external_mylib})

undefined reference to symbol '_ZN5boost6system15system_categoryEv'
/PATH/TO/libboost_system-mt-d.so.1.57.0: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status

如果我再次明确链接到 Boost_LIBRARIES,问题就解决了。 target_link_libraries(newproject.exe ${external_mylib} ${Boost_LIBRARIES))

这并不能避免再次找到 boost_libraries,也许解决方案是将 boost_libraries 放在环境变量 LD_LIBRARY_PATH 中? 那就太过分了……

【问题讨论】:

    标签: c++ boost linker cmake


    【解决方案1】:

    将您的 CMake 版本更新到 2.8.12 或更高版本。

    您正在寻找的功能是transitive dependency handling。它由 CMake 策略 CMP0022 切换,因此请确保您不会在某处意外将其关闭。引用自manpage for target_link_libraries in CMake 3.1

    默认情况下,使用此签名的库依赖项是可传递的。 当此目标链接到另一个目标时,库 链接到此目标的链接将出现在其他目标的链接行上 目标也。这个传递的“链接接口”存储在 INTERFACE_LINK_LIBRARIES 目标属性,可以被覆盖 直接设置属性。当 CMP0022 未设置为 NEW 时, 传递链接是内置的,但可能会被 LINK_INTERFACE_LIBRARIES 属性。调用此的其他签名 命令可以设置使任何库以独占方式链接的属性 通过此签名私人。

    顺便说一句,Boost.SystemBoost.Filesystem 不同。确保您确实链接到正确的库。

    从您的编辑看来,您正在处理两个单独的 CMake 项目,这意味着您必须将 mylib 的依赖链传递到另一个项目。请查看CMake's packaging mechanism 了解如何执行此操作。

    【讨论】:

    • 我尝试过:target_link_libraries(mylib PUBLIC and INTERFACE ${Boost_Libraries)) 但没有运气。因为我没有将该库链接到任何可执行文件,所以我想知道 cmake 是否正确构建它,我必须为 BUILD 和 INSTALL 添加明确的要求。感谢指出文件系统,我在我的项目中都使用了这两个,但为了简单起见,在这里将其删除,因为我从系统中收到链接错误。我有 cmake 3.2
    • @phcerdan 你在建什么样的图书馆?请注意,这些依赖项仅由链接器解析,而不是由图书管理员解析,因此如果您构建静态库,则不会链接任何内容。始终确保将完整的依赖链带到链接器,即构建 dll 或可执行文件的位置。
    • 我已经制定了策略,即使我使用的是现代 cmake。如果您愿意,请检查我的更新,我正在构建一个共享库。
    • 从您的编辑看来,您正在处理两个独立的 CMake 项目,这意味着您必须将 mylib 的依赖链传递到另一个项目。看看CMake's packaging mechanism 了解如何做到这一点。另请注意,从您的问题中仍然很难看出您的实际设置是什么样的。将来发布此类问题时,请考虑建立minimal, complete and verifiable example
    • @phcerdan 从您的编辑看来,您正在处理两个单独的 CMake 项目,这意味着您必须将 mylib 的依赖链带到另一个项目。看看CMake's packaging mechanism 了解如何做到这一点。另请注意,从您的问题中仍然很难看出您的实际设置是什么样的。以后发布此类问题时,请考虑建立minimal, complete and verifiable example
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-21
    相关资源
    最近更新 更多