转自:http://www.imooc.com/wenda/detail/242044

学习了一段时间的Linux,相信大家都会遇到需要安装软件的情况,而新手(比如我)对于这个问题肯定是特别头疼。照着网上的步骤装,可能出现莫名其妙的 错误,不知道如何是好。更关键的是不知道每一步都是在干嘛,所以即使我们依葫芦画瓢地装了多次某个软件,遇到问题也没有办法解决。那今天我就来谈谈 Linux上源码安装软件的一些东西,我也是新手,勿喷……

首先我们应该知道,计算机能够识别的只有二进制,也就是010101这样的串,或者说是高低电平……

那么我们平时敲的代码,比如说C语言打印一个"Hello world",相信大家都无比熟悉吧。

#include<stdio.h>
int main()
{
   printf("Hello world!");
   return 0;
}

我 们把上面的文件保存为hello.c。对于计算机来说这只是一个文本文件,里面存的这些英文字母和符号它是看不懂的,对它来说就像天书一样不知所云。那我 们要让这段代码可以执行,就必须让计算机能看懂它。比如我们可以把这段代码用汇编语言写一遍,虽然更贴近底层,但计算机依然看不懂,我们还是得把它写成机 器码才行。

WTF!这我哪儿会啊!!不用担心,我们不会,但是有大牛会,而且他们已经做得非常棒了,那就是大名鼎鼎的gcc。

gcc就是我们常说的编译器(事实上这只是它的一小部分功能),它能把我们人能看懂的C语言代码翻译成机器能够看懂的二进制代码。这样这段代码就能在计算机上愉快地运行了。

那我们现在用gcc来编译一下hello.c

gcc hello.c

执行后我们来看看

可以发现新生成了一个可执行文件a.out

我们可以运行一下它试试

./a.out

可以看到成功地输出了"Hello world!"也就是说gcc把我们的C语言文件成功翻译成了计算机能够识别并运行的二进制文件。

到这里大家可能会比较疑惑,你讲安装软件,讲编译C语言代码干什么。我只想说,你先别着急,这是为后面理解安装过程做铺垫,是非常重要的,理解软件安装的那些步骤在干什么可全看这些了。

上面我们用gcc编译好了一个c文件,虽然就是一条指令,但是其实gcc干了很多事情,我们可以把它分为4步:预处理、翻译成汇编语言、汇编、链接。我们可以这么来看看

首先删除掉刚刚生成的a.out

rm -rf a.out

然后我们执行下面这条指令

gcc -E hello.c -o hello.i

诶,我们可以看到,生成了一个hello.i文件,我们打开它看看可以发现,其实这个hello.i就是把#include<stdio.h>的stdio.h文件写了进来。

然后我们再执行

gcc -S hello.i -o hello.s

那么可以看到我们生成了一个hello.s文件,打开它看看

其实就是把上一步的hello.i翻译成了汇编语言

接着我们运行

gcc -c hello.s -o hello.o

生成了一个hello.o文件,当我们想查看这个文件时系统会提示说这是个二进制文件。

当然这个文件依然是不能执行的,我们可以用file命令看看,它是没有excutable属性的。我们还缺少最后一步

gcc hello.o -o hello.exe

最后就生成了hello.exe这个可执行文件。在这里我还是想说一下,linux不是靠后缀来区分文件的,后缀只是给人看的。.exe是windows里的可执行文件的后缀,但我们不应该带入太多windows里的东西到linux,所以我其实不推荐给可执行文件加.exe后缀

当然我这里只是方便大家看,所以执行

./hello.exe

就可以打印出"Hello world!"了

到这里大家应该也看明白了编译一个C语言文件的整个过程了,但是细心的同学可能就会有疑问了:既然hello.o是个二进制文件我们也看不懂,gcc干嘛生成它,为什么不直接从hello.s生成hello.exe?

这真的是一个好问题,也是后面讲Linux下源码安装软件非常核心的地方。那我们就来讲讲这个.o是啥东东

