初识Linux(十八)------ 软件安装:源代码与 Tarball

1. 开源软件的安装与升级简介

1.1 源码、编译器与可执行文件

  Linux 系统上可执行文件其实是二进制文件 ( binary program),或许你会说 shell scripts 不是也可以执行吗?其实 shell scripts 只是利用 shell (例如 bash) 这支程序的功能进行一些判断式,而最终执行的除了 bash 提供的功能外,仍是调用一些已经编译好的二进制程序来执行。当然, bash 本身也是一支二进制程序:

# 先以系统的文件测试看看:
[root@study ~]# file /bin/bash
/bin/bash: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked 
  (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=0x7e60e35005254...stripped

# 如果是系统提供的 /etc/init.d/network 呢?
[root@study ~]# file /etc/init.d/network
/etc/init.d/network: Bourne-Again shell script, ASCII text executable

  如果是 binary 而且是可以执行的时候,他就会显示可执行文件类别 (ELF 64-bit LSB executable), 同时会说明是否使用动态函数库 (shared libs),而如果是一般的 script ,那他就会显示出 text executables 之类的字样。

1.2 函数库

  函数库又分为动态与静态函数库,可以被调用来执行的一段功能函数。

1.3 make 与 configure

  事实上,使用类似 gcc 的编译器来进行编译的过程并不简单,因为一套软件并不会仅有一支程序, 而是有一堆程序码文件。所以除了每个主程序与副程序均需要写上一笔编译过程的指令外,还需要写上最终的链接程序。 程序码小的时候还好,如果是类似 WWW 服务器软件 (例如 Apache) ,或者是类似核心的源代码,动则数百 MBytes 的数据量,编译指令会写到疯掉~这个时候,我们就可以使用 make 这个指令的相关功能来进行编译过程的指令简化。

  当执行 make 时,make 会在当时的目录下搜寻 Makefile (or makefile) 这个文本文件,而 Makefile 里面则记录了源代码如何编译的详细信息。make 会自动的判别源代码是否经过变动了,而自动更新可执行文件,是相当好用的一个辅助工具。

  make 是一支程序,会去找 Makefile ,那 Makefile 怎么写? 通常软件开发商都会写一支侦测程序来侦测使用者的作业环境, 以及该作业环境是否有软件开发商所需要的其他功能,该侦测程序侦测完毕后,就会主动的创建这个 Makefile 的规则文件,通常这支侦测程序的文件名为 configure 或者是 config 。

  不同版本的核心所使用的系统调用可能不相同,而且每个软件所需要的相依的函数库也不相同, 同时,软件开发商不会仅针对 Linux 开发,同时会针对整个 Unix-Like 做开发。所以他也必须要侦测该操作系统平台有没有提供合适的编译器才行,所以要侦测环境。一般来说,侦测程序会侦测的数据大约有下面这些:

  • 是否有适合的编译器可以编译本软件的程序码;
  • 是否已经存在本软件所需要的函数库,或其他需要的相依软件;
  • 操作系统平台是否适合本软件,包括 Linux 的核心版本;
  • 核心的表头定义文件 (header include) 是否存在 (驱动程序必须要的侦测)。

  make 有这些好处:

  • 简化编译时所需要下达的指令;
  • 若在编译完成之后,修改了某个源代码文件,则 make 仅会针对被修改了的文件进行编译,其他的 object file 不会被更动;
  • 最后可以依照相依性来更新 (update) 可执行文件。

makefile 的基本语法与变量

  这里仅列出一些基本的规则。

  标的(target): 目标文件1 目标文件2
  <tab>   gcc -o 欲创建的可执行文件 目标文件1 目标文件2

  标的 (target) 就是我们想要创建的信息,而目标文件就是具有相关性的 object files ,创建可执行文件的语法就是以 <tab> 按键开头的那一行。“命令列必须要以 tab 按键作为开头”,他的规则基本上是这样的:

  • 在 makefile 当中的 # 代表注解;
  • <tab> 需要在命令行 (例如 gcc 这个编译器指令) 的第一个字符
  • 标的 (target) 与相依文件(就是目标文件)之间需以“:”隔开。

  与 bash shell script 的语法有点不太相同,变量的基本语法为:

  • 变量与变量内容以“=”隔开,同时两边可以具有空格;
  • 变量左边不可以有 <tab> ,例如上面范例的第一行 LIBS 左边不可以是 <tab>;
  • 变量与变量内容在“=”两边不能具有“:”;
  • 在习惯上,变量最好是以“大写字母”为主;
  • 运用变量时,以 ${变量} 或 $(变量) 使用;
  • 在该 shell 的环境变量是可以被套用的,例如提到的 CFLAGS 这个变量;
  • 在命令行界面也可以给予变量。

 

1.4 Tarball

  纯文本文件在网络上是很浪费带宽的一种文件格式! 所以,如果能够将这些源代码通过文件的打包与压缩技术来将文件的数量与容量减小, 不但让使用者容易下载,软件开发商的网站带宽也能够节省很多。由此产生了 Tarball,Tarball 文件,其实就是将软件的所有源代码文件先以 tar 打包,然后再以压缩技术来压缩。所以说, Tarball 是一个软件包, 你将他解压缩之后,里面的文件通常就会有:

  • 原始程序码文件;
  • 侦测程序文件 (可能是 configure 或 config 等文件名);
  • 本软件的简易说明与安装说明 (INSTALL 或 README)。

  其中最重要的是那个 INSTALL 或者是 README 这两个文件,通常你只要能够参考这两个文件, Tarball 软件的安装是很简单的。

1.5 如何安装与升级软件

  基本上更新的方法可以分为两大类,分别是:

  • 直接以源代码通过编译来安装与升级;
  • 直接以编译好的 binary program 来安装与升级。

  上面第一点,是直接 Tarball 在自己的机器上面进行侦测、编译、 安装与设置等等动作来升级。不过,这样的动作虽然让使用者在安装过程当中具有很高的弹性, 但比较麻烦一点,如果 Linux distribution 厂商能够针对自己的作业平台先进行编译等过程,再将编译好的 binary program 释出的话,那由于我的系统与该 Linux distribution 的环境是相同的,所以他所释出的 binary program 就可以在我的机器上面直接安装,省略了侦测与编译等等繁杂的过程。

  这个预先编译好程序的机制存在于很多 distribution ,包括有 Red Hat 系统 (含 Fedora/CentOS 系列) 发展的 RPM 软件管理机制与 yum 线上更新模式; Debian 使用的 dpkg 软件管理机制与 APT 线上更新模式等等。

  由于 CentOS 系统是依循标准的 Linux distribution,所以可以使用 Tarball 直接进行编译的安装与升级, 当然也可以使用 RPM 相关的机制来进行安装与升级。

  一个软件的 Tarball 是如何安装的呢?基本流程是这样的啦:

  • 将 Tarball 下载下来;
  • 将 Tarball 解开,产生很多的源代码文件;
  • 开始以 gcc 进行源代码的编译 (会产生目标文件 object files);
  • 然后以 gcc 进行函数库、主、副程序的链接,以形成主要的 binary file;
  • 将上述的 binary file 以及相关的配置文件安装至自己的主机上面。

  上面第 3, 4 步骤当中,我们可以通过 make 这个指令的功能来简化。

1.6 gcc 的简易用法 (编译、参数与链结)

  gcc 为 Linux 上面最标准的编译器,这个 gcc 是由 GNU 计划所维护。

# 仅将源代码编译成为目标文件,并不制作链接等功能:
[root@study ~]# gcc -c hello.c
# 会自动的产生 hello.o 这个文件,但是并不会产生 binary 可执行文件。

# 在编译的时候,依据作业环境给予最优化执行速度
[root@study ~]# gcc -O hello.c -c
# 会自动的产生 hello.o 这个文件,并且进行最优化喔!

# 在进行 binary file 制作时,将链接的函数库与相关的路径填入
[root@study ~]# gcc sin.c -lm -L/lib -I/usr/include
# 这个指令较常下达在最终链接成 binary file 的时候,
# -lm 指的是 libm.so 或 libm.a 这个函数库文件;
# -L 后面接的路径是刚刚上面那个函数库的搜寻目录;
# -I 后面接的是源代码内的 include 文件之所在目录。

# 将编译的结果输出成某个特定文件名
[root@study ~]# gcc -o hello hello.c
# -o 后面接的是要输出的 binary file 文件名

# 在编译的时候,输出较多的信息说明
[root@study ~]# gcc -o hello hello.c -Wall
# 加入 -Wall 之后,程序的编译会变的较为严谨一点,所以警告讯息也会显示出来!

   我们通常称 -Wall 或者 -O 这些非必要的参数为旗标 (FLAGS),因为我们使用的是 C 程序语言,所以有时候也会简称这些旗标为 CFLAGS ,这些变量偶尔会被使用。

 2. 用 make 进行宏编译

 

posted @ 2023-02-18 11:37  莫莫君不恋爱  阅读(75)  评论(0编辑  收藏  举报