【Linux】【编译】编译及Makefile的调试手段和技巧

简介: 【Linux】【编译】编译及Makefile的调试手段和技巧

前言


在Linux开发过程中,经常会遇到各种编译问题。比较简单的问题一目了然,但有些比较复杂,较难分析。本文将编译中常见的调试手段、技巧做一总结,供各位参考。


常用手段和技巧


错误代码


经常遇到某个宏不生效的问题,这种情况,可以在宏控制的部分增加错误,看是否会有编译报错。


部分编译


如果一个项目比较庞大,直接make比较耗时间,此时,有两个选择:


  • 只编译出问题的模块或目录;


  • 注掉部分暂时无问题的模块(比如,有的sdk驱动和用户态app在一起编译,在调试app的编译的过程中,就可以把sdk驱动暂时注掉);


gcc相关


  • -E选项


– 当需要确定预处理相关的信息,如头文件包含、宏展开等情况,可使用这个选项;


– 只激活预处理,不生成文件;


– 仅对依赖关系做初步解析,没有-M等全面深入;


gcc -E hello.c               #默认输出到屏幕上;
gcc -E hello.c -o hello.i    #将输出重定向到文件;
gcc -E hello.c > hello.txt   #将输出重定向到文件;
gcc -E -C hello.c -o hello.i #在第二条的基础上,可阻止预处理器删除源文件和头文件中的注释;


  • 编译器依赖生成选项,-M选项、-MM选项、-MMD选项


其作用在于自动找寻源文件中包含的头文件,并生成一个依赖关系。


gcc -M obj.c              #获取目标obj.c的完整依赖关系
gcc -MD obj.c             #在-M的基础上,将输出导出到.d文件;
gcc -MM obj.c             #在-M的基础上,去除标准库的头文件;
gcc -MMD obj.c            #在-MM的基础上,将输出将导到.d文件:
gcc -MM -MF "obj.d" obj.c #-MF可以指定输出文件,前面几个命令默认用obj.d文件;


例1、一个简单例子:


[qxhgd@localhost]$ gcc -M test.c
test.o: test.c /usr/include/stdc-predef.h /usr/include/stdio.h \
 /usr/include/features.h /usr/include/sys/cdefs.h \


例2、一个完整例子:


SRCS=$(wildcard *.c)
OBJS=$(SRCS:.c=.o)
DEPS=$(SRCS:.c=.d)
.PHONY: all clean
all: main
-include $(DEPS)  
%.o:%.c
    gcc -c -g -Wall $< -o $@ -MD -MF $*.d -MP  #“-MF $*.d ”可以去除;
main: $(OBJS)
    gcc $^ -o $@  
clean: 
  rm -f  *.d *.o main


shell命令


  • echo方法


echo  some info  #显示echo这条命令本身和后面要输出的内容
@echo some info  #不会显示echo这条命令,只会显示后面要输出的内容


例1、打印一个变量值:


@echo "########### VAR=" $(VAR)


例2、将宏定义输入到h文件中:


@echo "#define BUILD_DATE            \"`date +%Y-%m-%d`\"" > $(INCDIR)/version.h


Makefile内置函数


$(info ...)    #不打印当前makefile名和行号
$(warning ...) #不中断makefile的执行,打印信息,并打印当前makefile文件名和行号
$(error ...)   #含warning的功能,同时会中断makefile的执行并退出


例1、打印信息


$(warning These ARMv8 Crypto Extensions modules need binutils 2.23 or higher)


例2、打印变量


$(warning The '$(SPHINXBUILD)' command was not found.)


编译重定向


make xxx > build_output.txt #将编译过程重定向到txt文件,错误在屏幕会显示;
make xxx 2> build_output.txt #仅将make输出中的错误(及警告)信息输出到文件中
make xxx 1> build_output.txt #仅需要把make输出中的正常(非错误,非警告)的信息输出到文件
make xxx 1> build_output_normal.txt 2>build_output_error.txt #正常信息和错误信息,都输出到对应文件中
make xxx > build_output_all.txt 2>&1 #所有的信息都输出到同一个文件中


make命令行选项


--just-print(-n)         #输出makefile中的所有数据,包括所有的规则和变量;只显示命令,但不会执行命令;
--dry-run                  #和-n类似,只是打印命令,不管目标是否更新,把规则和连带规则下的命令打印出来,但不执行
--recon                    #和-n类似,只是打印命令,不管目标是否更新,把规则和连带规则下的命令打印出来,但不执行
--print-data-base(-p)    #显示GNU版权信息以及make 所运行的命令,然后输出它的内部数据库;
--debug                    #当你需要知道make如何分析你的依存图时,可以使用--debug 选项。共计五个调试级别和一个修饰符可用,basic、verbose、implicit、jobs、all 以及makefile;
--trace                    #类似于Shell 里头的 set -x;
-W <file>                  # 这个参数需要指定一个文件。一般是是源文件(或依赖文件),Make会根据规则推导来运行依赖于这个文件的命令,一般来说,可以和“-n”参数一同使用,来查看这个依赖文件所发生的规则命令。另外一个很有意思的用法是结合“-p”和“-v”来输出makefile被执行时的信息
--what-if=<file>           #类似于-W;
--assume-new=<file>        #类似于-W;
--new-file=<file>          #类似于-W;
--touch(-t)               #把目标文件的时间更新,但不更改目标文件。也就是说,make假装编译目标,但不是真正的编译目标,只是把目标变成已编译过的状态。


