cmake是一个跨平台的编译工具,可以快速编辑构建项目编译环境,自动生成Makefile

示例一

1
2
3
4
5
cmake_minimum_required (VERSION 2.8) #要求cmake最低的版本号
project (demo) # 定义当前工程名字
set(CMAKE_BUILD_TYPE "Debug")#设置debug模式,如果没有这一行将不能调试设断点
set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -g)# 设置编译参数选项
add_executable(helloworld main.cpp)# 生成可执行文件

外部构建:mkdir build && cd build && cmake ..

在build生成二进制文件,方便删除

直接构建:cmake .

示例二

1
2
3
4
5
├── CMakeLists.txt
├── include
│ └── func.h
├── func.cpp
├── main.cpp
1
2
3
4
5
6
7
8
9
cmake_minimum_required (VERSION 2.8)
project (demo)
# aux_source_directory(. SRC_LIST)
include_directories(include)
set( SRC_LIST
./main.cpp
./func.cpp)
add_executable(main ${SRC_LIST})
# target_include_directories(main PRIVATE include)

区别:

aux_source_directory把当前目录下所有文件命名SRC_LIST

include_directories是全局性的,为整个项目设置包含目录;target_include_directories只为特定目标添加包含目录,通常在子目录的add_executableadd_library使用

  • PRIVATE:包含目录只对指定的目标有效,不会传递给依赖该目标的其他目标。
  • PUBLIC:包含目录对指定的目标有效,并且会传递给依赖该目标的其他目标。
  • INTERFACE:包含目录只对依赖该目标的其他目标有效,不会对指定的目标本身有效。

示例三

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
.
├── bin
│ ├── ChatClient
│ └── ChatServer
├── build
├── CMakeLists.txt
├── include
│ ├── public.hpp
│ └── server
│ ├── chatserver.hpp
│ ├── chatservice.hpp
│ ├── db
│ │ └── db.h
│ ├── model
│ │ ├── friendmodel.hpp
│ │ ├── group.hpp
│ │ ├── groupmodel.hpp
│ │ ├── groupuser.hpp
│ │ ├── offlinemessagemodel.hpp
│ │ ├── user.hpp
│ │ └── usermodel.hpp
│ └── redis
│ └── redis.hpp
├── lib
│ └── json.hpp
├── src
│ ├── client
│ │ ├── CMakeLists.txt
│ │ └── main.cpp
│ ├── CMakeLists.txt
│ └── server
│ ├── chatserver.cpp
│ ├── chatservice.cpp
│ ├── CMakeLists.txt
│ ├── db
│ │ └── db.cpp
│ ├── main.cpp
│ ├── model
│ │ ├── friendmoel.cpp
│ │ ├── groupmodel.cpp
│ │ ├── offlinemessagemodel.cpp
│ │ └── usermodel.cpp
│ └── redis
│ └── redis.cpp
└── test
├── json
│ ├── json.hpp
│ └── testjson.cpp
└── muduo
└── muduo_server.cpp

项目根目录下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
cmake_minimum_required(VERSION 3.0)
project(chat)

# 配置编译选项
set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -g)

# 配置最终的可执行文件输出的路径
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

# 配置头文件的搜索路径
include_directories(${PROJECT_SOURCE_DIR}/include)
include_directories(${PROJECT_SOURCE_DIR}/include/server)
include_directories(${PROJECT_SOURCE_DIR}/include/server/db)
include_directories(${PROJECT_SOURCE_DIR}/include/server/model)
include_directories(${PROJECT_SOURCE_DIR}/include/server/redis)
include_directories(${PROJECT_SOURCE_DIR}/lib)
link_directories(/usr/lib64/mysql)

# 加载子目录
add_subdirectory(src)

src下添加子目录

1
2
add_subdirectory(server)
add_subdirectory(client)

client和server

1
2
3
4
5
6
7
# 定义了一个SRC_LIST变量,包含了该目录下所有的源文件
aux_source_directory(. SRC_LIST)

# 指定生成可执行文件
add_executable(ChatClient ${SRC_LIST})
# 指定可执行文件链接时需要依赖的库文件
target_link_libraries(ChatClient pthread)
1
2
3
4
5
6
7
8
9
10
# 定义了一个SRC_LIST变量,包含了该目录下所有的源文件
aux_source_directory(. SRC_LIST)
aux_source_directory(./db DB_LIST)
aux_source_directory(./model MODEL_LIST)
aux_source_directory(./redis REDIS_LIST)

# 指定生成可执行文件
add_executable(ChatServer ${SRC_LIST} ${DB_LIST} ${MODEL_LIST} ${REDIS_LIST})
# 指定可执行文件链接时需要依赖的库文件
target_link_libraries(ChatServer muduo_net muduo_base mysqlclient hiredis pthread)

当包含多个cmake文件时,在最高层添加全局性的设置,然后add_subdirectory,一个好的设计是只包含include_directories(${PROJECT_SOURCE_DIR}/include),头文件加上目录路径#include “server/db/db.h”,这样可以有效防止文件名冲突

CMake常用的预定义变量

  • PROJECT_NAME : 通过 project() 指定项目名称
  • PROJECT_SOURCE_DIR : 工程的根目录
  • PROJECT_BINARY_DIR : 执行 cmake 命令的目录
  • CMAKE_CURRENT_SOURCE_DIR : 当前 CMakeList.txt 文件所在的目录
  • CMAKE_CURRENT_BINARY_DIR : 编译目录,可使用 add subdirectory 来修改
  • EXECUTABLE_OUTPUT_PATH : 二进制可执行文件输出位置
  • LIBRARY_OUTPUT_PATH : 库文件输出位置
  • BUILD_SHARED_LIBS : 默认的库编译方式 ( shared 或 static ) ,默认为 static
  • CMAKE_C_FLAGS : 设置 C 编译选项
  • CMAKE_CXX_FLAGS : 设置 C++ 编译选项
  • CMAKE_CXX_FLAGS_DEBUG : 设置编译类型 Debug 时的编译选项
  • CMAKE_CXX_FLAGS_RELEASE : 设置编译类型 Release 时的编译选项
  • CMAKE_GENERATOR : 编译器名称
  • CMAKE_COMMAND : CMake 可执行文件本身的全路径
  • CMAKE_BUILD_TYPE : 工程编译生成的版本, Debug / Release

cmake指令

  • -G <generator>:指定构建系统类型,如 “Unix Makefiles”、”Visual Studio 15 2017” 等。
  • -S <path/to/source>:指定源代码目录。
  • -B <path/to/build>:指定构建目录。
  • -D <variable>=<value>:设置 CMake 变量的值。
  • -U <variable>:取消设置 CMake 变量。
  • -DCMAKE_BUILD_TYPE=<type>:设置构建类型,如 “Debug”、”Release”、”RelWithDebInfo” 或 “MinSizeRel”。
  • -DCMAKE_INSTALL_PREFIX=<path>:设置安装目录。
  • -H <path/to/source>:等同于 -S
  • -B <path/to/build>:等同于 -B
  • --check-build-system:检查构建系统是否损坏。
  • --config <config>:指定构建配置,如 “Debug” 或 “Release”。
  • --target <name>:指定构建目标。
  • --build <path/to/build>:构建项目。
  • --clean-first:在构建之前先清理构建目录。
  • --target <name>:指定构建目标。
  • -- <options>:将后续参数传递给构建工具。