前提
来来回回使用cmake已经多次了,有一些cmake中使用的命令还是比较模糊,这里进行简单地梳理并进行记录。如有问题,欢迎大家指教。
CMake 相关命令
CMake是一个跨平台的安装(编译)工具,而不是编译器。CMake不能直接构建出可以在机器上运行的软件(这就是为什么我们经常cmake ..
后,还要使用make
),它的主要作用是能够使用统一的语法,在特定平台下,生成能够指导编译器完成编译工作的文件,这个文件称为构建档(在UNIX上是Makefile
,在windows上是.sln
)。用于生成构建档的统一语法的文件,即CMakeLists.txt
,我们称之为组态档。
cmake_minimum_required(VERSION <min>[...<policy_max>] [FATAL_ERROR])
需要cmake的最小版本,这里"[]"之内的为可选参数。一般的使用,例如cmake_minimum_required(VERSION 3.21)
,表明cmake的最小版本为3.21。project(<PROJECT-NAME> [<language-name>...])
设置项目的名称,同时把这个名称赋值给cmake中的变量PROJECT_NAME
,可选参数[<language-name>]
代表是哪种编程语言要被build,默认是C和C++。一般使用:project(hello_world)
,表明项目名称为hello_world。message([<mode>] "message text" ...)
记录一条信息,可以理解为c++中的printf,我们可以使用这个命令将我们想要的一些信息输出。[<mode>]
是一个可选参数,用于指定消息的级别。常见的模式包括 STATUS、WARNING、AUTHOR_WARNING、SEND_ERROR 和 FATAL_ERROR。默认情况下,消息的模式是 STATUS,表示一般的信息。不同的模式可以改变消息的显示方式和影响构建的行为。一般使用:message(STATUS "I am a cmaker")
add_executable(<name> <options>... <sources>...)
添加一个名为name的可执行目标,这个目标从后面的<source>
源文件中构建(build)。一般使用add_executable(demo main.cpp)
,表明要使用main.cpp来构建可执行文件的目标demo
(并不是可执行文件demo)。demo
是目标名,而不是可执行文件名。set(<variable> <value>... [PARENT_SCOPE])
设置一个变量的值。<variable>
是要设置的变量的名称。<value>...
是一个或多个要分配给变量的值。
[PARENT_SCOPE]
是一个可选参数,用于指定将变量设置为父作用域中的变量。如果不指定[PARENT_SCOPE]
参数,那么变量将被设置为当前作用域中的变量。如果指定了[PARENT_SCOPE]
参数,那么变量将被设置为父作用域中的变量。一般使用:set(CMAKE_CXX_STANDARD 14)
,将CMAKE_CXX_STANDARD
这个变量的值设置为14。add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL] [SYSTEM])
向 CMake 项目中添加一个子目录,并将该子目录中的 CMakeLists.txt 文件包含到当前项目中,从而允许在子目录中构建其他的目标。source_dir
是要添加的子目录的路径。这个命令就牵扯到了两个及两个以上CMakeLists.txt的情况,假如我父目录有一个CMakeLists.txt,子目录里也有一个CMakeLists.txt,在build父目录时,也想build子目录,就可以使用这条命令。一般使用:add_subdirectory(subdirectory)
。target_link_libraries(<target> ... <item>... ...)
将一个或多个库链接到特定的目标(例如可执行文件或库)。具体来说,它将库文件链接到目标,使得目标可以使用这些库中定义的函数和符号。简单来说,比如我们在程序中使用了Glog的库函数,那我们编译时肯定要带上Glog的库,这个命令就可以帮助我们将Glog库文件链接到目标(预处理->编译->汇编->链接)。一般使用:target_link_libraries(demo glog::glog)
。target_include_directories(<target> [SYSTEM] [AFTER|BEFORE] <INTERFACE|PUBLIC|PRIVATE> [items1...])
指定要build一个目标是要使用的头文件,这里的头文件可以理解为.h
文件。也就是在我们写代码过程中,只有include
头文件后,才可以找到头文件中声明的函数等。SYSTEM
是一个可选参数,表示指定的包含目录应被视为系统目录。这通常用于包含系统提供的头文件,例如 C 标准库。一般使用:target_include_directories(demo ../include)
add_library(<name> [<type>] [EXCLUDE_FROM_ALL] <sources>...)
添加一个名为name
的库文件,它从<sources>
源文件构建。具体来说,它将源文件编译成一个库文件,以供其他目标(如可执行文件或其他库)使用 。<name>
是库名称;[<type>]
是构建出的库类型,常见的类型包括 STATIC(静态库)和 SHARED(共享库)。如果不提供类型,默认情况下将会创建一个静态库;<sources>
指源文件。
一般使用:# 声明要构建的静态库的名称为 mylib add_library(mylib STATIC # 添加源文件列表 src/foo.cpp src/bar.cpp ) # 指定头文件目录 target_include_directories(mylib PUBLIC include)
aux_source_directory(<dir> <variable>)
查找目录中的所有源文件。具体来说,它会在指定目录下查找所有的源文件,并将它们的文件名(包括路径)添加到指定的变量中。
一般使用:# 将 src 目录下的所有源文件添加到 SRC_FILES 变量中 aux_source_directory(src SRC_FILES) # 输出 SRC_FILES 变量的内容,可以看到它包含了 src 目录下所有源文件的路径 message("Source files: ${SRC_FILES}")
参考链接
- https://b23.tv/kVk5IcA
- https://cmake.org/cmake/help/latest/index.html