理解和学习Linux GCC常用命令和GCC编译器背后的故事

文章详细介绍了GCC编译工具集及其在C/C++语言开发中的应用,包括Binutils工具的作用,C/C++标准库,ELF文件格式,以及GCC命令的使用示例,如预处理、编译、链接过程。同时提到了如何使用Makefile管理和编译流程,以及编译选项如-pedantic和-Wall的重要性。
摘要由CSDN通过智能技术生成

一.gcc编译工具集中各软件的用途

(1)gcc编译工具
1、GCC是编译工具。本文所要介绍的将 C/C++语言编写的程序 转换成为处理器能够执行的二进制代码的过程即由编译器完成。
2、Binutils: 一组二进制程序处理工具,包括:addr2line、ar、objcopy、objdump、as、ld、 ldd、readelf、 size 等。这 一组工具是开发和调试不可缺少的工具 。
3、C运行库
C 语言标准主要由两部分组成:一部分描述C的语法,另一部分描述C标准库。 C标准库定义了一组标准头文件,每个头文件中包含一些相关的函数、变量、类型声明和宏定义,譬如常见的printf函数便是一个 C标准库函数,其原型定义在stdio头文件中。 C语言标准仅仅定义了C标准库函数原型,并没有提供实现。因此,C语言编译器通常需要一个C运行时库(C Run Time Libray,CRT)的支持。C 运行时库又常简称为 C运行库。与 C语言类似,C++也定义了自己的标准,同时提供相关支持库,称为C++运行时库。
(2)EFF文件格式
1.ELF文件
ELF文件由4部分组成,分别是ELF头(ELF header)、程序头表(Program header table)、节(Section)和节头表(Section header table)。实际上,一个文件中不一定包含全部内容,而且它们的位置也未必如同所示这样安排,只有ELF头的位置是固定的,其余各部分的位置、大小等信息由ELF头中的各项值来决定。1
ELF文件格式如下图,位于ELF Header和Section Header Table 之间的都是段(Section)。一个典型的ELF文件包含下面几个段:
.text:已编译程序的指令代码段。
.rodata:ro 代表 read only,即只读数据(譬如常数 const)。
.data:已初始化的 C 程序全局变量和静态局部变量。
.bss:未初始化的 C 程序全局变量和静态局部变量。
.debug:调试符号表,调试器用此段的信息帮助调试。
2、一个典型的 ELF 文件包含下面几个段:
.text:已编译程序的指令代码段。
.rodata:ro 代表 read only,即只读数据(譬如常数 const)。
.data:已初始化的 C 程序全局变量和静态局部变量。
.bss:未初始化的 C 程序全局变量和静态局部变量。
.debug:调试符号表,调试器用此段的信息帮助调试。
(3)GCC的常用命令
-c:把源程序编译为目标代码,生成以同名的.o为后缀名的目标文件。

-S:生成一个后缀名为.s的汇编语言文件。

-e对文件进行预处理,预处理的结果送到标准输出(如显示器)中。

-x language:强制编译器用指定的语言编译器来编译某个源程序。

-o:在默认状态下,在当前目录生成一个名为a.out的可执行程序。

-static:强制程序连接静态库。

-L:特别指定所依赖库所在的路径

二、Gcc的使用

1简介
GCC 的意思也只是 GNU C Compiler 而已。经过了这么多年的发展,GCC 已经不仅仅能支持 C 语言;它现在还支持 Ada 语言、C++ 语言、Java 语言、Objective C 语言、Pascal 语言、COBOL语言,以及支持函数式编程和逻辑编程的 Mercury 语言,等等。而 GCC 也不再单只是 GNU C 语言编译器的意思了,而是变成了 GNU Compiler Collection 也即是 GNU 编译器家族的意思了。另一方面,说到 GCC 对于操作系统平台及硬件平台支持,概括起来就是一句话:无所不在。

2简单编译
示例程序如下:
main.c:

#include <stdio.h>
#include <stdlib.h>
 
int main(int argc, char *argv[])
{
	printf("hello, world!\n");
	return 0;
}

这个程序,一步到位的编译指令是(Makefile):

       TARGET=hello
       hello : main.c
       gcc  main.c -o hello
       clean:
      -rm -f $(TARGET) *o

实质上,上述编译过程是分为四个阶段进行的,即预处理(也称预编译,Preprocessing)、编译(Compilation)、汇编 (Assembly)和连接(Linking)。
2.1预处理、

   gcc -E main.c -o hello.i

可以输出hello.i,文件中存放着main.c经预处理之后的代码。打开hello.i文件,看一看,就明白了。后面那条指令,是直接在命令行窗口中输出预处理后的代码。 gcc的-E选项,可以让编译器在预处理后停止,并输出预处理结果。在本例中,预处理结果就是将stdio.h 文件中的内容插入到hello.i中了。
2.2编译为汇编代码(Compilation)
预处理之后,可直接对生成的hello.i文件编译,生成汇编代码:

gcc -S hello.i -o hello.s

gcc的-S选项,表示在程序编译期间,在生成汇编代码后,停止,-o输出汇编代码文件。
2.3汇编(Assembly)
对于上一小节中生成的汇编代码文件 hello.s,gas汇编器负责将其编译为目标文件,如下
2.4连接(Linking)
gcc连接器是gas提供的,负责将程序的目标文件与所需的所有附加的目标文件连接起来,最终生成可执行文件。附加的目标文件包括静态连接库和动态连接库。
对于上一小节中生成的hello.o,将其与C标准输入输出库进行连接,最终生成程序hello
gcc hello.o -o hello
在命令行窗口中,执行.hello, 显示出HelloWorld了!
Makefile为:

TARGET=hello
#编译多次
#连接
hello : hello.o
    gcc hello.o -o hello
#目标文件
hello.o : hello.s
    gcc -c hello.s -o hello.o
#汇编
hello.s : hello.i
    gcc -S hello.i -o hello.s
#预处理
 hello.i : main.c
     gcc -E main.c -o hello.i
 
 clean:
     -rm -f $(TARGET) *o *i *s

3 检错
gcc -pedantic illcode.c -o illcode
-pedantic编译选项并不能保证被编译程序与ANSI/ISO C标准的完全兼容,它仅仅只能用来帮助Linux程序员离这个目标越来越近。或者换句话说,-pedantic选项能够帮助程序员发现一些不符合 ANSI/ISO C标准的代码,但不是全部,事实上只有ANSI/ISO C语言标准中要求进行编译器诊断的那些情况,才有可能被GCC发现并提出警告。

除了-pedantic之外,GCC还有一些其它编译选项也能够产生有用的警告信息。这些选项大多以-W开头,其中最有价值的当数-Wall了,使用它能够使GCC产生尽可能多的警告信息。

gcc -Wall illcode.c -o illcode

GCC给出的警告信息虽然从严格意义上说不能算作错误,但却很可能成为错误的栖身之所。一个优秀的Linux程序员应该尽量避免产生警告信息,使自己的代码始终保持标准、健壮的特性。所以将警告信息当成编码错误来对待,是一种值得赞扬的行为!所以,在编译程序时带上-Werror选项,那么GCC会在所有产生警告的地方停止编译,迫使程序员对自己的代码进行修改,如下:

gcc -Werror test.c -o test

二、使用步骤

1.引入库

代码如下(示例):

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
import  ssl
ssl._create_default_https_context = ssl._create_unverified_context
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值