最常用的 GCC 编译器命令行选项

举报
Tiamo_T 发表于 2022/07/13 21:46:52 2022/07/13
【摘要】 本文解释了一些流行的 GCC 编译器选项。

GCC Compiler 是一个非常强大且流行的 C 编译器,适用于各种 Linux 发行版。本文解释了一些流行的 GCC 编译器选项。

示例 C 代码

本文将使用以下基本 C 代码 (main.c):

#include<stdio.h>

int main(void)
{
   printf("\n The hgst tiamo\n");
   return 0;
}

GCC 编译器选项

1.指定输出可执行文件名

在其最基本的形式中,gcc 编译器可以用作:

gcc main.c

上述命令执行完整的编译过程,并输出一个名为 a.out 的可执行文件。

如下所示,使用选项 -o 指定可执行文件的输出文件名。

gcc main.c -o main

上面的命令将生成一个名为“main”的输出文件。

2.启用通过-Wall选项设置的所有警告

此选项启用 GCC 中的所有警告。

#include<stdio.h>

int main(void)
{
   int i;
   printf("\n The hgst tiamo[%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 选项。

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

上面提到的 gcc 命令将代码 main.c 与共享库 libCPPfile.so 链接起来,以生成最终的可执行文件“main”。

8. 使用 -fPIC 选项创建与位置无关的代码

创建共享库时,应生成与位置无关的代码。这有助于将共享库加载为任何地址,而不是某个固定地址。为此,使用了 -fPIC 选项。

例如,以下命令从源文件 Cfile.c 创建一个共享库 libCfile.so:

$ gcc -c -Wall -Werror -fPIC Cfile.c
$ gcc -shared -o libCfile.so Cfile.o

所以我们看到选项 -fPIC 用于创建共享库。

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 hgst tiamo\n");
   return 0;
}

如果上面的代码是使用 -ansi 选项编译的,那么 gcc 会产生错误,因为 ISO C89 样式中不允许 C++ 注释。

这是输出:

$ gcc -Wall -ansi main.c -o main
main.c: In function ‘main’:
main.c:5:3: error: expected expression before ‘/’ token

所以我们看到 gcc 抛出了一个与评论风格相关的错误。

11. 使用 -funsigned-char 选项将 char 解释为 unsigned char

通过该选项,char 类型被视为无符号类型。

例子:

#include<stdio.h>

int main(void)
{
  char c = -10;
  // Print the string
   printf("\n The hgst tiamo [%d]\n", c);
   return 0;
}

当上面的代码使用 funsigned-char 选项编译时,输出如下:

$ gcc -Wall -funsigned-char main.c -o main
$ ./main

 The hgst tiamo[246]

所以我们看到 char 确实被视为无符号。

12. 使用 -fsigned-char 选项将 char 解释为有符号字符

这与我们在上面(12)中讨论的相反。使用此标志,char 变量被视为有符号。

例子:

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

 The hgst tiamo [-10]

输出确认 char 被视为已签名。

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 hgst tiamo[%d]\n", c);
   return 0;
}

编译器选项 -D 可用于从命令行定义宏 MY_MACRO。

$ gcc -Wall -DMY_MACRO main.c -o main
$ ./main

 Macro defined 

 The hgst tiamo [-10]

输出中与宏相关的打印确认宏已定义。

14. 使用 -Werror 选项将警告转换为错误

通过此选项,gcc 可以报告的任何警告都将转换为错误。

例子:

#include<stdio.h>

int main(void)
{
  char c;
  // Print the string
   printf("\n The hgst tiamo [%d]\n", c);
   return 0;
}

上述代码的编译应该生成与未定义变量 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

15. 使用@选项通过文件提供gcc选项

gcc 的选项也可以通过文件提供。这可以使用 @ 选项后跟包含选项的文件名来完成。多个选项由空格分隔。

例子:

$ cat opt_file 
-Wall -omain

opt_file 包含选项。

现在通过提供 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

输出确认文件 opt_file 已被解析以获取选项,并且相应地完成了编译。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。