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

本文介绍了C++工程的构建和调试方法,包括使用Makefile和Cmake进行编译,以及如何利用GDB进行调试。详细讲述了Makefile中的头文件路径指定、链接库、编译源文件,Cmake的源文件编译、头文件和库文件的添加,以及GDB的调试模式配置、断点设置和Coredump分析。通过对预处理、编译、汇编和链接过程的解析,深入理解C++程序的构建流程,并掌握GDB调试技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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的路径(如果只写header.h,则只查找Makefile当前路径;如果header.h不在Makefile的同一路径下,则显示 No rule to make target ‘header.h’, needed by 'target.o'. Stop.

2.3.3 链接生成可执行文件

target: target.o 
&lt;think&gt;好的,我需要帮助用户了解如何在CMake项目中使用GDB调试C++程序。首先,我需要回忆相关的步骤和知识点,确保信息准确。 用户的问题是关于配置CMake项目以使用GDB调试,所以得先确认CMake如何生成带有调试信息的构建配置。记得在编译时添加-g或-g3选项,这样GDB才能获取符号和源代码信息。CMake中通常是通过设置CMAKE_BUILD_TYPE为Debug,这会自动包含调试标志。 接下来,可能需要分步骤说明:如何修改CMakeLists.txt,如何构建项目,以及如何使用GDB启动调试。此外,用户可能想知道在IDE(如VSCode)中的配置方法,因为引用里提到了VSCode的配置。需要结合引用中的信息,比如引用[2]提到命令行编译时使用pkg-config,引用[4]提到VSCode的CMake插件设置。 还要考虑生成相关的问题,比如如何设置断点、常用GDB命令,或者如何优化调试体验。确保每个步骤都有引用支持,比如引用[3]详细介绍了GDB的使用流程和命令,可能需要引用这些部分。 需要检查是否有遗漏的步骤,例如确保GDB已安装,或者CMake生成Makefile时的具体命令。同时,提醒用户构建前清理输出,如引用[4]中提到的勾选清除生成输出,这可能影响构建的准确性。 最后,生成相关问题要考虑用户可能进一步的问题,比如性能分析、优化构建配置,或者与其他工具集成。确保问题覆盖用户可能的后续疑问,帮助他们深入理解。&lt;/think&gt;### 如何在 CMake 项目中使用 GDB 调试 C++ 程序 #### 1. **确保编译时包含调试信息** 在 CMake 构建配置中,需启用调试符号生成。通过设置 `CMAKE_BUILD_TYPE` 为 `Debug`,CMake 会自动添加 `-g` 或 `-g3` 编译选项(生成调试信息)[^3]。 在 `CMakeLists.txt` 中添加: ```cmake set(CMAKE_BUILD_TYPE Debug) ``` 若需手动指定编译选项,可使用: ```cmake add_compile_options(-g3) ``` #### 2. **构建项目** 使用以下命令生成构建文件并编译: ```bash mkdir build cd build cmake .. make ``` 此操作会生成带有调试信息的可执行文件[^2]。 #### 3. **启动 GDB 调试** 通过 GDB 加载生成可执行文件: ```bash gdb ./your_executable ``` #### 4. **常用 GDB 调试操作** - **设置断点**:`break filename:lineno` 或 `b function_name` - **运行程序**:`run` - **单步执行**:`next`(跳过函数)或 `step`(进入函数) - **查看变量**:`print variable_name` - **查看调用栈**:`backtrace` - **继续运行**:`continue` #### 5. **在 VSCode 中集成调试** 1. 安装 CMakeGDB 插件(如 `CMake Tools` 和 `C/C++`)。 2. 在 `CMakeLists.txt` 中确保启用调试模式。 3. 配置 `launch.json`: ```json { &quot;configurations&quot;: [ { &quot;name&quot;: &quot;GDB Debug&quot;, &quot;type&quot;: &quot;cppdbg&quot;, &quot;request&quot;: &quot;launch&quot;, &quot;program&quot;: &quot;${workspaceFolder}/build/your_executable&quot;, &quot;args&quot;: [], &quot;stopAtEntry&quot;: false, &quot;cwd&quot;: &quot;${workspaceFolder}&quot;, &quot;environment&quot;: [], &quot;externalConsole&quot;: false, &quot;MIMode&quot;: &quot;gdb&quot; } ] } ``` 通过 VSCode 可直接设置断点并可视化调试[^4]。 #### 6. **调试多文件或第三方** 若项目依赖外部(如 OpenCV),需确保编译时包含头文件和路径。在 `CMakeLists.txt` 中使用 `find_package` 或 `pkg-config` 集成: ```cmake find_package(OpenCV REQUIRED) target_link_libraries(your_target ${OpenCV_LIBS}) ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

yuyuelongfly

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

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

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

打赏作者

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

抵扣说明:

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

余额充值