使用 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,问题也会消失。
我尝试静态链接 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,问题也会消失。