CMake:重建链接包时重新链接

时间:2014-07-01 20:23:20

标签: c++ linker cmake

如果已经提出这个问题我很抱歉,但我无法在网上找到让这件事工作的正确方法。

我有一个cmake项目Foo,它取决于另一个cmake项目Bar。目标:每当重新安装Bar(仅更改库而不是标题)时,Foo应该重新链接(当然不需要重建)。

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

FIND_PACKAGE(Bar REQUIRED)

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

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)

在这种情况下,它有效。但它并不令人满意。首先,导致路径可以改变。但你可能会说,你可以从变量中读取它。真正。但是,第二,即使在这种情况下,如果项目栏中包含许多未知的库,那么就不得不冒汗创建正确的字符串来添加...

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

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

由于

编辑:更清楚:如果库栏设置了包含其所有库的完整路径的变量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
  5. 并重新链接,如果自上次链接以来已创建依赖关系的任何一个。

1 个答案:

答案 0 :(得分:1)

  

并且仅包含以下说明

您不需要手动设置所有这些变量,只需使用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
...

重新链接!