我正在将大规模C ++应用程序的构建系统从SCons转换为CMake。我们依赖于构建树外部的20多个不同的软件包,这些软件包由各种构建系统构建。我现在正在编写Find [package] .cmake脚本,将这些脚本作为导入的目标暴露给新的CMake构建系统。
典型的配置文件可能如下所示
add_library(sqlite SHARED IMPORTED)
set_target_properties(sqlite PROPERTIES
IMPORTED_LOCATION
"${PACKAGE_ROOT}/sqlite-${sqlite_VERSION}/lib/sqlite.dll"
IMPORTED_IMPLIB
"${PACKAGE_ROOT}/sqlite-${sqlite_VERSION}/lib/sqlite.lib"
INTERFACE_INCLUDE_DIRECTORIES
"${PACKAGE_ROOT}/sqlite-${sqlite_VERSION}/include"
)
每当我将项目中的一个dll链接到sqlite目标时,包含文件夹并根据需要传播必要的链接库。我可以构建我的项目,但只要可执行文件不知道sqlite.dll的路径就不会运行
要解决此问题,我可能想要获取所依赖的所有IMPORTED_LOCATION文件的路径,并将它们附加到启动器路径,如here所述。缺点是我无法在Visual Studio之外运行可执行文件,所以试图运行python单元测试的人会感到失望。
另一个解决方案是在每个包配置脚本中传递[package] _DLL列表,并创建一个post-build事件,其中DLL被复制到生成的可执行文件旁边。这会给构建带来开销(尽管可能不会过高)。但是这会污染Find [package]脚本,其中的变量并不属于那里。
我认为CMake会以平台无关的方式处理可执行文件所依赖的所有IMPORTED_LOCATION,但似乎CMake在这种情况下没有任何帮助。这让我很困惑,因为我确信这一定是许多开发团队必须面对的问题,这让我觉得我错过了一些明显的东西。
更新: 我意识到标准的方法是将DLL复制到build文件夹。后续问题是find_package脚本是否有任何标准方法来传递有关其运行时依赖性的信息?我已经考虑让每个包脚本设置两个变量,例如[package] _RUNTIMES_DEBUG和[package] _RUNTIMES_RELEASE并创建一个目标,复制这些变量中列出的所有文件。此外,我需要对像Qt和Boost这样的软件包进行特殊处理,我使用提供的find_package脚本,它不设置任何这样的变量(因为我可以告诉它没有用于转发此信息的惯例)