【CMake】project() 命令详解-定义整个项目的基础信息

project() 是 CMake 中最基础且必须的命令之一,用于定义整个项目的基本信息,包括名称、版本、描述、编程语言等。它通常紧跟在 cmake_minimum_required() 之后调用。

主要作用:

  1. 定义项目名称: 设置项目的标识符。
  2. 设置版本信息: 方便版本管理和条件编译。
  3. 指定编程语言: 告知 CMake 项目使用哪些语言(如 C, CXX, Fortran, ASM, CUDA 等),CMake 会据此查找并配置相应的编译器。
  4. 设置项目描述: 提供项目的简要说明(可选)。
  5. 隐式定义关键变量: 调用 project() 后,CMake 会自动定义一系列与项目相关的有用变量(如 PROJECT_NAME, PROJECT_VERSION, CMAKE_PROJECT_NAME, 以及针对每种语言的变量如 CMAKE_CXX_STANDARD 的默认值等)。
  6. 启用语言支持: 激活指定语言的编译器等工具链检测和标准设置。
  7. 顶级作用域: 通常在顶级 CMakeLists.txt 文件中调用。

基本语法:

project(
        [VERSION [.[.[.]]]]
        [DESCRIPTION ]
        [HOMEPAGE_URL ]
        [LANGUAGES ...])
  • (必需): 项目的名称。这是唯一必需的参数。例如: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 (可选): 项目使用的编程语言列表。如果不指定,默认为 CCXX (C++)。常用的语言标识符包括:
    • C: C 语言
    • CXX: C++ 语言
    • CUDA: NVIDIA CUDA
    • Fortran: Fortran 语言
    • ASM: 汇编语言 (注意不同平台汇编器差异大)
    • None: 明确指定不使用任何语言(很少用)。

调用 project() 后自动定义的关键变量:

  • PROJECT_NAME: 当前项目的名称(即 的值)。
  • PROJECT_VERSION, _VERSION: 项目的完整版本号(如果设置了 VERSION)。
  • PROJECT_VERSION_MAJOR, _VERSION_MAJOR: 主版本号。
  • PROJECT_VERSION_MINOR, _VERSION_MINOR: 次版本号。
  • PROJECT_VERSION_PATCH, _VERSION_PATCH: 修订版本号。
  • PROJECT_VERSION_TWEAK, _VERSION_TWEAK: 构建号(如果提供了)。
  • PROJECT_DESCRIPTION, _DESCRIPTION: 项目描述(如果设置了 DESCRIPTION)。
  • PROJECT_HOMEPAGE_URL, _HOMEPAGE_URL: 项目主页 URL(如果设置了 HOMEPAGE_URL)。
  • CMAKE_PROJECT_NAME: 顶级项目的名称(在包含子项目的项目中很有用)。
  • _SOURCE_DIR, _BINARY_DIR: 分别指向项目源码目录和构建目录的绝对路径。通常等同于顶级 CMAKE_SOURCE_DIRCMAKE_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 的目录

重要注意事项:

  1. cmake_minimum_required 优先: project() 命令前必须先调用 cmake_minimum_required(VERSION ...) 来指定 CMake 的最低兼容版本。
  2. 语言检测: 通过 LANGUAGES 指定的语言,CMake 会尝试在系统路径中查找对应的编译器。如果找不到,配置过程会失败。
  3. 变量定义时机: project() 命令定义的所有变量(如 PROJECT_VERSION, CMAKE_CXX_COMPILER只有在该命令执行之后才可用
  4. 版本号格式: VERSION 参数接受由点分隔的数字列表(最多 4 个部分)。CMake 会将其拆分为 MAJOR, MINOR, PATCH, TWEAK 组件存储在相应的变量中。
  5. 描述和主页URL: DESCRIPTIONHOMEPAGE_URL 主要是提供元信息,CMake 本身在构建过程中不会特别处理它们(除了定义对应的变量),但其他工具(如 CPack 打包)或你的代码/文档生成器可以利用它们。
  6. 作用域: project() 在它被调用的 CMakeLists.txt 文件及其包含的所有子目录(直到下一个 project() 调用)中定义其变量。子目录中的 project() 会创建新的作用域。

总结:

project() 是 CMake 项目的起点和基石。它不仅仅是为项目命名,更重要的是它触发了编译器的检测、语言环境的设置,并定义了大量关键的项目信息变量,为后续定义目标(add_executable, add_library)、设置编译选项、链接库等操作奠定了基础。正确使用 project() 及其可选参数(尤其是 VERSIONLANGUAGES)是编写清晰、可维护 CMake 脚本的关键第一步。

你可能感兴趣的:(CMake,c++)