gcc的几个妙用gcc的学习在C接触到linux以后就开始不断的学习,也知道了一些基本的用法,但是关于gcc的使用还是有很多值得我们加深的地方。
gcc 只是一个编译工具而已。
也就相当于我们在windows环境下的visual c++等一样,区别是visual c++是基于IDE的,而gcc是这些IDE的基础。
学习linux程序设计必然会学习gcc。
gcc实质是完成程序的编译和链接,程序的编译是指从一种文件类型转换到另一种文件类型的过程。
一个C语言程序转换为可执行程序的基本步骤如下:1、编写程序(vi,emacs等软件)2、程序预编译(cpp)3、编译成汇编程序(cc)4、汇编程序(as)5、链接程序(ld)其中的这些过程都已经被gcc包含,我们在实际的编译过程中采用了gcc main.c -o main.exe即可实现一个程序的编译和链接。
并不需要一步一步的实现,但是我们在分析的过程中又必须注意一个C语言文件的处理过程以及相应的处理程序。
关于gcc的基本含义用法就不再详细的说明了,我觉得最简单的使用方法是通过软件的help学习软件。
[gong@Gong-Computer test]$ gcc --helpUsage: gcc [options] file...Options:-pass-exit-codesExit with highest error code from a phase--helpDisplay this information--target-helpDisplay target specific command line options--help={target|optimizers|warnings|params|[^]{joi ned|separate|undocumented}}[,...]Display specific types of command line options (Use '-v --help' to display command line options of sub-processes)--versionDisplay compiler version information-dumpspecsDisplay all of the built in spec strings-dumpversionDisplay the version of the compiler-dumpmachineDisplay the compiler's target processor-print-search-dirsDisplay the directories in the compiler's search path-print-libgcc-file-name Display the name of the compiler's companion library-print-file-name=;Display the full path to library ;-print-prog-name=; Display the full path to compiler component ;-print-multi-directoryDisplay the root directory for versions of libgcc-print-multi-libDisplay the mapping between command line options andmultiple library search directories-print-multi-os-directory Display the relative path to OS libraries-print-sysrootDisplay the target libraries directory-print-sysroot-headers-suffix Display the sysroot suffix used to find headers-Wa,;Pass comma-separated ; on to the assembler-Wp,;Pass comma-separated ; on to the preprocessor -Wl,;Pass comma-separated ; on to the linker-Xassembler ;Pass ; on to the assembler-Xpreprocessor ;Pass ; on to the preprocessor-Xlinker ;Pass ; on to the linker-combinePass multiple source files to compiler at once -save-tempsDo not delete intermediate files-save-temps=;Do not delete intermediate files-no-canonical-prefixesDo not canonicalize paths when building relativeprefixes to other gcc components-pipeUse pipes rather than intermediate files-timeTime the execution of each subprocess-specs=;Override built-in specs with the contents of ; -std=;Assume that the input sources are for ;--sysroot=;Use ; as the root directory for headersand libraries-B ;Add ; to the compiler's search paths-b ;Run gcc for target ;, if installed-V ;Run gcc version number ;, if installed-vDisplay the programs invoked by the compiler -###Like -v but options quoted and commands not executed-EPreprocess only; do not compile, assemble or link-SCompile only; do not assemble or link-cCompile and assemble, but do not link-o ;Place the output into ;-x ;Specify the language of the following input filesPermissible languages include: c c++ assembler none'none' means revert to the default behavior ofguessing the language based on the file's extensionOptions starting with -g, -f, -m, -O, -W, or --param are automaticallypassed on to the various sub-processes invoked by gcc. In order to passother options on to these processes the -W; options must be used.For bug reporting instructions, please see:;.从上面的结果可以知道基本的用法。
但是还是有几个需要注意的地方,这也是我们学习gcc时不经常使用,但又非常有用的几个用法。
1、采用gcc实现预编译,预编译可以实现代码的检查,特别是宏定义的检查,通过预编译检查实际的代码是否出错,这是非常有用的检查方式。
由于预编译以后宏定义被扩展了,这时对源码的分析就能找出代码宏定义等是否存在错误,特别时一些不容易发现的错误。
基本的实现形式为:gcc -E file.c >; file.pre.c[gong@Gong-Computer Example]$ vi main.c采用重定向的方式改变输出流,便于检查错误所在。
[gong@Gong-Computer Example]$ gcc -E main.c >; main.pre.c[gong@Gong-Computer Example]$ vi main.pre.c从上面的结果可以发现我们的宏已经实现了扩展。
通过分析宏的扩展可以分析代码是否正确。
比如我将宏定义max(x,y)改写为max (x,y)就会出现下面的结果。
如下图所示。
从856行的结果我们可以知道,上面的代码并不是我们需要的情况,这说明我们的代码存在问题,从而实现了宏定义的检测。
这是非常有用的一种检测方式。
2、产生镜像文件基本的实现方法是:注意Wl逗号后面跟着需要传递的参数,逗号后面不能存在空格,否则出现错误。
gcc -Wl,-Map=file.map file.c -o target关于选项-Wl的使用可以参考help,这是我的一个截图从上面说明可以知道-Wl用于传递参数给链接器。
当然也有传递给汇编器和预编译的选项。
通过上面的选项可以得到一个镜像文件,通过打开镜像文件来程序的结构。
[gong@Gong-Computer Example]$ gcc-Wl,-Map=main.map main.c -o main.exe[gong@Gong-Computer Example]$ vi main.map上面只是其中的一部分,还有很多的内容。
其中这些内容指出了程序的基本分布情况。
3、汇编程序汇编语言是不可避免要学习的设计语言,但是很多时候并不需要完全手动的编写汇编语言,我们可以采用gcc实现一段程序的汇编形式,只需要选择正确的选项即可。
gcc -S file.c实现如下:[gong@Gong-Computer Example]$ gcc -S main.c [gong@Gong-Computer Example]$ vi main.s从上面的代码就知道了基本的汇编形式,当然也可以自己设计,但是该选项简化了汇编语言的设计。