gcc
is very popular compiler in Linux world. gcc
provides interpreter and compiler for programming languages like C, C++, Java etc. In this tutorial we will examine popular compiler options like error, pre-processor, output, optimization etc.
gcc
是Linux世界中非常流行的编译器。 gcc
为诸如C,C ++,Java等编程语言提供了解释器和编译器。在本教程中,我们将研究流行的编译器选项,例如错误,预处理器,输出,优化等。
示例C应用程序代码 (Example C Application Code)
During this tutorial we will use following simple example code. As we can see this code only prints HELLO POFTUT.COM
to the standard output.
在本教程中,我们将使用以下简单的示例代码。 如我们所见,此代码仅将HELLO POFTUT.COM
打印到标准输出。
#include<stdio.h>
int main(void)
{
printf("HELLO POFTUT.COM\n");
return 0;
}
指定输出可执行文件名 (Specify Output Executable File Name)
The default behavior of the the gcc is putting compiled executable file as a.out
. This may not be suitable of pretty solution for professional work. We can specify the compiled executable output file name with -o
option by providing the executable file name explicitly. In this example we will set the executable file name as app
.
gcc的默认行为是将编译后的可执行文件作为a.out
放置。 这可能不适合用于专业工作的漂亮解决方案。 我们可以通过显式提供可执行文件名来使用-o
选项指定编译后的可执行输出文件名。 在此示例中,我们将可执行文件名设置为app
。
$ gcc -o app main.c
We can check create executable file with file
command which will print
我们可以使用file
命令检查创建可执行文件,该命令将打印
- File type文件类型
- Architecture建筑
- Version版
- BuildIDBuildID
优化一点 (Optimize A Little Bit)
Optimization will make created binary run faster in general. We can use -O1
option in order to optimize a little bit.
优化通常会使创建的二进制文件运行更快。 我们可以使用-O1
选项来进行一些优化。
$ gcc -O1 main.c
优化更多 (Optimize More)
More optimization means more speed. This is level 2 optimization and best selection in most of the cases.
优化越多意味着速度越快。 在大多数情况下,这是2级优化和最佳选择。
$ gcc -O2 main.c
全面优化 (Comprehensive Optimization)
Compherensive optimization will make our binary faster but this may not work some cases. Use this optimization level accordingly. We will use -O3
option.
互补优化将使我们的二进制文件更快,但是在某些情况下可能无法正常工作。 相应地使用此优化级别。 我们将使用-O3
选项。
$ gcc -O3 main.c
优化尺寸 (Optimize For Size)
In embedded systems disk size may be a matter. We may need to compile the whole library or framework in a size optimized manner. So we can use the 0s
option which will reduce the size of the created binary executable.
在嵌入式系统中,磁盘大小可能是一个问题。 我们可能需要以大小优化的方式编译整个库或框架。 因此,我们可以使用0s
选项,这将减小创建的二进制可执行文件的大小。
$ gcc -Os -o main main.c
We can see the difference in the screenshot were before optimization the size was 8.2K
but after optimization it reduced to the 8.1K
.
我们可以看到在屏幕截图的不同是优化尺寸为前8.2K
,但优化后,减少到8.1K
。
启用所有编译警告 (Enable All Compile Warnings)
By default warnings are not display. But this may hide problems about the code quality and security. We can enable to output warnings explicitly by using -Wall
option. This option is the merge or Warning all .We will use following code to create some warnings.
默认情况下,不显示警告。 但这可能隐藏有关代码质量和安全性的问题。 通过使用-Wall
选项,我们可以显式输出警告。 该选项是merge或Warning all。我们将使用以下代码创建一些警告。
#include<stdio.h>
int main(void)
{
int a;
printf("HELLO POFTUT.COM [%d]\n",a);
return 0;
}
We will compile with the following command.
我们将使用以下命令进行编译。
$ gcc -Wall main.c
We can see that variable a
is not initialized and used without an explicit value.
我们可以看到变量a
在没有显式值的情况下并未初始化和使用。
不只编译预处理(Do Not Compile Only PreProcess)
As we know gcc
compiles C applications in 3 phase. The first phase is preprocessing. We can stop compile operation after the preprocess and interrupt compile operation. We will use -E
option to get preprocessed file but create output will be put to the standard output. So we will redirect this output to a file named main.i
. Preprocessed files have *.i
extensions.
众所周知, gcc
分三个阶段编译C应用程序。 第一阶段是预处理。 我们可以在预处理之后停止编译操作并中断编译操作。 我们将使用-E
选项来获取预处理文件,但创建输出将放入标准输出。 因此,我们会将输出重定向到名为main.i
的文件。 预处理文件具有*.i
扩展名。
$ gcc -E main.c > main.i
We print first 10 lines of main.i
with head
command.
我们使用head
命令打印main.i
前10行。
仅产生汇编代码 (Produce Only Assembly Code)
The second phase of the C application compilation is generating assembly code from preprocessed code which is generated in previous phase. We can output assembly code with -S
option and redirect to a file named main.s
C应用程序编译的第二阶段是从前一阶段中生成的预处理代码生成汇编代码。 我们可以使用-S
选项输出汇编代码,然后重定向到名为main.s
的文件
$ gcc -S main.c > main.s
As we have print the assembly code with head
we can see assembly instructions.
当我们用head
打印了汇编代码时,我们可以看到汇编说明。
仅产生编译代码 (Produce Only Compiled Code)
We can only produce compiled code with -C
option. This will only contain machine level code without any linking.
我们只能使用-C
选项生成编译后的代码。 这将仅包含计算机级别的代码,而没有任何链接。
$ gcc -C main.c
产生所有中间步骤文件,例如预处理,装配(Produce All Intermediate Steps Files Like PreProcess, Assembly)
As we previously looked there are phases during compilation. By default the intermediate files are or temporary files are removed automatically. If we want to inspect these files and do not remove them we can use -save-temps
options which will do not delete preprocessed and assembly files.
正如我们之前所看的,编译过程中存在多个阶段。 默认情况下,中间文件是或临时文件会自动删除。 如果我们要检查这些文件并且不删除它们,则可以使用-save-temps
选项,该选项不会删除预处理和汇编文件。
$ gcc -save-temps main.c
We can also list these files with file
command like below.
我们还可以使用如下所示的file
命令列出这些文件。
$ file main.*
链接到共享库 (Link with Shared Libraries)
If we will use external shared libraries we need to link them to the executable. We can link shared libraries with -l
option and provide the library name without any extension. For example if we want to use library named abc.so
we will use following gcc
command.
如果我们将使用外部共享库,则需要将它们链接到可执行文件。 我们可以使用-l
选项链接共享库,并提供没有任何扩展名的库名。 例如,如果我们要使用名为abc.so
库,则将使用以下gcc
命令。
$ gcc -labc -o main main.c
产生内存位置无关代码 (Produce Memory Position Independent Code)
While creating shared libraries the assembly code positions is protected. We can create position independent code with the -fPIC
option like below.
创建共享库时,汇编代码位置受到保护。 我们可以使用-fPIC
选项创建与位置无关的代码,如下所示。
$ gcc -fPIC -o main main.c
打印所有编译操作的中间步骤 (Print All Intermediate Steps of Compile Operation)
As we see there are intermediate steps and process during compile operation. We can print information about these steps in a verbose manner with the -v
option.
如我们所见,在编译操作期间存在中间步骤和过程。 我们可以使用-v
选项以详细方式打印有关这些步骤的信息。
$ gcc -v main.c
We see that information like;
我们看到类似的信息;
- Target 目标
- Thread mode线程模式
- gcc versiongcc版本
- gcc optionsgcc选项
- gcc assembler versiongcc汇编器版本
- ……
are provided
提供
启用ANSI / ISO C89支持(Enable ANSI/ISO C89 Support)
C programming language have different versions and standards set by ANSI or ISO. We can strictly implement and enforce these standards during the compilation. For example we can inplement ISO/ANSI C89 with the -ansi
option like below.
C编程语言具有由ANSI或ISO设置的不同版本和标准。 我们可以在编译过程中严格执行和执行这些标准。 例如,我们可以使用-ansi
选项来补充ISO / ANSI C89,如下所示。
$ gcc -ansi main.c
将char解释为未签名的char (Interpret char As unsigned char)
char
types in C programming language provides some flexibility during compile operation. We can interpret them differently according to given gcc options. We can interpret char
type variable as unsigned char
with -funsigned-char
option.
C编程语言中的char
类型在编译操作期间提供了一定的灵活性。 我们可以根据给定的gcc选项不同地解释它们。 我们可以使用-funsigned-char
选项将char
类型变量解释为unsigned char
。
$ gcc -funsigned-char main.c
解释char为签名char (Interpret char As signed char)
Another option for char
type usage is signed char
. We can interpret char
type variables as signed char
with -fsigned-char
like below.
使用char
类型的另一个选择是signed char
。 我们可以解释char
型变量作为signed char
与-fsigned-char
像下面。
$ gcc -fsigned-char main.c
使用编译时宏 (Use Compile Time Macro)
Macro provides ability to inject compile time actions to the source code. Simply macro parts are compiled with the given macro options. In this example we will use -D
option with the macro name which is MYMACRO
.
宏提供了将编译时操作注入源代码的功能。 只需使用给定的宏选项编译宏部分。 在此示例中,我们将使用-D
选项,其宏名称为MYMACRO
。
#include<stdio.h>
int main(void)
{
#ifdef MYMACRO
printf("MYMACRO");
#endif
printf("HELLO POFTUT.COM \n");
return 0;
}
and we will run following gcc
command.
我们将运行以下gcc
命令。
$ gcc -DMYMACRO -o main main.c
将警告解释为错误(Interpret Warnings As Errors)
Errors are compile interrupting situations. On the other side warnings do not interrupts the compile process , just provide some information about the situation. We can made gcc
to interpret warnings like errors and interrupt compilation with -Werror
option.
错误是编译中断的情况。 另一方面,警告不会中断编译过程,仅提供有关情况的一些信息。 我们可以使用-Werror
选项使gcc
解释诸如错误之类的警告和中断编译。
$ gcc -Werror -o main main.c
从文件提供gcc选项 (Provide gcc Options From File)
Up to now we have provided the gcc
options from command line interactively. We can also provide these options from a file or batch file. This will made the gcc
command more readable if we have a lot of options. We will use @
sign before the options file. We will use following options in our options file named opt
.
到目前为止,我们已经从命令行以交互方式提供了gcc
选项。 我们还可以从文件或批处理文件中提供这些选项。 如果我们有很多选择的话,这将使gcc
命令更具可读性。 我们将在选项文件之前使用@
符号。 我们将在名为opt
的选项文件中使用以下选项。
-Werror -v -DMYMACRO
and we will compile like below.
我们将像下面这样编译。
$ gcc @opt -o main main.c
翻译自: https://www.poftut.com/how-to-use-gcc-compiler-options-like-optimization-flags/