背景
windows平台使用MSVC开发的程序,默认会依赖运行时库,因此将程序安装到纯净的电脑环境后,执行程序时会弹窗提示缺少库,如下图。
解决方案
为保证程序在新的电脑环境中正常运行,需要保证运行时库在程序内是自含有(self-contained)的。依据实现方式的不同可以分为假自含和真自含。
假自含
当纯净的电脑环境中没有相对应的运行时库时,将运行时库与程序一同提供即可,在纯净的电脑环境中,程序找到相对应的运行时库便可正常运行。
这种方法多应用于客户端软件,将软件依赖的运行时库打包到安装包内,安装可执行程序时将相对应的运行时库一同安装上,保证可执行程序能够找到相对应的运行时库,进而保证程序的正常运行。如下为某大型程序的所依赖的运行库。
真自含
运行时库的链接类型
打开MSVC项目的属性页,可以在代码生成中看到运行时库的四种不同依赖类型。项目右键->属性->配置属性->C/C++->代码生成->运行库
由上图可知,对于运行时库的依赖,MSVC提供了四种方式,分别是
而MD MDd作为MSVC的默认设置,这才使得程序或库需要依赖运行时库,为了保证程序或库是真正自含的,需要主动修改代码对于运行时库的依赖为MT或MTd。
如果是MSVC组织的工程,通过项目属性页修改代码生成中运行库的依赖为MT或MTd即可。
如果使用CMake组织工程,需要手动修改CMaleLists.txt,可参考如下的示例CMaleLists.txt文件
# !!!需要大于3.15版本,
cmake_minimum_required(VERSION 3.15)
# !!!需要设置辞属性
# !!!此属性的设置需要在project前
# !!!父类设置后所有subdirectory均生效
if (POLICY CMP0091)
cmake_policy(SET CMP0091 NEW)
endif (POLICY CMP0091)
project(test_add CXX)
include_directories(./dll_source)
add_subdirectory(dll_source)
add_executable(${PROJECT_NAME} main.cpp
)
target_link_libraries(${PROJECT_NAME}
add
)
# !!!设置MT/MTd
# !!!所有依赖的库需要设置相同的属性,需同为MT或同为MTd
set_property(TARGET ${PROJECT_NAME} PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
总结
为了解决程序对于运行时库的依赖,提出了2类方法,一种是将相对应的运行库一同打包;一种是修改程序对于运行库是静态依赖,进而提出了两种修改静态依赖的方法,在MSVC工程中修改或修改CMakeLists.