cmake - 如何在 CMake 中构建过程后复制目标的所有运行时依赖项?

标签 cmake dependencies post-build

我正在尝试将可执行目标的运行时依赖项自动复制到其构建的目录中。

例如,我使用 GTest 进行链接为共享库的单元测试。构建之后,如果我尝试启动单元测试,将会出现类似“gtest.dll isn't found”的错误。对于其他外部依赖项,存在同样的问题(对于目标是共享库的本地)。

我可以在链接后将每个外部库添加到安装过程并在该目录中运行测试,但这不是启动 CTest 的实用方法。

我想使用 file(GET_RUNTIME_DEPENDENCIES) 但它必须在构建之后调用,而且我没有找到 INSTALL(CODE) 模拟 POST_BUILD 阶段。

仅使用 add_custom_command 处理 DLL 也行不通,因为可能存在依赖继承。 例如,A 依赖于 B,而 B 又依赖于 C。如果我尝试通过这种方法进行依赖项复制,那么只有 B 会在 APOST_BUILD 过程中被复制。

我不喜欢将所有构建的工件存储在一个目录中,因为它会造成困惑,并可能在未来造成冲突。

最佳答案

找到了解决方案,但它不可移植且只能在 Windows 中使用。

CMake 3.21 版中有一个新的 TARGET_RUNTIME_DLLS生成器表达式,它以文件路径列表的形式返回运行时目标的所有运行时依赖项。 该表达式可用于 ADD_CUSTOM_COMMAND命令在 POST_BUILD 阶段。

项目中有共享库SomeLib 和测试可执行文件SomeLib_tests 的目标。 GTest 共享库的目标由 FIND_PACKAGE 找到功能。

cmake_minimum_required(VERSION 3.21)
project(ExampleProject)

add_library(SomeLib SHARED
            "include/SomeLib/api.h"
            "src/SomeLib/api.cpp")
target_include_directories(SomeLib PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")


find_module(GTest COMPONENTS gtest gtest_main REQUIRED)

add_executable(SomeLib_tests
               "ut/api_tests.cpp")
target_link_libraries(SomeLib_tests
                      PRIVATE SomeLib
                      PRIVATE GTest::gtest GTest::gtest_main)

gtest_add_tests(TARGET SomeLib_tests)

在这一步,如果我在Windows下调用CTest会出现类似“gtest.dll isn't found”的错误。

需要将可执行文件的所有依赖项复制到它的目录中。可以通过调用ADD_CUSTOM_COMMAND来实现结合TARGET_RUNTIME_DLLS表达。目标目录来自TARGET_FILE_DIR生成器表达式。

add_custom_command( TARGET SomeLib_tests POST_BUILD
                    COMMAND ${CMAKE_COMMAND} -E copy
                        $<TARGET_RUNTIME_DLLS:SomeLib_tests>
                        $<TARGET_FILE_DIR:SomeLib_tests>
                    COMMAND_EXPAND_LISTS)

这样,如果我构建项目并再次调用 CTest,测试将按预期运行。

关于cmake - 如何在 CMake 中构建过程后复制目标的所有运行时依赖项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68579934/

相关文章:

c++ - Qt 和 CMake 因重复符号而失败

java - java中的依赖管理

Android Ivy ActionBarSherlock

linux - 在 buildroot 中使用构建后脚本

c# - 对于我在 visual Studio 2013 中的类库项目;使用构建后事件如何将创建的 dll 复制到另一个路径?

android - arm-linux-androideabi/bin/ld : fatal error: -soname: must take a non-empty argument

c++ - 在何处/如何将构建文件放置在 OpenCV 中

android - 错误无法解决'com.yqritic :recylerview-flexibledivider:1. 2.4;

visual-studio-2008 - "Attach to Process"作为构建后事件

QtCreator : Issues not displayed in Issue panel any more