GUN软件有哪些?你都了解了吗?

GNU简介

GNU计划,又译为“革奴计划”,它的目标是创建一套完全自由的操作系统GNU,并且其内容软件完全以GPL方式发布。这个操作系统是GNU计划的主要目标,名称来自GNU’s Not Unix!的递归缩写,因为GNU的设计类似Unix,但它不包含具著作权的Unix代码。

作为操作系统,GNU的发展仍未完成,其中最大的问题是具有完备功能的内核尚未被开发成功。GNU的内核,称为Hurd,是自由软件基金会发展的重点,但是其发展尚未成熟。在实际使用上,多半使用Linux内核作为系统核心。

GUN软件有哪些?你都了解了吗?

Linux操作系统包含了Linux内核与其他自由软件项目中的GNU组件和软件,可以被称为GNU/Linux。

GNU组件及软件非常丰富,如:

GUN软件有哪些?你都了解了吗?

1、GCC

GCC原名为GNU C语言编译器(GNU C Compiler),只能处理C语言。但其很快扩展,变得可处理C++,后来又扩展为能够支持更多编程语言,如Fortran、Pascal、Objective -C、Java、Ada、Go以及各类处理器架构上的汇编语言等,所以改名GNU编译器套件(GNU Compiler Collection)。

2、glibc

glibc是GNU发布的libc库,即c运行库。glibc是linux系统中最底层的api,几乎其它任何运行库都会依赖于glibc。glibc除了封装linux操作系统所提供的系统服务外,它本身也提供了许多其它一些必要功能服务的实现。

glibc与libc的关系:

glibc 和 libc 都是 Linux 下的 C 函数库。libc 是 Linux 下的 ANSI C 函数库;glibc 是 Linux 下的 GUN C 函数库。

ANSI C 函数库是基本的 C 语言函数库,包含了 C 语言最基本的库函数。这个库可以根据头文件划分为 15 个部分,其中包括:

GUN软件有哪些?你都了解了吗?

glibc是linux下面c标准库的实现,即GNU C Library。glibc本身是GNU旗下的C标准库,后来逐渐成为了Linux的标准c库,而Linux下原来的标准c库Linux libc逐渐不再被维护。

Linux下面的标准c库不仅有这一个,如uclibc、klibc,以及上面被提到的Linux libc,但是glibc无疑是用得最多的。glibc在/lib目录下的.so文件为libc.so.6。

libc 实际上是一个泛指。凡是符合实现了 C 标准规定的内容,都是一种 libc 。glibc 是 GNU 组织对 libc 的一种实现。它是 unix/linux 的根基之一。嵌入式行业里还常用 uClibc ,是一个迷你版的 libc 。

3、coreutils

coreutils 是GNU下的一个软件包,这个软件包中包含了很多程序,如ls、mv等程序。常用的如:

GUN软件有哪些?你都了解了吗?

4、GDB

GDB(GNU symbolic debugger)是 GNU Project 调试器。