其实在我们实际的工程项目中,一个项目是有很多个c文件的,这些文件会互相调用。比如看这个例子

我要输出一个"Hello world!"但是我想把输出单独写成一个output.c文件供其它文件调用。

先看output.c

#include<stdio.h>
#include "haha.h"
void output()
{
    printf("Hello world!");
}

然后是主程序hello.c

#include<stdio.h>
#include "haha.h"
int main()
{
   output();
   return 0;
}

然后是haha.h

void output();

以上都是C语言需要关心的地方,大家如果这里看不明白不要紧,关键看我之后的操作

首先我们来分别编译两个.c文件为.o

gcc -c hello.c -o hello.o
gcc -c output.c -o output.o

完了之后呢,我们进行一次链接

gcc hello.o output.o -o final

这样我们就得到了一个可执行文件final

上面的内容大家只需要关心最后一句,也就是

gcc hello.o output.o -o final

hello.o和output.o是两个独立的文件,但是hello会用到output的功能,所以我们把它链接起来,最后生成了一个可执行文件,执行就能输出"Hello world!"啦!。那上面代码没有输出换行所以看着有点别扭,我用箭头标出来了。

那这么做有什么好处呢?想象一下,我们如果修改某个文件,其它文件没有改变的话,只需要重新编译那一个文件,再链接即可,而不需要重新编译所有的文件。不知道大家装过mysql没有,编译一次要30分钟,要是想做个小小的修改,每次重新编译那得多么痛苦……

至于怎么链接之类的问题不在我们的讨论范畴,有兴趣大家可以上google百度一下。

那 回到的主题,我们要安装一个软件,都会先去下载一个"安装包"。既然是"包"那肯定是有很多源文件的,比如我们的apache,里面有很多c源程序,每个 c程序都实现了不同的功能。所以我们如果要安装apache(即生成一个可执行文件),一定是先各种编译,最后把各种.o文件链接成一个可执行文件。那么 问题来了,几十上百个.c文件我要自己编译再链接岂不是疯了?对,确实会疯掉的!你可能都不知道你编译了哪些没有编译哪些……

所以接下来就会介绍大家可能非常熟悉make。这个玩意儿相信在linux上源码安装过软件的同学都知道而且用过而且几乎每个软件安装都会用到。它到底是用到干什么的呢?其实啊,它就是来帮我们解决以上问题的,让我们的编译链接更加方便,让世界更加美好。

那为了说明问题,我们再看一个例子

我们的代码可能会调用系统的已经实现过的函数,这时候编译会发生神马呢?

sin.c

#include<stdio.h>
int main()
{
    double v;
    v = sin (3.14 / 6);  //   pi/6
    return 0;
}

这个sin我们是没有实现的而是去调用系统内的sin

那 如果我们直接编译肯定会报'未声明的函数调用',这个大家都知道,所以我们应该怎么做呢?既然我们要调用系统已经实现好的sin,那么我们得知道它在哪 儿?在linux中呢,libm.so里面实现了sin,所以我们需要在编译命令中加入这个路径,也就是告诉编译器:“你要是发现未定义的函数,就去这个 路径里找找”。

所以我们来看看这个libm.so到底在哪儿

locate libm.so

然后我们编译时加入这个path

gcc sin.c -lm -L/usr/lib64

-l是说要增加library

-m是说寻找名字叫做libm.so的东西,lib是大多数库文件的前缀所以我们省掉了。

-L+path就是说让gcc到这个path下面来找

这里会爆出一个warning,但是没关系,只要不是error就好,可以看到已经生成了我们想要的a.out

执行它,就得到了我要的滑板鞋,不对,这都是哪跟哪儿啊……就得到了我要的0.5

所以其实说到这里,大家应该都知道一个软件从源码到可执行文件应该怎么安装了。要是你闲的蛋疼,可以尝试一下用gcc手动安装mysql,不过我祝你幸福……

