1.4.1 makefile,cmake
目录
- 1.4.1 makefile,cmake
- 1. makefile
- 1. 简单makefile
- 1. 变量赋值
- 2. 规则(Rule)
- 3. 特殊变量
- 4. 伪目标(Phony Targets)
- 6. 导入外部 Makefile
- 2. makefile工作原理
- 1. make 的工作流程
- 3. 例子
- 1.
- 2.
- 4. 安装
- 2. cmake
- 1. 安装
- 2. 使用
- 1. CMakeLists.txt,这个文件是 cmake 的构建定义文件,文件名是大小写相关的,如果工程存在多个目录,需要确保每个要管理的目录都存在一个CMakeLists.txt
- 2. 基本语法规则
- 3. 常用指令
- 4. 内部构建和外部构建
- 3. 示例
- 1. 单个目标文件
- 2. 多个目录
- 加载所有的源码,和makefile wildcard类似
- SET(DIR_SRCS dir1.c dir12.c)
- 默认是静态库
- ADD_LIBRARY (dir1 ${DIR_SRCS})
- 单个目录实现
- CMake 最低版本号要求
- 工程
- 手动加入文件
- 添加头文件路径
- 相对路径的方式
- 添加 dir1 子目录
- 添加头文件路径
- 添加 dir2 子目录
- 将执行文件安装到bin目录
- 3. 动态库,静态库,调用
- 项目名称和支持的语言
- 设置 C++ 标准
- 添加 lib1 和 lib2 子目录
- 添加可执行文件,main.cpp 是根目录下的源文件
- 链接静态库 lib1 和动态库 lib2 到最终可执行文件
- 4. 设置执行目录,并为 ZLToolKit 工程创建 Debug 和 Release 版本的构建配置
1.4.1 makefile,cmake
1. makefile
1. 简单makefile
三要素:目标,依赖,命令
1. 变量赋值
=:普通赋值,用于设置变量。
:=:立即展开赋值,表示变量的值在赋值时立即被计算。
?=:仅当变量未定义时才赋值。
+=:在变量的现有值后追加内容。
CC = gcc
CFLAGS = -Wall
SRC = main.c utils.c
OBJ = $(SRC:.c=.o)
2. 规则(Rule)
- 规则格式:
target:目标文件,通常是你想要生成的文件(如 .o 或可执行文件)。target: dependencies command
dependencies:依赖文件,表示生成目标所需的文件或其他目标。
command:用于生成目标的命令。 - 例子
myprogram: main.o utils.o gcc -o myprogram main.o utils.o3. 特殊变量
$@:表示当前规则中的目标文件。
$<:表示第一个依赖文件(通常是源文件)。
$^:表示所有依赖文件的列表,去除重复项。
$?:表示所有比目标文件新的依赖文件。%.o: %.c gcc -c $< -o $@4. 伪目标(Phony Targets)
伪目标是没有实际文件名的目标,通常用于清理或强制执行某些任务。
```makefile
.PHONY: clean all
all: myprogram
clean:
rm -f *.o myprogram
#### 5. 条件判断
Makefile 支持条件判断,以决定是否执行某些部分。
- ifeq / ifneq:条件判断,判断两个值是否相等或不相等。
- ifdef / ifndef:判断某个变量是否已定义。
```makefile
ifeq ($(CC),gcc)
CFLAGS += -O2
else
CFLAGS += -O0
endif
#1. ifeq ($(CC),gcc)
#这个条件判断检查变量 CC 是否等于 gcc,也就是判断使用的编译器是否是 gcc(GNU 编译器)。#如果 CC 的值是 gcc,则执行 ifeq 语句中的代码块,否则执行 else 语句中的代码。
#2. CFLAGS += -O2
#如果编译器是 gcc,就给 CFLAGS 变量添加 -O2 编译选项。-O2 是 GCC 的优化选项,它启用中
#等级别的优化,在编译过程中提高程序的执行效率,但不会过度增加编译时间。
#3. CFLAGS += -O0
#如果编译器不是 gcc,则给 CFLAGS 变量添加 -O0 编译选项。-O0 表示禁用所有优化,通常在调#试阶段使用,这样可以避免优化对调试过程的干扰
- 循环
Makefile 支持简单的循环结构,通常用于批量处理文件。
objects = main.o utils.o
all: $(objects)
gcc -o myprogram $(objects)
6. 导入外部 Makefile
你可以在 Makefile 中使用 include 来导入外部的 Makefile 或配置文件。
include config.mk
2. makefile工作原理
1. make 的工作流程
make 根据以下步骤处理 Makefile:
- 读取 Makefile: make 读取当前目录下的 Makefile(或者通过 -f 选项指定其他文件)。Makefile 描述了所有的目标、依赖关系和命令。
- 检查目标的更新时间: make 会查看目标文件的修改时间,如果目标文件不存在或其依赖文件比目标文件更新,make 就会执行相应的命令来重新构建目标。
- 执行命令: 如果目标的依赖文件发生了变化,make 就会执行相应的命令(如编译或链接),并生成或更新目标文件。
- 递归处理依赖关系: make 会递归地检查每个依赖项的更新情况。如果某个依赖项本身也有依赖项,make 会继续检查这些依赖项,直到所有需要更新的目标文件都被重新生成。依赖从左到右依次编译
3. 例子
1.
.PHONY: clean
#.PHONY 是一个特殊的目标,表示 clean 不是一个文件名,而是一个伪目标。
#即使有一个名为 clean 的文件,Make 也会执行这个规则而不是认为它是一个过期的目标。
CC = gcc
RM = rm
EXE = simple
# 上述都是定义变量
#SRCS = main.c foo.c
SRCS = $(wildcard *.c)
#使用 wildcard 函数来列出当前目录下所有的 .c 文件。这个变量 SRCS 包含所有源文件名(例如:main.c, foo.c)。
# 把.c换成对应的.o
#OBJS = foo.o foo2.o main.o
OBJS = $(patsubst %.c,%.o,$(SRCS))
$(EXE): $(OBJS)
$(CC) -o $@ $^
#这是链接命令,使用 gcc 编译器将目标文件 $(OBJS) 链接成最终的可执行文件。
#$@ 代表规则的目标,这里是 $(EXE)(即 simple)。
#$^ 代表规则的所有依赖文件,这里是 $(OBJS)(即所有的 .o 文件)
%.o: %.c
$(CC) -o $@ -c $^
clean:
$(RM) $(EXE) $(OBJS)
src: # 测试make src显示相应的xx.c
@echo $(SRCS)
objs:# 测试make objs显示相应的xx.o
@echo $(OBJS)
2.
CROSS =
#这里定义了一个名为 CROSS 的变量,但它为空。
#通常,这个变量用于交叉编译(cross-compilation)。例如,如果你需要为不同的架构(比如 ARM、x86、MIPS 等)编译程序,你可以设置 CROSS 为相应的编译前缀,如 arm-linux- 或 x86_64-。
#CROSS 为空,意味着默认使用系统的 gcc 和 g++ 编译器。
# 定义CC为gcc编译
CC = $(CROSS)gcc
# 定义CXX为g++编译
CXX = $(CROSS)g++
# 定义DEBUG 方式为 -g -O2
DEBUG = -g -O2
CFLAGS = $(DEBUG) -Wall -c
RM = rm -rf
# /定义SRC为当前工程目录下所有的.cpp文件
SRCS = $(wildcard ./*.c)
# 定义OBJS为SRCS对应的.o文件
OBJS = $(patsubst %.c, %.o, $(SRCS))
# 定义HEADER_PATH为当前工程中的头文件路径
#-I 是 gcc 和 g++ 编译器的一个选项,用来指定 头文件的搜索路径。
HEADER_PATH = -I ./include/
# 定义LIB_PATH为当前工程中的头文件路径
#-L 是 gcc 和 g++ 编译器的一个选项,用来指定 库文件的搜索路径。
LIB_PATH = -L ./lib/
# 输出当前LIB_PATH中的内容
#$(warning ...) 是 make 的一个内置函数,用来在执行 make 时输出警告信息。
$(warning LIB_PATH)
# 制定LIBS链接库的名称
#用于指定 链接的库。
#-lpthread 是 gcc 和 g++ 的一个选项,用于链接 pthread 库,它提供了多线程相关的功能。
#-l 是一个链接选项,用来指定一个库,pthread 是要链接的库的名称(通常在 Linux 上会是 libpthread.so 或 libpthread.a)。
#作用:在链接阶段,gcc 会链接 pthread 库,允许程序使用多线程功能。
LIBS=-lpthread
# lib中的库文件名称为libpthread.so
# 定义当前生成的版本
VERSION = 1.0.0
# 定义生成可执行文件的名称
TARGET = simple.$(VERSION)
$(TARGET) : $(OBJS)
# 告诉编译器生成可执行文件时库存放的目录,以及库的名字
$(CXX) $^ -o $@ $(LIB_PATH) $(LIBS)
#表示如何从源文件 .c 生成目标文件 .o。它意味着:对于每个 .c 文件,都会生成一个对应的 .o 文件。
$(OBJS):%.o : %.c
#告诉编译器生成中间文件时头文件的所在目录
$(CXX) $(CFLAGS) $< -o $@ $(HEADER_PATH)
clean:
$(RM) $(TARGET) *.o
4. 安装
在 Linux 系统中,Makefile 是用于自动化构建过程的脚本。它并不需要单独的“安装”,因为 Makefile 本身是一个文本文件,而 make 是一个工具,通常已经预安装在大多数 Linux 发行版中。
- 安装 make 工具
在 Debian/Ubuntu 系统中
使用以下命令来安装 make 工具:sudo apt update sudo apt install make - 验证安装
安装完成后,可以通过以下命令检查 make 是否正确安装:
make --version
如果成功安装,你将看到类似以下输出:
GNU Make 4.3
2. cmake
cmake基于makefile二次开发,难度较小
1. 安装
- 卸载已安装版本
apt-get autoremove cmake - 文件下载
wget https://cmake.org/files/v3.21/cmake-3.21.3-linux-x86_64.tar.gz - 解压
tar zxvf cmake-3.21.3-linux-x86_64.tar.gz - 软连接
mv cmake-3.21.3-Linux-x86_64 /opt/cmake-3.21.3
ln -sf /opt/cmake-3.21.3/bin/* /usr/bin/
2. 使用
1. CMakeLists.txt,这个文件是 cmake 的构建定义文件,文件名是大小写相关的,如果工程存在多个目录,需要确保每个要管理的目录都存在一个CMakeLists.txt
2. 基本语法规则
注释:使用 # 表示注释。
# 这是一个注释命令调用:CMake 命令不区分大小写,但通常使用小写。
command(arg1 arg2 ...)变量:使用 ${} 来引用变量。
set(MY_VAR "Hello") message(${MY_VAR}) # 输出 Hello变量使用和取值
定义变量:使用 set() 命令定义变量。set(MY_VAR "Hello World")set( [CACHE [FORCE]])
:变量名。
:变量的值。
CACHE:将变量存储在 CMake 缓存中,使其在多次运行 CMake 时保持不变。
:变量的类型,常见类型包括 STRING、BOOL、PATH 等。
:变量的描述信息。
FORCE:强制覆盖缓存中的变量值(如果变量已存在)。引用变量:使用 ${} 引用变量。
message(${MY_VAR}) # 输出 Hello World环境变量:使用 $ENV{} 引用环境变量。
message($ENV{HOME}) # 输出当前用户的主目录3. 常用指令
project():定义项目名称和版本。
project(MyProject VERSION 1.0)message():打印消息。
message("This is a message")MESSAGE([] "message text")
:指定消息的类型,常见的模式有:
STATUS:输出状态信息(通常以 -- 开头)。
WARNING:输出警告信息。
FATAL_ERROR:输出错误信息并停止 CMake 的执行。
DEBUG:输出调试信息(仅在调试模式下可见)。
"message text":要输出的消息内容。add_executable():定义可执行文件。
add_executable(my_app main.cpp)add_library():定义库(静态库或动态库)。
add_library(my_lib STATIC lib.cpp) # 静态库 add_library(my_lib SHARED lib.cpp) # 动态库target_link_libraries():链接库到目标。
target_link_libraries(my_app my_lib)清理工具
- 清理构建文件:CMake 生成的构建文件可以通过以下方式清理:
- 删除 build 目录(如果使用外部构建)。就是创建一个build目录,然后在里面cmake ..去编译上一级目录,生成的乱七八糟会在build里面,直接删文件夹就行
- 使用 make clean(如果使用 Makefile 生成器)。
- 使用 cmake --build . --clean-first。
4. 内部构建和外部构建
- 内部构建:在源代码目录中直接构建。
cmake .
make
- 外部构建:在单独的目录中构建(推荐)。
mkdir build cd build cmake .. make
3. 示例
1. 单个目标文件
# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)
# 工程,他不是执行文件名
PROJECT(HIT)
# 手动加入文件 ${变量名}} ,比如${SRC_LIST}
SET(SRC_LIST main.c)
set(SRC_LIST2 main2.c)# 关键字无所谓大小写
# MESSAGE和echo类似
MESSAGE(STATUS "PROJECT_BINARY_DIR DIR " ${PROJECT_BINARY_DIR})
# 输出类似:-- PROJECT_BINARY_DIR DIR /path/to/build/directory
MESSAGE(STATUS "PROJECT_SOURCE_DIR DIR " ${PROJECT_SOURCE_DIR})
# 生产执行文件名0voice 0voice2
ADD_EXECUTABLE(0voice ${SRC_LIST})
ADD_EXECUTABLE(0voice2 ${SRC_LIST2})
#ADD_SUBDIRECTORY 命令用于将一个子目录(如 src)添加到当前项目中,并使该子目录中的 CMakeLists.txt 文件被处理。这意味着,CMake 会递归地进入 src 子目录,执行该子目录中的 CMake 配置文件,并生成相关的构建文件(如 Makefile 或 Visual Studio 项目文件)。
# 添加子目录
ADD_SUBDIRECTORY(src)
#INSTALL(FILES COPYRIGHT README DESTINATION share/doc/cmake/0voice)
# 安装doc到 share/doc/cmake/0voice目录
# 默认/usr/local/
#指定自定义目录,比如 cmake -DCMAKE_INSTALL_PREFIX=/tmp/usr ..
INSTALL(DIRECTORY doc/ DESTINATION share/doc/cmake/0voice)
#这条命令会将 doc/ 目录及其内容安装到 share/doc/cmake/0voice 目录下。
#DIRECTORY:用于指定要安装的目录(doc/)。
#DESTINATION:指定安装的目标目录(share/doc/cmake/0voice)
#这种方式非常适合需要跨平台和模块化管理的项目,尤其是当你需要在多个目录下组织代码或将项目安装到指定位置时
2. 多个目录
将子目录编译成库文件,然后再给到上一级进行链接
HIT/ # 项目的根目录
├── CMakeLists.txt # 项目的 CMake 配置文件
├── src/ # 存放源代码的子目录
│ ├── CMakeLists.txt # src 子目录的 CMake 配置文件
│ ├── dir1/ # 子目录 1
│ │ ├── CMakeLists.txt # dir1 的 CMake 配置文件
│ │ └── dir1.c # dir1 子目录中的源文件
│ └── dir2/ # 子目录 2
│ ├── CMakeLists.txt # dir2 的 CMake 配置文件
│ └── dir2.c # dir2 子目录中的源文件
└── doc/ # 文档文件夹
├── README.md # 项目的文档
└── COPYRIGHT # 项目的版权信息
- dir1中CMakeLists.txt
```makefile加载所有的源码,和makefile wildcard类似
AUX_SOURCE_DIRECTORY(. DIR_SRCS)
#AUX_SOURCE_DIRECTORY 是一个特殊的 CMake 命令,用于在指定目录中查找所有源代码文件(如 .c 或 .cpp 文件),并将它们添加到 DIR_SRCS 变量中。DIR_SRCS 将包含当前目录下的所有源代码文件。
#在此示例中,DIR_SRCS 将包含 src/dir1 或 src/dir2 目录下的所有源文件。
SET(DIR_SRCS dir1.c dir12.c)
默认是静态库
ADD_LIBRARY (dir1 SHARED ${DIR_SRCS})
ADD_LIBRARY (dir1 ${DIR_SRCS})
2. dir2中CMakeLists.txt
```makefile
AUX_SOURCE_DIRECTORY(. DIR_SRCS)
ADD_LIBRARY(dir2 ${DIR_SRCS})
#同上
- src中的CMakeLists.txt
```makefile单个目录实现
CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)工程
PROJECT(HIT)手动加入文件
SET(SRC_LIST main.c)
MESSAGE(STATUS "THIS IS BINARY DIR " ${PROJECT_BINARY_DIR})
#PROJECT_BINARY_DIR 是 CMake 内置的变量,表示二进制文件(即构建文件)所在的路径。
MESSAGE(STATUS "THIS IS SOURCE DIR " ${PROJECT_SOURCE_DIR})
#PROJECT_SOURCE_DIR 是 CMake 内置的变量,表示源代码目录的路径。
添加头文件路径
#CMAKE_CURRENT_SOURCE_DIR 是 CMake 内置的变量,表示当前 CMake 配置文件所在的目录。
INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/dir1")
相对路径的方式
INCLUDE_DIRECTORIES(dir1)
MESSAGE(STATUS "CMAKE_CURRENT_SOURCE_DIR -> " ${CMAKE_CURRENT_SOURCE_DIR})
添加 dir1 子目录
ADD_SUBDIRECTORY("${CMAKE_CURRENT_SOURCE_DIR}/dir1")
添加头文件路径
INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/dir2")
添加 dir2 子目录
ADD_SUBDIRECTORY("${CMAKE_CURRENT_SOURCE_DIR}/dir2")
ADD_EXECUTABLE(li ${SRC_LIST} )# 创建一个可执行文件li
TARGET_LINK_LIBRARIES(li dir1 dir2)
#将库文件链接到可执行文件。此处将 dir1 和 dir2 库链接到 li可执行文件。这样,lili就可以使用 dir1 和 dir2 中定义的函数和符号。
将执行文件安装到bin目录
INSTALL(TARGETS li RUNTIME DESTINATION bin)
4. 整体CMakeLists.txt
```makefile
# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)
PROJECT(0VOICE)
ADD_SUBDIRECTORY(src)
# FILES代表文件
# DIRECTORY 代表目录
# INSTALL(FILES README.md COPYRIGHT DESTINATION share/doc/cmake/0voice)
INSTALL(DIRECTORY doc/ DESTINATION share/doc/cmake/0voice)
3. 动态库,静态库,调用
- 项目目录结构
MyProject/ ├── CMakeLists.txt # 根目录 CMake 配置文件 ├── lib1/ # 第一个子目录,生成静态库 │ ├── CMakeLists.txt # lib1 子目录的 CMake 配置文件 │ └── lib1.cpp # lib1 的源文件 ├── lib2/ # 第二个子目录,生成动态库 │ ├── CMakeLists.txt # lib2 子目录的 CMake 配置文件 │ └── lib2.cpp # lib2 的源文件 └── main.cpp # 主源文件,链接到 lib1 和 lib2 - 根目录 CMakeLists.txt
根目录的 CMakeLists.txt 文件负责设置基本的 CMake 配置,添加子目录,并定义最终的可执行文件。
```makefile
cmake_minimum_required(VERSION 3.10)
项目名称和支持的语言
project(MyProject)
设置 C++ 标准
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
添加 lib1 和 lib2 子目录
add_subdirectory(lib1)
add_subdirectory(lib2)
添加可执行文件,main.cpp 是根目录下的源文件
add_executable(my_app main.cpp)
链接静态库 lib1 和动态库 lib2 到最终可执行文件
target_link_libraries(my_app PRIVATE lib1 lib2)
3. lib1/CMakeLists.txt (生成静态库)
在 lib1 目录中,创建一个静态库(lib1.a)。
```makefile
# lib1 的 CMake 配置文件
# 查找 lib1 目录下的所有源文件
set(LIB1_SRC lib1.cpp)
# 创建静态库 lib1
add_library(lib1 STATIC ${LIB1_SRC})
# 如果有头文件目录需要添加,可以在这里使用 INCLUDE_DIRECTORIES
# 例如:INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/include")
- lib2/CMakeLists.txt (生成动态库)
在 lib2 目录中,创建一个动态库(lib2.so 或 lib2.dll)。
# lib2 的 CMake 配置文件
# 查找 lib2 目录下的所有源文件
set(LIB2_SRC lib2.cpp)
# 创建动态库 lib2
add_library(lib2 SHARED ${LIB2_SRC})
# 如果有头文件目录需要添加,可以在这里使用 INCLUDE_DIRECTORIES
# 例如:INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/include")
- main.cpp (主程序)
这是项目的主源文件,使用 lib1 静态库和 lib2 动态库。
#include <iostream>
#include "lib1.h" // 假设 lib1 提供了一个 lib1.h 头文件
#include "lib2.h" // 假设 lib2 提供了一个 lib2.h 头文件
int main() {
std::cout << "Hello from main!" << std::endl;
// 使用 lib1 和 lib2 中的函数
lib1_function();
lib2_function();
return 0;
}
4. 设置执行目录,并为 ZLToolKit 工程创建 Debug 和 Release 版本的构建配置
- 项目结构
假设项目结构如下:ZLToolKit/ ├── CMakeLists.txt # 根目录 CMake 配置文件 ├── src/ # 源代码目录 │ ├── CMakeLists.txt # src 子目录的 CMake 配置文件 │ ├── lib1.cpp # lib1 的源文件 │ ├── lib2.cpp # lib2 的源文件 │ └── main.cpp # 主程序 └── build/ # 用于构建的目录(运行 CMake 和 make 时生成) - 根目录 CMakeLists.txt
在根目录的 CMakeLists.txt 文件中,我们会设置工程的基本配置,处理不同的构建类型(Debug 和 Release),并设置执行文件的输出路径。
cmake_minimum_required(VERSION 3.10)
# 设置项目名称
project(ZLToolKit)
# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
# 设置调试debug和发布release版本的输出目录
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/debug_bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/release_bin)
# 添加 src 子目录
add_subdirectory(src)
# 设置构建类型:如果没有指定,默认是 "Release"
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
endif()
# 打印出当前的构建类型
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
- src/CMakeLists.txt
src/CMakeLists.txt 文件将会处理源代码的编译,并生成最终的可执行文件或库。
# src 子目录的 CMake 配置文件
# 设置源文件
set(SRC_LIST main.cpp lib1.cpp lib2.cpp)
# 创建可执行文件
add_executable(ZLToolKitApp ${SRC_LIST})
# 设置调试和发布版本的编译选项
target_compile_options(ZLToolKitApp PRIVATE
"$<$<CONFIG:Debug>:-g>"
"$<$<CONFIG:Release>:-O3>"
)
#target_compile_options 用于指定目标(ZLToolKitApp)的编译选项。PRIVATE 表示这些编译选项只对目标 ZLToolKitApp 有效。
#$<$<CONFIG:Debug>:-g>:这表示如果构建类型是 Debug,则编译时添加 -g 选项,通常用于生成调试符号。
#$<$<CONFIG:Release>:-O3>:这表示如果构建类型是 Release,则编译时添加 -O3 选项,通常用于优化代码(更高的优化级别)。
#target_compile_options 是通过 generator expressions 来动态选择不同的编译选项。$<$<CONFIG:Debug>:-g> 是 CMake 的条件语法,意思是,如果当前构建类型是 Debug,则使用 -g 选项。
# 设置 CMake 自动选择链接库和头文件
target_include_directories(ZLToolKitApp PRIVATE ${CMAKE_SOURCE_DIR}/include)
# 根据构建类型设置不同的链接库
target_link_libraries(ZLToolKitApp PRIVATE
"$<$<CONFIG:Debug>:/path/to/debug/lib>"
"$<$<CONFIG:Release>:/path/to/release/lib>"
)
- src/main.cpp
这是项目的主源文件,它会调用 lib1 和 lib2 中的功能。
#include <iostream>
#include "lib1.h" // 假设 lib1 提供了一个 lib1.h 头文件
#include "lib2.h" // 假设 lib2 提供了一个 lib2.h 头文件
int main() {
std::cout << "Hello from ZLToolKit!" << std::endl;
// 使用 lib1 和 lib2 中的函数
lib1_function();
lib2_function();
return 0;
}
- 构建
首先在根目录创建一个构建目录,并切换到该目录:
mkdir build cd build生成构建文件
运行 CMake 配置命令:cmake ..这时 CMake 会根据 CMakeLists.txt 配置文件生成 Makefile(或适用于系统的构建文件)。
构建项目
然后运行 make 来编译项目:makeCMake 会根据所选择的构建类型(Debug 或 Release)进行编译。如果没有手动指定构建类型,默认是 Release。
调试版本 vs 发布版本
CMake 会自动根据 CMAKE_BUILD_TYPE 变量切换到 Debug 或 Release 配置:
Debug 版本:会添加 -g 编译选项生成调试符号,并将输出文件放在 ${CMAKE_BINARY_DIR}/debug_bin 目录中。
Release 版本:会添加 -O3 编译选项进行优化,并将输出文件放在 ${CMAKE_BINARY_DIR}/release_bin 目录中。
例如,要生成 Debug 版本,执行:
cmake -DCMAKE_BUILD_TYPE=Debug ..
make
或者,要生成 Release 版本:
cmake -DCMAKE_BUILD_TYPE=Release ..
make
- 输出目录
在构建完成后,Debug 版本的可执行文件将位于 build/debug_bin/ 目录中,而 Release 版本的可执行文件将位于 build/release_bin/ 目录中。


