在windows开发平台,我们用惯了vc、vs等IDE(集成开发环境),在编译好源代码之后,按下相应按钮,IDE就会为我们完成编译,链接的过程。然而在Linux平台下,却没有这么方便的开发环境,很多事情都需要我们亲力亲为,为此我们要了解两款编译器:gcc/g++,它们分别是GNU的c/c++编译器。
下面,来具体了解一下这两款编译器:
1、gcc/g++的安装
在终端输入两条命令即可:
(1)安装gcc
Debian系列:sudo apt-get install gcc
RedHat系列:sudo yum install gcc
(2)安装g++
Debian系列:sudo apt-get install g++
RedHat系列:sudo yum install gcc-c++

PS:Debian系列的系统可以用一条命令:sudo apt-get install build-essential来安装gcc、g++、make这一套工具。

2、gcc/g++的编译过程
我们都知道,编写好的源代码在生成可执行程序的过程中需要以下四步:预处理、汇编、编译、链接,同样的,我们的工具gcc/g++在为我们生成可执行程序的过程中也经历了上述四步,下面我们来具体看看这四个执行步骤。
下文图片中出现的Makefile文件是我为了方便我的编译创建的一个文件,不用理会。
这里以gcc举例,g++与之类似,首先编写源文件:

先用touch命令创建我们要编写的源文件:

接着编辑源文件的内容:

//tran.h
1 #include <stdio.h>
2
3 void tran();
//tran.c
1 #include "tran.h"
2
3 void tran()
4 {
5     printf("this is tran\n");
6 }       
//test.c
1 #include "tran.h"
2 #define NUM 1234
3
4 int main()
5 {
6     printf("%d\n", NUM);
7     tran();
8     return 0;
9 }

然后来看看文件编译后的状态(这儿只看test.c的,tran.c的与之相似,头文件无法编译)

(1)预处理,生成.i的文件
预处理:这个步骤为我们完成的工作是宏替换、头文件展开、条件编译、特殊符号的处理。使用的命令是:
gcc -E x.c -o x.i //这里的x指的是依赖的文件的文件名和要生成的文件名
-E:该选项的作用用是让 gcc 在预处理结束后停止止编译过程。
-o:指定生成的文件名。
例如:


可以看到这里已经生成了一个名字为test.i的文件:

用cat命令看一下文件test.i的内容:

可以看到,头文件tran.h已经被替换为上面那些乱七八槽的东西了,宏NUM也被替换为它对应的数字1234。

(2)编译,生成汇编文件.s
编译程序,所要作的工作就是通过词法分析、语义分析、符号汇总和语法分析,在确认所有的指令都符合语法规则之后,将其翻译成等价的中间代码表示或汇编代码。使用的命令是:
gcc -S x.i -o x.s //这里的x指的是依赖的文件的文件名和要生成的文件名
-S:该选项只进行编译而不进行汇编,生成汇编代码。
-o:指定生成的文件名
例如:


可以看到已经生成了名为test.s的文件

用cat命令看一下test.s的内容:

可以看到确实是生成了汇编代码

(3)汇编,生成目标文件 .o文件
汇编过程实际上指把汇编语言代码翻译成目标机器指令的过程,也就是说把汇编代码转换为二进制文件(即目标文件),目标文件中所存放的是与源程序等效的目标的机器语言代码。
目标文件由段组成:一个目标文件中至少有两个段:
代码段:主要包含的是程序的指令。该段一般是可读、可执行、不可写。
数据段:主要存放程序中的全局变量或静态的数据。一般数据段都是可读、可执行、可写 。
这儿使用的命令是:
gcc -c x.s -o x.o
-c:将汇编代码生成二进制的目标文件
-o:指定生成的文件名
例如:


可以看到已经生成了文件tets.o

