为什么CMake为Visual Studio项目添加了不必要的库?

时间:2016-12-30 17:57:17

标签: visual-studio cmake

我有这个简单的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会添加所有这些库,我该怎么办才能在我的项目中添加它们?

2 个答案:

答案 0 :(得分:3)

正如@Vertexwahn评论的那些是CMakeCXXInformation.cmakeCMAKE_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

看到了吗?与手动链接相同的库。