会用就行,我不想写
2025/06 Ubuntu 24.04 AMD64
https://cmake.org/download/ 在这里可以下载到一个50MB左右的sh文件(Binary distributions: cmake-4.0.2-linux-x86_64.sh),这是一个自解压程序,下载执行(选择解压目录),然后把这个目录(里面的bin/)添加到环境变量即可,没有什么别的依赖
# llvm的构建命令 # -S 指定 Source 目录,也就是放CMakeLists.txt的位置 # -B 指定 Build 构建目录 # -G 指定构建工具 # -D 指定参数 cmake -S llvm -B build -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug # 自动调用正确的构建工具,在build下面执行编译 # --target指定Makefile的Target # --后面的参数会传递给真正的构建工具,比如make cmake --build build --target install -- -j8
一条命令行启动CMake的例子,展示了如何指定编译环境和一些参数,-D是Define的意思,用于设定变量的值:
cmake .. -G"MinGW Makefiles" -DCMAKE_CXX_FLAGS=-Wa,-mbig-obj -D BUILD_SHARED_LIBS=OFF
警告:以下这样传递参数其实是不安全的
-D BUILD_SHARED_LIBS=OFF
中间多了一个空格可能会导致参数识别错误,想一下程序读取参数的过程,连起来的肯定是不会错的,中间加了空格的顺序可能会错,所以结论是:除非空格是强制要求,否则不要加空格,参考一下cl编译器的参数,也是不加空格的,要适应一下这种方式
执行CMake会生成对应平台的工程文件(比如在Windows上会生成VS Solution),这一个完整的工程中会包含几个固定的Build Target(在Windows上是VS Project),分别用于不同的目的
Q:CMake生成的ALL_BUILD和INSTALL和ZERO_CHECK工程都是做什么的?
from AI
CMake是一个跨平台的构建系统,它可以自动生成各种构建工具的项目文件。当使用CMake生成一个项目时,通常会生成以下三个工程文件:
1. ALL_BUILD:ALL_BUILD工程是一个用于构建整个项目的工程,它包含了所有项目的构建目标。当你运行ALL_BUILD工程时,CMake将会构建整个项目。
2. INSTALL:INSTALL工程用于安装项目文件到指定的目录。在构建完成后,你可以运行INSTALL工程,将项目安装到指定的目录。
3. ZERO_CHECK:ZERO_CHECK工程用于检查项目文件是否需要重新生成。如果项目文件有任何变化,那么CMake会重新生成相应的构建工具项目文件。因此,当你修改了项目文件后,你可以运行ZERO_CHECK工程,CMake将检查文件是否需要重新生成,如果需要,就会重新生成构建工具项目文件。
需要注意的是,这三个工程是由CMake自动生成的,并不是你手动创建的。它们的作用是方便你构建、安装和检查项目文件的状态。
Q:在Linux上也会生成这3个工程吗?
from AI
是的,在Linux上也会生成这三个工程。CMake是一个跨平台的构建系统,可以在多种操作系统上运行,包括Linux。因此,无论你在哪个平台上使用CMake生成项目,它都会自动生成这三个工程。
在Linux上,CMake通常会生成Makefile文件来构建项目,而ALL_BUILD、INSTALL和ZERO_CHECK都是Makefile的构建目标。因此,当你使用CMake在Linux上生成项目时,你可以使用Make命令来构建、安装和检查项目,例如:
goCopy codemake all // 构建整个项目 make install // 安装项目文件 make clean // 清除构建文件 make zero_check // 检查项目文件状态
需要注意的是,在Linux上,CMake还可以生成其他类型的构建工具,例如Ninja和Unix Makefiles等。不过,无论使用哪种构建工具,CMake都会自动生成这三个工程。
在一个项目的子目录中再使用CMake来管理子项目或模块,CMake对此有官方支持。
实现方式就是在你的主CMakeLists.txt里用 add_subdirectory() 命令,把子目录包含进来。
每个子目录会有自己的编译规则、target、源文件等,这是现代CMake推荐的管理大型工程的方式。
不是直接执行子目录里的 CMake,而是通过主目录的CMake统一管理整个工程。
注意:这里的「子目录」有一定的迷惑性!其实不一定是真的子目录,比如也可以使用「../xxx」这种方式添加同级目录。这样子就很灵活了:一个主CMakeLists.txt可以管理子项目的CMakeLists.txt(比如LLVM就是这样做的)
AI: CMake 是 C++ 项目中非常常见的构建系统,而 CMake Presets 可以让项目维护者预设好多种常用的编译/构建选项,用户可以直接选择,不用自己手动配置那么多复杂的参数。本质上 preset 就是帮你省去了很多命令行参数的配置,预设好了环境。
#单行注释 #[[多行注释]] ${var_name}:读取变量值 set(<var_name> <var_value>):设置变量的值 cmake_minimum_required:CMake的最低版本要求 project:指定项目的名称 file:使用正则表达式匹配文件 list:用于列表的操作 message:输出消息 aux_source_directory:在目录中查找所有源文件,不递归 add_executable:列出使用的源文件,构建可执行文件 add_library:使用指定的源文件,生成静态或动态库 include_directories:添加头文件搜索路径 link_directories:指定静态库或动态库的搜索路径 target_link_libraries:将指定的静态库连接到可执行文件上
CMakeLists.txt
cmake_minimum_required(VERSION 3.10) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED True) set(CMAKE_BUILD_TYPE Release) project(reEngine) set(sourDir ${PROJECT_SOURCE_DIR}/Source) set(inclDir ${PROJECT_SOURCE_DIR}/Include) set(suppDir ${PROJECT_SOURCE_DIR}/Support) set(sourceFiles ) set(sourceFiles ${sourceFiles};${sourDir}/FFT/FFT.cpp) add_library(FFT STATIC ${sourceFiles}) target_include_directories(FFT PRIVATE ${suppDir}/Include;${inclDir}/FFT) target_compile_definitions(FFT PRIVATE NO_MIN_MAX;_CRT_SECURE_NO_WARNINGS) set_target_properties(FFT PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Lib) set(sourceFiles ) set(sourceFiles ${sourceFiles};${sourDir}/reEngine/Main.cpp) set(sourceFiles ${sourceFiles};${sourDir}/reEngine/Support.cpp) add_executable(reEngine ${sourceFiles}) target_link_directories(reEngine PRIVATE ${suppDir}/Lib;${CMAKE_BINARY_DIR}/Lib) target_link_libraries(reEngine PRIVATE FFT) target_link_libraries(reEngine PRIVATE glfw3) target_link_libraries(reEngine PRIVATE assimp) target_include_directories(reEngine PRIVATE ${suppDir}/Include;${inclDir}) target_compile_definitions(reEngine PRIVATE NO_MIN_MAX;_CRT_SECURE_NO_WARNINGS) set_target_properties(reEngine PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Bin)
CPack是CMake带的一个工具,用于打包