如何最好地告诉CMake的在哪里可以找到DLL
我有惊人的教程得出一个简单的项目结构如何最好地告诉CMake的在哪里可以找到DLL
https://rix0r.nl/blog/2015/08/13/cmake-guide/
它看起来如下:
- src
- CMakeLists.txt
- mylib
- include/mylib/mylibclass.h
- src/mylibclass.cpp
- CMakeLists.txt
- myapp
- src/myapp.cpp
- CMakeLists.txt
顶级的CMakeLists.txt包含:
cmake_minimum_required(VERSION 3.6)
project(sample_project VERSION 0.1 LANGUAGES CXX)
set(BUILD_SHARED_LIBS ON CACHE BOOL "")
add_subdirectory(mylib)
add_subdirectory(myapp)
mylib文件夹中的CMakeLists.txt包含:
add_library(mylib src/mylibclass.cpp include/mylib/mylibclass.h)
set_target_properties(mylib PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON)
target_include_directories(mylib
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> PRIVATE src)
而且一个在MyApp文件夹包含:
add_executable(myapp src/myapp.cpp)
target_link_libraries(myapp mylib)
我想利用这个结构同时开发MYLIB(如由BUILD_SHARED_LIBS确定的共享或静态库)和MYAPP。为此,我想将myapp设置为Visual Studio中的启动项目,然后编译并在MSVC调试器中运行。对于没有额外CMake代码的共享库情况,这是不可能的,因为myapp.exe不知道在哪里可以找到mylib.dll。
什么是最好的CMake实践告诉程序在哪里可以找到DLL?
编辑:
基于由@Andre的建议,我已经添加了以下几行到顶级的CMakeLists.txt:
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/out CACHE STRING "")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/out CACHE STRING "")
出现该问题,因为你的MYLIB。 dll与您的myapp.exe不在同一个文件夹中,当Visual Studio尝试启动您的myapp.exe时,它也不在%PATH%环境变量中
明显的解决方案是确保dll和exe都在同一文件夹。有几种方法可以做到这一点:
-
把这两样EXE和DLL到一个单一的“输出”目录设置你的目标RUNTIME_OUTPUT_DIRECTORY和LIBRARY_OUTPUT_DIRECTORY属性:
set_target_properties(myapp PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${sample_project_BINARY_DIR}/build_results/bin) set_target_properties(mylib PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${sample_project_BINARY_DIR}/build_results/bin)
这将产生myapp.exe和mylib.dll合并到顶级生成文件夹中的一个
build_results/bin
文件夹中。 或者通过设置全局变量CMAKE_RUNTIME_OUTPUT_DIRECTORY和CMAKE_LIBRARY_OUTPUT_DIRECTORY变量,这将为您的sample_project中的所有目标执行此操作。
-
构建完成后,将dll复制到exe文件位置。与
add_custom_command(TARGET MYLIB POST_BUILD 命令$ {} CMAKE_COMMAND复制-E $中是指mylib.dll {} myapp_BINARY_DIR /。 )
谢谢您的回答。你会说哪种解决方案是最佳实践?关于答案1,这是应该在应用程序还是在顶层确定的东西? – DrPepperJo
我更喜欢选项2,我可以放在我的顶级CMakeLists.txt中。只有极少数情况下,将所有dlls/exes放在同一个bin文件夹中是不可取的。请注意,这仅作为开发人员在构建环境中使用。对于“真正的”部署,我将使用CMake的[install](https://cmake.org/cmake/help/v3.4/command/install.html)机制。 –
假设我有一些预构建的外部库,我也需要这些DLL,我不想设置任何额外的运行时路径。选项3是促进dll文件复制的唯一方式,还是有某种选项可以复制与链接到存根文件相关联的所有dll? – DrPepperJo