我有这个简单的CMake文件
cmake_minimum_required(VERSION 2.8)
project(test)
set(SOURCES source.cpp)
add_executable(test ${SOURCES})
其中source.cpp是一个简单的hello world程序。然后我生成Visual Studio项目
cmake -G"Visual Studio 14 2015" ..\Sources
生成的Visual Studio项目在Configuration Properties > Linker > Input > Additional Dependencies
:
kernel32.lib
user32.lib
gdi32.lib
winspool.lib
shell32.lib
ole32.lib
oleaut32.lib
uuid.lib
comdlg32.lib
advapi32.lib
如果我删除这些库,我仍然可以成功构建并运行hello world。
为什么CMake会添加所有这些库,我该怎么办才能在我的项目中添加它们?
答案 0 :(得分:3)
正如@Vertexwahn评论的那些是CMakeCXXInformation.cmake
中CMAKE_CXX_STANDARD_LIBRARIES_INIT
从CMake定义的默认值。
我只是想添加一个简单的AdditionalDependencies
宏替代here:
cmake_minimum_required(VERSION 3.0)
file(
WRITE "${CMAKE_BINARY_DIR}/MakeRulesOverwrite.cmake"
[=[
if (MSVC)
set(CMAKE_CXX_STANDARD_LIBRARIES_INIT "%(AdditionalDependencies)")
endif()
]=]
)
set(CMAKE_USER_MAKE_RULES_OVERRIDE "${CMAKE_BINARY_DIR}/MakeRulesOverwrite.cmake")
project(test)
...
<强>参考强>
答案 1 :(得分:1)
MSVC 链接器不会链接不需要的库,即使在命令行中指定。您可以在 Dependency Walker 或 dumpbin 中检查它。例如,cmake 将“gdi32.lib”传递给链接器,但如果不需要它,它就不会出现在生成的可执行文件中。无论是手动链接,还是让 cmake 链接,生成的库都完全相同,我比较了它们。手动链接:
命令行:
... -DCMAKE_EXE_LINKER_FLAGS_RELEASE:STRING="/INCREMENTAL:NO /OPT:REF,ICF /LTCG" -DCMAKE_C_STANDARD_LIBRARIES:STRING=""
cmakelists.txt :
set_target_properties(XXX PROPERTIES LINKER_LANGUAGE C)
target_link_libraries(XXX PUBLIC
oleacc
user32
shell32
ole32
)
所以我必须自己将所有库传递给链接器。如果我让cmake来做,我只需要把“oleacc.lib”传给它,其他库由cmake处理:
link.exe ... oleacc.lib user32.lib shell32.lib ole32.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib
dumpbin /imports "c:\windows\system32\ietab.exe"
Section contains the following imports:
oleacc.dll
user32.dll
shell32.dll
ole32.dll
kernel32.dll
msvcp140.dll
vcruntime140.dll
看到了吗?与手动链接相同的库。