您如何在 cmake install 脚本语句中使用file(GET_RUNTIME_DEPENDENCIES...)?我在网上找不到这种用法的例子,而且我不清楚使用 [[ ]] 嵌入式自定义脚本的文档和错误消息中的声明。
我得到的印象是,在安装时,这可用于定位您的 cmake 目标的文件依赖项,并可能将它们与您的安装操作一起带过来,使其以独立形式使用。
例如,我的应用程序依赖于 QT,并且期望如果配置正确,则该应用程序所需的 QT dll 将被复制到 bin。(我只是想确保在这种情况下我也没有误解它的功能)。它可能不会直接复制文件,但我假设提供了要复制的文件列表,然后安装将处理(全部在安装时完成)。
我天真地尝试只是抛出一些东西开始是:
set(TARGET_NAME "myapp")
# installation settings
install(TARGETS ${TARGET_NAME}
[[
file(GET_RUNTIME_DEPENDENCIES
RESOLVED_DEPENDENCIES_VAR RES
UNRESOLVED_DEPENDENCIES_VAR UNRES
CONFLICTING_DEPENDENCIES_PREFIX CONFLICTING_DEPENDENCIES
EXECUTABLES ${TARGET_NAME}
)]]
RUNTIME DESTINATION "${INSTALL_X_BIN}" COMPONENT libraries
LIBRARY DESTINATION "${INSTALL_X_LIB}" COMPONENT libraries
)
Run Code Online (Sandbox Code Playgroud)
然而,这当然给了我:
CMake Error at applications/CMakeLists.txt:117 (install):
install TARGETS given target " file(GET_RUNTIME_DEPENDENCIES
RESOLVED_DEPENDENCIES_VAR RES
UNRESOLVED_DEPENDENCIES_VAR UNRES
CONFLICTING_DEPENDENCIES_PREFIX CONFLICTING_DEPENDENCIES
EXECUTABLES ${TARGET_NAME}
)" which does not exist.
-- Configuring incomplete, errors occurred!
Run Code Online (Sandbox Code Playgroud)
我觉得这很愚蠢,就像我错过了一些非常基本的东西。
顶层CMakeLists.txt包含:
include(CTest)
add_subdirectory(lib)
add_subdirectory(demo)
add_subdirectory(test)
Run Code Online (Sandbox Code Playgroud)
lib/CMakeLists.txt本质上是:
add_library(MyLib <sources>)
Run Code Online (Sandbox Code Playgroud)
demo/CMakeLists.txt本质上是:
add_executable(Demo demo.c)
target_link_libraries(Demo MyLib)
Run Code Online (Sandbox Code Playgroud)
test/CMakeLists.txt只是:
add_test(NAME Demo COMMAND Demo)
Run Code Online (Sandbox Code Playgroud)
从 gitlab-runner 中,我们执行:
cmake -G "Ninja" -DCMAKE_INSTALL_PREFIX=C:\opt\x64 -B. ..
cmake --build
ctest --output-on-failure
Run Code Online (Sandbox Code Playgroud)
前两步成功;第三个失败并显示:
Start 1: Demo
1/1 Test #1: Demo .......................Exit code 0xc0000135
***Exception: 0.03 sec
Run Code Online (Sandbox Code Playgroud)
如果我重试:
cmake --install
ctest
Run Code Online (Sandbox Code Playgroud)
然后测试成功。所以唯一的问题是build/lib/mylib.dll运行时没有发现ctest。而C:\opt\x64\lib是PATH,因此 DLL 是在 后找到的cmake --install。然而,这不是我们想要的:ctest应始终使用当前版本中的新 DLL,而不是已安装的版本。
在Linux下,一切正常。为什么 Windows 和 MinGW 不支持呢?这是 CMake 中的错误吗?我们如何解决这个问题,以便ctest …
所以,有很多方法可以复制文件(和目录)在CMake运行时(file(COPY ...),configure_file(...)和add_custom_command()所有的工作*),但我还没有发现如何从源复制到目录中建立文件或目录出现在生成的压缩文件通过CPack.我虽然这个SO答案会修复它,因为它实际上将复制链接到目标,然后将链接到它的安装:
install(TARGET mytarget DESTINATION bin)
Run Code Online (Sandbox Code Playgroud)
而我确实认识到file()和configure_file()命令没有明显的方法被添加到目标.但是,这没有用.因此,给定一个简单的CMakeLists.txt,如下所示,如何使所有文件(包括exmaple目录)出现在存档中?!
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
enable_language(FORTRAN)
add_executable(mytarget ${PROJECT_SOURCE_DIR}/myprog.for)
install(TARGETS mytarget DESTINATION bin)
add_custom_command(TARGET mytarget PREBUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
${PROJECT_SOURCE_DIR}/examplefiles ${PROJECT_BINARY_DIR}/examplefiles)
set(CPACK_GENERATOR "TGZ")
include(CPack)
Run Code Online (Sandbox Code Playgroud)
*我还没有发现这三种方法中哪一种实际上(大多数?)正确 - 所以对此的任何建议都将非常感激
我的项目的二进制目录结构目前是这样的(Windows):
bin/mainProject/{Debug,Release}
bin/library1/{Debug,Release}
bin/library2/{Debug,Release}
...
bin/libraryN/{Debug,Release}
Run Code Online (Sandbox Code Playgroud)
我想将库library1lib.dll, ...复制libraryNlib.dll到bin/mainProject/{Debug,Release}构建后的目录中。
对于 CMake,我认为使用构建后事件是可行的,因此我尝试将其添加到每个库中CMakeLists.txt:
add_custom_command(TARGET library1 POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/library1lib.dll
${CMAKE_BINARY_DIR}/mainProject/${CMAKE_BUILD_TYPE}/
)
Run Code Online (Sandbox Code Playgroud)
目前,有两个问题:
${CMAKE_BUILD_TYPE} 似乎没有定义,至少我在输出窗口中得到了该变量的空字符串。这个问题询问类似的问题,但只需要手动指定要复制哪些dll。我的问题是:有没有一种方法可以简单地让 CMake 复制链接到可执行库的所有 dll,而不需要手动告诉 CMake 要复制哪些文件?有时 CMake 更了解是否需要 dll。例如,在安装了同一库(例如Boost)的dll和静态库的系统中,并且我们选择静态链接到Boost,那么我们不需要复制dll。因此,与手动指定要复制哪些文件相比,CMake 可以做出更好的决定。另一个例子是,我的QT库链接到ICU库,并且在编写CMakeLists.txt时,我对此一无所知,所以我不可能告诉CMake复制ICU dll,所以这应该由CMake而不是完成人类。
假设操作系统是Windows。
我正在使用CMake生成可视化工作室文件.我想将xyz.dll添加到abc.exe所在的同一文件夹中.
我曾经读过某个地方,当我手动将xyz.dll文件复制到同一个文件夹中时abc.exe,问题就解决了.但每次都不可能..我想编写CMake命令,以便找到该xyz.dll文件并复制到所在的文件夹中abc.exe.
下面提到的是.exe和.dll文件驻留在我的PC 中的路径.
${MyWorkSpace_ROOT_DIR}/algoCommon/pthread/dll/xyz.dll
${MyWorkSpace_ROOT_DIR}/xml/addAlgo/.../cmakeOut.VS12/Debug/abc.exe
Run Code Online (Sandbox Code Playgroud)
abc是我的项目,我想确认以下提到的是否错误.
add_custom_command(TARGET abc PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${MyWorkSpace_ROOT_DIR}/algoCommon/pthread/dll"
$<{MyWorkSpace_ROOT_DIR}/xml/addAlgo/.../cmakeOut.VS12/Debug/:abc>)
Run Code Online (Sandbox Code Playgroud)
如果这是错误的,请帮助我.如果它是正确的,那么我想问一些疑问..这个命令会自动将xyz.dll文件复制到文件夹abc.exe中驻留还是其他地方正在发生?