如何让MSYS2环境下的CMake使用静态库
解决MinGW64+CMake静态链接生成独立可执行文件的问题
问题1:静态链接libstdc++等系统库
要让CMake强制使用libstdc++、libgcc的静态版本,直接在CMakeLists开头添加链接器参数:
# 静态链接C++标准库和GCC运行时库 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libstdc++ -static-libgcc") # 如果需要完全静态链接所有系统库(包括Win32 API相关),可以加-static,但会增大文件体积 # set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
注意:-static会强制静态链接所有库,而-static-libstdc++仅针对C++标准库,按需选择。
问题2:使用MSYS2 Pacman安装的静态库版本
步骤1:安装对应库的静态版本包
MSYS2中大部分库的静态包后缀为-static,比如curl和openssl的静态包:
打开MSYS2的mingw64终端,执行:
pacman -S mingw-w64-x86_64-curl-static mingw-w64-x86_64-openssl-static
安装后静态库文件会放在C:/msys64/mingw64/lib目录下,比如libcurl.a、libssl.a等。
步骤2:让CMake优先查找静态库
在CMakeLists开头添加以下设置,强制CMake优先搜索静态库:
# 设置优先查找静态库 set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) # 告诉find_package优先选择静态链接 set(BUILD_SHARED_LIBS OFF) set(CMAKE_LINK_STATIC ON)
修复curl静态链接错误
你直接链接libcurl.a出错,是因为curl静态库依赖了openssl、zlib、winmm、ws2_32等其他库,必须一并链接这些依赖。用find_package配合静态库设置可自动处理依赖,修改后的完整CMakeLists.txt如下:
cmake_minimum_required(VERSION 3.26.4) project(Project LANGUAGES C CXX) # 静态链接C++标准库和GCC运行时 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libstdc++ -static-libgcc") # 优先查找静态库 set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) set(BUILD_SHARED_LIBS OFF) set(CMAKE_LINK_STATIC ON) set(CMAKE_CXX_STANDARD 17) add_executable(Project main.cpp) target_include_directories(Project PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) # 查找静态版本的CURL find_package(CURL REQUIRED) target_link_libraries(Project ${CURL_LIBRARIES}) # 查找静态版本的OpenSSL find_package(OpenSSL REQUIRED) target_link_libraries(Project ${OpenSSL_LIBRARIES})
额外注意事项
- 必须使用MSYS2的mingw64终端运行CMake和编译,不要用MSYS终端,否则会出现链接错误。
- 优先选择Release模式编译,Debug模式下部分库的静态版本可能存在兼容性问题,且Release生成的文件体积更小。
- 如果仍有链接错误,可在mingw64终端执行
pkg-config --static --libs libcurl,获取curl的完整链接参数,将这些参数添加到target_link_libraries中。
内容的提问来源于stack exchange,提问作者ConnoK0lan
相关产品推荐
相关产品推荐

