使用 cmake 进行静态链接

Static linking using cmake

我尝试静态链接 libstdc++-6 和 libgcc_s_seh-1.I'' 使用使用 cmake 的 Clion。我正在使用 SFML,但它没有必要动态链接。

谢谢

cmake_minimum_required(VERSION 2.8.4)
project(Game_Project)
set(EXECUTABLE_NAME "Game_Project")

# Enable debug symbols by default
if(CMAKE_BUILD_TYPE STREQUAL "")
    set(CMAKE_BUILD_TYPE Debug)
else()
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mwindows")
endif()
# (you can also set it on the command line: -D CMAKE_BUILD_TYPE=Release)


set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -s")

set(BUILD_SHARED_LIBS OFF)
set(CMAKE_EXE_LINKER_FLAGS "-static -static-libgcc -static-libstdc++")

set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/SFML-2.2/cmake/Modules/" ${CMAKE_MODULE_PATH})

set(CMAKE_SOURCE_DIR src)
file(GLOB_RECURSE SRCS src/*.cpp)

#Find any version 2.X of SFML
#See the FindSFML.cmake file for additional details and instructions
set(SFML_ROOT "SFML-2.2")
find_package(SFML 2 REQUIRED system window graphics network audio)

include_directories(${CMAKE_SOURCE_DIR} include)

add_executable(${EXECUTABLE_NAME} ${SRCS})

if(SFML_FOUND)
    include_directories(${SFML_INCLUDE_DIR})
    target_link_libraries(${EXECUTABLE_NAME} ${SFML_LIBRARIES})
    target_link_libraries(${EXECUTABLE_NAME} ${SFML_DEPENDENCIES})
endif()

install(TARGETS ${EXECUTABLE_NAME} DESTINATION bin)

如果您 link 动态地针对 SFML,而后者又 link 动态地针对 libstdc++,您的应用程序仍然需要 so/dll libstdc++ 文件,因为 SFML。

将 SFML.dll 视为一个单独的可执行文件。该可执行文件具有对 libstdc++ 的动态运行时依赖性。你无法摆脱它,因为 SFML 已经被 linked 并且没有办法让它指向静态 linked 到你的可执行文件的 libstdc++ 部分。

消除依赖性的唯一方法是确保所有组件 link 在其 linking 阶段静态地针对库。

这里要注意的重要一点是静态库与此无关。静态库永远不会通过 linker(将它们视为一堆打包在一起的目标文件),因此将它们拉入的顶级可执行文件或动态库决定了它们如何 link标准库。

因此,如果您将 SFML 构建为静态库,而不是由您的可执行文件引入,该可执行文件被配置为针对 libstdc++ 静态 link,问题也会消失。