CmakeLearn

好的,我来更详细地解释这个CMakeLists.txt文件,我会尽量用通俗易懂的语言。

  1. 基础设置部分:
cmake_minimum_required(VERSION 3.18)
  • 这行代码告诉CMake需要的最低版本是3.18
  • 如果您的CMake版本低于3.18,将会报错
  • 这是一个安全措施,确保使用足够新的CMake版本,以支持所有需要的功能
  1. 自定义宏定义:
macro(source_group_by_dir source_files)
    if(MSVC)
        set(sgbd_cur_dir ${CMAKE_CURRENT_SOURCE_DIR})
        foreach(sgbd_file ${${source_files}})
            string(REGEX REPLACE ${sgbd_cur_dir}/\(.*\) \\1 sgbd_fpath ${sgbd_file})
            string(REGEX REPLACE "\(.*\)/.*" \\1 sgbd_group_name ${sgbd_fpath})
            string(COMPARE EQUAL ${sgbd_fpath} ${sgbd_group_name} sgbd_nogroup)
            string(REPLACE "/" "\\" sgbd_group_name ${sgbd_group_name})
            if(sgbd_nogroup)
                set(sgbd_group_name "\\")
            endif(sgbd_nogroup)
            source_group(${sgbd_group_name} FILES ${sgbd_file})
        endforeach(sgbd_file)
        add_compile_options($<$<CXX_COMPILER_ID:MSVC>:/MP>)
    endif(MSVC)
endmacro(source_group_by_dir)

这是一个自定义的宏(可以理解为函数),主要用于Visual Studio项目:

  • macro 定义了一个名为source_group_by_dir的宏
  • if(MSVC) 表示只在Visual Studio环境下执行
  • 这个宏的主要功能是:
    1. 获取当前源文件目录
    2. 遍历所有源文件
    3. 根据文件路径创建对应的文件夹结构
    4. 在Visual Studio中组织文件显示
  • /MP选项启用多处理器编译,可以加快编译速度
  1. 项目设置:
project(UserApp)
set(UserAppRoot ${PROJECT_SOURCE_DIR})
  • project(UserApp) 定义项目名称为"UserApp"
  • PROJECT_SOURCE_DIR 是CMake的内置变量,表示当前CMakeLists.txt所在的目录
  • set(UserAppRoot ${PROJECT_SOURCE_DIR}) 将项目根目录保存到变量中,方便后续使用
  1. 源文件收集:
