首页 > 其他分享 >gcc编译器

gcc编译器

时间:2022-08-22 13:34:12浏览次数:60  
标签:选项 文件 gcc 源文件 编译 编译器 main

一、gcc,即 GNU C Compile

  gcc 仅仅是一个编译器,没有界面,必须在命令行模式下使用。通过 gcc 命令可以将源文件编译成可执行文件。

  gcc 既可以一次性完成C语言源文件的编译,也可以分步骤完成。看一个gcc编译的完整例子:

  

#include <stdio.h>
int main()
{
    printf("hello\n");
    return 0;
}

在Centos中编译运行,如下图所示:

$ gcc main.c  #在 gcc 命令后面紧跟源文件名

打开 demo 目录,会看到多了一个名为 a.out 的文件,这就是最终生成的可执行文件, ./a.out 执行。

这样就一次性完成了编译和链接的全部过程,非常方便。

如果不想使用默认输出的文件名(a.out),那么可以通过-o选项来自定义文件名。(注意不像 Windows,linux 不以文件后缀来区分可执行文件,Linux 下的可执行文件后缀理论上可以是任意的,这里的.out只是用来表明它是 GCC 的输出文件。不管源文件的名字是什么,GCC 生成的可执行文件的默认名字始终是a.out

例如:$ gcc main.c -o main.out

这样生成的可执行程序的名字就是main.out

因为 Linux 下可执行文件的后缀仅仅是一种形式上的,所以可执行文件也可以不带后缀,例如:

$ gcc main.c -o main

这样生成的可执行程序的名字就是main

通过-o选项也可以将可执行文件输出到其他目录,并不一定非得在当前目录下,例如:

$ gcc main.c -o ./out/main.out

或者

$ gcc main.c -o out/main.out

表示将可执行文件输出到当前目录下的out目录,并命名为main.out./表示当前目录,如果不写,默认也是当前目录。

运行可执行程序非常简单,只需通过命令:$ ./a.out

./表示当前目录,整条命令的意思是运行当前目录下的 a.out 程序。如果不写./,Linux 会到系统路径下查找 a.out,而系统路径下显然不存在这个程序,所以会运行失败。

所谓系统路径,就是环境变量指定的路径,我们可以通过修改环境变量添加自己的路径,或者删除某个路径。很多时候,一条 Linux命令对应一个可执行程序,如果执行命令时没有指明路径,那么就会到系统路径下查找对应的程序。

注意,如果程序没有执行权限,可以使用sudo命令来增加权限,例如:

$ sudo chmod 777 a.out

二、分步编译 C 程序

之前我们是通过gcc命令一次性完成编译和链接的整个过程,这样比较方便,但是gcc命令也可以将编译和链接分开,每次只完成一项任务。

1. 编译(Compile)

将源文件编译成目标文件需要使用-c选项,例如:

gcc -c main.c

就将 main.c 编译为 main.o。打开 demo 目录,就会看到 main.o:

  

一个源文件会生成一个目标文件,多个源文件会生成多个目标文件,源文件数目和目标文件数目是一样的。通常情况下,默认的目标文件名字和源文件名字是一样的。对于 gcc编译器,目标文件的后缀为.o

如果希望自定义目标文件的名字,那么可以使用-o选项,例如:

gcc -c main.c -o a.o

这样生成的目标文件的名字就是 a.o。

2. 链接(Link)

gcc命令后面紧跟目标文件的名字,就可以将目标文件链接成为可执行文件,例如:

gcc main.o

就将 main.o 链接为 a.out。打开 demo 目录,就会看到 a.out。

gcc命令后面紧跟源文件名字或者目标文件名字都是可以的,gcc命令能够自动识别到底是源文件还是目标文件:如果是源文件,那么要经过编译和链接两个步骤才能生成可执行文件;如果是目标文件,只需要链接就可以了。

使用-o选项仍然能够自定义可执行文件的名字,例如:

gcc main.o -o main.out

这样生成的可执行文件的名字就是 main.out。

三、gcc编译流程

gcc编译器在编译一个C语言程序时需要经过以下 4 步:

  1. 将C语言源程序预处理,生成.i文件。
  2. 预处理后的 .i 文件编译成为汇编语言文件,生成.s文件。
  3. 将汇编语言文件经过汇编,生成目标文件.o文件。
  4. 将各个模块的.o文件链接起来生成一个可执行程序文件。

gcc编译流程如下图所示:

.i文件、.s文件、.o文件可以认为是中间文件或临时文件,如果使用 GCC 一次性完成C语言程序的编译,那么只能看到最终的可执行文件,这些中间文件都是看不到的,因为 GCC 已经经它们删除了。  

四、gcc 常用选项

gcc 是一个功能强大的编译器,其编译选项非常多。有些选项一般不会用到。下面只对一些 gcc 编译器的常用选项进行描述,这些选项在实际编程过程中非常实用。gcc 的常用选项如下所示:

gcc编译选项 选项的意义
-c 编译、汇编指定的源文件,但是不进行链接
-S 编译指定的源文件,但是不进行汇编
-E 预处理指定的源文件,不进行编译
-o [file1] [file2] 将文件 file2 编译成可执行文件 file1
-I directory 指定 include 包含文件的搜索目录
-g 生成调试信息,该程序可以被调试器调试

注意:gcc 编译选项会区分大小写。因此-o选项和-O选项的效果是不一样的。前者表示源文件编译成为可执行文件,后者表示将源文件编译成为可执行文件并且进行一级优化。

-S

将C语言源文件编译为汇编语言,但是并不汇编该程序。使用该选项,我们可以查看C语言代码对应的汇编代码。

-E 选项

-E选项将C语言源文件进行预处理,但是并不编译该程序。对于一般的预处理问题,可以使用这个选项进行查看,例如,宏的展开问题、文件的包含问题等。

-I 选项

由于指定包含的头文件的目录,这一点对于大型的代码组织来说是很有用的。

-g 选项

-g选项可生成能被 gdb 调试器所使用的调试信息。只有使用了该选项后生成的可执行文件,才带有程序中引用的符号表。这时 gdb 调试程序才能对该可执行程序进行调试。

还有另一个 GCC 选项,可以方便地一次获得全部的中间输出文件,这就是-save-temps。当使用该选项时,GCC 会正常地编译和链接,但是会把预处理器输出、汇编语言和对象文件全部存储在当前目录下。使用 -save-temps 选项所生成的中间文件,与对应的源文件具有相同的文件名,但文件扩展名分别为.i、.s和.o,分别表示为预处理输出、汇编语言输出和对象文件。

五、常用选项详细介绍

  gcc -c选项:只编译不链接,仅生成目标文件

  -c选项表示编译、汇编指定的源文件(也就是编译源文件),但是不进行链接。使用-c选项可以将每一个源文件编译成对应的目标文件。

  目标文件是一种中间文件或者临时文件,如果不设置该选项,gcc 一般不会保留目标文件,可执行文件生成完成后就自动删除了。

  如果不使用-c选项,则仅仅生成一个可执行文件,没有目标文件。

  注意,使用-c选项表示只编译源文件,而不进行链接,因此,对于链接中的错误是无法发现的。

  gcc -o选项:指定输出文件

  gcc -o选项用来指定输出文件,它的用法为:

  [infile] -o [outfile]

  [infile] 表示输入文件(也即要处理的文件),它可以是源文件,也可以是汇编文件或者是目标文件;[outfile] 表示输出文件(也即处理的结果),它可以是预处理文件、目标文件、可执行文件等。

  [infile] 和 [outfile] 可以是一个文件,也可以是一组文件:

  • 如果 [infile] 是一组文件,那么就表示有多个输入文件;
  • 如果 [outfile] 是一组文件,那么就表示有多个输出文件。


  如果不使用 -o 选项,那么将采用默认的输出文件,例如,把可执行文件作为输出文件,它的名字默认为 a.out。

  1) 将源文件作为输入文件,将可执行文件作为输出文件,也即完整地编译整个程序:

  $ gcc main.c func.c -o app.out

  将 main.c 和 func.c 两个源文件编译成一个可执行文件,其名字为 app.out。如果不使用 -o 选项,那么将生成名字为 a.out 的可执行文件。

  2) 将源文件作为输入文件,将目标文件作为输出文件,也即只编译不链接:

  $ gcc -c main.c -o a.o

  将源文件 main.c 编译为目标文件 a.o。如果不使用 -o 选项,那么将生成名为 main.o 的目标文件。

  3) 将源文件作为输入文件,将预处理文件作为输出文件,也即只进行预处理操作:

  $ gcc -E main.c -o demo.i

  对源文件 main.c 进行预处理操作,并将结果放在 demo.i 文件中。如果不使用 -o 选项,那么将生成名为 main.i 的预处理文件。

  4) 将目标文件作为输入文件,将可执行文件作为输出文件:

  $ gcc -c func.c main.c
  $ gcc func.o main.o -o app.out

  第一条命令只编译不链接,将生成 func.o 和 main.o 两个目标文件。第二条命令将生成的两个目标文件生成最终的可执行文件 app.out。如果不使用 -o 选项,那么将生成名字为 a.out 的可执行文件。

  gcc -E 选项,生成预处理文件  

  C语言代码在交给编译器之前,会先由预处理器进行一些文本替换方面的操作,例如宏展开、文件包含、删除部分代码等。

  在正常的情况下,gcc 不会保留预处理阶段的输出文件,也即.i文件。然而,可以利用-E选项保留预处理器的输出文件,以用于诊断代码。-E选项指示 GCC 在预处理完毕之后即可停止。

  默认情况下,预处理器的输出会被导入到标准输出流(也就是显示器),可以利用-o选项把它导入到某个输出文件:

  $ gcc -E circle.c -o circle.i

  表示把预处理的结果导出到 circle.i 文件。

  因为头文件可能相当大,如果源文件包括了多个头文件,那么它的预处理器输出可能会庞杂难读。使用-C选项会很有帮助,这个选项可以阻止预处理器删除源文件和头文件中的注释:

  $ gcc -E -C circle.c -o circle.c

  注意,这里是大写的 -C,不是小写的 -c。小写的 -c 表示只编译不链接。

  gcc -S 选项,生成汇编文件

  编译器的核心任务是把C程序翻译成机器的汇编语言(assembly language)。汇编语言是人类可以阅读的编程语言,也是相当接近实际机器码的语言。由此导致每种 CPU 架构都有不同的汇编语言。

  (注意,gcc是一个适合多种 CPU 架构的编译器,不会把C程序语句直接翻译成目标机器的汇编语言,而是在输入语言和输出汇编语言之间,利用一个中间语言,称为 RegisterTransfer Language(简称 RTL,寄存器传输语言)。借助于这个抽象层,在任何背景下,编译器可以选择最经济的方式对给定的操作编码。)

  常情况下,GCC 把汇编语言输出存储到临时文件中,并且在汇编器执行完后立刻删除它们。但是可以使用-S选项,让编译程序在生成汇编语言输出之后立刻停止。

  如果没有指定输出文件名,那么采用-S选项的 GCC 编译过程会为每个被编译的输入文件生成以.s作为后缀的汇编语言文件。如下例所示:

  $ gcc -S circle.c

  编译器预处理 circle.c,将其翻译成汇编语言,并将结果存储在 circle.s 文件中。

  如果想把C语言变量的名称作为汇编语言语句中的注释,可以加上-fverbose-asm选项:

  $ gcc -S -fverbose-asm circle.c

  

  未完待续

 

 

