linux下写CMakeLists.txt以及json调试配置文件的学习总结(很重要)
一般而已,一个Cpp项目我们都不是直接用g++编译器去编译的话,因为这样干不通用,而且遇到稍微大型点的项目手写g++命令行是件很复杂的事情。因此,我们必须要手写CMakeLists.txt去再使用cmake命令来生成对应的MakeFile来帮助我们编译器源文件和链接头文件产生可执行程序。cmake_minimum_required(VERSION X.X.X) #指定项目使用的cmake的最低要求
一、解释为什么用CMake
一般而已,一个Cpp项目我们都不是直接用g++编译器去编译的。因为这样干不通用,而且遇到稍微大型点的项目手写g++命令行是件很复杂的事情。
因此,我们必须要手写CMakeLists.txt去再使用cmake命令来生成对应的MakeFile来帮助我们编译源文件和链接头文件进而再用make命令产生可执行文件。
注意①:当然,cmake的底层还是帮我们使用gcc + -lstdc++ 或者 g++来做编译链接工作的!
注意②:CMakeLists.txt用写好之后,用cmake命令生成一次makefile即可。后面若你还修改了.h头文件或者.cpp源文件的话,可以直接在linux终端下用make命令生成新的可执行文件即可!
这样的一个好处就是,当你的Cpp项目很大时,有几百上千个.cpp源文件和.h头文件,若你只修改了某个.cpp or .h头文件的话,就不需要再使用g++重新编译链接了,这样会耗费大量的时间,改一次就得重新build一次,效率可太低了!你只需要再用make命令去生成对应的新的可执行文件即可!哪儿改了就从哪儿重新编译而已!
比如:
//xusanduo.cpp中的代码:
Xusanduo::~Xusanduo(){
cout<<"hhhwolail!"<<endl;
}
//变成
Xusanduo::~Xusanduo(){
cout<<"hhh"<<endl;
}