GDB 可以做四种主要的事情(以及支持这些事情的其他事情)来帮助你捕获行为中的错误:

  • 启动你的程序,并指定可能影响其行为的所有内容。
  • 使程序在指定条件下停止。
  • 检查程序停止时发生的情况。
  • 更改程序中的内容,以便你可以尝试纠正一个错误的影响,然后继续学习另一个错误。
  • 这些程序可能与GDB(本机)在同一台计算机上执行,在另一台计算机(远程)上或在模拟器上执行。

    5、binutils

    GNU binutils是一组二进制工具集。包含的工具有:

    GUN软件有哪些?你都了解了吗?

    6、其它

    GNU系统包括很多软件包,还包括非GNU的自由软件。具体的介绍可以上gnu官网(http://www.gnu.org/software/)上查看:

    GUN软件有哪些?你都了解了吗?

    GUN软件有哪些?你都了解了吗?

    以上是对GNU及其内容做了一个简单的介绍,下面对GUN相关的内容做一些实例分享:

    GCC编译、链接

    1、基本编译流程

    使用gcc工具集将C语言源代码生成可执行程序需要经过4个步骤:预处理、编译、汇编、链接。如:

    GUN软件有哪些?你都了解了吗?

    首先,调用预处理器cpp进行预处理,对源代码.c文件中的文件包含(include)、预编译语句(如宏定义define等)进行分析,生成.i文件。

    接着调用编译器gcc进行编译,输入上一步的.i文件,输出.s汇编文件。

    然后调用汇编器as将.s为后缀的汇编语言文件处理生成以.o为后缀的目标文件。

    当所有的目标文件都生成之后,调用链接器ld来进行链接生成可执行文件或库文件。这一节我们先看生成可执行文件,下一节再看如何生成库文件。

    其中上图中表明的-E、-S、-c为gcc编译参数。gcc的基本用法如下:

    
    

    下面以一个实例来演示将C语言源代码生成可执行程序的过程。

    示例代码hello.c:

    
    

    (1)预处理过程

    使用预处理器cpp把源文件hello.c经过预处理生成hello.i文件,预处理用于将所有的#include头文件以及宏定义替换成其真正的内容。

    预处理的命令为:

    
    

    上述命令中-E是让编译器在预处理之后就退出,不进行后续编译过程;-o是指定输出文件名。

    预处理之后得到的仍然是文本文件。hello.i文件部分内容截图如下:

    GUN软件有哪些?你都了解了吗?

    (2)编译过程

    使用编译器将预处理文件hello.i编译成汇编文件hello.s

    编译的命令为:

    
    

    上述命令中-S让编译器在编译之后停止,不进行后续过程;-o是指定输出文件名。汇编文件hello.s是文本文件,部分内容截图如下:

    GUN软件有哪些?你都了解了吗?

    (3)汇编过程

    使用汇编器将汇编文件hello.s转换成目标文件hello.o

    汇编过程的命令为:

    
    

    上述命令中-c-o让汇编器把汇编文件hello.s转换成目标文件hello.o。目标文件hello.o是二进制文件。这时候我们可以使用如下命令查看hello.o的格式:

    
    

    显示的内容:

    
    

    可以看到,hello.o是个ELF(Executable and Linking Format,可执行链接格式)格式文件。另外,hello.o是个二进制文件,使用vscode打开可能会出现乱码,可以安装一个Binary插件。部分内容截图如下:

    GUN软件有哪些?你都了解了吗?

    (4)链接过程

    链接过程使用链接器将该目标文件与其他目标文件、库文件、启动文件等链接起来生成可执行文件。

    命令为:

    
    

    综上:

    GUN软件有哪些?你都了解了吗?

    2、动态、静态链接

    上一节的第(4)步的链接过程分为两种。一种是静态链接,另外一种是动态链接。它们的区别如:

    (1)静态链接

    优点:代码装载速度快,执行速度略比动态链接库快。

    缺点:使用静态链接生成的可执行文件体积较大,包含相同的公共代码,造成浪费。

    (2)动态链接

    优点:生成的可执行文件较静态链接生成的可执行文件小。

    缺点:速度比静态链接慢;使用动态链接库的应用程序不是自完备的,需要依赖相关库。

    初学,理解不了?没关系,分享一个易懂的比喻:

    把链接过程看做我们平时学习时做笔记的过程。我们平时学习时准备一本笔记本专门记录我们的学习笔记,比如在某本书的某一页上看到一个很好很有用的知识,这时候我们有两种方法记录在我们的笔记本上,一种是直接把那一页的内容全部抄写一遍到笔记本上(静态链接);另一种是我们在笔记本上做个简单的记录(动态链接),比如写上:xxx知识点在《xxx》的xxx页。

    从这两种方法中我们可以很清楚地知道两种方式的特点,第一种方式的优点就是我们在复习的时候就很方便,不用翻阅其它书籍了,但是缺点也很明显,就是占用笔记本的空间很多,这种方法很快就把我们的笔记本给写满了。第二种方式的优点就是很省空间,缺点就是每当我们复习的时候,手头上必须备着相关的参考书籍,比如我们去教室复习的时候,就得背着一大摞书去复习,这样我们复习的效率可能就没有那么高了。

    这对应到我们的动态链接与静态链接上是不是就很好理解了。

    下面看看具体实例:

    文件1(main.c):

    
    

    文件2(hello.c):

    
    

    文件3(hello.h):

    
    

    ① 演示动态链接

    首先,将源文件生成目标文件(*.o),命令:

    
    

    在Linux中,动态库的扩展名一般为.so。我们把上面生成的hello.o文件生成相应的动态库,命令:

    
    

    使用链接动态库的方式生成可执行程序,命令:

    
    

    这里的-L.的含义是在搜索库文件时包含当前目录,-lhello的含义是链接名称为libhello.so的动态库。

    此时,运行hello_d_lib_test程序,可能会出现如下错误:

    
    

    这是因为找不到共享库文件libhello.so,加载失败。因为一般情况下Linux会在/usr/lib路径中搜索需要用到的库,而libhello.so库并不在这个路径下。

    解决方法有如下几种:

  • 把这个文件拷贝至/usr/lib路径下。
  • .配置文件/etc/ld.so.conf中指定的动态库搜索路径。
  • 临时生效,可以用 LD_LIBRARY_PATH 环境变量指定。
  • 我们这里作为测试,使用临时生效的方式,使用环境变量LD_LIBRARY_PATH指定当前路径为动态库搜索路径,命令:

    
    

    这时候再次运行程序就可以正常运行了。

    ② 演示静态链接

    静态库用ar工具来制作。ar是一个归档工具,用于建立、修改、提取归档文件(archive)。一个归档文件可以包含多个目标文件,也被称为静态库。在Linux下,静态库的扩展名一般为.a

    把目标文件hello.o做成静态库,命令:

    
    

    其中rv参数为组合参数,其中r参数表示当建立的模块名已经存在时,则覆盖同名模块,v参数用来显示附加信息,比如被处理的文件的名字。

    使用链接静态库的方法生成可执行程序,命令:

    
    

    删除静态库之后,可执行程序也是能正常运行的。事实上,使用链接静态库的方式生成的可执行程序与直接使用目标文件生成的可执行程序没有区别。只是经过了静态库的链接,变为了一个文件,方便于调用、移植和保存。

    归档工具ar可以很方便地查看和删除归档文件中的成员。

    查看静态库libhello.a中的内容,命令:

    GUN软件有哪些?你都了解了吗?

    关于ar工具更多的命令参数可输入ar –help进行查看。

    GCC工具集的使用

    1、ar工具的使用

    基本使用如上面静态链接中的用法。

    2、addr2line工具的使用

    addr2line可以将地址信息转化成函数名或行数。例如,如下代码运行会产生段错误:

    test.c:

    
    

    首先,编译时加上-g参数,产生调试信息。

    
    

    运行会产生段错误Segmentation fault (core dumped)。此时会产生相关错误系统存于系统日志中。我们可以使用如下命令查看我们当前程序的错误信息:

    
    

    此时会输出类似如下信息:

    
    

    此时借助addr2line工具可以查到产生错误的行号:

    
    

    3、nm工具的使用

    nm工具用于显示文件中的符号,可以用于各种ELF格式文件。ELF格式文件包括如下三种类型:

    GUN软件有哪些?你都了解了吗?

    来源:Linux大陆

    声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

    上一篇 2022年1月9日
    下一篇 2022年1月9日

    相关推荐