zoukankan      html  css  js  c++  java
  • ---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 !!!!

  • 相关阅读:
    mysql 历史版本下载
    mysql 5.7 版本 You must reset your password using ALTER USER statement before executing this statement报错处理
    5.7 zip 版本的安装 以及遇到的坑
    mysql 5.6zip版本的卸载与5.7 zip 版本的安装
    mysql数据库的备份与还原
    本地Navicat连接docker里的mysql
    docker修改数据库密码
    docker 在push镜像到本地registry出现的500 Internal Server Error
    linux 没有界面内容显示不全解决办法
    json与map互相转换
  • 原文地址:https://www.cnblogs.com/bzhao/p/14237400.html
Copyright © 2011-2022 走看看