例子:


make --trace xxx #展开xxx目标代码的执行过程;
make --debug xxx #展开整个make解析和执行xxx的过程;


remake


官方链接


  • remake is an enahanced version of GNU Make that adds improved error reporting, better tracing, profiling and a debugger.


小结


上述这些方法,基本可以覆盖Makefile常用的调试场景。

相关文章
|
Linux 编译器 开发工具
【Linux快速入门(三)】Linux与ROS学习之编译基础(Cmake编译)
【Linux快速入门(三)】Linux与ROS学习之编译基础(Cmake编译)
679 2
|
6月前
|
NoSQL Linux 开发工具
Linux环境基础开发工具的使用(yum、vim、gcc、g++、gdb、make/Makefile)
本文介绍了yum 包管理工具、Vim 编辑器、gcc/g++ 编译器、gdb 调试器、编译原理及 Makefile 的使用,同时还配备了如何使用,以及图解。旨在帮助读者更好地理解和应用这些工具与技术。
347 0
|
9月前
|
监控 Shell Linux
Android调试终极指南:ADB安装+多设备连接+ANR日志抓取全流程解析,覆盖环境变量配置/多设备调试/ANR日志分析全流程,附Win/Mac/Linux三平台解决方案
ADB(Android Debug Bridge)是安卓开发中的重要工具,用于连接电脑与安卓设备,实现文件传输、应用管理、日志抓取等功能。本文介绍了 ADB 的基本概念、安装配置及常用命令。包括:1) 基本命令如 `adb version` 和 `adb devices`;2) 权限操作如 `adb root` 和 `adb shell`;3) APK 操作如安装、卸载应用;4) 文件传输如 `adb push` 和 `adb pull`;5) 日志记录如 `adb logcat`;6) 系统信息获取如屏幕截图和录屏。通过这些功能,用户可高效调试和管理安卓设备。
|
缓存 NoSQL Linux
Linux调试
本文介绍了Linux调试、性能分析和追踪的培训资料,涵盖调试、性能分析和追踪的基础知识及常用工具。
821 63
Linux调试
|
11月前
|
Rust Ubuntu Java
[Linux工具] Makefile
Makefile是Linux环境下用于自动化编译和链接程序的配置文件,常用于简化大型项目的编译流程。通过定义目标文件、依赖文件及生成命令,Makefile能高效管理编译任务。它不仅适用于C语言项目,还可扩展到其他编程语言和非编程任务中。
[Linux工具] Makefile
|
10月前
|
Unix Linux C语言
【Linux】 Linux makefile 教程
本文详细介绍了 Linux 环境下 Makefile 的基本结构、语法和使用方法,并通过一个简单的 C++ 项目示例演示了 Makefile 的实际应用。Makefile 是一个强大而灵活的工具,通过合理配置,可以极大地简化项目的编译和管理过程,提高开发效率。希望本文能帮助您更好地理解和应用 Makefile,在实际项目中高效管理代码的编译和构建。
675 20
|
10月前
|
Unix Linux C语言
【Linux】 Linux makefile 教程
本文详细介绍了 Linux 环境下 Makefile 的基本结构、语法和使用方法,并通过一个简单的 C++ 项目示例演示了 Makefile 的实际应用。Makefile 是一个强大而灵活的工具,通过合理配置,可以极大地简化项目的编译和管理过程,提高开发效率。希望本文能帮助您更好地理解和应用 Makefile,在实际项目中高效管理代码的编译和构建。
238 16
|
12月前
|
Ubuntu Linux Go
golang编译成Linux可运行文件
本文介绍了如何在 Linux 上编译和运行 Golang 程序,涵盖了本地编译和交叉编译的步骤。通过这些步骤,您可以轻松地将 Golang 程序编译成适合 Linux 平台的可执行文件,并在目标服务器上运行。掌握这些技巧,可以提高开发和部署 Golang 应用的效率。
1936 14
|
12月前
|
存储 NoSQL Linux
linux之core文件如何查看和调试
通过设置和生成 core 文件,可以在程序崩溃时获取详细的调试信息。结合 GDB 等调试工具,可以深入分析 core 文件,找到程序崩溃的具体原因,并进行相应的修复。掌握这些调试技巧,对于提高程序的稳定性和可靠性具有重要意义。
5690 6
|
运维 监控 Linux
BPF及Linux性能调试探索初探
BPF技术从最初的网络数据包过滤发展为强大的系统性能优化工具,无需修改内核代码即可实现实时监控、动态调整和精确分析。本文深入探讨BPF在Linux性能调试中的应用,介绍bpftune和BPF-tools等工具,并通过具体案例展示其优化效果。
540 14