在 CMake 项目中传递复制 dll
Transitively copy dlls in a CMake project
假设我有一个 CMake 项目,其中包含两个库 foo
和 bar
,以及一个可执行文件 app
:
cmake_minimum_required(VERSION 3.1)
project(app)
add_library(foo SHARED foo.cpp)
add_library(bar SHARED bar.cpp)
target_link_libraries(foo PUBLIC bar)
add_executable(app main.cpp)
target_link_libraries(app foo)
所以首先,当我尝试在 Windows 上编译这个项目时,它因错误 LNK1104 - cannot open file 'bar.lib'
而失败。我究竟做错了什么?我的意思是,这就像有史以来最基本的例子,它怎么会失败呢?我正在使用 Visual Studio 15.4.2 (MSVC 14.11.25503) 和 CMake 3.9.1.
进行编译
下一个问题,我想让我的foo.dll
和bar.dll
自动复制到编译app.exe
的文件夹中(我假设是$<TARGET_FILE_DIR:app>
) .我可以通过向 foo
和 bar
添加 properties/custom 命令而不修改 foo
和 bar
链接到 [= 的方式来做到这一点 13=]?
换句话说,我想修改上面的脚本,这样,如果我添加一个新的目标可执行文件 app2
,我只需要对 target_link_libraries(app2 foo)
的简单调用 将我的 foo.dll
和 bar.dll
复制到 app2
的目标文件夹。
我目前遇到的问题是涉及 add_custom_command( ... COMMAND ${CMAKE_COMMAND} -E copy_if_different ... )
的现有解决方案需要添加到 final 目标 app
和 app2
明确地说,我不能只是 add_custom_command(foo ...)
因为 app
和 app2
可以在任意文件夹中结束。
我正在考虑修改 target_link_libraries(app ...)
以包装对我自己的函数(复制 dll 的函数)的调用并调用旧的 _target_link_libraries(app ...)
,但我不确定那是否是最干净的方法,想知道是否有更好的方法。
最后,我希望我们找到的任何解决方案也适用于 IMPORTED
未编译为 CMake 子项目的目标和库。
So first, when I try to compile this project on Windows, it failed
with an error LNK1104 - cannot open file 'bar.lib'. What am I doing
wrong?
您的库不导出任何内容,这就是它不创建导入库(他抱怨的 .lib
文件)的原因。确保您的源文件确实定义了一些符号,然后确保这些符号实际上是从 DLL 中导出的。 CMake 甚至附带 a module that provides portable macros for exporting symbols.
Next question, I want my foo.dll and bar.dll to be automatically
copied to the folder where app.exe will be compiled (I assume it will
be $). Can I do that by adding properties/custom
commands to foo and bar without modifying the way that foo and bar are
linked to app?
不幸的是,CMake 目前没有对运行时依赖管理的适当支持。这就是阻止它与对 target_link_libraries
的简单调用一起工作的原因。 CMake 开发人员已经多次讨论过这样的功能,但似乎很难做到正确(不过我对这里的细节不太熟悉)。
我能想到的最方便的方法是让提供库提供一个 CMake function
,它将所有相关的 DLL 复制到作为参数提供给它的文件夹中。这仍然很痛苦,但至少您保留了有关要使用提供的库复制哪些 DLL 的详细信息。
假设我有一个 CMake 项目,其中包含两个库 foo
和 bar
,以及一个可执行文件 app
:
cmake_minimum_required(VERSION 3.1)
project(app)
add_library(foo SHARED foo.cpp)
add_library(bar SHARED bar.cpp)
target_link_libraries(foo PUBLIC bar)
add_executable(app main.cpp)
target_link_libraries(app foo)
所以首先,当我尝试在 Windows 上编译这个项目时,它因错误 LNK1104 - cannot open file 'bar.lib'
而失败。我究竟做错了什么?我的意思是,这就像有史以来最基本的例子,它怎么会失败呢?我正在使用 Visual Studio 15.4.2 (MSVC 14.11.25503) 和 CMake 3.9.1.
下一个问题,我想让我的foo.dll
和bar.dll
自动复制到编译app.exe
的文件夹中(我假设是$<TARGET_FILE_DIR:app>
) .我可以通过向 foo
和 bar
添加 properties/custom 命令而不修改 foo
和 bar
链接到 [= 的方式来做到这一点 13=]?
换句话说,我想修改上面的脚本,这样,如果我添加一个新的目标可执行文件 app2
,我只需要对 target_link_libraries(app2 foo)
的简单调用 将我的 foo.dll
和 bar.dll
复制到 app2
的目标文件夹。
我目前遇到的问题是涉及 add_custom_command( ... COMMAND ${CMAKE_COMMAND} -E copy_if_different ... )
的现有解决方案需要添加到 final 目标 app
和 app2
明确地说,我不能只是 add_custom_command(foo ...)
因为 app
和 app2
可以在任意文件夹中结束。
我正在考虑修改 target_link_libraries(app ...)
以包装对我自己的函数(复制 dll 的函数)的调用并调用旧的 _target_link_libraries(app ...)
,但我不确定那是否是最干净的方法,想知道是否有更好的方法。
最后,我希望我们找到的任何解决方案也适用于 IMPORTED
未编译为 CMake 子项目的目标和库。
So first, when I try to compile this project on Windows, it failed with an error LNK1104 - cannot open file 'bar.lib'. What am I doing wrong?
您的库不导出任何内容,这就是它不创建导入库(他抱怨的 .lib
文件)的原因。确保您的源文件确实定义了一些符号,然后确保这些符号实际上是从 DLL 中导出的。 CMake 甚至附带 a module that provides portable macros for exporting symbols.
Next question, I want my foo.dll and bar.dll to be automatically copied to the folder where app.exe will be compiled (I assume it will be $). Can I do that by adding properties/custom commands to foo and bar without modifying the way that foo and bar are linked to app?
不幸的是,CMake 目前没有对运行时依赖管理的适当支持。这就是阻止它与对 target_link_libraries
的简单调用一起工作的原因。 CMake 开发人员已经多次讨论过这样的功能,但似乎很难做到正确(不过我对这里的细节不太熟悉)。
我能想到的最方便的方法是让提供库提供一个 CMake function
,它将所有相关的 DLL 复制到作为参数提供给它的文件夹中。这仍然很痛苦,但至少您保留了有关要使用提供的库复制哪些 DLL 的详细信息。