Linux GCC常用命令总结

Posted 沉迷单车的追风少年

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux GCC常用命令总结相关的知识,希望对你有一定的参考价值。

目录

1、指定编译输出的名字

2、通过-Wall参数启用所有警告

3、使用-E参数只产生预处理输出

4、使用-S参数只产生汇编代码

5、使用-C参数只产生编译的代码

6、使用-save-temps参数产生所有的中间步骤的文件

7、使用-l参数链接共享库

8、使用-fPIC产生位置无关的代码

9、使用-V打印所有的执行命令

10、使用-ansi参数支持 ISO C89程序

11、使用-funsigned-char将char解释为符号的char

12、使用-fsigned-char将char解释为有符号的char

13、使用-D参数可以使用编译时的宏

13、使用-Werror将警告升级为错误

14、使用@参数从文件中读取参数

15、使用参数-I指定头文件的文件夹

16、使用参数-std指定支持的c++/c的标准

17、使用-static生成静态链接的文件

18、使用-static-libstdc++静态链接libstdc++

19、使用-M生成文件关联的信息


1、指定编译输出的名字

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

2、通过-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]

3、使用-E参数只产生预处理输出

-E参数是产生预处理阶段的输出。

$ gcc -E main.c > main.i

gcc命令将结果输出在stdout中,所以你可以把它重定向到任意的文件中,在上面的例子中,重定向到main.i文件中。

4、使用-S参数只产生汇编代码

-S 参数产生汇编级别的代码。

gcc -S main.c > main.s

文件main.s包含汇编代码。

5、使用-C参数只产生编译的代码

-C参数只产生编译的代码(没有链接link)。

gcc -C main.c

上面的代码产生main.o, 包含机器级别的代码或者编译的代码。

6、使用-save-temps参数产生所有的中间步骤的文件

-save-temps可以做4,5,6步骤的工作。通过这个参数,所有中间阶段的文件都会存储在当前文件夹中,注意它也会产生可执行文件。

$ gcc -save-temps main.c

$ ls

a.out main.c main.i main.o main.s

从例子中我们可以看到各个中间文件以及可执行文件。

7、使用-l参数链接共享库

-l可以用作链接共享库,例如:

gcc -Wall main.c -o main -lCPPfile

上面的代码会链接libCPPfile.so,产生可执行文件main

8、使用-fPIC产生位置无关的代码

当产生共享库的时候,应该创建位置无关的代码,这会让共享库使用任意的地址而不是固定的地址,要实现这个功能,需要使用-fPIC参数。

下面的例子产生libCfile.so动态库。

$ gcc -c -Wall -Werror -fPIC Cfile.c

$ gcc -shared -o libCfile.so Cfile.o

产生共享库的时候使用了-fPIC参数。

注意-shared产生共享库。

9、使用-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)

...

...

这样我们可以看到所有的细节。

10、使用-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

我们可以看待上面编译的时候抛出一个注释错误。

11、使用-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是无符号的字节。

12、使用-fsigned-char将char解释为有符号的char

和上面的功能相反, 使用这个参数, char类型被看作是有符号的:

$ gcc -Wall -fsigned-char main.c -o main

$ ./main

The Geek Stuff [-10]

结果输出为负数。

13、使用-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.

13、使用-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

14、使用@参数从文件中读取参数

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

输出结果表明参数的确从文件中读取了,并且正确的应用到编译过程中。

以下是附加的一些编译参数

15、使用参数-I指定头文件的文件夹

gcc -I/home/codeman/include input-file.c

-I-取消前一个参数功能,一般用在-Idir之后。

16、使用参数-std指定支持的c++/c的标准

gcc -std=c++11 hello-world.cpp

标准如 c++11, c++14, c90, c89等。

17、使用-static生成静态链接的文件

静态编译文件(把动态库的函数和其它依赖都编译进最终文件)

gcc main.c -static -o main -lpthread

相反的使用-shared使用动态库链接。

18、使用-static-libstdc++静态链接libstdc++

如果没有使用-static,默认使用libstdc++共享库,而-static-libstdc++可以指定使用libstdc++静态库。

19、使用-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

 

以上是关于Linux GCC常用命令总结的主要内容,如果未能解决你的问题,请参考以下文章

转Linux GCC常用命令

Linux GCC常用命令

Linux下GCC常用命令

20175221 《信息安全系统设计基础》第3周学习总结

GCC编译命令常用选项

GCC常用命令总结