• 使用autotools辅助linux程序开发


    前面我们提到了linux的动态库和静态库的开发,也许各位都注意到了,虽然我们的程序现在还很小,但是当编译错误后我们需要作大量的工作来重新从头开始,有时一不小心连自己都忘了进行到了哪一步。毫无疑问大家第一想到的是自己写个makefile,但是为什么不在进一步,为什么不用autotools呢。

    需要工具
    autoscan
    autoreconf
    autoconf
    automake
    libtool

    下面就让我们来做一个小工程
    test/lib/test1.c
    #include <stdio.h>

    int hello_world1()
    {
        printf("hello world1/n");
        return 1;
    }

    test/lib/test2.c
    #include <stdio.h>

    void hello_world2()
    {
        printf(" hello world2/n");
    }

    test/app.c
    #include <stdio.h>

    int main()
    {
        hello_world1();
    }

    现在我们要将lib目录下的文件编译成静态库,并把他整合到最终的app程序中。
    $autoscan
    $ls
    app.c  autoscan.log  configure.scan  lib
    $mv configure.scan configure.in
    autoscan 命令将用来生成初步的configure.in文件

    现在我们更改configure.in文件
    加入
    AM_INIT_AUTOMAKE([-Wall -Werror])
    初始化Automake,开启所有的警告,并将它们上报为错误

    AC_PROG_RANLIB
    声明静态库编译工具为ranlib,GUN ranlib是另一个形式的ar

    AC_CONFIG_FILES([
            Makefile
            lib/Makefile])
    声明Makefile和lib/Makefile为输出文件

    test/Makefile.am
    SUBDIRS = lib
    bin_PROGRAMS=app
    app_SOURCES=app.c
    app_LDADD= lib/libtest.a
    递归构建lib
    bin目录下的为app
    app的源代码是app.c
    app的链接库是lib/libtest.a

    test/lib/Makefile.am
    lib_LIBRARIES = libtest.a
    libtest_a_SOURCES = test1.c test2.c
    安装到$(libdir)目录下的文件为libtest.a
    编译libtest.a的源代码是test1.c test2.c

    $ls -R
    .:
    app.c  configure.in  lib  Makefile.am

    ./lib:
    Makefile.am  test1.c  test2.c
    $autoreconf --install
    configure.in:6: installing `./missing'
    configure.in:6: installing `./install-sh'
    lib/Makefile.am: installing `./depcomp'
    标志--install意思是拷贝遗失的辅助文件
    每个人的输出可能有点不同,不出错就基本上没问题
    $./configure --prefix ~/test
    ...
    --prefix指定了要安装的目录
    $make && make install
    也许有人发现了在目录下有个app可执行程序,但是他并非是我们所要的目标二进制文件
    他是一个bash脚本,我们所要的已经在~/test/bin目录下了

    好了,我们核对下是否正确
    $cd ~/test
    $ls -R
    .:
    bin  lib

    ./bin:
    app

    ./lib:
    libtest.a
    $ldd bin/app
            linux-gate.so.1 =>  (0x0011e000)
            libc.so.6 => /lib/libc.so.6 (0x00ad2000)
            /lib/ld-linux.so.2 (0x00101000)
    没有动态链接的libtest.a的迹象
    $bin/app
    hello world1



    动态库的编译有点不同
    test/configure.in中
    将AC_PROG_RANLIB改为AC_PROG_LIBTOOL
    并加入AC_DISABLE_STATIC,禁止静态库的生成

    test/Makefile.am
    中的app_LDADD= lib/libtest.a 改为 app_LDADD= lib/libtest.la
    对于动态库,libtool帮助产生的是一种比较通用形式即la文件

    test/lib/Makefile.am
    lib_LTLIBRARIES = libtest.la
    libtest_la_SOURCES = test1.c test2.c
    注意是lib_LTLIBARIES,
    指明了是libtool产生的库形式

    继续编译静态库的形式
    注意:为了不混淆请先清除~/test文件内容
    $autoreconf --install
    $./configure --prefix ~/test
    $make && make install

    剩下检验结果
    $cd ~/test/
    $ldd bin/app
            linux-gate.so.1 =>  (0x0011e000)
            libtest.so.0 => /home/secularbird/test/lib/libtest.so.0 (0x0011f000)
            libc.so.6 => /lib/libc.so.6 (0x00ad2000)
            /lib/ld-linux.so.2 (0x00101000)
    我们看到app程序的运行需要连接到相应的libtest文件上
    $bin/app
    hello world1
    有兴趣的话可以尝试下把app移到其他的地方去执行下

    作每一步的时候,请注意细节,好了,good luck

    参考资料
    man ar
    man ranlib
    autotool book 1.5
    man autoreconf
    http://www-src.lip6.fr/Alexandre.Duret-Lutz/autotools.html
     
  • 相关阅读:
    网线帘幕动画
    图片缩放/旋转/平移/设置分辨率
    贝塞尔样条
    线性梯度画刷
    画七彩五角星
    kafka安装
    在windows远程提交任务给Hadoop集群(Hadoop 2.6)
    把Spark SQL的metadata存储到mysql
    使用IDEA开发SPARK提交remote cluster执行
    Netty的Channel
  • 原文地址:https://www.cnblogs.com/zelos/p/3402912.html
Copyright © 2020-2023  润新知