软件工具通常提供多种功能,但是 - 大部分人都同意 - 并不是所有人都使用它们的所有功能。 一般来说,没有任何错误,因为每个用户都有自己的要求,他们只使用该领域的工具。 然而,继续探索您使用的工具总是很好,因为它们的一个功能可能会派上用场,从而节省了您宝贵的时间。
例如:编译器。 一个好的编程语言编译器总是提供大量的选项,但用户通常只能使用有限的集合。 具体来说,如果您是C语言开发人员并使用Linux作为开发平台,那么您很可能会使用gcc编译器,该编译器提供无尽的命令行选项列表。
你知道,如果你愿意,你可以要求gcc在编译过程的每个阶段保存输出? 您是否知道 - 用于生成警告的“选项”不包含某些特定警告? 有许多命令行gcc选项不常用,但在某些情况下可能非常有用,例如在调试代码时。
所以,在这篇文章中,我们将介绍几个这样的选项,提供所有必要的细节,并通过容易理解的例子在必要时解释它们。
但是,在我们向前推进之前,请记住,本教程中提到的所有示例,命令和说明都已在Ubuntu 16.04 LTS上进行了测试,而我们使用的gcc版本为5.4.0。
请参见每个编译阶段的中间输出
您是否知道当您使用gcc编译器编译C代码时,总共有四个阶段? 这些是预处理,编译,汇编和链接。 在每个阶段之后,gcc产生临时输出文件,该文件被交给下一个阶段。 现在,这些都是生成的临时文件,因此我们不会看到它们 - 我们看到的是我们已经发出了编译命令,它生成了可以运行的二进制/可执行文件。
但是如果在调试的时候,需要看看代码如何处理,比如预处理阶段。 那么你会做什么? 那么好的好处是,gcc编译器提供了一个可以在标准编译命令中使用的命令行选项,你会得到编译器删除的那些中间文件。 我们所说的选择是-save-temps 。
以下是gcc手册页面对此选项的说明:
Store the usual "temporary" intermediate files permanently; place
them in the current directory and name them based on the source
file. Thus, compiling foo.c with -c -save-temps produces files
foo.i and foo.s, as well as foo.o. This creates a preprocessed
foo.i output file even though the compiler now normally uses an
integrated preprocessor.
When used in combination with the -x command-line option,
-save-temps is sensible enough to avoid over writing an input
source file with the same extension as an intermediate file. The
corresponding intermediate file may be obtained by renaming the
source file before using -save-temps.
以下是一个示例命令,可以让您了解如何使用此选项:
gcc -Wall -save-temps test.c -o test-exec
这是我如何验证所有的中间文件是否确实在上述命令执行后生成:
因此,您可以在上面的截图中看到 , test.i , test.s和test.o文件是由-save-temps选项生成的。 这些文件分别对应于预处理,编译和链接阶段。
使您的代码调试和分析准备就绪
有专门的工具让您调试和配置您的源代码。 例如, gdb用于调试目的,而gprof是用于分析目的的常用工具。 但是,您知道gcc提供的特定命令行选项是为了使您的代码调试以及分析准备好吗?
让我们从调试开始吧。 为了能够使用gdb进行代码调试,必须使用-g命令行选项编译代码,提供gcc编译器。 此选项基本上允许gcc生成gdb所需的调试信息,以成功调试程序。
如果您打算使用此选项,建议您查看gcc手册页提供的详细信息,其中有些可能在某些情况下证明是至关重要的。 例如,以下是从手册页中摘录的摘录:
GCC allows you to use -g with -O. The shortcuts taken by optimized
code may occasionally produce surprising results: some variables
you declared may not exist at all; flow of control may briefly move
where you did not expect it; some statements may not be executed
because they compute constant results or their values are already
at hand; some statements may execute in different places because
they have been moved out of loops.
Nevertheless it proves possible to debug optimized output. This
makes it reasonable to use the optimizer for programs that might
have bugs.
不仅gdb,使用-g选项编译代码也开启了使用Valgrind的memcheck工具完成潜力的可能性。 对于那些不了解的人,程序员使用memcheck来检查代码中的内存泄漏(如果有的话)。 您可以在这里了解有关此工具的更多信息。
继续,为了能够使用gprof进行代码分析,您必须使用-pg命令行选项编译代码。 它允许gcc生成额外的代码来编写分析信息,这是gprof进行代码分析所需要的。 gcc手册页面说:“在编译需要数据的源文件时必须使用此选项,并且还必须在链接时使用该选项。 要了解有关如何使用gprof执行代码分析的更多信息,请访问我们网站上的专用教程 。
注意 : -g和-pg选项的使用与上一节中使用-save-temps选项的方式类似。
结论
除非你是gcc专家,否则我相信你已经学到了一些新的东西。 请尝试这些选项,看看它们是如何工作的。 同时,等待本教程系列的下一部分 ,我们将在其中讨论更多这样有趣且有用的gcc命令行选项。