1、简易:
cmake_minimum_required ( VERSION 2.8)//确定cmake最低版本
project ( learn_cmake CXX) //项目名称和编译语言
add_executable (hello hello.cpp)
注意:变量的使用和Makefile不同,CMake是利用大括号,如${SRC_LIST}
2、多个源文件
cmake_minimum_required ( VERSION 2.8)//确定cmake最低版本
project ( learn_cmake CXX) //项目名称和编译语言,C++使用CXX, C语言使用C
aux_source_directory(. SRC_LIST) //将dir(.)目录中的所有源文件都存储在var变量中
set(CMAKE_CXX_STANDARD ...) //设置编译语言版本
add_executable (hello ${SRC_LIST})
3、头文件在别的文件夹
include_directories(dir)//自动去其他文件夹寻找头文件
4、头文件和源文件分离:
#引入头文件
Include_directories(./inc_dir1 ./inc_dir2)
#获源文件
aux_source_directory( src_dir1 SRC_LIST1)
aux_source_directory( src_dir2 SRC_LIST2)
aux_source_directory( main_dir MAIN_DIR)
#生成可执行文件。
add_executable(hello ${SRC_LIST1} ${SRC_LIST2} ${MAIN_DIR} )
一个CMakeLists.txt文件。
解释一下:
PROJECT_BINARY_DIR是cmake系统变量,意思是执行cmake命令的目录,我们计划在build目录下执行cmake命令,所以这个变量也就等同于build目录
生成命名存放库文件,add_library,set_target_properties函数,LIBRARY_OUTPUT_PATH 系统变量使用set该白你
add_library(lib_name STATIC/SHARED src) //添加动态库,指定生成静态库或动态库。src:源文件
函数作用:生成库。
参数lib_name:是要生成的库名称,文件为liblib_name.so 或者liblib_name.a(静态库)。
参数STATIC/SHARED:指定生成静态库或动态库,
参数src:指明库的生成所需要的源文件
set_target_properties重新定义了库的输出名称,如果不使用set_target_properties也可以,那么库的名称就是add_library里定义的名称。具体可以参考官方文档。
LIBRARY_OUTPUT_PATH 是cmake系统变量,项目生成的库文件都放在这个目录下。这里我指定库生成到lib目录。 开始编译
在build目录下执行 cmake .:根据CMakeLists.txt构建生成makefile。
在build目录下执行 make :使用makefile构建可执行程序。
查看lib目录下是否生成库文件。
出现库文件就算编译成功
七、链接库文件
EXECUTABLE_OUTPUT_PATH 是cmake系统变量,意思是生成的可执行文件的目录,这里把他改为bin目录,因此设生成的可执行文件会出现在bin目录中。
find_library(var lib_name lib_path1 lib_path2)
函数作用:查找库,并把库的绝对路径和名称存储到第一个参数里
参数var:用于存储查找到的库
参数lib_name:想要查找的库的名称,默认是查找动态库,想要指定查找动态库或静态库
可以加后缀,例如 funcname.so 或 funcname.a
参数lib_path:想要从哪个路径下查找库,可以指定多个路径
target_link_libraries(target lib_name)
函数作用:把库lib_name链接到target可执行文件中
八、添加编译选项:
add_compile_options(-std=c++11,-wall, -O2)
程序启动流程:
1) 加载可执行文件
操作系统首先将可执行文件加载到内存中。
这包括读取可执行文件的头部信息(如 ELF 文件头)以及分配内存空间。
(2) 解析动态链接器
如果可执行文件依赖动态库(
.so
或.dll
),操作系统会调用动态链接器(如 Linux 上的/lib64/ld-linux-x86-64.so.2
)。动态链接器负责加载所有所需的动态库,并将它们映射到进程的地址空间中。
(3) 符号解析与重定位
动态链接器会解析动态库中的符号表,找到程序中引用的函数和变量,并将它们与动态库中的实现关联起来。
这一过程称为 符号解析 和 地址重定位。
(4) 运行全局构造函数
在 C++ 中,如果存在全局对象或静态对象,它们的构造函数会在
main()
函数之前被调用。这些构造函数的代码可能也依赖于动态库,因此需要在动态库加载完成后才能执行。
(5) 调用 main()
函数
完成上述所有准备工作后,控制权才会转移到
main()
函数,程序的逻辑才开始执行。
核心就是目标和依赖。
使用vscode配合构建并调试:
1、核心就是launch.json指定可执行文件,如果需要构建的话:pretask指定task.json文件的任务。tasks.json中需要指定构建命令,自己可以选择makefile,或者CMAKE的命令行,或者直接gcc 指定参数等等。