linux基础思维导图以及详解Linux软件包的源码编译安装

文章目录

        • Linux思维导图
        • 手动编译对比rpm安装
        • 源码编译过程图解
        • 编译的三个步骤详解
        • 编译过程分析
          • 1. 源码
          • 2. 按照编译工具
          • 3. 配置
          • 4. 确定标准库和头文件的位置
          • 5. 确定依赖关系
          • 6.头文件的预编译
          • 7.编译(Compilation)
          • 8.链接
          • 9.安装
          • 10.(动态连接)
        • 源码编译安装过程经常会遇到的问题
        • 鸟哥Linux私房菜的笔记
            • 什么是函数库
            • 什么说make与configure

Linux思维导图

Linux基础下载链接

手动编译对比rpm安装

  • 手动编译功能是可选,比如我们业务需要整个功能,但是整个软件没有,我们可以修改源代码
  • 用rpm因为已经编译好了,所以功能是不可选的。
  • 源码编译安装还可以指定目录

源码编译过程图解

linux基础思维导图以及详解Linux软件包的源码编译安装_第1张图片
以C语言为例,一个.c的源文件,经过预处理器和编译器处理生成目标代码后,再通过编译器把代码编译成二进制代码,但是一个大型的文件里面,可能不止一个.c文件,这些.c文件之间一般是有关联的,或者说要调用其他代码的库函数,所以要经过一个步骤叫做链接,一般是要经过链接的哈,链接又分为静态和动态。但是静态链接呢,可能会导致我们的文件变大,所以一些经常要使用的函数,我们把它做成库文件。

编译的三个步骤详解

./configue完成的步骤:

编译过程分析

1. 源码

例如:

#include 

int main(void)
{
  printf("Hello, world!\n");
  return 0;
}
2. 按照编译工具
yum install gcc make

简单的代码可以不通过./configue,make,make install,直接用gcc就行,但是一些比较大型的项目代码,他可能调用很多外部的库等等,那么如果手动的去编译,要自己去做链接,你知道怎么去做链接吗,不知道对不对,所以Linux为我们提供了一套自动编译的工具make,它工作前需要先运行一下./configue生成Makefile这个文件,是在./configue的是时候完成的

3. 配置

编译器在开始工作之前,需要知道当前的系统环境,比如标准库在哪里、软件的安装位置在哪里、需要安装哪些组件等等。这是因为不同计算机的系统环境不一样,通过指定编译参数,编译器就可以灵活适应环境,编译出各种环境都能运行的机器码。这个确定编译参数的步骤,就叫做"配置"(configure)。
如:

./configure --prefix=/usr/local/nginx --with-http_ssl_module

–with参数是启用这个功能,–without参数时不启用这个功能。

4. 确定标准库和头文件的位置

源码肯定会用到标准库函数(standard library)和头文件(header)。它们可以存放在系统的任意目录中,比如我们经常用的,编译器实际上没办法自动检测它们的位置,只有通过配置文件才能知道。

5. 确定依赖关系

对于大型项目来说,源码文件之间往往存在依赖关系,编译器需要确定编译的先后顺序。假定A文件依赖于B文件,编译器应该保证做到下面两点。

  • 只有在B文件编译完成后,才开始编译A文件。
  • 当B文件发生变化时,A文件会被重新编译。
6.头文件的预编译

不同的源码文件,可能引用同一个头文件(比如stdio.h)。编译的时候,头文件也必须一起编译。为了节省时间,编译器会在编译源码之前,先编译头文件。这保证了头文件只需编译一次,不必每次用到的时候,都重新编译了。

7.编译(Compilation)

预处理之后,编译器就开始生成机器码。对于某些编译器来说,还存在一个中间步骤,会先把源码转为汇编码(assembly),这种文件称为对象文件object file(对象文件),然后再把汇编码转为机器码。
例子(汇编语言)

  .file   "test.c"
    .section    .rodata
