gpt4 book ai didi

c++ - CMake:重建链接包时重新链接

转载 作者:太空宇宙 更新时间:2023-11-04 11:31:42 31 4
gpt4 key购买 nike

如果有人问过这个问题,我深表歉意,但我无法在网上找到让这个东西正常工作的正确方法。

我有一个 cmake 项目 Foo,它依赖于另一个 cmake 项目 Bar。目标:无论何时重新安装 Bar(仅更改库,不更改 header ),Foo 都应重新链接(当然无需重建)。

因此,在项目 Foo(只有一个目标,一个可执行文件)的顶级文件夹中的 CMakeLists.txt 中,我有 cmake 命令

FIND_PACKAGE(Bar REQUIRED)

它在配置时正确地找到了项目 Bar。在我创建目标的部分,我有

LINK_DIRECTORIES (${BAR_LIBRARY_DIRS} )
ADD_EXECUTABLE(foo.exe main.cpp)
TARGET_LINK_LIBRARIES(foo.exe ${BAR_LIBRARIES})

里面的两个变量是在BarConfig.cmake中定义的,就是FIND_PACKAGE(Bar)要找的那个,只包含下面的指令

SET(BAR_INCLUDE_DIRS "${CMAKE_CURRENT_LIST_DIR}/../../../include")
SET(BAR_LIBRARY_DIRS "${CMAKE_CURRENT_LIST_DIR}/../../../lib")
SET(BAR_LIBRARIES bar)

我在屏幕上打印了这些变量,它们包含您期望它们包含的内容(/path/to/folder/include、/path/to/folder/lib 和 bar)。

所以,我在某处读到 cmake 无法向未指定完整路径的库添加依赖项。应该写

TARGET_LINK_LIBRARIES (foo.exe full-path-to-bar-libraries)

在这种情况下,它有效。但它并不令人满意。首先,导致路径可以改变。但是您可能会说,您可以从变量中读取它。真的。但是,其次,即使在那种情况下,如果项目 Bar 包含许多未知的库,那么创建正确的字符串以添加到那里将不得不大费周章...

但是,我还读到如果该库也是使用 cmake 构建和安装的,它应该会自动运行。事实上,我还有另一个项目对,A 依赖于 B,都是用 cmake 构建的。在那种情况下,依赖性起作用。不幸的是,项目 B 很大,定义了大量的 cmake 宏,我无法确定它设置正确变量的部分。

每次重新安装库 Bar 时,您是否知道如何让 Foo 重新链接(无需重建)?我想避免使用完整路径。

谢谢

编辑:为了更清楚:如果库 Bar 设置了一个变量 BAR_LIBRARIES 包含其所有具有完整路径的库,那么 TARGET_LINK_LIBRARIES 将起作用。但是,BAR_LIBRARIES 很可能包含“bar”,而不是“/some/path/libbar.a”。鉴于 LINK_DIRECTORIES 提供的目录和 TARGET_LINK_LIBRARIES 提供的库名称,我希望 cmake 能够将这两部分放在一起。例如。如果 BAR_LIBRARY_DIRS 包含“/folder1/;/folder2/”并且 BAR_LIBRARIES 包含“bar1;bar2”,我希望 cmake 建立对 libbar1.a 和 libbar2.a 的依赖,在以下任何一个中找到:

  1. /folder1/libbar1.a
  2. /folder2/libbar1.a
  3. /folder1/libbar2.a
  4. /folder2/libbar2.a

如果自上次链接以来已创建依赖项的任何一个发生更改,则重新链接。

最佳答案

and contains only the following instructions

您不需要手动设置所有这些变量,只需使用 CMakePackageConfigHelpers模块:

configure_package_config_file(
"./FooConfig.cmake.in"
"${foo_config}"
INSTALL_DESTINATION ${CONFIG_INSTALL_DESTINATION}
PATH_VARS CONFIG_INSTALL_DESTINATION
)

install(
FILES "${foo_config}"
DESTINATION ${CONFIG_INSTALL_DESTINATION}
)

并安装目标:

install(
TARGETS foo DESTINATION ${LIB_INSTALL_DESTINATION} EXPORT FooTargets
)
install(
EXPORT FooTargets NAMESPACE Foo:: DESTINATION ${CONFIG_INSTALL_DESTINATION}
)

在其他项目中的使用:

find_package(Foo CONFIG REQUIRED)
target_link_libraries(boo Foo::foo)

就是这样。像魅力一样工作(Makefile 生成器 example ):

> cmake -HFoo -B_builds/Foo -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="`pwd`/_install"
> cmake --build _builds/Foo/ --target install
> cmake -HBoo -B_builds/Boo -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="`pwd`/_install" -DCMAKE_VERBOSE_MAKEFILE=ON
> cmake --build _builds/Boo

再来一次(检查没有重新链接):

> cmake --build _builds/Boo

修改目标 Foo 并重新安装:

> echo "void some(){}" >> Foo/foo.cpp
> cmake --build _builds/Foo/ --target install

现在构建Boo:

> cmake --build _builds/Boo
...
Linking CXX executable boo.exe
...

重新链接!

关于c++ - CMake:重建链接包时重新链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24518673/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com