2016-10-01 93 views
1

我有惊人的教程得出一个简单的项目结构如何最好地告诉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 "") 

回答

1

出现该问题,因为你的MYLIB。 dll与您的myapp.exe不在同一个文件夹中,当Visual Studio尝试启动您的myapp.exe时,它也不在%PATH%环境变量中

明显的解决方案是确保dll和exe都在同一文件夹。有几种方法可以做到这一点:

  1. 把这两样EXE和DLL到一个单一的“输出”目录设置你的目标RUNTIME_OUTPUT_DIRECTORYLIBRARY_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文件夹中。

  2. 或者通过设置全局变量CMAKE_RUNTIME_OUTPUT_DIRECTORYCMAKE_LIBRARY_OUTPUT_DIRECTORY变量,这将为您的sample_project中的所有目标执行此操作。

  3. 构建完成后,将dll复制到exe文件位置。与

    add_custom_command(TARGET MYLIB POST_BUILD 命令$ {} CMAKE_COMMAND复制-E $中是指mylib.dll {} myapp_BINARY_DIR /。 )

+0

谢谢您的回答。你会说哪种解决方案是最佳实践?关于答案1,这是应该在应用程序还是在顶层确定的东西? – DrPepperJo

+1

我更喜欢选项2,我可以放在我的顶级CMakeLists.txt中。只有极少数情况下,将所有dlls/exes放在同一个bin文件夹中是不可取的。请注意,这仅作为开发人员在构建环境中使用。对于“真正的”部署,我将使用CMake的[install](https://cmake.org/cmake/help/v3.4/command/install.html)机制。 –

+0

假设我有一些预构建的外部库,我也需要这些DLL,我不想设置任何额外的运行时路径。选项3是促进dll文件复制的唯一方式,还是有某种选项可以复制与链接到存根文件相关联的所有dll? – DrPepperJo

相关问题