了解automake和autoconf(autoreconf)

机器语言,汇编语言与高级语言

机器语言是机器指令的集合。机器指令展开来讲就是一台机器可以正确执行的命令。电子计算机的机器指令是一列二进制数字。计算机将之转变为一列高低电平,以使计算机的电子器件受到驱动,进行运算。
早期的程序设计均使用机器语言。程序员们将用0, 1数字编成的程序代码打在纸带或卡片上,1打孔,0不打孔,再将程序通过纸带机或卡片机输入计算机,进行运算。这样的机器语言由纯粹的0和1构成,十分复杂,不方便阅读和修改,也容易产生错误。

编语言的主体是汇编指令。汇编指令和机器指令的差别在于指令的表示方法上。汇编指令是机器指令便于记忆的书写格式。

1000100111011000 机器指令
mov ax,bx 汇编指令

将汇编指令转换成机器指令的翻译程序,这样的程序我们称其为编译器。程序员用汇编语言写出源程序,再用汇编编译器将其编译为机器码,由计算机最终执行。
由于汇编语言依赖于硬件体系,且助记符量大难记,于是人们又发明了更加易用的所谓高级语言。在这种语言下,其语法和结构更类似普通英文,且由于远离对硬件的直接操作,使得一般人经过学习之后都可以编程。

高级语言: 面向过程-C, 面向对象C++,Java.

所以, 高级语言要执行,最终是要经过编译转化为汇编语言才能被机器执行。

C语言的编译和链接

编译是把源码编译成中间代码文件,
在Windows下是.obj文件, 在Linix下是.o 的文件,即Object File, 目标文件

链接处理的是目标文件之间的调用关系。方式就是把目标文件打个包, 在Windows 下这个包文件爱你叫Library-库文件, 以.lib结尾。
在Linux下叫Archive文件, 以 .a结尾。

源文件首先会生成中间目标文件,再由中间目标文件生成执行文件。在编译时,编译器只检测程序语法,和函数、变量是否被声明。如果函数未被声明,编译器会给出一个警告,但可以生成Object File。而在链接程序时,链接器会在所有的Object File中找寻函数的实现。

没有Makefile的编译
gcc -o myapp main.c func1.c func2.c func3.c

以上编码包括代码:
主程序代码 main.c
三个子函数 : funcx.c

写在Makefile 文件中:
myapp: main.c func1.c func2.c func3.c
gcc -o calc main.c func1.c func2.c func3.c
这是一个基本的Makefile语句,它主要分成了三个部分,
第一部分:第一行冒号之前的myapp,我们称之为目标(target),被认为是这条语句所要处理的对象,具体到这里就是我们所要编译的这个程序myapp。
第二部分:冒号后面的部分(main.c func1.c func2.c func3.c),我们称之为依赖关系表,也就是编译所需要的文件
第三部分: 命令部分,就是一条编译命令

什么是Makefile?

Makefile是一个文件。

makefile定义整个工程的编译规则。一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。

Makefile文件被 make命令使用。make是如何工作的呢?
在默认的方式下,
1. make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
2. 如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“edit”这个文件,并把这个文件作为最终的目标文件。
3. 如果edit文件不存在,或是edit所依赖的后面的 .o 文件的文件修改时间要比edit这个文件新,那么,他就会执行后面所定义的命令来生成edit这个文件。
4. 如果edit所依赖的.o文件也存在,那么make会在当前文件中找目标为.o文件的依赖性,如果找到则再根据那一个规则生成.o文件。(这有点像一个堆栈的过程)
5. make会生成 .o 文件,然后再用 .o 文件声明make的终极任务,也就是执行文件edit了。
这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。make只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,我就不工作啦

autoconf&automake

Makefile中纪录有文件的信息,在make时会决定在链接的时候需要重新编译哪些文件。
Makefile的宗旨就是:让编译器知道要编译一个文件需要依赖其他的哪些文件。当那些依赖文件有了改变,编译器会自动的发现最终的生成文件已经过时,而重新编译相应的模块。
当系统环境变量或路径发生了变化后,Makefile可能还要跟着修改。这样就造成了手工书写Makefile的诸多问题,automake恰好能很好地帮助我们解决这些问题。

使用automake,程序开发人员只需要写一些简单的含有预定义宏的文件,由autoconf根据一个宏文件生成configure,由automake根据另一个宏文件生成Makefile.in,再使用configure依据Makefile.in来生成一个符合惯例的Makefile
autoconf用来生成configure configure生成makefile make就去调gcc编译源文件

使用autoconf和automake两个工具来帮助我们自动地生成符合*软件惯例的Makefile.

实例

  1. 在工作目录下新建testmake目录
mkdir testmake
cd testmake
  • 1
  • 2
  • 3
  1. 编写源代码 helloworld.c
    vi helloworld.c
int main(int argc,char** argv)
{
    printf("Hello,My First Linux Make");
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  1. 生成configure.
    使用autoscan命令,生成configure.scan的文件
    autoscan
    重命名为configure.in, 并修改文件内容
    mv configure.scan configure.in
                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_INIT(helloworld.c)

AM_INIT_AUTOMAKE(helloworld,1.0)

# Checks for programs.
AC_PROG_CC

# Checks for libraries.

# Checks for header files.

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.

AC_OUTPUT(Makefile)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  1. 执行 aclocal 和autoconf, 产生aclocal.m4及configure
    aclocal根据configure.in文件的内容,自动生成aclocal.m4文件。aclocal是一个perl脚本程序,它的定义是:“aclocal - create aclocal.m4 by scanning configure.ac”。
     autoconf 是用来生成自动配置软件源代码脚本(configure)的工具。configure脚本能独立于autoconf运行,且在运行的过程中,不需要用户的干预。
     autoconf需要GNU m4宏处理器来处理aclocal.m4,生成configure脚本。
      m4是一个宏处理器。将输入拷贝到输出,同时将宏展开。宏可以是内嵌的,也可以是用户定义的。除了可以展开宏,m4还有一些内建的函数,用来引用文件,执行命令,整数运算,文本操作,循环等。m4既可以作为编译器的前端,也可以单独作为一个宏处理器.

5.创建Makefile.am
新建Makefile.am文件,命令:$ vi Makefile.am
automake会根据你写的Makefile.am来自动生成Makefile.in。Makefile.am中定义的宏和目标,会指导automake生成指定的代码。例如,宏bin_PROGRAMS将导致编译和连接的目标被生成。

AUTOMAKE_OPTIONS=foreign

bin_PROGRAMS=helloworld

helloworld_SOURCES=helloworld.c
  • 1
  • 2
  • 3
  • 4
  • 5

6.运行automake –add-missing

automake会根据Makefile.am文件产生一些文件,包含最重要的Makefile.in。

  1. 执行configure生成Makefile
./configure
  • 1

8.使用Makefile编译代码

make 
  • 1

9.运行

./helloworld