Linux软件安装:源代码与软件安装

1 开源软件的一些基本概念

1.1 什么是开放源码,编译程序与可执行文件

  • 可执行文件
    • Linux上真正可以执行的文件是二进制文件,例如/usr/bin/passwd,/bin/touch
    • shell script只是调用这些二进制文件,完成某种功能
    • 可以用file命令检验文件类型
      $ file /bin/bash
      /bin/bash: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0xf199a4a89ac968c2e0e99f2410600b9d7e995187, stripped
      $ file /etc/init.d/rc
      /etc/init.d/rc: POSIX shell script, ASCII text executable
      
  • 编译程序
    • 这些可以执行的二进制文件是哪儿来的呢?首先,必须要写程序的源代码,然后,由编译程序将程序的源代码 编译成二进制形式。源代码是由程序员编写的,使用特定的程序语言,如C,C++,Java,Python.但是机器看不懂 这些语言,所以要使用编译程序将这些语言编写的源代码编译成机器可以看懂的二进制文件。如C语言常用的编译器 为gcc。

1.2 什么是函数库

函数库由一系列函数组成,每一个函数都是一个代码片段,完成特定的功能,这样我们使用一些常用功能时,就不必 自己重新编写代码,只需要调用函数库里的函数就可以了。函数库分为静态函数库和动态函数库。

  • 静态函数库
    • 扩展名:.a
    • 编译时会直接编译到二进制文件中,所以生成的文件通常比较大,升级时需要重新编译
  • 动态函数库
    • 扩展名:.so
    • 编译时不会直接编译到二进制文件中,只是给出一个路径,指向相应函数库,程序执行调用时动态地向此路径读取, 升级时,只需要替换原路径中的动态函数库就可以了,不需要重新编译
    • 使用ldd命令可以知道程序使用了哪些动态函数库
      $ ldd /usr/bin/passwd
              linux-gate.so.1 =>  (0xb7784000)
              libpam.so.0 => /lib/i386-linux-gnu/libpam.so.0 (0xb775c000)
              libpam_misc.so.0 => /lib/i386-linux-gnu/libpam_misc.so.0 (0xb7758000)
              libselinux.so.1 => /lib/i386-linux-gnu/libselinux.so.1 (0xb7738000)
              libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb758e000)
              libdl.so.2 => /lib/i386-linux-gnu/libdl.so.2 (0xb7589000)
              /lib/ld-linux.so.2 (0xb7785000)
      

1.3 什么是 make 与 configure

当程序的文件数目非常大时,直接使用gcc编译会变得非常麻烦,这时,我们可以写一个文件,定义好如何编译整个程序, 这个文件即是makefile,然后再调用make命令,make命令会使用makefile完成编译。那么makefile如何产生呢,通常软件 提供者都会提供一个configure程序,用于检测机器环境,生成makefile。检测的内容包括是否有合适的编译器,是否存在 需要的函数库,操作系统版本是否合适等等。

2 C语言编译简单范例

  • 使用vim编写两个程序源代码
    #include <stdio.h>
    
    int main(void) {
        thankYou();
        printf ("hello,world\n");
        return 0;
    }
    
    #include <stdio.h>
    
    void thankYou() 
    {
        printf ("Thank you\n");
    }
    
    
  • 使用gcc编译 这一步,源代码文件被编译成为目标文件
    $ gcc -c hello.c -o hello.o
    $ gcc -c thank.c -o thank.o
    
  • 使用gcc链接 通过链接,我们可以将函数库中已经编译好的目标文件与我们自己编写生成的目标文件链接在一起,成为 一个最终的二进制文件
    $ gcc hello.o thank.o -o hi
    
  • 执行
    $ ./hi
    Thank you
    hello,world
    
  • 注意
    • 可以使用 -l指定函数库,-L指定函数库路径,-I指定头文件路径
      gcc sin.c -lm -L/lib -L/usr/lib -I/usr/include
      

      上面的-l指加入函数库,m指的是libm.so这个函数库

3 使用make进行宏编译

文件很多时,编译的过程非常繁琐,有些文件更新过,需要重新编译,有的没有更新过,不需要重新编译, 有些编译过程需要重复很多次,为了能实现编译过程的自动化,可以编写makefile描述如何编译,然后用make 完成整个过程的自动编译。

  • makefile的编写
    hi:hello.o thank.o
            gcc -o hi hello.o thank.o
    

    注意第二行前的Tab缩进。

  • make的使用
    $ make
    cc    -c -o hello.o hello.c
    cc    -c -o thank.o thank.c
    
  • 运行
    $ ./hi
    hello,world
    Thank you
    

从make作用来看,我们直接写一个shell script不就好了?其实不然,可以看到makefile中只需要指出生成hi 需要的目标文件,make就可以自动找到相应的源代码文件并且编译好,然后用我们给出的链接方式进行链接。 此外,如果hello.c更新过,那么再次make时,make会加以判断,只重新编译hello.c,这对于较大的程序而言 会节省很多资源和时间。 另外,makefile中还可以定义变量,定义如何删除编译出的目标文件

OBJS = hello.o thank.o 
hi:hello.o thank.o
        gcc -o hi ${OBJS}

clean:
        rm hi ${OBJS}

测试一下:

$ ls hello.o thank.o hi
hello.o  hi  thank.o

$ make clean
rm hi hello.o thank.o 

$ ls hello.o thank.o hi
ls: cannot access hello.o: No such file or directory
ls: cannot access thank.o: No such file or directory
ls: cannot access hi: No such file or directory

$ make 
cc    -c -o hello.o hello.c
cc    -c -o thank.o thank.c
gcc -o hi hello.o thank.o 

$ ls hello.o thank.o hi
hello.o  hi  thank.o

$ ./hi
hello,world
Thank you

4 通过编译源代码进行软件安装

  • 先取得源代码,解压,然后进入源代码目录
  • ./configure 执行configure,建立makefile,这一步非常重要,configure程序会检测编译源代码需要的操作系统,库文件等等, 执行前最好看看目录下的README或者INSTALL文件,看看有什么需要注意的地方
  • make clean 根据makefile中定义的clean操作执行一些清理工作
  • make 根据makefile的内容进行编译
  • make install 根据makefile中定义的install将编译生成的文件安装到相应目录
Logo

更多推荐