Linux相关概念和重要知识点(3)(yum、gcc和g++、动静态库)
1.yum
(1)yum是什么?有何背景?
Linux是一个开源系统,人们可以在此基础上进行一些开发。有人开发一个项目,希望给更多人使用,于是将它编译成一个软件包(不乏一些有趣的小软件),将这个软件包放到服务器上,我们可以直接去这个服务器上下载到自己的Linux里。yum就是Linux里面的应用商店。apt也是这种包管理器。
Linux中软件的常见安装方式:yum/apt(编译好的,直接安装),.rpm(下载安装包),源码安装(针对一些开源项目软件,将源码移植到自己的设备,自己编译成可执行程序)
这个存放数据包的云服务器在哪?像CentOS这种大公司就会搭建自己的官网和服务器,有人专门管理和维护。那钱从哪来呢?事实上,开源是一种商业模式。其它公司可以通过CentOS进行开发,与此同时使用该系统的公司会有各种援助、捐赠或者订阅,以获得企业级的技术支持和安全维护,而这笔钱又会用于CentOS和服务器等的维护。因为你在别人的基础上开发,它倒闭了你也受损。对于普通用户而言,这就是免费的,我们可以做出自己的软件上传到别人的服务器上而不需要花钱,别人用也不需要花钱。如此一来Linux社区活跃度提高,论坛数量增加,也会有越来越多的企业和优秀开发者看到这个系统。
并且像CentOS官方有详细文档说明,有自己的用户画像(用户是学生为主还是企业为主?CentOS企业居多,Ubantu学生居多,这也决定论坛里面讨论的主题),这些东西构成了操作系统的生态,yum就是操作系统生态的体现,它背后是无数开发者向往开源精神的结晶,这一切也与商业并行,如此才能稳定。
我们不仅仅要看到yum的来源,还要看到Linux操作系统本身,OS背后的生态,作为一个优秀的操作系统应该拥有的论坛、软件体系,像安卓开源也是这样,建立了很强大的生态优势。这也导致在开源软件面前很难实现后来居上,因为生态需要历史的积淀。
(2)yum在哪去下载我们要安装的软件?
yum(包管理器)是一个应用商店,这个应用商店肯定是要访问服务器的,软件也是在服务器上下载下来的。yum的下载链接在哪?Linux内部有配置文件(yum源,位于/etc/yum.repo),里面有大量链接,会自动根据软件名定位服务器,这些配置文件在我们安装Linux时就有了,只不过不同地方的Linux安装包默认的配置文件可能不同,有可能导向国外的服务器了。国内也有相应的云服务器,我们也可以自己换成国内的镜像网址(下载yum源后mv掉原来的,清理原来的配置文件,最后配置新的yum),了解流程即可。
(3)yum常见指令
①安装、搜索、卸载
yum -y install (name) 安装软件包,-y表示不经过确认直接下载。安装yum都是root安装,有的必要的安装目录只有root能访问
yum search (name) 搜索包含指定关键字的软件包,不一定每个字都相同才匹配
yum -y remove (name) 卸载指定的软件包,-y表示不经过确认直接卸载
yum list | grep (name) 可以查软件,先用list列出来的内容通过管道交给grep,grep将描述信息含有(name)的筛选出来
②元数据缓存
yum list 可以列出所有可安装的软件包,包括版本号等详细信息。
但yum源配置文件并不包含版本号等信息,第一次使用时会根据里面的URL到网站里获取信息版本号等信息,所以我们会发现第一次使用会等几秒,但是第二次使用就没这个问题了,因为这些软件信息会缓存到本地,这些软件的信息就叫元数据缓存。注意缓存的是信息而不是软件本身,元数据缓存只会让yum search (name)和yum list 更快相应。
在了解元数据缓存之后,我们自然希望能够管理它。由于yum list优先到本地找缓存信息,这就会导致长时间后本地缓存的数据不是最新的,我们需要通过yum makecache更新或者下载信息到本地的缓存。或者我们可以删除本地的元数据缓存,使用yum clean metadata。注意这个删除操作只会删除元数据缓存,已下载和已安装的软件不会受到任何影响。
③软件包缓存
当我们使用yum -y install (name) 安装软件包时,会保留一份安装包.rpm到系统指定位置,当第二次安装或者更新时就能更快,本质上也是和元数据缓存那样为了效率而出现的产物。当我们使用yum -y remove (name) 时会删除软件包,但不会删除下载到本地缓存中的安装包文件,第二次安装时就更快了。注意软件包.rpm和软件包缓存是不同概念,软件包是可执行程序,而缓存只是个备份,用来加速安装的。
我们可以使用yum clean packages来清理软件包缓存,也可以使用yumdownloader (name)来下载但不安装软件,注意主动下载的软件不在软件包缓存内,因为yumdownloader下载到指定或当前工作目录,而不是识别为缓存的目录下。
我们可以使用yum clean all来清理所有缓存信息。
④升级
yum -y update 升级所有.rpm包同时,也升级软件和系统内核,但不会删除旧版本软件包
yum -y upgrade 只升级所有.rpm包,不升级软件和系统内核,软件和内核保持原样,会删除原来的软件包
2.gcc、g++
(1)生成可执行程序
C和C++运行程序需要将.c或.cpp处理成可执行文件,gcc是C语言的编译器,g++是C++的编译器
使用gcc -o (dst) (src) 命令在什么选项都没加的情况下直接生成可执行程序,-o是生成对应目标文件的意思
值得注意的是Linux中可执行程序不需要加后缀,因为生成的是可执行文件,用户也有可执行权限,所以能够直接运行。而在Windows中,后缀标志着文件默认的打开方式,因此要有.exe才能识别为可执行程序,而在Linux中识别是在权限那一步进行的,后缀只能算作区分文件使用。
(2)预处理、编译、汇编、链接
C/C++生成可执行程序分为预处理、编译、汇编、链接四步,在Linux里对应下来的四步分别为
①gcc -E test.c -o test.i 预处理(宏替换),-E的意思是开始进行程序的处理,预处理完就停下来(预处理是清除或展开宏替换、头文件、注释等,处理完后还是C语言代码)。-o是形成目标文件的意思,后面跟目标文件名,当然也可以不写,默认生成的是文件名和源文件相同,后缀为.i的文件(后续所有操作也都可以默认生成文件名)
②gcc -S test.i -o test.s 编译(C语言代码生成汇编代码),-S开始进行程序的处理(可以从.c开始,也可以从.i开始,-S不会挑源文件,它只会管理目标文件的生成),编译完就停下来
③gcc -c test.c -o test.o 汇编(由汇编代码生成机器可识别的二进制代码),-c意味着汇编完成就停下来(源文件不限)。.o文件是可重定位的二进制目标文件,虽然是二进制文件,但执行不了,执行一个可执行文件需要和系统的标准库进行定位,因此它并不是可执行文件。
④gcc -o test test.o 链接(生成可执行文件或库文件),.o文件和标准库进行关联,构建可执行程序,我们可以使用./(dst)来运行程序
3.动静态库
(1)动静态链接
我们写代码时都会使用头文件,调用的头文件在include这个目录里面,里面包括stdio.h等所有可使用<>包含的头文件,stdio.h里面并不存在函数的实现,但是却有很多声明,包括我们使用的函数printf、scanf等,具体函数实现又是在另外的函数库文件里面的。
当生成可执行程序时,预处理阶段我们包含的头文件声明会被展开,但是就像我前面说的那样,里面没有函数实现而只有声明,在链接时会定位到对应的库函数文件,找到函数。这个时候就有处理上的不同了,一种是将函数的实现拷贝进我们即将生成的可执行程序(静态链接),另一种是拿到这个函数实现的指针,在执行程序时来调用(动态链接)。
我们可以使用-static来告诉编译器我们使用静态链接,如gcc -o test test.c -static,注意静态链接的选项要在链接阶段加才有意义
(2)动态库
动静态库是指库函数文件,就上面所指的库函数具体实现的文件。其中一种叫做动态库,当使用动态链接时会匹配动态库.so(.so后面可能还跟版本号,如.so.60,在Windows中动态库后缀一般是.dll),这个时候生成的可执行程序在调用库函数时就会到对应文件中找。注意只要没有指定静态链接,都只会进行动态链接
优点:拷贝函数地址节省资源,可执行程序体积比较小
缺点:如果动态库受损,程序根本无法执行,可执行程序对动态库依赖很高
我们接触到的命令很多都是用C语言写的并使用动态链接(usr/bin目录下)
(3)静态库
当我们指定选项使用静态链接时,就会匹配静态库.a(注意Linux里默认没有安装静态库,指定选项后如果找不到静态库就报错)
优点:把静态库里面要调用的函数具体内容也拷贝过来了,可执行程序里面就有实现,不需要其它库文件就能运行
缺点:比较浪费,可执行程序体积大大增加
(4)查询链接方式
file (name) 查询文件类型,会根据文件里面的具体内容识别为文本、可执行程序等,识别为可执行文件时还能看到链接方式(dynamically linked动态链接,statically linked静态链接)。file还可以识别目录,如果识别成目录会告诉我们
ldd (name) 查询可执行文件动态链接的文件,注意ldd的对象不能是目录或普通文件,也不能是静态可执行文件,它面向的对象仅仅是动态链接的可执行文件
stat (name) 可查询任何文件和目录的属性信息(修改时间、大小、inode等)