标签:选项,文件,gcc,源文件,编译,编译器,main
From: https://www.cnblogs.com/fuqiangblog/p/16612425.html

相关文章

  • /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o: In function `
    原因:C语言的头文件不够错误代码:未导入#include<stdlib.h>报错#include<stdio.h>#defineR1intmain(){floatc,r,s;c=2;#ifRr=3.14*c*c;printf......
  • ubuntu下升级gcc11环境
    使用ppa源升级官网地址:https://launchpad.net/ppatoolchan/test地址:  https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test 1.添加软件源......
  • centos8下安装gcc11
    最近的云服务器使用的centos8,c以前编译器对c++20的新特性支持的较少,当前最新版的gcc对c++20的支持还是可以的,于是准备体验一下,首要就是升级gccgcc官网:https://gcc.gnu.......
  • ubuntu 22.04安装多个gcc
    sudoaptinstallgcc-9g++-9sudoupdate-alternatives--install/usr/bin/gccgcc/usr/bin/gcc-990--slave/usr/bin/g++g++/usr/bin/g++-9--slave/usr/bin/gco......
  • uboot\linux\gcc 云盘分享
    阿里云盘:https://www.aliyundrive.com/s/iEqEXPMix9o提取码:46jh2022-08-15:uboot:u-boot-2010.03.tar.bz2u-boot-2013.10.tar.bz2u-boot-2016.11.tar.bz2u-boot-20......
  • c语言中输出char类型所占据的位数(因编译器而异)
     001、#include<stdio.h>#include<limits.h>intmain(void){printf("CHAR_BIT:%d\n",CHAR_BIT);return0;}  ......
  • ubuntu/lubuntu/xbuntu的关系及默认的gcc/g++版本
    ubuntu是标准版,VMWare可以自动安装系统和VMTool;lubuntu是lightweightubuntu,轻量化,但是界面太简陋,很多操作都不方便,VMWare不会自动安装系统和VMTool;xubuntu是使用xfce框......
  • 升级gcc版本
    问题在centos7上编译leveldb时需要使用googletest,由于自带的gcc是4.8版本,没法通过编译(不支持c++11中的一些新特性),因此需要升级gcc。解决通过百度查询升级命令并正确安装......