Bootstrap

cmake命令使用

有关cmake的入门简介可参见

CMake入门教程_cmake静态test.c编译-CSDN博客

本文是进一步对cmake常用命令做进一步详述

配置项目

cmake_minimum_required

作用

配置cmake最低版本

用法

cmake_minimum_required(VERSION 3.0)

project

作用:设置预设变量

  • PROJECT_NAME
  • PROJECT_SOURCE_DIR
  • ROJECT_BINARY_DIR

用法

project(demo_project c cxx)

其中,后边的c和cxx用于设置编译的语言,一般可以不用

案例:创建CMakeLists.txt,编写该文件内容,使用project命令设置项目名称,然后打印上述预设变量

cmake_minimum_required(VERSION 3.0)
project(demo_project)
#打印预设变量
message(STATUS "PROJECT_NAME:${PROJECT_NAME}")
message(STATUS "PROJECT_SOURCE_DIR:${PROJECT_SOURCE_DIR}")
message(STATUS "PROJECT_BINARY_DIR:${PROJECT_BINARY_DIR}")

保存退出后,使用下述命令编译cmake

cmake -S . -B build
  • -S选项表示指定CMakeLists.txt文件的目录文件,后边的.表示当前目录
  • -B选项表示指定生成的文件存放在哪里

因此上述命令表示使用当前目录下的 CMakeLists.txt 生成Makefile文件等文件,并将生成的文件放到build文件夹内(注意build文件夹需要首先创建好)

运行结果

信息打印

上述命令中message函数可以帮助我们打印相关信息,如

message(STATUS "This is a status message.")
message(WARNING "This is a warning message.")
message(FATAL_ERROR "This is a fatal error message.")
  • STATUS:打印一般信息,输出为绿色。
  • WARNING:打印警告信息,输出为黄色。
  • FATAL_ERROR:打印错误信息并停止配置过程。

 同时可以设置 CMake 的调试输出,可以在命令行中设置 CMAKE_VERBOSE_MAKEFILE 变量,以显示详细的构建命令。例如:

cmake -S . -B build -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON

这将使 CMake 在执行构建时打印每个命令的详细信息。

添加头文件目录

添加头文件搜索路径的命令有两种

  • include_directories:指定的头文件路径会被应用于整个 CMakeLists 文件中所有后续的目标
  • target_include_directories:允许你为特定的目标(例如库或可执行文件)设置头文件路径

 以下是两种方式使用代码实例

include_directories(${PROJECT_SOURCE_DIR}/include)

该代码表示整个项目所有源文件的自定义头文件搜索路径都指定为include 

add_executable(app main.cc)
target_include_directories(app PRIVATE ${PROJECT_SOURCE_DIR}/include)

而该代码表示仅为目标文件app中包含的自定义头文件搜索路径指定为include

target_include_directories命令的语法格式为

target_include_directories(<target> <INTERFACE|PUBLIC|PRIVATE> <directory1> <directory2> ...)

 如上所示,该命令会为指定的头文件添加三个属性

  • INTERFACE
  • PUBLIC
  • PRIVATE

要理解上述三个属性的区别,首先要知道,Cmake会为每个目标文件设置两个属性,分别是

  • INCLUDE_DIRECTORIES:只在当前目标文件中有效
  • INTERFACE_INCLUDE_DIRECTORIES:随着目标文件的依赖而传播

上述两个属性的区别在于:

  • 如果使用PRIVATE,则只会在INCLUDE_DIRECTORIES属性中添加头文件搜索路径
  • 如果使用INTERFACE,则只会在INTERFACE_INCLUDE_DIRECTORIES属性中添加头文件搜索路径
  • 如果使用PUBLIC,则相当于同时使用INCLUDE_DIRECTORIES和INTERFACE_INCLUDE_DIRECTORIES

 如下所示,如果使用PRIVATE,则每个目标文件(在这里是base和app)的头文件的搜索路径包含在各自维护的INCLUDE_DIRECTORIES变量里 

add_library(base base/base.cc)
target_include_directories(base PRIVATE ${PROJECT_SOURCE_DIR}/util)

add_executable(app base)
target_include_directories(app 
PRIVATE ${PROJECT_SOURCE_DIR}/base
PRIVATE ${PROJECT_SOURCE_DIR}/util
)

但是如果使用的是PUBLIC,那么util的路径就会被同时存储在INTERFACE_INCLUDE_DIRECTORIES变量里,同时这个路径会跟随base这个目标文件存在,因此当第二个target_include_directories包含base的时候,base就已经包含了util路径,将不再需要单独列出这个路径了

add_library(base base/base.cc)
target_include_directories(base PUBLIC ${PROJECT_SOURCE_DIR}/util)

add_executable(app base)
target_include_directories(app 
PRIVATE ${PROJECT_SOURCE_DIR}/base
)

 编译可执行程序

添加可执行程序的命令为

add_executable(app main.cc)
add_executable(app2 EXCLUDE_FROM_ALL main.cc)

app为最后编译成功的可执行程序,main.cc表示编译这个可执行程序需要的源文件,而可选项EXCLUDE_FROM_ALL 表示将可执行程序app2排除在all之外,需要明确指定才能编译

EXCLUDE_FROM_ALL 这个可选项什么意思呢?

我们在CMakeLists.txt文件中写入以下内容

cmake_minimum_required(VERSION 3.0)
project(demo_project)

add_executable(app main.cc)
add_executable(app2 EXCLUDE_FROM_ALL main.cc)

然后执行

cmake -S . -B build

首先进入build文件夹

先执行

make

可以看到,此时使用make,仅仅只编译了app,并未编译app2 

事实上,make命令其实执行的是make all

接下来我们重新执行

make app2

可以看到,由于EXCLUDE_FROM_ALL 的作用,我们在使用make命令编译时,必须手动指明要编译的目标文件名

 库文件编译

如果要编译库文件,则使用的命令是

add_library(<name>[STATICSHAREDMODULE]
[EXCLUDE FROM ALL][<source>...])

其使用方式与add_executable一样,只是库文件有静态库和动态库之分,因此add_library命令有一个可选项用于指定编译动态库还是静态库,默认情况下不指定选项时编译为静态库

add_library(mprpc mprpcapplication.cpp)

如上述命令表示将   mprpcapplication.cpp文件编译为静态库

而如果要编译为动态库,则需要指定为

add_library(mprpc SHARED mprpcapplication.cpp)

引用库文件

引用库文件时使用命令

target_link_libraries

比如以下命令,表示我要编译生成一个静态库文件mprpc,而这个库文件在编译时要依赖于其他的第三方库,这是就需要使用target_link_libraries命令

add_library(mprpc ${SRC_LIST})
 target_link_libraries(mprpc muduo_net muduo_base pthread zookeeper_mt)

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;