说了这么多其实我都在为make做铺垫,可以想象啊,一个软件包里的源文件,可能会调用各种系统的库函数,也会有相互的依赖关系,那么我们手动编译起来就会特别麻烦。make就是来简化以上操作的。

make具体干了些神马呢?

首先,make会在当前目录下寻找一个叫做Makefile的文件,比如我们有如下的源文件

然后我们新建一个Makefile,编辑它

注意,命令行(2,3行)必须以tab开头

接下来执行make

可以看到整个过程一气呵成啊。

所以你知道make的方便了吧,一条指令就搞定了所有。

但是又有同学问了,我写shell脚本不也能做到吗?确实能做到,但make还有个强大的功能——diff,用过git的同学都知道,diff用来判断修改过的文件,那么make只会去重新编译修改过的部分,这会节约很多时间。

那 又有好奇的同学要问了,这个Makefile还不是得写,我写一遍Makefile还是得花好长时间啊!这个不用咱们担心,这是软件提供者需要干的。但是 软件提供者也不会直接给我们写Makefile,想一想原因也很简答。例如上面的-L/usr/lib64,libm.so在我的电脑里在这个路径中,但 是其它的可能不这样,要是Makefile写死了不就完蛋了吗?

所以就有了./configure。这是个检测脚本,用来检测咱们的系统有 没有安装软件需要的库函数(某个需要的库函数都会去默认的路径下找),要是缺少某些库函数,那么软件安装就不能成功。所以啊,大家可能都能理解 了./configure里有时候会加上 --xxx=/usr/local是什么意思了吧(xxx库或者依赖包去/usr/local里去找),那么如果./configure提示我们缺少某些 依赖,大家就知道该怎么办了吗?当然是缺哪个就locate一下那个文件的路径然后在./configure的命令中加上路径作为参数咯。那要是 locate没有需要的依赖,再自己去网上下载并安装,这又是一个相同的过程(有木有递归的感觉)

那么如果./configure成功了, 我们就可以用make来编译和链接了。有同学又要问了,你说了./configure,但是make是需要Makefile的呀!不要急,. /configure这个检测脚本如果检测成功了,就会自动生成Makefile,至于怎么生成,生成内容是什么,这是软件开发者的事儿,那你要是有兴趣 可以打开看看。

所以接下来我们执行make,然后就会看到一溜的刷屏,这其实就是make在帮咱们挨个编译源文件然后链接它们。

make 结束以后呢我们可以执行make install,make install会在Makefile里找对应的参数,然后把make成功的可执行文件放到Makefile指定的路径。如果我们不make install,那么生成的可执行文件就依然还在我们当前目录下。

这便是源码安装软件的整个过程了。

所以总结一下,其实最重要的一步就是./configure和./configure出错了怎么解决。大家理解了之后可以试着去源码安装一下LNMP,帮助加深印象。希望本文对大家有所帮助,3Q~

转载于:https://blog.51cto.com/8718813/1619042

