如何最好地告诉CMake在哪里找到DLL

时间:2016-10-01 14:15:27

标签: c++ windows visual-studio dll cmake

我有一个源自神奇教程的简单项目结构

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。为此,我想在My Studio中将myapp设置为我的启动项目,并在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 个答案:

答案 0 :(得分:2)

出现问题,因为当您的myapp.exe尝试启动myapp.exe时,您的mylib.dll与myapp.exe不在同一文件夹中,也不在%PATH%环境变量中

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

  1. 通过在目标上设置RUNTIME_OUTPUT_DIRECTORYLIBRARY_OUTPUT_DIRECTORY属性,将exe和dll放入单个“输出”目录中:

     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           COMMAND $ {CMAKE_COMMAND} -E copy mylib.dll $ {myapp_BINARY_DIR} /。 )