---Autotool帖子阅读比笔记

#伴随这个教学链接演练一下:
 

第<->部分 帽子:关于autotool的介绍:
http://markuskimius.wikidot.com/programming:tut:autotools:1
拿到一份开源软件你你的正规步骤是这样的:    你需要read一下目录下readme.txt文件, 看看下面这三个命令还需要什么选项
./configure  ....  # 分析你的系统的可执行文件和库的路径和配置, 以便我知道如何最好的编译方法,  然后生成Makefile       
make ...        #编译过程
make install   #安装过程

看看你的系统这两个工具是否安装,和版本情况是, 给你演练打下基础, 因为你可能不能找到一个和作者一样的系统了!

作者用的是2.53版本的autoscan和autoconf


我的电脑现在是XUbuntu 20.04, 显示如下:
autoscan --version 
2.69
autoconf --version
2.69

第<二> 部分
http://markuskimius.wikidot.com/programming:tut:autotools:2
  整一个简单的hello.c文件和手工写一个Makfile, 让他可以编译成功可以运行
make hello; cd hello; 
Makefile: .....
hello.c: .....

$ autoscan
$ mv configire.scan config.ac       # config.in is old name for config.ac   eg. for v2.13
$ autoconf
生成得到了->configure 文件

$ mv Makefile Makefile.in #把你写Makefile改成Makefile.in
$ ./configure  # 生成Makefile

  这里出了一个错误, 先不用管:
