如何最好地告诉 CMake 在哪里可以找到 dll

DrP*_*rJo 3 c++ windows dll cmake visual-studio

我有一个来自惊人教程的简单项目结构

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
Run Code Online (Sandbox Code Playgroud)

顶级 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 )
Run Code Online (Sandbox Code Playgroud)

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 )  
Run Code Online (Sandbox Code Playgroud)

而 myapp 文件夹中的一个包含:

add_executable( myapp src/myapp.cpp )
target_link_libraries( myapp mylib )
Run Code Online (Sandbox Code Playgroud)

我想使用这个结构来开发 mylib(作为由 BUILD_SHARED_LIBS 确定的共享或静态库)和 myapp。为此,我想在 Visual Studio 中将 myapp 设置为我的启动项目,并在 MSVC 调试器中编译和运行。这对于没有额外 CMake 代码的共享库情况是不可能的,因为 myapp.exe 不知道在哪里可以找到 mylib.dll。

告诉程序在哪里可以找到 dll 的最佳 CMake 实践是什么?

编辑:

根据@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 "" )
Run Code Online (Sandbox Code Playgroud)

And*_*dré 6

出现问题,因为当 Visual Studio 尝试启动 myapp.exe 时,您的 mylib.dll 与 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 )
    
    Run Code Online (Sandbox Code Playgroud)

    这会将 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}/.)

  • 我更喜欢选项 2,我可以把它放在我的顶级 CMakeLists.txt 中。只有在极少数情况下,将所有 dll/exe 文件放在同一个 bin 文件夹中是不可取的。请注意,这是我作为开发人员仅在构建环境中使用的东西。对于“真实”部署,我将使用 CMake 的 [install](https://cmake.org/cmake/help/v3.4/command/install.html) 机制。 (2认同)
  • 选项 1 和 2 需要您在 3rdparty 二进制文件的安装文件夹中构建自己的二进制文件,这真的非常尴尬。只剩下选项 3。或者,您可以设置 PATH 环境变量(或 LD_LIBRARY_PATH 在 linux 上),请参阅 http://stackoverflow.com/q/28533012/417197 (2认同)