如何配置CMakeLists.txt跨平台编译SFML/TGUI项目并解决auto_ptr报错
问题解决与CMake配置优化
一、编译错误解决(std::auto_ptr相关)
错误根源是SFML 2.5.1不支持C++20——C++20已彻底移除std::auto_ptr,而SFML 2.5.1代码中仍在使用该类型。有两种可行解决方案:
方案1:升级SFML与TGUI到兼容C++20的版本
SFML 2.6+已将std::auto_ptr替换为std::unique_ptr,TGUI 0.10+对应适配SFML 2.6。修改CMakeLists中的FetchContent部分:
# 安装SFML(升级到2.6.1) FetchContent_Declare( SFML GIT_REPOSITORY https://github.com/SFML/SFML.git GIT_TAG 2.6.1 ) FetchContent_MakeAvailable(SFML) # 安装TGUI(升级到0.10.1,适配SFML2.6) FetchContent_Declare( TGUI GIT_REPOSITORY https://github.com/texus/TGUI.git GIT_TAG v0.10.1 ) FetchContent_MakeAvailable(TGUI)
此方案保留C++20标准,同时彻底解决兼容性问题。
方案2:降级C标准到C17
如果不想升级库,将CMake中的C标准改为17(C17仅弃用std::auto_ptr但未移除,仍可正常编译):
set(CMAKE_CXX_STANDARD 17)
二、CMakeLists.txt优化建议
以下是针对现有配置的现代CMake规范优化:
- 替换全局include为目标专属包含
移除include_directories,改用target_include_directories针对具体目标设置,避免全局路径污染:
target_include_directories(r-type_client PRIVATE ${PROJECT_SOURCE_DIR}/includes ${PROJECT_SOURCE_DIR}/includes/external )
- 简化链接配置
移除冗余的${SFML_LIBRARIES}链接,直接使用SFML的目标名更清晰可靠:
target_link_libraries(r-type_client PRIVATE sfml-audio sfml-graphics tgui )
- 用FetchContent管理enet库
替换手动下载enet的代码,改用FetchContent更易维护版本、避免路径问题:
FetchContent_Declare( enet GIT_REPOSITORY https://github.com/zpl-c/enet.git GIT_TAG latest # 或指定具体版本号 ) FetchContent_MakeAvailable(enet) # 链接enet目标 target_link_libraries(r-type_client PRIVATE enet)
- 添加FetchContent静默选项
在FetchContent前添加,减少构建时的冗余输出:
set(FETCHCONTENT_QUIET ON)
- 设置构建类型的默认值
允许用户通过命令行覆盖构建类型,同时保留Debug作为默认:
if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Debug CACHE STRING "Build type" FORCE) endif()
三、跨平台通用二进制配置
macOS M1 通用二进制(arm64 + x86_64)
添加以下配置,让CMake同时构建支持两种架构的二进制:
if(APPLE) set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "Build architectures for macOS" FORCE) set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum macOS version" FORCE) endif()
Linux 与 Windows 兼容性
- Linux:确保安装GCC 9+/Clang 10+以上版本以支持C++17/20,CMake会自动适配系统原生架构(x86_64/arm64)。
- Windows:使用MSVC 2019+或MinGW-w64,CMake通过选择不同生成器(Visual Studio、MinGW Makefiles)自动适配架构;如需交叉编译,可手动设置
CMAKE_SYSTEM_PROCESSOR。
最终优化后的完整CMakeLists.txt示例:
cmake_minimum_required(VERSION 3.19) project(r-type VERSION 1.0) # 构建类型配置 if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Debug CACHE STRING "Build type" FORCE) endif() # C++标准配置(选择17或20,对应上述方案) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(BUILD_SHARED_LIBS OFF) # FetchContent配置 set(FETCHCONTENT_QUIET ON) include(FetchContent) # 安装SFML(2.6.1支持C++20) FetchContent_Declare( SFML GIT_REPOSITORY https://github.com/SFML/SFML.git GIT_TAG 2.6.1 ) FetchContent_MakeAvailable(SFML) # 安装TGUI(0.10.1适配SFML2.6) FetchContent_Declare( TGUI GIT_REPOSITORY https://github.com/texus/TGUI.git GIT_TAG v0.10.1 ) FetchContent_MakeAvailable(TGUI) # 安装enet FetchContent_Declare( enet GIT_REPOSITORY https://github.com/zpl-c/enet.git GIT_TAG latest ) FetchContent_MakeAvailable(enet) # 定义可执行文件 add_executable(r-type_client src/client/Main.cpp src/client/OtherFiles.cpp ) # 目标包含目录 target_include_directories(r-type_client PRIVATE ${PROJECT_SOURCE_DIR}/includes ${PROJECT_SOURCE_DIR}/includes/external ) # 目标链接库 target_link_libraries(r-type_client PRIVATE sfml-audio sfml-graphics tgui enet ) # 跨平台配置 if(APPLE) set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "Build architectures for macOS" FORCE) set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum macOS version" FORCE) endif()
内容的提问来源于stack exchange,提问作者Lucy Janssens
相关产品推荐
相关产品推荐

