内容简介:原文: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++编译器优化
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Mechanics of Web Handling
David R. Roisum
This unique book covers many aspects of web handling for manufacturing, converting, and printing. The book is applicable to any web including paper, film, foil, nonwovens, and textiles. The Mech......一起来看看 《The Mechanics of Web Handling》 这本书的介绍吧!