CmakeLearn
好的,我来更详细地解释这个CMakeLists.txt文件,我会尽量用通俗易懂的语言。
- 基础设置部分:
cmake_minimum_required(VERSION 3.18)
- 这行代码告诉CMake需要的最低版本是3.18
- 如果您的CMake版本低于3.18,将会报错
- 这是一个安全措施,确保使用足够新的CMake版本,以支持所有需要的功能
- 自定义宏定义:
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环境下执行- 这个宏的主要功能是:
- 获取当前源文件目录
- 遍历所有源文件
- 根据文件路径创建对应的文件夹结构
- 在Visual Studio中组织文件显示
/MP
选项启用多处理器编译,可以加快编译速度
- 项目设置:
project(UserApp)
set(UserAppRoot ${PROJECT_SOURCE_DIR})
project(UserApp)
定义项目名称为"UserApp"PROJECT_SOURCE_DIR
是CMake的内置变量,表示当前CMakeLists.txt所在的目录set(UserAppRoot ${PROJECT_SOURCE_DIR})
将项目根目录保存到变量中,方便后续使用
- 源文件收集:
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
变量中 - 调用之前定义的宏来组织文件结构
- 平台特定配置:
文件使用条件语句处理不同平台:
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编码
- 通用设置:
set_target_properties(UserApp PROPERTIES CXX_STANDARD 17)
- 设置C++标准为C++17
- 这确保代码可以使用C++17的特性
- 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目录
- 调试配置:
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文件展示了一个完整的跨平台项目配置,包含了:
- 平台检测和条件编译
- 源文件管理
- 库的创建和链接
- 编译选项设置
- 调试环境配置
- 目录结构管理
对于初学者来说,建议:
- 先理解基本的CMake命令(如add_library, target_link_libraries等)
- 了解变量和条件语句的使用
- 学习如何设置编译选项和链接库
- 理解平台特定的配置方式
这样可以帮助您逐步掌握CMake的使用。
如果要我去写这个cmakelists.txt,是不是全部都要我去写?还是说大部分可以自动导入?你理解我的意思吗?就是我需要掌握到什么程度
我完全理解您的问题。让我从实用角度来解释CMakeLists.txt的编写:
- 基本掌握程度:
- 您需要掌握的基础命令:
cmake_minimum_required(VERSION 3.18) # 设置CMake最低版本 project(项目名称) # 设置项目名称 # 添加可执行文件或库 add_executable(可执行文件名 源文件列表) # 创建可执行文件 # 或 add_library(库名 源文件列表) # 创建库文件 # 链接库 target_link_libraries(目标名 库名列表) # 包含目录 target_include_directories(目标名 PRIVATE 目录路径)
- 自动生成工具:
- 现代IDE(如Visual Studio、CLion)可以自动生成基础的CMakeLists.txt
- 可以使用CMake GUI工具来可视化配置
- 有一些CMake模板生成器可以使用
- 实际工作中:
- 大多数情况下,您不需要从头写整个CMakeLists.txt
- 通常会基于现有项目模板修改
- 主要需要修改的部分是:
# 1. 项目名称 project(YourProjectName) # 2. 源文件列表 add_executable(YourProject main.cpp other_file.cpp ) # 3. 依赖库 target_link_libraries(YourProject SomeLibrary AnotherLibrary )
- 建议学习路径:
-
第一阶段(基础):
- 理解基本的项目结构
- 掌握添加源文件
- 学会链接基本库
- 会设置包含目录
-
第二阶段(进阶):
- 条件编译(if/else)
- 变量使用
- 平台特定配置
- 自定义函数/宏
-
第三阶段(高级):
- 复杂项目结构
- 跨平台配置
- 自定义构建规则
- 性能优化
- 实用建议:
- 开始时可以复制现有项目的CMakeLists.txt进行修改
- 使用IDE的自动生成功能
- 遇到问题时查看官方文档或Stack Overflow
- 逐步学习和理解更复杂的配置
- 常见场景示例:
# 简单项目示例
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
)
总结:
- 不需要掌握所有CMake特性
- 重点是理解基本概念和常用命令
- 可以依赖IDE和模板
- 随着项目需求逐步学习更多特性
- 实际工作中主要是修改而不是从头编写
建议:
- 先掌握基础命令
- 学会使用IDE的自动生成功能
- 理解项目结构
- 需要时再学习更高级的特性
- 多参考现有项目的配置
这样可以让您更有效地学习和使用CMake,而不是被其复杂性所困扰。