如何在cmake中将libs和dll添加到项目中?

时间:2014-07-30 05:05:18

标签: c++ cmake

我们有一个相当大的项目分为不同的子项目(在Visual Studio中这是一个包含多个项目的解决方案)。一些子项目依赖于一个外部库,它提供了一组要链接的库。文件夹结构类似于:

root
    external
        thing-with-libs
           inc
           libs
              thinger.lib
    proj1
    proj2
    proj3

其中,例如,proj1和proj2都链接有关于libs的东西。

要实现这一点,我们有root / external / thing-with-libs / CMakeLists.txt,它看起来与此类似:

project (ThingWithLibs)
set (lib_dir "${CMAKE_CURRENT_SOURCE_DIR}/libs")
add_library(ThingWithLibs STATIC IMPORTED GLOBAL)
set_target_properties(ThingWithLibs PROPERTIES IMPORTED_LOCATION_DEBUG ${lib_dir}/ThingWithLibs_D.lib)

然后,在proj1和proj2的CMakeLists.txt中,我们使用target_link_libraries (ThingWithLibs)。这增加了对ThingWithLibs的依赖性,一切正常。

现在,在最新的ThingWithLibs中,有dll和libs。我们需要静态链接lib并动态链接dll。 ThingWithLibs的新结构是:

thing-with-libs
    inc
    libs
        thinger.lib
    dlls
        thinger.dll

所以现在我们需要proj1和proj2来静态链接到thinger.lib,但是我们还需要在构建期间的某个时刻将thinger.dll复制到我们的bin目录。我相信我可以通过后期构建步骤来复制dll来解决这个问题,但我只能将其作为proj1和proj2中的后构建步骤,而不是作为ThingWithLibs的后构建步骤。让ThingWithLibs知道有关使用ThingWithLibs的所有内容似乎更好,所以我宁愿让CMakeLists.txt文件处理副本。

也许是相关的,也许是无关的,没有针对ThingWithLibs的visual studio项目--cmake没有创建一个。我目前的猜测是,在ThingWithLibs的CMakeLists.txt中我们没有得到复制后工作的后期步骤的原因是因为没有visual studio项目,没有任何东西可以执行构建后的步骤。

有其他人解决了这个问题吗?谢谢。

1 个答案:

答案 0 :(得分:2)

这是CMake真正使用某些改进的领域之一。

目前,除了在构建后步骤中手动复制dll之外别无其他方法。

有几种方法可以做到这一点:如果dll是由一个单独的项目构建的,我发现在使用软件包时使用CMake的安装机制或从导入的目标获取DLL的位置最方便。

如果dll是从同一个包构建的,你可以adjust the output directory,这样dll文件已经构建到与需要它的exe相同的目录中。如果这不是一个选项,您可以使用单独的复制步骤。这可能发生as a custom command,它作为构建dll的目标的构建后步骤附加,或者作为需要dll的目标的预构建步骤附加,或to a custom target执行此操作复制,反过来所有the targets that need the dll depend on

可以从$<TARGET_FILE:tgt> generator expression获取dll的完整路径。

找到适合您的正确方法可能有点繁琐。这取决于您的构建设置的外观以及您希望在哪些情况下运行dll复制操作。因此,我建议您设置一个小型测试项目,并花一个下午探索不同的选项。一旦掌握了它,它就不像它看起来那么难,但你应该花时间彻底探索不同的选择。