file(GLOB_RECURSE source
    ${UserAppRoot}/source/private/*.cpp
    ${UserAppRoot}/source/private/*.h
)

set(all_files ${source} ${header})
source_group_by_dir(all_files)
  • file(GLOB_RECURSE ...) 递归搜索所有匹配的文件
  • 搜索路径是source/private目录下的所有.cpp和.h文件
  • GLOB_RECURSE会搜索子目录
  • 将找到的文件保存到source变量中
  • 调用之前定义的宏来组织文件结构
  1. 平台特定配置:
    文件使用条件语句处理不同平台:

a) iOS平台配置:

if(IOS)
    set(PLATFORM_PREFIX platform/iphone)
    add_library(UserApp STATIC
        ${source}
    )

    target_compile_definitions(UserApp
        PRIVATE
        GW_PLATFORM_APPLE
        GW_PLATFORM_IOS
        GW_LOG_ENABLE
        ENABLE_JNI
    )
  • add_library 创建一个静态库(.a文件)
  • target_compile_definitions 定义编译宏:
    • GW_PLATFORM_APPLE: 表示这是苹果平台
    • GW_PLATFORM_IOS: 表示这是iOS系统
    • GW_LOG_ENABLE: 启用日志功能
    • ENABLE_JNI: 启用Java本地接口

b) Android平台配置:

elseif(ANDROID)
    set(PLATFORM_PREFIX platform/android)
    add_library(UserApp SHARED
        ${source}
    )

    target_compile_definitions(UserApp
        PRIVATE
        GW_PLATFORM_ANDROID
        GW_LOG_ENABLE
        ENABLE_JNI
    )

    target_link_libraries(UserApp
        PRIVATE
        libGWApp.so
        libGWEngine.so
        libGWPlatform.so
    )

    target_compile_options(UserApp PRIVATE -Werror)
  • 创建动态库(.so文件)
  • 链接Android特定的库
  • -Werror 将所有警告视为错误

c) Windows平台配置:

else()
    set(PLATFORM_PREFIX platform/windows)
    add_library(UserApp SHARED
        ${source}
    )

    target_compile_definitions(UserApp
        PRIVATE
        GW_PLATFORM_WINDOWS
        GW_LOG_ENABLE
    )

    target_link_libraries(UserApp
        PRIVATE
        GWCore
        GWEngine
        GWMath
        GWPlatform
        GWRenderEngine
        GWGameUI
    )

    target_compile_options(UserApp PRIVATE /MP /bigobj /utf-8)
  • 创建动态库(.dll文件)
  • 链接Windows特定的库
  • 编译选项说明:
    • /MP: 多处理器编译
    • /bigobj: 支持大对象文件
    • /utf-8: 使用UTF-8编码
  1. 通用设置:
set_target_properties(UserApp PROPERTIES CXX_STANDARD 17)
  • 设置C++标准为C++17
  • 这确保代码可以使用C++17的特性
  1. Windows特定配置:
if(WIN32)
    target_link_directories(UserApp PRIVATE ${UserAppRoot}/${PLATFORM_PREFIX}/lib)
    target_include_directories(UserApp
        PRIVATE
        ${UserAppRoot}/source/public
        ${UserAppRoot}/source/private
        ${UserAppRoot}/${PLATFORM_PREFIX}/include
        ${UserAppRoot}/${PLATFORM_PREFIX}/3rd
    )
  • target_link_directories: 指定库文件搜索路径
  • target_include_directories: 指定头文件搜索路径
  • 包含了public、private、include和3rd目录
  1. 调试配置:
    set(GW_SDK_PATH "C:/newWork/2bd9ae70")
    set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT UserApp)
    set_target_properties(UserApp PROPERTIES VS_DEBUGGER_COMMAND  "${GW_SDK_PATH}/CPRenderInstance.exe")
  • 设置SDK路径
  • 配置Visual Studio的启动项目
  • 设置调试器命令和工作目录

这个CMakeLists.txt文件展示了一个完整的跨平台项目配置,包含了:

  1. 平台检测和条件编译
  2. 源文件管理
  3. 库的创建和链接
  4. 编译选项设置
  5. 调试环境配置
  6. 目录结构管理

对于初学者来说,建议:

  1. 先理解基本的CMake命令(如add_library, target_link_libraries等)
  2. 了解变量和条件语句的使用
  3. 学习如何设置编译选项和链接库
  4. 理解平台特定的配置方式

这样可以帮助您逐步掌握CMake的使用。

如果要我去写这个cmakelists.txt,是不是全部都要我去写?还是说大部分可以自动导入?你理解我的意思吗?就是我需要掌握到什么程度

我完全理解您的问题。让我从实用角度来解释CMakeLists.txt的编写:

  1. 基本掌握程度:
  • 您需要掌握的基础命令:
    cmake_minimum_required(VERSION 3.18)  # 设置CMake最低版本
    project(项目名称)                     # 设置项目名称
    
    # 添加可执行文件或库
    add_executable(可执行文件名 源文件列表)  # 创建可执行文件
    # 或
    add_library(库名 源文件列表)           # 创建库文件
    
    # 链接库
    target_link_libraries(目标名 库名列表)
    
    # 包含目录
    target_include_directories(目标名 PRIVATE 目录路径)
    
  1. 自动生成工具:
  • 现代IDE(如Visual Studio、CLion)可以自动生成基础的CMakeLists.txt
  • 可以使用CMake GUI工具来可视化配置
  • 有一些CMake模板生成器可以使用
  1. 实际工作中:
  • 大多数情况下,您不需要从头写整个CMakeLists.txt
  • 通常会基于现有项目模板修改
  • 主要需要修改的部分是:
    # 1. 项目名称
    project(YourProjectName)
    
    # 2. 源文件列表
    add_executable(YourProject 
        main.cpp
        other_file.cpp
    )
    
    # 3. 依赖库
    target_link_libraries(YourProject
        SomeLibrary
        AnotherLibrary
    )
    
  1. 建议学习路径:
  • 第一阶段(基础):

    • 理解基本的项目结构
    • 掌握添加源文件
    • 学会链接基本库
    • 会设置包含目录
  • 第二阶段(进阶):

    • 条件编译(if/else)
    • 变量使用
    • 平台特定配置
    • 自定义函数/宏
  • 第三阶段(高级):

    • 复杂项目结构
    • 跨平台配置
    • 自定义构建规则
    • 性能优化
  1. 实用建议:
  • 开始时可以复制现有项目的CMakeLists.txt进行修改
  • 使用IDE的自动生成功能
  • 遇到问题时查看官方文档或Stack Overflow
  • 逐步学习和理解更复杂的配置
  1. 常见场景示例:
# 简单项目示例
cmake_minimum_required(VERSION 3.18)
project(MyProject)

# 添加源文件
add_executable(MyProject 
    src/main.cpp
    src/helper.cpp
)

# 添加头文件目录
target_include_directories(MyProject PRIVATE
    include
)

# 链接库
target_link_libraries(MyProject PRIVATE
    SomeLibrary
)

总结:

  1. 不需要掌握所有CMake特性
  2. 重点是理解基本概念和常用命令
  3. 可以依赖IDE和模板
  4. 随着项目需求逐步学习更多特性
  5. 实际工作中主要是修改而不是从头编写

建议:

  1. 先掌握基础命令
  2. 学会使用IDE的自动生成功能
  3. 理解项目结构
  4. 需要时再学习更高级的特性
  5. 多参考现有项目的配置

这样可以让您更有效地学习和使用CMake,而不是被其复杂性所困扰。

posted @ 2025-04-19 20:56  無碍  阅读(10)  评论(0)    收藏  举报