二、介绍写CMakeLists.txt的一般格式:
cmake_minimum_required(VERSION X.X.X) #指定项目使用的cmake的最低要求的版本
#在linux终端下可用 cmake --version来查看对应当前系统下的cmake版本
project(Project_Name) #生成的项目的名字(英文)这个一般你自定义即可!
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall ") #这行代码是给
#项目程序如果是为了进行调试而编译时, 必须要打开调试选项 (-g)。另外还有一些可选项,比如:在尽量不
#-g 选项的作用:是在可执行文件中加入源代码的信息,比如可执行文件中第几条机器指令对应源代码的第几
#行,但并不是把整个源文件嵌入到可执行文件中,所以在调试时必须保证 gdb 能找到源文件。
#-o2 选项的作用:开启优化代码的选项(一般不要加这个选项,因为不利于debug调试)
#-o0 选项的作用:当影响程序运行的行为的情况下,关掉编译器的优化选项
#-Wall 选项的作用:打开所有 warning,即可以发现许多警告问题,避免一些不必要的 bug。
include_directories(${CMAKE_SOURCE_DIR}/include) # or include_directories(./include)
#这行命令代码用来包含头文件
#()里面是添加能找到include这个文件在你的linux系统下的相对路径/绝对路径
#当然,我用${CMAKE_SOURCE_DIR}这个变量来写就代表是取include文件夹的绝对路径
#当然,左边这种是万能写法!写左边的include_directories(${CMAKE_SOURCE_DIR}/include)比较稳妥!
#一般而言,我们都把头文件都放在一个叫include的文件夹中 然后用这个cmake命令include进项目
#且一般我们都把源文件放在一个叫src的文件夹中,把头文件放在一个叫include的文件夹中
#创建一个叫build的文件夹,把生成的关于makefile相关的all文件都放在里面
#并在$ ...XXX/build的目录下 用命令行:$cmake .. 来生成对应的makefile文件
# 用命令行:$make 生成可执行文件,这样你的程序就可以运行了!
#(因为我们一般都是把CMakeLists.txt、include、src、build这4东西放在同级目录下)
#. or ./ 表示当前本级目录
#.. or ../ 表示当前本级的上一级目录
#这样这行命令可以直接写为include_directories( ./include) or include_directories(include)
#这就是写Cpp项目的一般代码管理规范
set(CMAKE_BUILD_TYPE Debug)
#设置编译类型为 Debug,当你的程序要发布出去时,可以改Debug为Release
add_executable(Project_Exe_Name main.cpp src/X1.cpp src/X2.cpp ... src/Xn.cpp)
#这行命令代码用来将源文件生成可执行文件
# ==> g++ main.cpp src/X1.cpp src/X2.cpp ... src/Xn.cpp -o Project_Exe_Name
无注释版CMakeLists.txt一般必写的几行命令代码:(写一般项目都可以直接套用)
cmake_minimum_required(VERSION X.X.X)
project(Project_Name)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall")
set(CMAKE_BUILD_TYPE Debug)
include_directories(${CMAKE_SOURCE_DIR}/include)
add_executable(Project_Exe_Name main.cpp src/X1.cpp src/X2.cpp ... src/Xn.cpp)
具体例子:
(案例的代码在我的这篇博客中):为多态基类定义纯虚析构函数时必须给其一个空实现代码
当前的CMakeLists.txt:
cmake_minimum_required(VERSION 3.0.0)
project(SOLDIER_TUJI)
set(CMAKE_BUILD_TYPE Debug)
include_directories(${CMAKE_SOURCE_DIR}/include)
add_executable(TUJI_cmake main.cpp src/gun.cpp src/soldier.cpp src/xusanduo.cpp)
注意:不论是在windows下还是在linux下,当你按照我上述说的文件目录方式来组织文件后,一定要在build这个文件夹下去做cmake ..和make命令!!!
注意:不论是在windows下还是在linux下,当你按照我上述说的文件目录方式来组织文件后,一定要在build这个文件夹下去做cmake ..和make命令!!!
注意:不论是在windows下还是在linux下,当你按照我上述说的文件目录方式来组织文件后,一定要在build这个文件夹下去做cmake ..和make命令!!!
注意:不论是在windows下还是在linux下,当你按照我上述说的文件目录方式来组织文件后,一定要在build这个文件夹下去做cmake ..和make命令!!!
注意:不论是在windows下还是在linux下,当你按照我上述说的文件目录方式来组织文件后,一定要在build这个文件夹下去做cmake ..和make命令!!!
注意:不论是在windows下还是在linux下,当你按照我上述说的文件目录方式来组织文件后,一定要在build这个文件夹下去做cmake ..和make命令!!!
注意:不论是在windows下还是在linux下,当你按照我上述说的文件目录方式来组织文件后,一定要在build这个文件夹下去做cmake ..和make命令!!!
注意:不论是在windows下还是在linux下,当你按照我上述说的文件目录方式来组织文件后,一定要在build这个文件夹下去做cmake ..和make命令!!!
重要的事情说8遍!!!
执行cmake命令后:

执行make命令后:
(make是linux下的编译命令。如果你是在windows下使用vscode编译cpp文件的话,就在终端用mingw32-make.exe命令来do即可)

经过make后,成功built目标可执行文件 TUJI_cmake!
执行TUJI_cmake这个可执行文件:

添加了这行cmake命令前,再main.cpp中添加测试代码:
int main(void){
int a{1};//test codes
//...
return 0;
}
添加了set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -o2") 这行cmake命令后:
当前的CMakeLists.txt:
cmake_minimum_required(VERSION 3.0.0)
project(SOLDIER_TUJI)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall")
set(CMAKE_BUILD_TYPE Debug)
include_directories(${CMAKE_SOURCE_DIR}/include)
add_executable(TUJI_cmake main.cpp src/gun.cpp src/soldier.cpp src/xusanduo.cpp)
终端命令执行结果:

会提示我们,a这个int型变量根本就没有使用过!这很利于我们发现项目代码中的问题!
(若你再CMakeLists.txt中不加-Wall选项来do编译的话根本就不会显示出来这个warning的信息!)
三、介绍写json调试配置文件的一般格式:
在写cpp项目时,除了要写CMakeLists.txt来帮助我们生成makefile文件以供我们make编译外,还需要添加2份便于调试的json文件,分别是launch.json和tasks.jason。这2个文件也是我们使用Vscode时最容易被卡住的配置文件!但是这2个文件对于你项目的debug来说非常重要!!!
注意:json文件再Vscode中默认是会给你自动放在一个叫做.vscode的文件夹中的!