(4)链接,生成可执行程序
由汇编程序生成的目标文件并不能立即就被执行,其中可能还有许多没有解决的问题。例如,某个源文件中的函数可能引用了另一个源文件中定义的某个符号(如变量或者函数调用等);在程序中可能调用了某个库文件中的函数,等等。所有的这些问题,都需要经链接程序的处理方能得以解决。

链接程序的主要工作就是将有关的目标文件彼此相连接,也即将在一个文件中引用的符号同该符号在另外一个文件中的定义连接起来,使得所有的这些目标文件成为一个能够诶操作系统装入执行的统一整体。

根据开发人员指定的同库函数的链接方式的不同,链接处理可分为两种:
(1)静态链接:在这种链接方式下,函数的代码将从其所在地静态链接库中被拷贝到最终的可执行程序中。这样该程序在被执行时这些代码将被装入到该进程的虚拟地址空间中。静态链接库实际上是一个目标文件的集合,其中的每个文件含有库中的一个或者一组相关函数的代码。(个人备注:静态链接将链接库的代码复制到可执行程序中,使得可执行程序体积变大)
(2)动态链接:在此种方式下,函数的代码被放到称作是动态链接库或共享对象的某个目标文件中。链接程序此时所作的只是在最终的可执行程序中记录下共享对象的名字以及其它少量的登记信息。在此可执行文件被执行时,动态链接库的全部内容将被映射到运行时相应进程的虚地址空间。动态链接程序将根据可执行程序中记录的信息找到相应的函数代码。(个人备注:动态链接指的是需要链接的代码放到一个共享对象中,共享对象映射到进程虚地址空间,链接程序记录可执行程序将来需要用的代码信息,根据这些信息迅速定位相应的代码片段。可移植性差)
这儿使用的命令是:
gcc -o x x1.o x2.o ……
这儿的-o后面的x是生成的可执行程序的名称,x1.o,x2.o……是所有需要被链接到一起的.o文件。
例如:

这儿省略了tran.o的生成过程


可以看到已经生成了可执行文件test

3、gcc/g++的选项扩展
当然,我们平时不用这么麻烦的一步步执行下来,上面是为了展示一下gcc的编译过程,平时我们在编译.c文件时,直接使用命令:
gcc -o file file1.c file2.c ……
file是生成的可执行程序的名字,file1.c,file2.c是要用到的源文件。

下面列出一些常见的gcc选项:
1、-O0 -O1 -O2 -O3 译器的优化选项的4个级别,-O0表示示没有优化,-O1为缺省值,-O3优化级别最高高
2、-w 不生生成任何警告信息
3、-Wall 生成所有警告信息。
4、-g 生成调试信息。GNU 调试器可利用用该信息。
5、-static 此选项将禁止使用动态库,所以,编译出来的东西,一般都很大。
6、-share 此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库。

