project() 是 CMake 中最基础且必须的命令之一,用于定义整个项目的基本信息,包括名称、版本、描述、编程语言等。它通常紧跟在 cmake_minimum_required() 之后调用。
主要作用:
- 定义项目名称: 设置项目的标识符。
- 设置版本信息: 方便版本管理和条件编译。
- 指定编程语言: 告知 CMake 项目使用哪些语言(如 C, CXX, Fortran, ASM, CUDA 等),CMake 会据此查找并配置相应的编译器。
- 设置项目描述: 提供项目的简要说明(可选)。
- 隐式定义关键变量: 调用
project()后,CMake 会自动定义一系列与项目相关的有用变量(如PROJECT_NAME,PROJECT_VERSION,CMAKE_PROJECT_NAME, 以及针对每种语言的变量如CMAKE_CXX_STANDARD的默认值等)。 - 启用语言支持: 激活指定语言的编译器等工具链检测和标准设置。
- 顶级作用域: 通常在顶级
CMakeLists.txt文件中调用。
基本语法:
project(<PROJECT-NAME>
[VERSION <min>[.<patch>[.<tweak>[.<suffix>]]]]
[DESCRIPTION <project-description-string>]
[HOMEPAGE_URL <url-string>]
[LANGUAGES <language-name>...])
<PROJECT-NAME>(必需): 项目的名称。这是唯一必需的参数。例如:MyAwesomeApp。VERSION(可选): 项目的版本号。格式通常为主版本.次版本.修订版本[.构建号](例如1.0.0,2.3.1)。设置后会定义相关版本变量。DESCRIPTION(可选): 项目的简短描述文本。例如:"A cross-platform application for doing awesome things"。HOMEPAGE_URL(可选): 项目主页的 URL。例如:"https://github.com/me/myawesomeapp"。LANGUAGES(可选): 项目使用的编程语言列表。如果不指定,默认为C和CXX(C++)。常用的语言标识符包括:C: C 语言CXX: C++ 语言CUDA: NVIDIA CUDAFortran: Fortran 语言ASM: 汇编语言 (注意不同平台汇编器差异大)None: 明确指定不使用任何语言(很少用)。
调用 project() 后自动定义的关键变量:
PROJECT_NAME: 当前项目的名称(即<PROJECT-NAME>的值)。PROJECT_VERSION,<PROJECT-NAME>_VERSION: 项目的完整版本号(如果设置了VERSION)。PROJECT_VERSION_MAJOR,<PROJECT-NAME>_VERSION_MAJOR: 主版本号。PROJECT_VERSION_MINOR,<PROJECT-NAME>_VERSION_MINOR: 次版本号。PROJECT_VERSION_PATCH,<PROJECT-NAME>_VERSION_PATCH: 修订版本号。PROJECT_VERSION_TWEAK,<PROJECT-NAME>_VERSION_TWEAK: 构建号(如果提供了)。PROJECT_DESCRIPTION,<PROJECT-NAME>_DESCRIPTION: 项目描述(如果设置了DESCRIPTION)。PROJECT_HOMEPAGE_URL,<PROJECT-NAME>_HOMEPAGE_URL: 项目主页 URL(如果设置了HOMEPAGE_URL)。CMAKE_PROJECT_NAME: 顶级项目的名称(在包含子项目的项目中很有用)。<PROJECT-NAME>_SOURCE_DIR,<PROJECT-NAME>_BINARY_DIR: 分别指向项目源码目录和构建目录的绝对路径。通常等同于顶级CMAKE_SOURCE_DIR和CMAKE_BINARY_DIR。- 语言相关变量: 如
CMAKE_CXX_STANDARD的默认值会被设置(通常是编译器默认值),以及编译器标识符 (CMAKE_C_COMPILER,CMAKE_CXX_COMPILER等) 被检测到。
使用示例:
示例 1:最简形式(仅指定项目名,使用默认语言 C 和 C++)
cmake_minimum_required(VERSION 3.10) # 指定所需最低 CMake 版本
project(HelloWorld) # 定义项目名称为 HelloWorld
add_executable(HelloWorld main.cpp) # 添加一个可执行目标
示例 2:指定版本、描述、主页和语言(显式指定 C++)
cmake_minimum_required(VERSION 3.10)
project(
MyApp
VERSION 1.2.3
DESCRIPTION "A simple demonstration application"
HOMEPAGE_URL "https://myapp.example.com"
LANGUAGES CXX # 只使用 C++ 语言
)
# 使用自动定义的版本变量
message(STATUS "Building ${PROJECT_NAME} v${PROJECT_VERSION}")
message(STATUS "Description: ${PROJECT_DESCRIPTION}")
add_executable(MyApp main.cpp)
示例 3:指定多种语言(C 和 C++)并设置 C++ 标准(在 project 之后)
cmake_minimum_required(VERSION 3.10)
project(
MixedLangProject
VERSION 0.5.0
LANGUAGES C CXX # 同时使用 C 和 C++
)
# 设置 C++ 标准 (C 标准使用 c_std_11 等类似方式)
set(CMAKE_CXX_STANDARD 17) # 要求 C++17
set(CMAKE_CXX_STANDARD_REQUIRED ON) # 强制要求,如果编译器不支持则报错
add_executable(MainProg main.cpp helper.c)
示例 4:使用版本组件变量
cmake_minimum_required(VERSION 3.10)
project(VersionedApp VERSION 4.1.2.20240531)
# 配置一个头文件,将版本信息传递给源代码
configure_file(
version.h.in
version.h
)
# 在 version.h.in 文件中,你可以这样写:
# #define APP_VERSION_MAJOR @PROJECT_VERSION_MAJOR@
# #define APP_VERSION_MINOR @PROJECT_VERSION_MINOR@
# #define APP_VERSION_PATCH @PROJECT_VERSION_PATCH@
# #define APP_VERSION_BUILD @PROJECT_VERSION_TWEAK@
# #define APP_VERSION_STRING "@PROJECT_VERSION@"
add_executable(VersionedApp main.cpp)
target_include_directories(VersionedApp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) # 包含生成的 version.h 的目录
重要注意事项:
cmake_minimum_required优先:project()命令前必须先调用cmake_minimum_required(VERSION ...)来指定 CMake 的最低兼容版本。- 语言检测: 通过
LANGUAGES指定的语言,CMake 会尝试在系统路径中查找对应的编译器。如果找不到,配置过程会失败。 - 变量定义时机:
project()命令定义的所有变量(如PROJECT_VERSION,CMAKE_CXX_COMPILER)只有在该命令执行之后才可用。 - 版本号格式:
VERSION参数接受由点分隔的数字列表(最多 4 个部分)。CMake 会将其拆分为MAJOR,MINOR,PATCH,TWEAK组件存储在相应的变量中。 - 描述和主页URL:
DESCRIPTION和HOMEPAGE_URL主要是提供元信息,CMake 本身在构建过程中不会特别处理它们(除了定义对应的变量),但其他工具(如 CPack 打包)或你的代码/文档生成器可以利用它们。 - 作用域:
project()在它被调用的CMakeLists.txt文件及其包含的所有子目录(直到下一个project()调用)中定义其变量。子目录中的project()会创建新的作用域。
总结:
project() 是 CMake 项目的起点和基石。它不仅仅是为项目命名,更重要的是它触发了编译器的检测、语言环境的设置,并定义了大量关键的项目信息变量,为后续定义目标(add_executable, add_library)、设置编译选项、链接库等操作奠定了基础。正确使用 project() 及其可选参数(尤其是 VERSION 和 LANGUAGES)是编写清晰、可维护 CMake 脚本的关键第一步。
2978

被折叠的 条评论
为什么被折叠?



