C++ Makefile / Cmake 构建工程 & GDB调试

Table of Contents

一、基础知识

1.1 编译器

1.2 编译四步

1.3 链接

二、MAKE

2.1 指定头文件路径

2.2 指定链接库

2.3 编译源文件

三、CMAKE

3.1 编译源文件

3.2 加入头文件 & 链接库文件

a) 加入头文件

b) 引入可执行文件

c) 链接库文件

3.3 生成库文件

3.4 其他常用命令

四、GDB调试

4.1 配置gdb调试模式

4.2 gdb断点调试命令

4.3 gdb查看Coredump

 


一、基础知识

1.1 编译器

  • gcc: gnu的C编译器
  • g++:gnu的C++编译器。

对于简单工程,使用编译器直接在terminal中进行编译:

g++ main.cpp -o main  //main.cpp为需要编译的源文件, [-o main]为输出文件名。
g++ main.cpp -o main `pkg-config --cflags --libs opencv`  //使用pkg-config命令输出opencv的INCLUDE(--cflags)和LIBSPATH(--libs)

对于更复杂的工程,可以直接编写makefile后进行make, 或者使用cmake工具生成makefile,然后再make编译。

1.2 编译四步

  1. 预处理Pre-processing:把头文件写入cpp,生成.i的文档;   (预处理器cpp)
  2. 编译Compiling:检查语法错误,把代码翻译成汇编语言,生成文档.s; (编译器egcs) 
  3. 汇编Assembling:把编译生成的.s文件转为目标文件,生成.o的文档,即二进制的机器代码;(汇编器as) 
  4. 链接Linkling:将每个cpp文件生成的.o文件以及函数库链接在一起,生成可执行文件 。C++支持分离式编译,对源文件分别编译成目标文件,再链接生成可执行文件。(链接器ld,即linker eDitor)

参考链接:俊华的博客:GCC 编译详解liuchao1986105的博客:gcc编译选项

1.3 链接

这里着重讲一下链接。

函数库一般静态库(.a文件)和动态库(.so文件)

  • 静态库在编译链接时,把库文件的代码全部加入可执行文件中,运行时无需库文件,但生成的文件比较大;
  • 动态库在编译链接时不把库文件的代码加入到可执行文件中,而在程序执行时由运行时的链接文件加载库。这样的优点是:a. 不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,规避了空间浪费问题;  b. 如果静态库更新了,所以使用它的应用程序都需要重新编译、发布给用户;而动态库在程序运行是才被载入,用户只需要更新动态库即可,增量更新。

gcc在编译时默认使用动态库。

链接动态库有四种方法:

a) 动态库添加到/lib或者/usr/lib文件夹中,系统会默认搜索这些路径;

b) 每次运行程序前,临时将动态库所在的路径添加到环境变量LD_LIBRARY_PATH中,例如:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:TensorRT-5.1.5.0/lib

    此时,如果打开一个新的终端,则在之前的终端中添加的LD_LIBRARY_PATH无效。

c) 在配置文件中bashrc, /etc/profile或者/etc/ld.so.conf中添加动态链接库路径,例如:

sudo gedit ~/.bashrc

  在文件末尾加入

export LD_LIBRARY_PATH=/home/yly/Software/TensorRT-5.1.5.0/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}

 可以通过如下命令查看LD_LIBRARY_PATH:

echo $LD_LIBRARY_PATH

d) 在Cmake或makefile中添加libspath。

参考链接: 阿进的写字台的博客:运行时动态库

接下来分别介绍cmake和makefile的使用方法。

二、MAKE

对于简单的、文件比较少的工程,直接编写makefile,逻辑清晰可控。

GNU make的官方使用说明:http://www.gnu.org/software/make/manual/make.html

2.1 指定头文件路径

INCLUDE = -I $(OPENCV_ROOT)/include 

其中, -I表示将$(OPENCV_ROOT)/include作为第一个寻找头文件的目录,如果找不到,会搜索系统默认路径。

2.2 指定链接库

LIBSPATH= -L/usr/local/lib -lopencv_imgcodecs 

其中,-L表示将/usr/local/lib设为第一个寻找库文件的目录;-lopencv_imgcodecs表示在该路径中寻找libopencv_imgcodecs.so动态库文件。

2.3 编译源文件

2.3.1 语法规则

target … : prerequisites …
        recipe
        …

Makefile中清晰地指明了生成的目标文件名(target),目标文件的所有依赖文件(prerequisites),和生成规则(recipe)。

注意:recipe前要为<TAB>。

2.3.2 使用cpp生成 .o 文件,例如:

target.o:source.cpp
    g++ $(INCLUDE) -c source.cpp  -o target.o

使用g++编译器;

recipe中的$(INCLUDE)指定的是搜索cpp中#include包含的头文件的路径;

-o后指定生成的文件

-c 对指定的cpp文件进行编译和汇编(但不链接)

注意:

prerequistites中可不添加头文件,这样的问题是如果修改了头文件,Makefile不会识别到修改,因此不会重新编译。

如果想在prerequisites中加入头文件,例如:target.o:source.cpp header.h,  Makefile并不支持自动在$(INCLUDE)路径下搜索prerequisites添加的头文件,因此,需要在prerequisites中给出header.h的路径

  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yuyuelongfly

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值