$ config.status: error: cannot find input file: `config.h.in'

测一下:
$ make clean all

....还一直都没有发现和2.53有啥区别,
...还一直都和链接里面的例子一样的, 流程似乎都是对的了,你完成一个完整的autoconf的程序, 不过你还没看出来这有啥用,,,,,,,

第<三> 部分
http://markuskimius.wikidot.com/programming:tut:autotools:3
autoheader        #autohead is part of autoconf package
-->config.h.in    #宏定义模板
./configure
-->config.h
  # 里面是一堆PACKAGE_* 宏定义,  定义软件包的名字版本等等, 都不会对源代码有啥用了
add #include "config.h" in the top of hello.c
make clean all
这样子就搭好了源码可以适应不同平台的架子了,只是代码太简单了,只有一个printf在任何平台下有C库就有它了,C库是标准的库,任何平台下没啥不同
把main.c整复杂点把:

/* hello.c: A program to show the time since the Epoch */

#include <stdio.h>
#include <sys/time.h>

int main(int argc, char* argv[])
{
    double sec;
    struct timeval tv;

    gettimeofday(&tv, NULL);
    sec = tv.tv_sec;
    sec += tv.tv_usec / 1000000.0;

    printf("%f ", sec);

    return 0;
}
再次走上面的流程,,,,,
$ autoscan
$ bcompare  configure.ac configure.scan

 

 你看看autoscan都干了啥,就是它扫描源代码,看它都include了什么头文件还有呼叫了那些库, 这些头文件和困在不同平台或者平台库配置可能会不同的
这些都一一记录在案了.....
mv configure.scan configure.ac
autoconf
autoheader
./configure 
make clean all
你可以看看config.h 多了哪些些东西:
/* #undef HAVE_GETTIMEOFDAY */
/* #undef HAVE_INTTYPES_H */
/* #undef HAVE_MEMORY_H */
/* #undef HAVE_STDINT_H */
/* #undef HAVE_STDLIB_H */
/* #undef HAVE_STRINGS_H */
/* #undef HAVE_STRING_H */
/* #undef HAVE_SYS_STAT_H */
/* #undef HAVE_SYS_TIME_H */
/* #undef HAVE_SYS_TYPES_H */
/* #undef HAVE_UNISTD_H */
/* #undef STDC_HEADERS */    这些还算是宏定义的模板,再程序里面里面没有得到使用
到处为止才算真的把架子搭起来了,再下面看代码,让他可以在不同的平台/或者同样平台不同的库的下的自适应的代码,
hello.c:  顶上加上#include "config.h"
在看有啥变化:
 上面:这这些undef的定义都变成了
 #define HAVE_GETTIMEOFDAY  1
。。。。。
为什么呢? 后面再解释了吧!

换代码:

/* hello.c: A program to show the time since the Epoch */

#include <stdio.h>
#include "config.h"

#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#else
#include <time.h>
#endif

double get_sec_since_epoch()
{
       double sec;

#ifdef HAVE_GETTIMEOFDAY
       struct timeval tv;

       gettimeofday(&tv, NULL);
       sec = tv.tv_sec;
       sec += tv.tv_usec / 1000000.0;
#else
       sec = time(NULL);
#endif

       return sec;
}

int main(int argc, char* argv[]) {
       printf("%f ", get_sec_since_epoch());
      return 0;
}

重复刚从的流程
看看config.h.in  configure.ac 有啥变化
我实践是autoscan并没有扫描到time.h头文件和time(NULL)呼叫,是否说他们是编译器内置的

好的,over了
总结一下写一个可移植程序流程是这样子的:
1. 写好代码, Makefile.in 像写普通Makefile一样的, 但是时刻记得要portable
2. autoscan
3. mv configure.scan config.ac
4. autoheader
5. autoconf
6. ./configure
7. 检查config.h文件, 改代码, 有改动就要返回#2, 在走到这里, 这一步不改了,继续
8. make clean, make

*******到此处给源代码整可移植就完了, 下面讲的是automake部分, 讲的是关于编译部分的可移植性的处理

第<四>部分
http://markuskimius.wikidot.com/programming:tut:autotools:4
automake --version 
1.16.1
创建Makefile.am:
 bin_PROGRAMS=hello
 hello_SOURCES=hello.c
 ....... Makefile.am来说已经足够了, 以后都不需要改了

$ automake   #automake 会检查configure.ac文件
出错修复过程: 提示这个错误:
   configure.ac: error: no proper invocation of AM_INIT_AUTOMAKE was found.
  configure.ac: You should verify that configure.ac invokes AM_INIT_AUTOMAKE
.....  意思似乎是automake还不能运行, config还没有初始化

手工更改configure.ac: (在AC_INIT下面增加下面这行就足够了)
AM_INIT_AUTOMAKE([1.16 foreign no-define])   #1.16 要和上面的automake的版本号一致
alcohoc 
   Note: 改了这个文件后, 里面增加了AM_开头的变量, 必须运行alcohoc,然后autoconf才能通过

autoconf
automake --add-missing
automake   #直到这个命令没有错误为止,
 
./configure
make clean all

ref:
这个automake的版本和之前autoconfig配合性很强, 之前版本都是很多问题, 
configure.ac:
AC_PREREQ([2.69])
AC_INIT([hello], [1.0], [szbzhao@gmail.com])
AM_INIT_AUTOMAKE([1.16 foreign no-define])

这里的autoconfig和automake版本如果太新的话, 那么在旧的系统里面如何编译通过呢?

看最后的总结, 惨不忍睹了:

第<五>部分 全新来一遍一个新的可移植程序
http://markuskimius.wikidot.com/programming:tut:autotools:5
  之前的例子里面加太多铺垫了,现在,把那些都去掉, 全新整一遍:

1. 准备:
   Makefile.am
   hello.c

2. conf:
  looping steps:
    1. autoscan
       mv configure.scan configure.ac
    2.autoheader
    3. automake
    4. vi configure.ac
...fixing error in configure.ac ....
    5. automake --add-missing
    6.aclocal
    7. automake  #if error happen go back to step #4
    8 autoconf
   ./configure
   make clean all

  里面还有个后记, 
    大致意思是portable 程序是个过程,你首先在自己电脑的平台整过了,然后再放其他平台, 索性有人编译了你的程序发现went,把错误
发给你,你修改configure.ac文件,然后在发给他测试我或者你自己测试,再发布更新, 这样你程序就慢慢覆盖全部平台了,

   一般来说你依赖自己的开发环境的autotoll(autoconf/automake)的版本来完成开发portable程序的开发版本,其他人如果继续也要有同样的autotool版本或者不低于这个版本才能继续开发程序的Makefile.am/configure.ac和程序本身!
   其他人使用软件只要:./configire / make / make install 就可以了!

  如果你看到其他人包解开之后有这两个文件在: acinclude.m4”和“autogen.sh:
   1. acinclude.m4 #自定义的m4宏文件,名字不能改
   2. autogen.sh    #这个自动生成脚本,一键生成脚本,是作者自己写的,名字可以改成其他样子

  话说回来了这个古老的东西还有这么多bug, 真是个历史问题还是, 组合问题, 还是开源工程师根本不在乎这些, 反正我知道问题在哪里, 问题不大!

!!!!!! Over !!!!

原文地址:https://www.cnblogs.com/bzhao/p/14237400.html