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

How to best tell CMake where to find dll

本文关键字:在哪里 dll CMake 何最好      更新时间:2023-10-16

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

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相同的文件夹中,也不在%PATH%环境变量中,当Visual Studio试图启动您的myapp.exe

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

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