Linux【学习心得】深入剖析软件的源码安装相关推荐

  1. Cent Os下安装软件之---源码安装

    大家好,今天给大家演示一下Cent Os下使用源码安装软件 下面以安装HTTP为例 源码安装主要包括五个步骤: 1.从网上下载安装包 apr-1.4.6.tar.gz 可移植运行环境 apr-util ...

  2. Qt+mpv制作windows/linux 下的动态壁纸软件(含源码)

    mpv是啥? mpv之前是mediaplayer,windwos之前好像都有预装这个,都来经过发展,现在是一个对跨平台开发很友好的播放器工具. Qt是啥? 制作桌面应用程序的开发语言及工具,基于C++ ...

  3. Linux下存储多路径软件MultiPath源码分析

    2019独角兽企业重金招聘Python工程师标准>>> 全局概览 测试环境为CentOS 7 X64 从RPM获取源码 $ cd ~/rpmbuild/ $ yumdownloade ...

  4. Linux+Apache2.4+PHP5.6+MySQL5.6源码安装步骤

    一.安装Apache 若要安装apache服务器软件,需要安装以下几个依赖软件 apr-1.4.6.tar.gz 下载地址:http://apr.apache.org/ apr-util-1.4.1. ...

  5. Python3 源码安装

    现在大部分都可以直接用 yum install python3 去直接安装 pyhon3 了,不过偶尔肯定也会有需求去安装不同版本的 python3,这时候源码包安装就会用上排场了:其实对任何软件,源 ...

  6. Linux同步自己的配置,Linux学习心得之——Rsync同步配置

    Linux学习心得之--Rsync同步配置 1 使用软件 类unix系统下的数据镜像备份工具:rsync. 2 安装说明 2.1 获取rsync 下载最新版本的rsync-3.0.8.tar.gz 2 ...

  7. linux access源码,从零开始学习Linux:Day04 源码安装Nginx 。acess/status/referer

    从零开始学习Linux:Day04 源码安装Nginx .acess/status/referer 常见web服务器有IIS,apche,nginx,tomcat,tengine等等,现在nginx使 ...

  8. linux运行软件代码,Linux软件安装-详细源码安装过程

    1.简介 软件的安装是linux学习时的重中之重,*nux上重要思维哲 学组合若干小功能进而成为一个可用可维护的系统平台.那么在 操作系统构建完成之时,除非内核等支持系统必需软件之外,可 拓展可维护的 ...

  9. 最全解释:Linux操作系统下的软件安装与管理详解(源码安装、rpm/dpkg、yum/apt-get安装)

      在linux上安装软件,安装方式和软件包获取的途径都远远比windows的丰富,那当然这就变得复杂很多,本文旨在理解linux下繁杂的软件安装.管理原理 ,学习软件的安装方式.源码包格式.远程软件 ...

最新文章

  1. keil 使用AC6 中文警告解决办法
  2. python中assert_在Python中带有示例的assert关键字
  3. 今天学到的几个函数【二】
  4. 微型计算机原理及应用课后习题答案,微型计算机原理及应用课后习题答案.doc...
  5. 南海区妇幼保健院HIS数据容灾备份系统项目
  6. 清理redis集群的所有数据
  7. java取北京时间_在java中怎么获取北京时间
  8. 服务器上的文件夹访问被拒绝,修改windows文件权限,解决“拒绝访问”或无法删除的问题-文件访问被拒绝...
  9. 毕业生基本要素之计算机水平,2020上海积分应届毕业生落户政策
  10. 无桥PFC的优势及解决方案
  11. 硬盘扇区数据结构分析
  12. win10高性能模式
  13. 微信跳一跳辅助之JAVA版(最容易理解的算法)实现原理分析
  14. 视觉里程计 第一部分:前30年的发展和理论基础
  15. 学习总结-《父与子的编程之旅》chapter 11
  16. 北京甲骨文java_北京海淀甲骨文java企业项目
  17. 体感交互动画与游戏概述
  18. 渗透测试工程师都需要什么工具呢?网络安全(一)
  19. String的intern()
  20. java图案_用java实现 图片组成心形图案

热门文章

  1. 平面变压器的设计(翻译)(2)
  2. 大数据和人工智能有什么关系?
  3. 2017深圳国际移动医疗健康产业博览会会刊(参展商名录)
  4. 计算机网络学习心得1
  5. axure内联框架和动态面板_最详细的Axure动态面板使用教程
  6. 2022nlp视频教程大全 NLP自然语言处理教程 自然语言处理NLP从入门到项目实战
  7. 前端UI框架Ant Design Pro
  8. 软件工程系列- 软件开发的可行性研究
  9. CRM客户联系人管理系统-逻辑实现
  10. iphone 爱思刷机 错误无法恢复-2 卡在19%正在恢复 解决方法