内容简介:原文:GCC编译器是一个日常流行的 C 编译器, 很多Linux的发布版本中都带有这个编译器。这篇文章列举了一些最常用的编译参数。本文中使用下面的C语言实现的例子:
原文: 15 Most Frequently Used GCC Compiler Command Line Options 以及评论中大家提供的一些参数。
GCC编译器是一个日常流行的 C 编译器, 很多 Linux 的发布版本中都带有这个编译器。这篇文章列举了一些最常用的编译参数。
本文中使用下面的 C语言 实现的例子:
#include<stdio.h> int main(void) { printf("\n The Geek Stuff\n"); return 0; }
指定编译输出的名字
gcc编译器最常用的使用格式是:
gcc main.c
上面的命令执行完整的编译过程,并且生成一个 a.out
文件。
使用参数 -o
, 可以指定输出的文件名。
gcc main.c -o main
上面的命令会产生输出文件 main
。
为了理解GCC编译器的完整的编译过程,可以阅读 Journey of a C Program to Linux Executable in 4 Stages 。
通过 -Wall
参数启用所有警告
这个参数可以启用所有警告。
#include<stdio.h> int main(void) { int i; printf("\n The Geek Stuff [%d]\n", i); return 0; }
上面的代码编译时,会出现 未初始化的i
类似的警告。
$ gcc -Wall main.c -o main main.c: In function ‘main’: main.c:6:10: warning: ‘i’ is used uninitialized in this function [-Wuninitialized]
使用 -E
参数只产生预处理输出
-E
参数是产生预处理阶段的输出。
$ gcc -E main.c > main.i
gcc命令将结果输出在 stdout
中,所以你可以把它重定向到任意的文件中,在上面的例子中,重定向到 main.i
文件中。
使用 -S
参数只产生汇编代码
-S
参数产生汇编级别的代码。
gcc -S main.c > main.s
文件 main.s
包含汇编代码。
使用 -C
参数只产生编译的代码
-C
参数只产生编译的代码(没有链接link)。
gcc -C main.c
上面的代码产生 main.o
, 包含机器级别的代码或者编译的代码。
使用 -save-temps
参数产生所有的中间步骤的文件
-save-temps
可以做4,5,6步骤的工作。通过这个参数,所有中间阶段的文件都会存储在当前文件夹中,注意它也会产生可执行文件。
$ gcc -save-temps main.c $ ls a.out main.c main.i main.o main.s
从例子中我们可以看到各个中间文件以及可执行文件。
使用 -l
参数链接共享库
-l
可以用作链接共享库,例如:
gcc -Wall main.c -o main -lCPPfile
上面的代码会链接 libCPPfile.so
,产生可执行文件 main
。
使用 -fPIC
产生位置无关的代码
当产生共享库的时候,应该创建位置无关的代码,这会让共享库使用任意的地址而不是固定的地址,要实现这个功能,需要使用 -fPIC
参数。
下面的例子产生 libCfile.so
动态库。
$gcc -c -Wall -Werror -fPIC Cfile.c $gcc -shared -o libCfile.so Cfile.o
产生共享库的时候使用了 -fPIC
参数。
注意 -shared
产生共享库。
使用 -V
打印所有的执行命令
参数 -V
提供详细的信息,打印出gcc编译一个文件的时候所有的步骤。
例如:
$ gcc -Wall -v main.c -o main Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-linux-gnu/4.6/lto-wrapper Target: i686-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.3-1ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu Thread model: posix gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) ... ... ...
这样我们可以看到所有的细节。
使用 -ansi
参数支持 ISO C89程序
使用 -ansi
参数可以支持 ISO C89风格。
比如下面的代码:
#include<stdio.h> int main(void) { // Print the string printf("\n The Geek Stuff\n"); return 0; }
使用 -ansi
参数编译上面的代码会出错,因为ISO C89不支持C++风格的注释。
下面是输出结果:
main.c: In function ‘main’: main.c:5:3: error: expected expression before ‘/’ token
我们可以看待上面编译的时候抛出一个注释错误。
使用 -funsigned-char
将char解释为符号的char
通过这个参数, char类型被看作为 unsigned char类型。
例子:
#include<stdio.h> int main(void) { char c = -10; // Print the string printf("\n The Geek Stuff [%d]\n", c); return 0; }
上面的代码通过这个参数编译后,输出结果为:
$ gcc -Wall -funsigned-char main.c -o main $ ./main The Geek Stuff [246]
可以看到char是无符号的字节。
使用 -fsigned-char
将char解释为有符号的char
和上面的功能相反, 使用这个参数, char类型被看作是有符号的:
$gcc -Wall -fsigned-char main.c -o main $./main The Geek Stuff [-10]
结果输出为负数。
使用 -D
参数可以使用编译时的宏
参数 D
可以用作定义编译时的宏。
例子:
#include<stdio.h> int main(void) { #ifdef MY_MACRO printf("\n Macro defined \n"); #endif char c = -10; // Print the string printf("\n The Geek Stuff [%d]\n", c); return 0; }
-D
可以用作从命令行定义宏 MY_MACRO
。
$ gcc -Wall -DMY_MACRO main.c -o main $ ./main Macro defined The Geek Stuff [-10]
可以看到宏被定义了,并打印出了结果。
tput confirms that the macro was defined.
使用 -Werror
将警告升级为错误
通过这个参数,gcc会将所有的警告转换成错误信息。
例子:
#include<stdio.h> int main(void) { char c; // Print the string printf("\n The Geek Stuff [%d]\n", c); return 0; }
上面的代码编译的时候会有一个 undefined variable c
警告, -Werror
会把这个警告升级成错误。
$ gcc -Wall -Werror main.c -o main main.c: In function ‘main’: main.c:7:10: error: ‘c’ is used uninitialized in this function [-Werror=uninitialized] cc1: all warnings being treated as errors
使用 @
参数从文件中读取参数
gcc参数可以从文件中读取,通过 @
后跟文件名的方式提供, 多个参数可以使用空格区隔。
例子:
$ cat opt_file -Wall -omain
opt_file
包含编译参数。
使用 @
参数:
$ gcc main.c @opt_file main.c: In function ‘main’: main.c:6:11: warning: ‘i’ is used uninitialized in this function [-Wuninitialized] $ ls main main
输出结果表明参数的确从文件中读取了,并且正确的应用到编译过程中。
以下是附加的一些编译参数
使用参数 -I
指定头文件的文件夹
gcc -I/home/codeman/include input-file.c
-I-
取消前一个参数功能,一般用在 -Idir
之后。
使用参数 -std
指定支持的c++/c的标准
gcc -std=c++11 hello-world.cpp
标准如 c++11, c++14, c90, c89
等。
使用 -static
生成静态链接的文件
静态编译文件(把动态库的函数和其它依赖都编译进最终文件)
gcc main.c -static -o main -lpthread
相反的使用 -shared
使用动态库链接。
使用 -static-libstdc++
静态链接libstdc++
如果没有使用 -static
,默认使用libstdc++共享库,而 -static-libstdc++
可以指定使用libstdc++静态库。
使用 -M
生成文件关联的信息
gcc -M main.c main.o: main.c /usr/include/stdc-predef.h /usr/include/stdio.h \ /usr/include/features.h /usr/include/sys/cdefs.h \ /usr/include/bits/wordsize.h /usr/include/gnu/stubs.h \ /usr/include/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stddef.h \ /usr/include/bits/types.h /usr/include/bits/typesizes.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stdarg.h \ /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h
全部参数介绍
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- LLVM接受NVIDIA的“f18” Fortran编译器作为官方Fortran编译器
- 编译原理实战入门:用 JavaScript 写一个简单的四则运算编译器(四)结语
- Scala.js 0.6.29 发布,将 Scala 编译成 js 的编译器
- Go 编译器介绍
- Go 编译器介绍
- C++编译器优化
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。