[Linux][VS code][C++]:g++编译过程和使用,gdb调试
理论过程
第一步:.cpp → .i 指令选项-E
第二步:.i → .s 是汇编文件 指令选项-S
第三步:.s → .o 此时已经算是目标文件的最终形态了,完整后缀是.obj 指令选项-c
第四步:通过链接器将用的到的库,如.dll和.o文件连接起来,执行.exe就是相当于执行前面连接起来的这堆文件,这个过程不需要指令选项,输出文件也不需要后缀
详细过程和G++调用参考:https://zhuanlan.zhihu.com/p/371323950
实际使用(g++)
一般来说可以一步到位编译成可执行文件(.o),注意-o表示output输出文件,而输出具体是哪个阶段的文件得看<源文件.cpp>前的参数,如-E就是预处理,-S就是编译,-c就是汇编,而不是-o就代表输出.o。
g++ <源文件.cpp> -o <输出文件名.o>
可以在-o前加入-O<n>表示优化代码,等级为n=1~3
连接头文件,一般来说如果默认使用/usr/include下的则不用管,如果所需.h在另外的文件夹如/code/abc,则需以当前路径为基准写进去
如当前在/code/src下编译,则
g++ test.cpp -I../abc -o output
因为需要回到上一级,再选择abc,所以是../
链接静态库文件
1. 生成静态库文件
1.1 生成目标文件,这里-c和-o的区别是-c不进行连接操作,只生成.o
g++ <源文件.cpp> -I<头文件> -c
1.2 归档到静态库文件.a
ar rs <lib归档文件> <.o文件>
2. 链接编译
g++ <源main文件.cpp> -I<头文件> -l<库名(不用后缀)> -L<路径(如果库不在同一目录)> -o <输出文件名>
**2.1 如果归档文件不以lib为前缀(当然最规范的还是得lib作为前缀),则直接写上完整路径,不用-l和-L
g++ <源main文件.cpp> -I<头文件> <绝对路径> -o <输出文件名>
参考:https://blog.csdn.net/u011461385/article/details/90482574
链接动态库文件
1. 生成动态库文件
g++ <源文件.cpp> -I<头文件> -fPIC -shared -o <lib库.so>
其中-fPIC表示生成位置无关的代码,位置无关即在加载时不会固定在哪个内存,进而不会出现内存矛盾冲突的情况,这样才能使其具有动态性
-shared则是生成动态库的意思,动态库的后缀是.so
2. 链接编译
同静态库
3. 运行可执行文件,当动态库不在可执行文件所在目录下,则需要指定
LIB_LIBRARY_PATH=<路径> ./<可执行文件>
task.json文件的编写
task.json保存了一些任务信息,可以将任务先自定义在里面,然后在别处触发里面的某些任务。比如在task.json里定义了任务"build",然后在launch.json里设置preLaunchTask触发任务“build”,那么就会在调试之前先触发task.json里的build任务
首先创建task.json:terminal→configure default build task
label:任务名称,别处触发设置里名称写入和label一样的名称,使其能够找到并触发相应任务
type:任务命令类型,如shell则是使用shell命令
command:任务内容的命令语句
args:任务内容的参数语句
多任务task.json编写:
先定义需要执行的多个任务,然后再额外定义一个作为触发头,使用dependsOrder说明按照顺序执行,dependsOn列表按顺序写入任务label
如构建任务一般顺序是cmake .. 然后 make,那么定义了他们两个子任务后再定义一个任务build,然后按顺序写入cmake和make,如下
"label":"build"
"dependsOrder":"sequence" "dependsOn":["cmake","make"]
然后在launch.json的preLaunchTask设置为build,那么其会触发build任务,然后按顺序先触发cmake然后make
Launch.json文件
进行调试过程的一些设置
首先创建Launch.json,一般我是在run→add configuration→C/C++:(gdb) Launch
program是要调试的可执行文件,一般是同步下面的"cwd"的目录,然后再加上相对路径得到绝对路径
preLaunchTask就如上一个小节里设置task的label,但如果是手动完成构建编译等过程,则可以直接注释掉preLaunchTask这一行