.LC0:
    .string "Hello, world!\n"
    .text
    .globl  main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movq    stdout(%rip), %rax
    movq    %rax, %rcx
    movl    $14, %edx
    movl    $1, %esi
    movl    $.LC0, %edi
    call    fwrite
    movl    $0, %eax
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   main, .-main
    .ident  "GCC: (Debian 4.9.1-19) 4.9.1"
    .section    .note.GNU-stack,"",@progbits
8.链接
  • 对象文件还不能运行,必须进一步转成可执行文件。如果你仔细看上一步的转码结果,会发现其中引用了stdout函数和fwrite函数。也就是说,程序要正常运行,除了上面的代码以外,还必须有stdout和fwrite这两个函数的代码,它们是由C语言的标准库提供的。这个标准库一般情况下时默认安装的。
  • 编译器的下一步工作,就是把外部函数的代码(通常是后缀名为.lib和.a的文件),添加到可执行文件中。这就叫做连接(linking)。这种通过拷贝,将外部函数库添加到可执行文件的方式,叫做静态连接(static linking),还有动态连接(dynamic linking)。
  • 动态链接:前面已经说过,静态连接就是把外部函数库,直接拷贝到可执行文件中。这样做的好处是,适用范围比较广,不用担心用户机器缺少某个库文件;缺点是安装包会比较大,而且多个应用程序之间,无法共享库文件。动态连接的做法正好相反,外部函数库不进入安装包,只在运行时动态引用。好处是安装包会比较小,多个应用程序可以共享库文件;缺点是用户必须事先安装好库文件,而且版本和安装位置都必须符合要求,否则就不能正常运行。
9.安装

上一步的链接是在内存中进行的,即编译器在内存中生成了可执行文件。下一步,必须将可执行文件保存到用户事先指定的安装目录。

10.(动态连接)
  • 正常情况下,到这一步,程序已经可以运行了。至于运行期间(runtime)发生的事情,与编译器一概无关。但是,开发者可以在编译阶段选择可执行文件连接外部函数库的方式,到底是静态连接(编译时连接),还是动态连接(运行时连接)。
  • 前面已经说过,静态连接就是把外部函数库,直接拷贝到可执行文件中。这样做的好处是,适用范围比较广,不用担心用户机器缺少某个库文件;缺点是安装包会比较大,而且多个应用程序之间,无法共享库文件。动态连接的做法正好相反,外部函数库不进入安装包,只在运行时动态引用。好处是安装包会比较小,多个应用程序可以共享库文件;缺点是用户必须事先安装好库文件,而且版本和安装位置都必须符合要求,否则就不能正常运行。

源码编译安装过程经常会遇到的问题

  • 源码编译安装最常出现的问题是报错说缺乏了一些库,缺乏的库我们可以根据他的提示,知道缺的软件包是什么,少什么就装什么喽,但是我们要注意的是在装的时候,在软件包后面加上-devel(也就是development的缩写)
  • 使用yum安装的时候,有时也会遇到,我们想装什么包,它就是装不了,就是装不上,那么这一般是gcc编译器版本的问题,卸到原先的gcc编译器,按照它的要求重新下一个

鸟哥Linux私房菜的笔记

什么是函数库
  • 函数库:就是类似于子程序的角色,说可以用来执行特定功能的一段功能函数
  • 举个例子:就像是pam认证模块,这个pam提供的功能可以让程序在执行的时候,验证用户的信息,那么如此一来,我就不用去编写一个验证用户信息的功能,直接调用就行
什么说make与configure
  • make:当执行make的时候,make会在当前目录下面搜索Makefile这个文件,而makefile里面记录了源代码如何编译的详细信息,make会自动判断源代码是否经过变动,而自动更新执行文件
  • ./configure:那makefile说是怎么来的呢,通常,软件发行厂商会写一个检测程序,这个检测程序的文件名就叫configure,大概会检测的内容有:是否有合适的编译器,是否有软件所依赖的函数库,操作平台是否适合本软件,内核的头文件是否存在等。

更多具体内容:参考《鸟哥的Linux私房菜》

你可能感兴趣的:(Linux整理)