基本语句
- 指定项目名称:
cpp
project(<project_name> [<languages>] [<options>])
其中:
<project_name>:项目的名称。
< languages>:指定该项目使用的编程语言(如 C、C++、Fortran 等)。
< options>:可以设置一些其他的选项,如版本等。
示例:
cpp
project(MyProject) # MyProject 是项目的名称,默认情况下,CMake会使用C和C++作为编程语言
project(MyProject C CXX) # MyProject 是项目名称,C 和 CXX(即 C++)表示项目将包含 C 和 C++ 语言源代码
project(MyProject C CXX VERSION 3.12) # MyProject 项目要求 CMake 支持 C 和 C++,并且要求 CMake 的版本至少是 3.12
- 设置变量:
set(SOURCE_FILES main.cpp app.cpp)
set() 用于设置变量。
示例:
set(MY_VAR "Hello, CMake!") # 设置 MY_VAR 变量的值为 "Hello, CMake!"
cpp
set(MY_INT 42) # 设置 MY_INT 变量的值为 42
set(MY_LIST "apple") # 初始化 MY_LIST 变量为 "apple"
set(MY_LIST ${MY_LIST} "banana") # 追加 "banana" 到 MY_LIST 中,变为 "apple;banana"
set(MY_PATH "/usr/local/bin") # 设置 MY_PATH 为 "/usr/local/bin"
set(MY_PATH "${MY_PATH}:/opt/tools") # 将 "/opt/tools" 追加到 MY_PATH 中,变为 "/usr/local/bin:/opt/tools"
set(MY_LIST "apple" "banana") # 初始化 MY_LIST 为 "apple" 和 "banana"
list(APPEND MY_LIST "cherry") # 使用 list(APPEND) 向 MY_LIST 追加 "cherry",变为 "apple;banana;cherry"
set(MY_VAR "World") # 设置 MY_VAR 为 "World"
message("Hello, ${MY_VAR}!") # 输出 "Hello, World!"
set(MY_LIST "apple" "banana" "cherry") # 设置 MY_LIST 为 "apple", "banana", "cherry"
message("First fruit: ${MY_LIST}") # 输出 "First fruit: apple;banana;cherry"
set(MY_VAR "Hello, CMake!" CACHE STRING "A simple string cache variable") # 设置缓存变量 MY_VAR,类型为 STRING,描述为 "A simple string cache variable"
set(MY_PATH "/usr/local/bin" CACHE PATH "Installation directory") # 设置缓存变量 MY_PATH,默认值为 "/usr/local/bin",类型为 PATH
set(MY_FILE_PATH "${CMAKE_SOURCE_DIR}/src/my_file.cpp") # 设置 MY_FILE_PATH 为源代码目录下的文件路径
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2") # 为 C 编译器设置优化选项 -O2
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2") # 为 C++ 编译器设置优化选项 -O2
- 指定编译器选项:
add_compile_options(-Wall)
add_compile_options() 用于为编译器添加命令行选项。在此例中,-Wall 用来启用所有警告。
示例:
cpp
add_compile_options(-Wall) # 向所有目标添加编译选项 -Wall,开启所有警告
add_executable(my_app main.cpp)
add_compile_options(my_app -O2) # 为 my_app 目标添加 -O2 优化选项
add_compile_options(-Wall -Wextra -O2) # 向所有目标添加多个选项:-Wall(所有警告),-Wextra(额外警告),-O2(优化)
# 为 C 编译器添加选项
add_compile_options(CLANG -Wall -Wextra) # 仅当使用 Clang 编译器时才添加这些选项
# 为 C++ 编译器添加选项
add_compile_options(CXX -std=c++11 -Wall) # 为 C++ 编译器添加 C++11 标准和警告选项
- 添加可执行文件:
add_executable(MyApp ${SOURCE_FILES})
add_executable() 指定构建可执行文件,并指定源文件。
示例:
cpp
# 创建可执行文件 MyApp,从 main.cpp 编译
add_executable(MyApp main.cpp)
# 创建可执行文件 MyApp,从多个源文件编译
add_executable(MyApp main.cpp utils.cpp)
# 使用一个变量指定源文件列表
set(SOURCE_FILES main.cpp utils.cpp)
add_executable(MyApp ${SOURCE_FILES})
set(SOURCE_DIR "${CMAKE_SOURCE_DIR}/src")
file(GLOB SOURCE_FILES "${SOURCE_DIR}/*.cpp") # GLOB 是一个用于文件匹配的操作,它是 file() 函数的一个命令参数,用来查找文件
add_executable(MyApp ${SOURCE_FILES})
- 添加库文件:
cpp
add_library(<name> <type> <source_files>...)
< name>: 库的名称。
< type>: 库的类型,可以是 STATIC、SHARED、MODULE、INTERFACE 等。
< source_files>: 库的源文件列表(可以是 .cpp、.c 等源代码文件)。
add_library() 是 CMake 中用于创建库的命令。它允许我们创建两种类型的库:静态库(STATIC)和共享库(SHARED)。同时,还可以创建接口库(INTERFACE)等,来支持特定的库构建需求。
示例:
cpp
# 设置源文件
set(SOURCE_FILES src/foo.cpp src/bar.cpp)
# 创建静态库 libmylib.a
add_library(mylib STATIC ${SOURCE_FILES})
# 设置源文件
set(SOURCE_FILES src/foo.cpp src/bar.cpp)
# 创建共享库 libmylib.so 或 libmylib.dll(取决于平台)
add_library(mylib SHARED ${SOURCE_FILES})
# 设置源文件
set(SOURCE_FILES src/foo.cpp src/bar.cpp)
# 创建一个模块库
add_library(mylib MODULE ${SOURCE_FILES})
# 创建一个接口库
add_library(mylib INTERFACE)
# 指定接口库的头文件
target_include_directories(mylib INTERFACE ${CMAKE_SOURCE_DIR}/include)
- 指定包含目录:
include_directories(${CMAKE_SOURCE_DIR}/include)
include_directories() 用来添加头文件目录,这样编译器可以在编译时找到相应的头文件。
示例:
cpp
include_directories(/path/to/include) # 将 /path/to/include 目录添加到编译器的头文件搜索路径
include_directories(/path/to/include /path/to/another/include) # 同时添加两个头文件目录
include_directories(${CMAKE_SOURCE_DIR}/include) # 添加相对路径的头文件目录,使用CMake变量CMAKE_SOURCE_DIR
include_directories(${PROJECT_SOURCE_DIR}/include) # 使用项目的源代码目录,添加项目中的include目录
add_executable(MyApp main.cpp) # 创建一个可执行文件MyApp
include_directories(${CMAKE_SOURCE_DIR}/include) # 全局添加头文件目录
target_include_directories(MyApp PRIVATE ${CMAKE_SOURCE_DIR}/app_include) # 针对MyApp目标单独添加头文件目
find_package(SomeLibrary REQUIRED) # 查找某个库
include_directories(${SomeLibrary_INCLUDE_DIRS}) # 添加找到的库的头文件目录
add_executable(TargetA srcA.cpp) # 创建目标TargetA
add_executable(TargetB srcB.cpp) # 创建目标TargetB
include_directories(${CMAKE_SOURCE_DIR}/common_include) # 为所有目标添加公共头文件目录
- 链接库文件:
target_link_libraries(MyApp MyLibrary)
target_link_libraries() 用于将指定的库链接到目标(如可执行文件或库)上。
示例:
cpp
add_executable(MyApp main.cpp) # 创建一个可执行文件 MyApp
target_link_libraries(MyApp MyLibrary) # 将静态库或共享库 MyLibrary 链接到 MyApp
add_executable(MyApp main.cpp)
target_link_libraries(MyApp MyLibrary AnotherLibrary) # 将多个库链接到 MyApp
add_executable(MyApp main.cpp)
target_link_libraries(MyApp pthread) # 链接系统库 pthread
add_executable(MyApp main.cpp)
target_link_libraries(MyApp /path/to/libmystaticlib.a) # 将静态库 libmystaticlib.a 链接到 MyApp
add_executable(MyApp main.cpp)
target_link_libraries(MyApp /path/to/libmysharedlib.so) # 将共享库 libmysharedlib.so 链接到 MyApp
add_executable(MyApp main.cpp)
add_library(MyLibrary STATIC lib.cpp)
add_library(AnotherLibrary STATIC anotherlib.cpp)
target_link_libraries(MyApp MyLibrary AnotherLibrary) # 将多个库链接到可执行文件 MyApp
find_package(OpenGL REQUIRED) # 查找 OpenGL 库
add_executable(MyApp main.cpp)
target_link_libraries(MyApp OpenGL::GL) # 将 OpenGL 库链接到 MyApp
- 指定安装规则:
install(TARGETS MyApp DESTINATION bin)
install() 用于定义构建后的安装规则。
同义语句对比
1.include_directories() vs target_include_directories()
include_directories() 会影响所有的目标,而 target_include_directories() 则只会影响指定的目标。
使用 include_directories():
cpp
include_directories(${CMAKE_SOURCE_DIR}/include)
使用 target_include_directories():
cpp
target_include_directories(MyApp PRIVATE ${CMAKE_SOURCE_DIR}/include)
target_include_directories() 是更现代的做法,推荐使用。
2.set() vs list(APPEND)
set() 用于初始化或覆盖变量,而 list(APPEND) 用于将元素添加到已有列表。
使用 set():
cpp
set(SOURCE_FILES main.cpp app.cpp)
使用 list(APPEND):
cpp
list(APPEND SOURCE_FILES main.cpp app.cpp)
list(APPEND) 在需要追加元素而不覆盖变量时更为常用。
3.target_compile_options() vs add_compile_options()
add_compile_options() 是全局设置,会影响整个项目中的所有目标。
target_compile_options() 只会影响指定的目标。
示例:
cpp
add_compile_options(-Wall)
target_compile_options(MyApp PRIVATE -Wall)
推荐使用 target_compile_options(),因为它作用于特定目标,而 add_compile_options() 会影响整个项目,可能会导致意外的副作用。
4.add_subdirectory() vs ExternalProject_Add()
add_subdirectory() 用于将一个子目录的 CMake 项目添加到当前项目。
ExternalProject_Add() 用于下载、构建和安装外部项目。
示例:
cpp
add_subdirectory(submodule)
cpp
include(ExternalProject)
ExternalProject_Add(MyExternalProject
GIT_REPOSITORY https://github.com/example/project.git
PREFIX ${CMAKE_BINARY_DIR}/_deps
)
add_subdirectory() 更适用于子模块,而 ExternalProject_Add() 适用于外部依赖。
5.install() vs export()
install() 用于安装目标和文件。
export() 用于导出目标和构建配置,使得其他项目可以使用这些目标。
示例:
cpp
install(TARGETS MyApp DESTINATION bin)
cpp
export(TARGETS MyApp FILE MyApp.cmake)
install() 更常用于创建可供外部系统使用的可执行文件或库,而 export() 用于创建可以被其他 CMake 项目导入的配置文件。