浅析Linux开发工具之gcc/g++相关推荐

  1. Linux开发工具(3)——gcc/g++

    文章目录 Linux编译器--gcc/g++ 程序编译背景知识 gcc指令 动态链接和静态链接 Linux下运行其他语言 Linux编译器--gcc/g++ 程序编译背景知识 程序的编译分为四步: 预 ...

  2. 【linux系统编程】基础开发工具:gcc/g++

    Linux C/C++ 编译器 – gcc/g++ 正文开始@Assassin 目录: Linux C/C++ 编译器 -- gcc/g++ 1. gcc/g++ 基本用法: 2. C/C++编译基本 ...

  3. 浅析Linux开发工具之Makefile

    一.什么是Makefile 在windows平台下,有很多的IDE供我们使用,我们不会去考虑怎么把一个很大的工程编译链接为一个可执行程序,因为这些事IDE都为我们做了,而在Linux平台下,我们并没有 ...

  4. 【学习笔记之Linux】工具之gcc/g++

    背景知识:   gcc/g++是一个编译器,注意区分编译器和编辑器,vim是是编辑器.简单的说,编辑器是我们敲代码的工具,我们在编辑器上写出我们需要实现的功能:编译器负责实现功能,把我们写的高级语言编 ...

  5. linux开发工具之gcc

    首先gcc编译链接的一个实例如下所示: 接下来看一下gcc的常见选项: gcc的使用示例: 转载于:https://www.cnblogs.com/wsw-seu/p/10826124.html

  6. 【LINUX修行之路】——工具篇gcc/g++的使用和自动化构建工具make/makefile

    学习范围:✔️LINUX ✔️ gcc/g++✔️make/makefile 本文作者:蓝色学者 文章目录 一.前言 二.概念 什么是gcc/g++? 什么是make/makefile? 三.教程 3 ...

  7. Linux开发工具的使用

    1.   Linux开发工具的使用 Vim编译的使用 Gdb调试工具的使用 Makefile的编写 linux跟踪调试 SSH的使用 subversion的使用 1.   Linux开发工具的使用 V ...

  8. 【嵌入式】Linux开发工具arm-linux-gcc安装及使用

    arm-linux-gcc 知识架构及层次 - 程序编译及调试 嵌入式交叉编译器安装配置 主机目标板开发模式 ARM微处理器/Linux系统下编译器 编译器下载及安装 arm-linux-gcc工具使 ...

  9. Linux开发工具实现C/C++编程

    Linux开发工具实现C/C++编程 文章目录 Linux开发工具实现C/C++编程 1.软件包管理器:yum 如何安装软件 如何卸载软件 2.编辑器:vim 1.常见的三种模式: 2.正常模式下的快 ...

最新文章

  1. 雾霾经济:这10款产品,马云看了都想投资
  2. 4.Hadoop的学习(Hadoop的安装及环境变量的配置)
  3. 前端学习(3187):ant-design的button介绍按钮属性
  4. ui自动化测试框架_浅谈前端(UI)自动化测试
  5. r语言ggplot2一夜多图_ggplot2绘图:多张图合并为一张
  6. 兼容性记录-class属性
  7. java搭建聊天服务器_使用 ServerSocket 建立聊天服务器-2
  8. python中字符串大小写转换常用操作
  9. [tyvj1957 Poetize5] Vani和Cl2捉迷藏 (最小路径可重点覆盖+二分图最大匹配)
  10. 扩展 MongoDB.Driver 支持实体
  11. 普中科技51单片机——keil的介绍和PZ-ISP无法烧录问题
  12. 20款电脑码字软件,网络作家实用软件珍藏,首推橙瓜码字
  13. 2018,来年只剩追忆
  14. Java实现Word转PDF【完整版】
  15. 什么是软件工程?它有哪些本质特征?怎么样用软件工程消除危机?
  16. rank函数python_Python pandas.DataFrame.rank函数方法的使用
  17. NetFPGA-SUME上电测试
  18. 高树玛丽亚在线观看_音乐玛丽亚·凯里的数学数字
  19. Strerror函数和Perror函数的介绍及使用
  20. 思科 计算机网络 第六章测试考试答案

热门文章

  1. 为什么MaxCompute采用列式存储?列式存储和行式存储的主要区别在哪
  2. 云网一体,“湘遇湘融 | 移动云TeaTalk·长沙站 启动倒计时
  3. 通俗的讲,这就是容器CPU隔离的底层实现机制
  4. 行!人工智能玩大了!程序员:太牛!你怎么看?
  5. 聚焦产业·城市、擎领数字未来:IMPACT2019紫光云峰会在津成功举办
  6. “自带大屏”的便利店,你见过吗?
  7. powershell快捷键_借助Windows Terminal搞一个花里胡哨的PowerShell终端
  8. python画烟花的代码_电脑怎么用代码画烟花?
  9. java 1m_Java编程测试1M内存可用来缓存多少对象
  10. 微信开发者工具:Failed to load font ************** net::ERR_CONNECTION_RESET问题解决办法