CMake使用

makefile依赖于不同编译平台,CMake可以跨平台。通过编写CMakeLists.txt文件,执行cmake命令,就可以自动生成对应平台的makefile文件,再执行命令make就能进行编译

语法

变量使用${}取值,if语句中直接使用变量名
指令格式为:指令(参数1 参数2),指令大小写无关,参数和变量大小写相关

基本指令

  1. cmake_minimum_required(版本):指定cmake所需最低版本
  2. project(工程名字 支持语言):指定工程名字
  3. set(变量 变量值)
    • 设置一个变量
    # 该add_executable(mytest main.c func.c)可变为
    set(src_list mytest main.c func.c)
    add_executable(mytest ${src_list})
    
    • 指定c++标准set(CMAKE_CXX_STANDARD 11)//使用c++11标准
    • 指定可执行程序的输出路径set(EXECUTABLE_OUTPUT_PATH 项目的路径/bin)
  4. message(信息类型 自定义信息):向用户终端输出自定义信息,用于调试,信息类型包含三种:
    • SEND_ERROR:产生错误,生成过程被跳过
    • STATUS:输出前缀为--的信息
    • FATL_ERROR:立即终止cmake过程
  5. add_executable(生成可执行文件名 源文件名称):生成可执行程序

例子
有如下文件,都在同一目录src中:head.h,main.c,func.c
在目录下添加一个新文件CMakeLists.txt,文件内容如下:

cmake_minimum_required(VERSION 3.0)
project(test)
add_executable(mytest main.c func.c)

执行cmake该录下生成了一个makefile文件,此时再执行make,就得到所需的可执行程序了mytest

外部构建与内部构建
上面的例子是外部构建,外部构建产生很多临时文件,清理麻烦
内部构建:新建文件夹build,在build目录下执行cmake .. 所有的临时文件都放在这个目录下

工程的基本结构
src:存放源代码
lib:存放库文件
include:存放头文件
build:cmake产生的临时文件
bin:编译生成的二进制文件
doc:存放工程文档
.sh脚本:来调用生成的二进制文件
CMakeLists文件:根目录要通过ADD_SUBDIRECTORY指定src与bin
COPYRIGHT
README

搜索文件

如果一个项目里边的源文件很多,将项目目录的各个文件罗列出来太麻烦。可以使用aux_source_directory命令或者file命令,将文件名都保存在一个变量中

# 将目录下搜索到的源文件列表存储到SRC_LIST变量中
# PROJECT_SOURCE_DIR是一个宏,是cmakelists.txt文件所在的目录
aux_source_directory(${PROJECT_SOURCE_DIR}/src SRC_LIST)
add_executable(app ${SRC_LIST})

头文件可能不在源文件当前目录,需将头文件路径指定出来,使编译器能够找到这些头文件include_directories(头文件目录)

静态库和动态库

windows中静态库后缀是.lib,动态库后缀是.dll
linux中静态库后缀是.a,动态库后缀是 .so

创建静态库和动态库
ADD_LIBRARY(生成库名 库类型 源代码文件)库类型有SHARED动态库 STATIC静态库

ADD_LIBRARY(hello_static STATIC hello.cpp)
ADD_LIBRARY(hello SHARED hello.cpp)

设置动态库/静态库输出路径set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

加载静态库和动态库
要加载库,需要有库文件和头文件

加载静态库link_libraries(多个库文件名)
加载动态库或者静态库target_link_libraries(需要链接库的文件 链接权限PRIVATE|PUBLIC|INTERFACE 库名)

对于系统提供的库,只要提供名字就可以找到库文件,其它库(非标准库),就需要指定库文件的路径link_directories(库文件路径)
另外还可以改变系统的环境变量来指定搜索路径CMAKE_INCLUDE_PATH(头文件目录),CMAKE_LIBRARY_PATH

自定义宏

add_definitions(-D宏名称)
可以在代码中添加一些宏定义,通过这些宏来控制这些代码是否生效

int main()
{
    int a = 10;
#ifdef DEBUG
    printf("debug\n");
#endif
}

在程序中对DEBUG宏进行了判断,如果该宏被定义了,就会进行日志输出,如果没有定义就相当于被注释掉了。为了让测试更灵活,可以不在代码中定义这个宏,而是在测试的时候去把它定义出来,就可以在CMake中定义宏

嵌套CMake

有时候如果只使用一个CMakeLists.txt,那么这个文件相对会比较复杂,可以给每个源代码目录都添加一个CMakeLists.txt 文件。所以在父目录的CMakeLists.txt文件中就需要指明子目录的位置add_subdirectory(源代码子目录)

安装库与头文件

使用CMake构建一个项目时,通常会生成库文件(如静态库或动态库)以及一些公共的头文件。这些库文件和头文件通常位于构建目录下,如果希望其他项目或用户能够方便地使用这些库和头文件,需要安装库与头文件。
通过在CMakeLists.txt文件中install命令,可以将库文件和头文件复制到指定的安装目录。

# 构建库
add_library(mylib SHARED mylib.cpp)
# 指定安装目录
install(TARGETS mylib DESTINATION /usr/local/lib)
install(FILES mylib.h DESTINATION /usr/local/include)

首先使用add_library命令构建一个名为mylib的共享库,它的源文件为mylib.cpp。然后,使用install命令指定要安装的目标(mylib)和目标位置(/usr/local/lib)。这将把mylib库文件复制到系统的/usr/local/lib目录中。同时,使用install命令将mylib.h头文件复制到系统的/usr/local/include目录中,以便其他项目或用户可以通过包含该头文件来访问库的接口。
安装库和头文件后,其他项目或用户就可以在其CMakeLists.txt文件中使用target_link_libraries命令来链接这个已安装的库,并通过#include语句来引用安装的头文件。

参考链接

CMake 保姆级教程及对应视频CMake 保姆级教程【C/C++】
从零开始详细介绍CMake
软件构建: CMake 快速入门

GDB使用

list 查看当前程序内容
b 行号/函数名 打断点
r 运行程序
n 下一步
s 步入函数
c 继续执行
watch 设置观察点,当观察的内容变化时自动中断,只能在程序运行时设置
p 打印变量值
info b/watchpoints 查看设置的断点/观察点

shell shell命令 使用shell命令
set logging on 开启日志,将输出内容存放在文件中

gdb 文件 core文件 调试core文件

gdb -p pid 调试运行的程序

checkpoint 生成快照,会返回一个新进程的pid
info checkpoints 显示快照,可以看到快照id
restart 快照id 恢复快照
delete checkpoint 快照id 删除快照

posted @ 2023-07-13 17:35  启林O_o  阅读(38)  评论(0编辑  收藏  举报