zoukankan      html  css  js  c++  java
  • autoconf automake libtool

    这是一个 autoconf / automake 的 "Hello World"
    gztt.ll@gmail.com

    主要步骤是
    - 准备工程目录结构和程序
    - autoscan 生成 configure.scan
    - 编辑修改 configure.scan,重命名为 configure.ac 或 configure.in
    - aclocal; libtoolize; autoheader; autoconf 生成 'configure' 可执行文件
    - 写 Makefile.am
    - automake 生成 Makefile
    - 完成。后面就可以 ./configure; make; make install; make dist; ...

    试验工程结构如下

    hello
    |
    |---- src
    |     |---- main
    |     |     |---- main.c
    |     |
    |     |---- foo
    |     |     |---- foo.c
    |     |
    |     |---- bar
    |           |---- bar.c
    |
    |---- include
           |---- foo.h
           |---- bar.h


    说明一下
    "hello"     工程的$(top_srcdir)
    "src/main"   生成可执行文件 hello 主目录
    "src/foo"   生成静态库的目录 libfoo.a;hello 主程序 link 时用
    "src/bar"   生成动态库的目录 libbar.so;hello 主程序运行时加载
    "include"   头文件目录

    $mkdir hello && cd hello

    准备示例程序,如下

    ### 文件内容 ###

    /* ### src/main/main.c ### */
    #include <stdio.h>
    #include "foo.h"
    #include "bar.h"
    int main(int argc, char *argv[])
    {
         printf("main + ");
         func_foo();
         func_bar();
         printf("main - ");
        return 0;
    }

    /* ### include/foo.h ### */
    #include <stdio.h>
    void func_foo(void);

    /* ### src/foo/foo.c ### */
    #include "foo.h"
    void func_foo(void)
    {
         printf("foo +- ");
    }

    /* ### include/bar.h ### */
    #include <stdio.h>
    void func_bar(void);

    /* ### src/bar/bar.c ### */
    #include "bar.h"
    void func_bar(void)
    {
         printf("bar +- ");
    }

    下面进入顶层目录 $(top_srcdir)

    $cd hello
    $autoscan

    自动生成 configure.scan 文件,我们要作稍许修改,重命名为 configure.ac 或 configure.in
    (configure.in 是老版本 autoconf 支持的)

    $mv configure.scan configure.ac

    修改 configure.ac 如下

    /* ### configure.ac ### */
    #                                               -*- Autoconf -*-
    # Process this file with autoconf to produce a configure script.

    AC_PREREQ(2.61)
    AC_INIT(hello, 1.0.0, gztt.ll@gmail.com)                ### Modified
    AM_INIT_AUTOMAKE(hello,1.0.0, gztt.ll@gmail.com)      ### Added
    AC_CONFIG_SRCDIR([src/main/main.c])
    AC_CONFIG_HEADER([config.h])

    # Checks for programs.
    AC_PROG_CC
    AC_PROG_RANLIB                                         ### Added if static libary used
    AC_PROG_LIBTOOL                                         ### Added if dynamic libary used

    # Checks for libraries.

    # Checks for header files.

    # Checks for typedefs, structures, and compiler characteristics.
    AC_C_CONST

    # Checks for library functions.
    AC_OUTPUT(Makefile                                       ### Added
               include/Makefile
               src/main/Makefile
               src/foo/Makefile
               src/bar/Makefile
              )

    说明一下:
    如果不使用静态库或动态库 'AC_PROG_RANLIB' 和'AC_PROG_LIBTOOL' 则都不需要
    如果仅使用静态库,增加 'AC_PROG_RANLIB' 即可
    如果需要使用动态库,需加上 'AC_PROG_LIBTOOL'
    'AC_CONFIG_HEADER(...)',我在 RedHat9 上试的时候,这行要改面 'AM_CONFIG_HEADER(...)',原因未知。
    用 RedHat 9 时,最后 'AC_OUTPUT(...)' 里文件也不太一样, RedHat9 需要多一行 'src/Makefile',详见下面说明。
    (我默认是用 debian 5)

    接着执行下面的命令

    $aclocal
    $libtoolize
    $autoheader
    $autoconf

    注:只有用到动态库时,才需要 '$libtoolize'
    否则,只需要运行

    $aclocal
    $autoheader
    $autoconf

    即可。

    此时应该可以生成 'configure' 可执行文件

    然后我们写 Makefile.am

    /* ### Makefile.am ### */
    SUBDIRS = include src/bar src/foo src/main 

    /* ### include/Makefile.am ### */
    helloincludedir=$(includedir)
    helloinclude_HEADERS=foo.h bar.h 

    /* ### src/main/Makefile.am ### */
    bin_PROGRAMS=hello
    hello_SOURCES=main.c
    hello_LDADD=$(top_srcdir)/src/foo/libfoo.a
    LIBS=-lbar
    INCLUDES=-I$(top_srcdir)/include
    hello_LDFLAGS=-L$(top_srcdir)/src/bar

    /* ### src/foo/Makefile.am ### */
    noinst_LIBRARIES=libfoo.a
    libfoo_a_SOURCES=foo.c
    INCLUDES=-I$(top_srcdir)/include  

    /* ### src/bar/Makefile.am ### */
    lib_LTLIBRARIES=libbar.la
    libbar_la_SOURCES=bar.c
    INCLUDES=-I$(top_srcdir)/include  

    说明一下,
    第一个 'Makefile.am' 文件,即'$(top_srcdir)/Makefile.am' 只说了子目录说明,按编译顺序排的。
    RedHat 9 会报错,说不能含 '/' 符号;解决办法是,我们新增加一个  '$(top_srcdir)/src/Makefile.am'
    这样:
    /* ### Makefile.am ### */
    SUBDIRS = include src
    /* ### src/Makefile.am ### */
    SUBDIRS = bar foo main
    此时,如前面所讲 'configure.ac' 最后的'AC_OUTPUT' 就需多一行'src/Makefile' 了

    '$(top_srcdir)/src/main/Makefile.am' 相对复杂一点,
    特别指出的是 'hello_LDFLAGS' 后,应是'...=-L$(top_srcdir)/...',而不是'...=-L $(top_srcdir)/...'
    多一个空格,后面就有错误。

    接着 automake 的话,无法通过的,还需要下面几个文件,我们暂时 touch 一下即可

    $touch README NEWS AUTHORS ChangeLog

    注意是在 $(top_srcdir) 目录下面

    然后
    $automake --add-missing
    $./configure

    至此,所有 Makefile 文件应该全部生成
    我们可以执行
    $make
    $make clean
    $make install
    $make uninstall
    $make dist
    $make ...

  • 相关阅读:
    js手写弹框和按钮显示
    Java类加载机制、双亲委派、Java类加载过程
    Java集合:HashMap必知必会
    查看oracle是否锁表
    消息队列Rabbit MQ 学习第一篇
    数据库blob图片文件,多图片打包下载
    HttpDebug下载
    将博客搬至CSDN
    android事件拦截处理机制详解
    回调函数
  • 原文地址:https://www.cnblogs.com/unixshell/p/3813112.html
Copyright © 2011-2022 走看看