我现在正在使用cmake和C ++在Windows中编写动态库。我使用以下命令导出库:
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/${libName}ConfigVersion.cmake"
VERSION ${version}
COMPATIBILITY AnyNewerVersion
)
configure_package_config_file(${input} ${output}
INSTALL_DESTINATION "${config_install}"
PATH_VARS target_export_name_local target_head_dir
)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${libName}Config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/${libName}ConfigVersion.cmake"
DESTINATION "${config_install}")
install(EXPORT ${libName}
NAMESPACE ""
DESTINATION ${config_install})
通过这样做,我也可以拥有库配置文件。就我而言,我将libConfig.cmake lib.cmake lib-debug.cmake lib-release.cmake
假设现在我有一个将使用此动态库的应用程序,我可以使用find_package
来导入我的应用程序项目中的库。一切都很顺利。但是当我创建可执行文件exe.exe
并尝试运行它时。然后,我将收到以下错误消息:
The program cannot start because lib.dll cannot be found ...
然后现在我有两个解决方案:第一个是将lib.dll复制到应用程序项目的输出文件夹。有一个名为IMPORTED_LOCATION_DEBUG
的属性与导入的库目标相关,我可以知道dll的位置,然后执行应对。
第二个解决方案是确保在运行应用程序时,它还会搜索包含lib.dll的文件夹。但是,我不知道如何在CMake中做到这一点。有任何想法吗?
顺便问一下,你有解决这个问题的其他方法吗?感谢。
答案 0 :(得分:1)
您遇到的问题似乎与二进制分发相关,而不是CMake的原始范围。在为第三方用户发布应用程序时,您要么以嵌入并查找所有库的方式进行分发,要么可以声明库是应用程序的明确要求,并让用户安装它(不常见)在Windows中我记得它。)
现在,当您在开发环境中遇到此问题时,您不需要太复杂化。我想说有两个不错的选择:
在Windows环境(我想象大多数其他操作系统)上,如果您有意使用共享库(即 DLL 文件),它或多或少意味着您想要分享库文件在几个使用它的应用程序中 如果这个假设成立,那么在每个应用程序文件夹中复制dll的想法似乎是矛盾的。如果你真的可以在每个使用它的应用程序中嵌入一个库二进制文件的副本,为什么不静态链接应用程序呢?它可以减少使用的总空间(因为链接器将仅为实际使用的函数嵌入对象代码,而如果复制 DLL ,则所有对象代码显然都随副本一起提供)。
您可以在编译库的CMake项目中将CMake变量BUILD_SHARED_LIBS
设置为OFF
以生成静态库。当您使用这样的静态库时,链接时需要库,但不是在运行时。
然后,另一方面,您可能希望在多个应用程序之间实际共享dll文件。在Windows环境中控制它的一个好方法是确保在Windows的PATH
环境变量中找到 DLL 文件的路径。
有两种显而易见的方法:
PATH
变量中已存在的路径中。PATH
变量。