> 文章列表 > MSVC Debug 与 Release 库

MSVC Debug 与 Release 库

MSVC Debug 与 Release 库

CMake Debug后缀

set_target_properties(liba PROPERTIES DEBUG_POSTFIX "d")
或者
set(CMAKE_DEBUG_POSTFIX "d")
这样生成的库或者exe程序名会多一个d字符。如下

链接 vc++ 运行时库

通过/MD、/MT 可以改变MSVC运行库,

  • /MD代表使用动态运行时库,程序运行时需要有MSVCRversionnumber.DLL,这些库是通过安装Download Microsoft Visual C++ Redistributables 获得。例如msvcp140.dll就是在 Microsoft Visual C++ Redistributable for Visual Studio 2015中。
  • /MT会使用静态运行时库,MSVC库会编译链接到exe程序中,所以系统不安装VC++库也可以正常运行,但是这会增加exe的大小,且由于不能共享使用公用的DLL也会消耗更多内存。
  • /MD、/MT都有对应的debug版,/MDd、/MTd,链接时使用的库也是对应的Debug版,例如msvcp140d.dll则是VC++ 2015的Debug版库。这种库需要安装Visual studio 20xx时才能获得,非开发设备一般都没有这种库。

MSVC 链接动态库

 对于动态库都有对应的DLL,DLL本身就是可以执行文件,系统可以直接读取并执行,其内部已经包含了所有运行时的函数或符号。所以动态库生成后其已经可以与编译环境分离,也就是说如果你编译了一个动态库,不管程序时Debug还是Release都可以链接这个库,这个库也不会受编译器版本的限制,大部分情况下不同VS版本都可以通用。

MSVC 链接静态库

静态库只是一个中间编译状态,并不能直接运行,还需要与调用者编译链接才能运行。应为是中间状态所以在VS2015之前,不同版本VS编译的静态库都不能通用,必须要相同版本才能编译链接。VS2015以后微软队各个版本的静态库abi做了兼容,所以VS2015后大部分静态库可以通用。

如果Debug版C++程序链接Release版静态库时,链接会报错,以下是VS2022的报错:

liba.lib(a.cpp.obj) : error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“0”不匹配值“2”(main.cpp.obj 中)
liba.lib(a.cpp.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MD_DynamicRelease”不匹配值“MDd_DynamicDebug”(main.cpp.obj 中)
LINK : warning LNK4098: 默认库“MSVCRT”与其他库的使用冲突;请使用 /NODEFAULTLIB:library
E:\\Study\\StudyProject\\cmake\\lib_debug_release\\main.exe : fatal error LNK1319: 检测到 2 个不匹配项

这是因为Debug版和Release版默认使用的vc++ 运行时库不相同,默认情况下Debug版使用/MDd,Release版使用/MD,两者不相同导致报错。

所以在链接库时需要区分Debug版和Release版。在CMake可以如下设置:

target_link_libraries(target $<$<CONFIG:Release>:liba.lib> $<$<CONFIG:Debug>:libad.lib>)

C语言静态库

上面说的都是关于C++的,实际上如果一个库是使用C开发的,那么这个库不会受VC++运行库的影响,也就是说你可以在Debug程序中链接一个C开发的Release的静态库。

很多开源库都是使用C开发的,所以在编译这些库的静态库时,只需要编译一个Release版。