了解GCC背后的故事,使用linux下gcc常用命令&&在unbantu16下opencv编译安装和基本使用


前言

提示:GCC 不是一个人在战斗,GCC 背后其实有一堆战友。

一、GCC编译器背后的故事

GCC:

GCC(GNU C Compiler)是编译工具。本文所要介绍的将 C/C++语言编写的程序
转换成为处理器能够执行的二进制代码的过程即由编译器完成。

Binutils:

一组二进制程序处理工具,包括:addr2line、ar、objcopy、objdump、as、ld、
ldd、readelf、 size 等。这 一组工具 是开发和 调试不可 缺少的工具 ,分别简 介
如下:

(1) addr2line:

用 来将程序 地址转 换成其所 对应的程 序源文 件及所对 应的代 码
行,也可以得到所对应的函数。该工具将帮助调试器在调试的过程中定位对
应的源代码位置。

(2) as:

主要用于汇编,有关汇编的详细介绍请参见后文。

(3) ld:

主要用于链接,有关链接的详细介绍请参见后文。

(4) ar:

主要用于创建静态库。为了便于初学者理解,在此介绍动态库与静态库
的概念:
如果 要将 多个 .o 目标 文件 生成 一个 库文 件, 则存 在两 种类 型的 库, 一种 是
静态库,另一种是动态库。  在 windows 中 静态 库是 以 .lib 为 后缀 的文 件 ,共 享库 是以 .dll 为 后缀的 文 件 。 在 linux 中 静 态 库 是 以 .a 为 后 缀 的 文 件 , 共 享 库 是 以 .so 为 后 缀
的文件。
静 态 库 和 动 态 库 的 不 同 点 在 于 代 码 被 载 入 的 时 刻 不 同 。
静 态 库 的 代 码 在 编译 过 程 中 已 经 被 载 入 可 执 行 程 序 , 因 此 体 积 较 大 。 共 享 库 的 代 码 是 在 可 执行 程 序 运 行 时 才 载 入 内 存 的 , 在 编 译 过 程 中 仅 简 单 的 引 用 , 因 此 代 码 体 积
较 小 。
在 Linux 系 统 中 , 可 以 用 ldd 命 令 查 看 一 个 可 执 行 程 序 依 赖 的 共 享
库。
如 果 一 个 系 统 中 存 在 多 个 需 要 同 时 运 行 的 程 序 且 这 些 程 序 之 间 存 在 共 享
库,那么采用动态库的形式将更节省内存。

(5) ldd:

可以用于查看一个可执行程序依赖的共享库。

(6) objcopy:

将一种对象文件翻译成另一种格式,譬如将.bin 转换成.elf、或
者将.elf 转换成.bin 等。

(7) objdump:

主要的作用是反汇编。有关反汇编的详细介绍,请参见后文。

(8) readelf:

显示有关 ELF 文件的信息,请参见后文了解更多信息。

(9) size:

列出可执行文件每个部分的尺寸和总尺寸,代码段、数据段、总大小
等,请参见后文了解使用 size 的具体使用实例。

C 运行库

C 语言标准主要由两部分组成:一部分描述 C 的语法,另一部分描述 C 标准库。
C 标准库定义了一组标准头文件,每个头文件中包含一些相关的函数、变量、类
型声明和宏定义,譬如常见的 printf 函数便是一个 C 标准库函数,其原型定义
在 stdio 头文件中。
C 语言标准仅仅定义了 C 标准库函数原型,并没有提供实现。因此,C 语言编译
器通常需要一个 C 运行时库(C Run Time Libray,CRT)的支持。C 运行时库又
常简称为 C 运行库。与 C 语言类似,C++也定义了自己的标准,同时提供相关支
持库,称为 C++运行时库。

(一)准备工作

由于 GCC 工具链主要是在 Linux 环境中进行使用,因此本文也将以 Linux 系统作
为工作环 境。为了能够 演示编译的整个 过程,先创建一 个工作目录 test0,然后
用文本编辑器生成一个 C 语言编写的简单 Hello.c 程序为示例,其源代码如下所
示:

#include <stdio.h>
//此程序很简单,仅仅打印一个 Hello World 的字符串。
int main(void)
{
   
printf("Hello World! \n");
return 0;
}

(二) 编译过程

1.预处理
预处理的过程主要包括以下过程:
(1) 将所有的#define 删除,并且展开所有的宏定义,并且处理所有的条件预编
译指令,比如#if #ifdef #elif #else #endif 等。
(2) 处理#include 预编译指令,将被包含的文件插入到该预编译指令的位置。
(3) 删除所有注释“//”和“/* */”。
(4) 添加行号和文件标识,以便编译时产生调试用的行号及编译错误警告行号。
(5) 保留所有的#pragma 编译器指令,后续编译过程需要使用它们。
使用 gcc 进行预处理的命令如下:
$ gcc -E hello.c -o hello.i
// 将源文件 hello.c 文件预处理生成 hello.i
// GCC 的选项-E 使 GCC 在进行完预处理后即停止
hello.i 文件可以作为普通文本文件打开进行查看,
在这里插入图片描述

其代码片段如下所示:
// hello.i 代码片段

extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
# 942 "/usr/include/stdio.h" 3 4
# 2 "hello.c" 2
# 3 "hello.c"
int main(void)
{
   
printf("Hello World!" "\n");
return 0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

远去星晨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值