注意:其实配置好launch.json文件就可以在linux下的vscode中按F5进行调试程序了,但是如果你想要在调试时边改动代码边按F5进行调试的话,就必须要配置好tasks.json文件! (抄着写即可)
①lauch.json(use for debug):
lauch.json中最为关键的2行代码就是:(配置lauch.json时着重关注这2条)
"program":...
"preLaunchTask":...
launch文件一般只需要改动2个地方:
①"program": "${workspaceFolder}/build/你的项目名称.exe",改成你的项目的名称
②"miDebuggerPath": "/usr/bin/gdb"这个gdb调试器文件目录一般是不用改的。因为你在linux下用命令行安装gdb时默认是装在这里的。
下面我直接给出一般写法(带注释版本):
{
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) 启动",
"type": "cppdbg",
"request": "launch",
//fill the absolutely path of your project
"program": "${workspaceFolder}/build/main_cmake",
//注释:
//这行代码是写上你的项目经过cmake和make后生成的可执行文件的绝对路径
//如果你按照我上述所说的创建和管理Cpp项目的一般规则,可知道
//我们一般都是使用外部构建cmake的方式来编译项目文件的
//也即创建一个叫做build的文件夹来存放cmake和make后产生的all文件
//(这其中就包括make后产生的你这个项目的可执行文件)
//这样你就可以直接在"program"这里写上"${workspaceFolder}/build/项目可执行文件名"
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "为 gdb 启用整齐打印",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask":"Build",
//在你调试debug前帮你自动build!lauch前先取执行label == Build的tasks任务!
//这样你就不需要每次debug改动代码时再执行一次make命令就能看到debug效果了!
//因为此时你配置好的launch和tasks这2个json文件可以帮你调试时自动编译一次代码
//(if你在调试代码时有修改的话)
"miDebuggerPath": "/usr/bin/gdb"
//这个gdb调试器文件目录一般是不用改的
//因为你在linux下用命令行安装gdb时默认是装在这里的
}
]
}
一般写法(不带注释版本):(写一般项目都可以直接套用)
{
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) 启动",
"type": "cppdbg",
"request": "launch",
//fill the absolutely path of your project
"program": "${workspaceFolder}/build/your_project_exe_name",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "为 gdb 启用整齐打印",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask":"Build",
"miDebuggerPath": "/usr/bin/gdb"
}
]
}
②tasks.json(use for build before debug):
一般无需改动,直接copy来用即可,只要你按照我这篇博客中说的项目文件目录的设置规则
有了tasks.json文件后,你就不需要在每一次调试改动了代码时都手动输入make命令再编译你最新的cpp文件生成最新的可执行文件了,这样就非常方便你去do调试的工作了!
下面我直接给出一般写法(带注释版本):
{
"version": "2.0.0",
"options": {
"cwd": "${workspaceFolder}/build"//这里写的是build文件的绝对路径
//只要你按照我上述所说的管理Cpp文件的一般规则,这里直接这样写就行!
//意思是:当前你的项目文件夹下的build文件夹的路径
},
"tasks": [
{
"type": "shell",
"label": "cmake",
"command": "cmake",
"args": [
".."
],
},
{
"label": "make",
"group": {
"kind": "build",
"isDefault": true
},
"command": "make",
"args": [
],
},
{
"label": "Build",
//这里的Build文件与lauch.json文件中的"preLaunchTask":"Build" 中的
//这个Build是指的一个Build文件夹!
"dependsOrder": "sequence",//按照一列来执行
"dependsOn":[
"cmake",
"make"
]
}
],
}
一般写法(不带注释版本):(写一般项目都可以直接套用)
{
"version": "2.0.0",
"options": {
"cwd": "${workspaceFolder}/build"
},
"tasks": [
{
"type": "shell",
"label": "cmake",
"command": "cmake",
"args": [
".."
],
},
{
"label": "make",
"group": {
"kind": "build",
"isDefault": true
},
"command": "make",
"args": [
],
},
{
"label": "Build",
"dependsOrder": "sequence",
"dependsOn":[
"cmake",
"make"
]
}
],
}
好了,当你的Cpp项目配置好CMakeLists.txt、include、src、build、lauch.json、tasks.json文件之后,就可以方便放心的编译运行和调试你的程序了!
以上就是我对于写CMakeLists.txt以及json调试配置文件的学习总结,写这篇博客是为了方便自己日后coding时候查漏补缺,希望也对看到这里的读者起到一点点的帮助~
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐

所有评论(0)