zoukankan      html  css  js  c++  java
  • Makefile 管理工具 — Automake and Autoconf

    该project下载路径:http://files.cnblogs.com/iTsihang/hello-2.0.zip

    automake 參考资料:http://www.linuxforum.net/books/automake.html

    autoconf 參考资料:http://www.linuxforum.net/books/autoconf.html

    automake源代码下载:ftp://ftp.gnu.org/gnu/automake/

    autoconf源代码下载:ftp://ftp.gnu.org/gnu/autoconf/

     

    Automake支持的文件夹结构

    眼下automake支持三种文件夹层次:flat、shallow和deep。

    • flat(平),指的是全部文件都位于同一个文件夹中

          就是全部源文件、头文件以及其它库文件都位于当前文件夹中,且没有子文件夹。Termutils就是这一类。

    • shallow(浅),指的是基本的源码都储存在顶层文件夹,其它各个部分则储存在子文件夹中

          就是主要源文件在当前文件夹中,而其他一些实现各部分功能的源文件位于各自不同的文件夹。automake本身就是这一类。

    • deep(深),指的是全部源码都被储存在子文件夹中;顶层文件夹主要包括配置信息

    本样例文件夹结构如图所看到的,属于deep类:

    复制代码
     1 hello-2.0
     2 ├── aclocal.m4
     3 ├── AUTHORS
     4 ├── autom4te.cache
     5 │   ├── output.0
     6 │   ├── output.1
     7 │   ├── requests
     8 │   ├── traces.0
     9 │   └── traces.1
    10 ├── autoscan.log
    11 ├── ChangeLog
    12 ├── configure
    13 ├── configure.in
    14 ├── COPYING -> /usr/share/automake-1.11/COPYING
    15 ├── depcomp -> /usr/share/automake-1.11/depcomp
    16 ├── home
    17 │   ├── li
    18 │   │   ├── inc
    19 │   │   │   └── li.h
    20 │   │   └── src
    21 │   │       ├── li.c
    22 │   │       ├── Makefile.am
    23 │   │       └── Makefile.in
    24 │   ├── wang
    25 │   │   ├── inc
    26 │   │   │   └── wang.h
    27 │   │   └── src
    28 │   │       ├── Makefile.am
    29 │   │       ├── Makefile.in
    30 │   │       └── wang.c
    31 │   └── zhang
    32 │       ├── inc
    33 │       │   └── zhang.h
    34 │       └── src
    35 │           ├── Makefile.am
    36 │           ├── Makefile.in
    37 │           └── zhang.c
    38 ├── INSTALL -> /usr/share/automake-1.11/INSTALL
    39 ├── install-sh -> /usr/share/automake-1.11/install-sh
    40 ├── main
    41 │   ├── main.c
    42 │   ├── Makefile.am
    43 │   └── Makefile.in
    44 ├── Makefile.am
    45 ├── Makefile.in
    46 ├── missing -> /usr/share/automake-1.11/missing
    47 ├── NEWS
    48 ├── park
    49 │   ├── Makefile.am
    50 │   ├── Makefile.in
    51 │   ├── public.c
    52 │   └── public.h
    53 └── README
    54 
    55 13 directories, 39 files
    复制代码

    这是一个主要的架构结构,能够形成一个比較成熟的软件框架。

     

    样例介绍

    如上图所看到的为该样例的结构层次,有主文件夹main,家文件夹home和公园文件夹part。home下依据姓氏分了三家:li家,wang家和zhang家,每家都有同样的结构:src和inc;part是三家共有的公共文件夹,里面包括了三家共用的接口;main文件夹是我们的主文件夹,存放运行入口。每家的人(程序)做一件事情,那就是依次在入口(main)中说一句:hello。

    复制代码
     1 int main(void)
     2 {
     3 
     4       /* access home li */
     5       lisayhello();
     6 
     7       /* access home wang */
     8       wangsayhello();
     9 
    10       /* access home zhang */
    11       zhangsayhello();
    12 
    13       return 0;
    14 }
    复制代码

     

    步骤    

    分别在每一个文件夹下创建Makefile.am文件,并编辑

    在使用autoconf和automake自己主动工具生成Makefile的时候,该工具会在project文件夹下查找Makefile.am文件,有该文件的文件夹下会自己主动生成对应的Makefile文件。当然也能够后期手动加入。一般的生成顺序是:

    1> 依据project结构,在须要生成Makefile的文件夹下创建Makefile.am文件。

    我们须要生成Makefile的文件夹有home/li/src/,home/wang/src/,home/zhang/src/和main/,所以我们共需创建4个Makefile.am文件。

    2> 编辑Makefile.am文件,指出须要在该文件夹下完毕的工作,如编译一些源文件,链接某些库文件等等;

    这里有三类Makefile.am,如今分类介绍其在整个project文件夹中实现的功能。  

    家文件夹下的Makefile.am主要用来编译同文件夹下的源文件。比如,编辑home/li/src/Makefile.am例如以下:

    复制代码
    1 noinst_PROGRAMS= li           #生成的目标 
    2 li_SOURCES= li.c              #生成目标依赖的源      
    3 
    4 li_LDADD=                     #可能须要载入的其它的目标
    5 li_LDFLAGS=                   #载入目标须要的配置參数
    6 li_a_LIBADD=                  #可能须要载入的其它的库
    7 
    8 DEFS += -D_GNU_SOURCE
    复制代码

    同理编辑其它两个姓氏文件夹以及公园文件夹下的Makefile.am文件,替换对应字段就可以。

    主文件夹下的Makefile.am主要用来生成终于的可运行目标程序,它须要家文件夹下的姓氏提供方法。编辑例如以下:

    复制代码
     1 # executable file last created
     2 
     3 noinst_PROGRAMS= hello
     4 
     5 # main entry file
     6 
     7 hello_SOURCES= main.c
     8 
     9 # object file that needed
    10 
    11 OBJECTS= $(top_srcdir)/home/li/src/li.o
    12 
    13          $(top_srcdir)/home/zhang/src/zhang.o
    14 
    15          $(top_srcdir)/home/wang/src/wang.o
    16 
    17 # load object file when linking
    18 
    19 hello_LDADD= $(OBJECTS)
    20 
    21 # flags of libs
    22 
    23 hello_LDFLAGS= -D_GNU_SOURCE
    24 
    25 DEFS += -D_GNU_SOURCE
    26 
    27 #LIBS= -lpthread
    复制代码

    篇幅有限,每行的详细含义,请自行查看相关文档,或者我提供的链接可能对你有帮助。

    顶层文件夹Makefile.am给automake工具提供project下各个子文件夹的路径。在make的时候,告诉automake应该进哪些文件夹运行makefile,运行过程依照SUBDIRS 定义顺序来。编辑例如以下:

    复制代码
     1 SUBDIRS= home/li/src
     2 
     3                  home/zhang/src
     4 
     5                  home/wang/src
     6 
     7                  park
     8 
     9                  main
    10 
    11 # automake need known where it is
    12 
    13 CURRENTPATH= $(shell pwd)
    14 
    15 # head files while linking
    16 
    17 INCLUDES= -I$(CURRENTPATH)/park/include -I$(CURRENTPATH)/home/li/inc -I$(CURRENTPATH)/home/wang/inc -I$(CURRENTPATH)/home/zhang/inc
    18 
    19 export INCLUDES
    复制代码

     

    执行autoscan命令,生成configure.scan文件

    复制代码
     1 #                                               -*- Autoconf -*-
     2 
     3 # Process this file with autoconf to produce a configure script.
     4 
     5 AC_PREREQ([2.68])
     6 
     7 AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
     8 
     9 AC_CONFIG_SRCDIR([home/zhang/src/zhang.c])
    10 
    11 AC_CONFIG_HEADERS([config.h])
    12 
    13 # Checks for programs.
    14 
    15 AC_PROG_CC
    16 
    17 # Checks for libraries.
    18 
    19 # Checks for header files.
    20 
    21 # Checks for typedefs, structures, and compiler characteristics.
    22 
    23 # Checks for library functions.
    24 
    25 AC_CONFIG_FILES([Makefile
    26 
    27                  home/li/src/Makefile
    28 
    29                  home/wang/src/Makefile
    30 
    31                  home/zhang/src/Makefile
    32 
    33                  park/Makefile
    34 
    35                  main/Makefile])
    36 
    37 AC_OUTPUT
    复制代码

    通过上面的步骤,能够发现,autoscan工具会自己主动查找project文件夹,包含子文件夹,在发现有Makefile.am存在的文件夹下为即将创建的Makefile指明project路径。当然,能够依据自己的须要,指定该文件,例如以下。

     

    改动configure.scan文件

    $ mv configure.scan configure.in(老版本号支持configure.ac,我没用过)

    改动例如以下部分:

    复制代码
     1 AC_CONFIG_SRCDIR([main/main.c])      #指明文件夹源文件,特指主方法所在源文件
     2 
     3 #AC_CONFIG_HEADERS([config.h])                    
     4 
     5 AM_INIT_AUTOMAKE("hello", "2.0.0")    #终于生成的目标文件和版本号,版本号一般在打包的时候用
     6 
     7 # Checks for programs.
     8 
     9 AC_PROG_CC
    10 
    11 # Checks for libraries.
    12 
    13 # Checks for header files.
    14 
    15 # Checks for typedefs, structures, and compiler characteristics.
    16 
    17 # Checks for library functions.
    18 
    19 AC_OUTPUT([Makefile
    20 
    21           home/li/src/Makefile
    22 
    23           home/wang/src/Makefile 
    24 
    25           home/zhang/src/Makefile
    26 
    27           park/Makefile
    28 
    29           main/Makefile])
    复制代码

     

    在project文件夹下创建:NEWS、 README、 ChangeLog 、AUTHORS

    touch NEWS README ChangeLog AUTHORS

     

    将/usr/share/automake-1.X/文件夹下的 depcomp 和 complie 文件复制到本文件夹下

    1 cp /usr/share/automake-1.x/depcomp   .
    2 cp /usr/share/automake-1.x/compile  .

     

    执行aclocal命令

    依据 configure.in 的配置,生成 aclocal.m4 文件和 autom4te.cache 文件夹

     

    执行autoconf

    依据configure.in的配置生成配置脚本 — configure。

     

    执行automake --add-missing

    执行automake后,就从各个文件夹下的Makefile.am中读取make的宏定义和目标或者很多其它參数,依据这些配置自己主动生成新的文件 — Makefile.in。比如,在Makefile.am中定义了要生成的目标文件,同一时候可能会定义生成目标所需的源文件,依赖文件—包含依赖的头文件,目标文件,目标库等,同一时候也指定软件的载入标志。

    当然,为了符合GNU 公布软件的标准,首次执行该命令后会提示缺少:AUTHORS,ChangeLog,NEWS,README。这些文件,你能够手动创建,假设不公布无需编辑。同一时候,也会生成install-sh,missing,INSTALL,COPYING 链接文件,这些链接文件分别指向auto工具默认安装路径:/usr/share/automake-1.XX/文件夹下的对应文件。

    此外,最关键的文件就是生成了除过上面的Makefile.in文件外,还生成了我们须要的configure文件。

     

    配置

    配置project安装和执行环境,通过该步骤能够向project传递配置和安装信息等,最后生成Makefile。

     

    编译

     运行Makefile ,编译project,链接文件,生成目标运行程序。

     

    问题探讨

    指定的install-sh,missing,INSTALL,COPYING文件的链接错误

    这依据自己系统当前安装的工具而定,你能够将这些链接又一次指向automake安装文件夹下的对应文件,也能够将automake安装文件夹下的文件复制到project文件夹。可是考虑GNU 风格的完整性,建议大家运行拷贝步骤,这样也省去又一次链接的麻烦,更基本的是不会像链接那样对安装路径和版本号的依赖那么高,拷贝会一劳永逸。

     

    假设由于不论什么原因改动了configure.in,改动后假设不运行autoconf命令,那么是不会生成新的configure

    在编译的时候,出现类似 “In function `_start'”的错误

    我们知道,automake要求在每一个具有源程序的文件夹下都要创建Makefile.am。但是automake编译完毕后,该工具会自己主动运行链接过程,即将编译的目标文件自己主动链接成同名的可运行程序,但是源程序中没有指定的入口(在Linux中为”main”方法),所以在链接的时候无法找到入口而产生 “链接错误”。

    改动方法:此时该文件夹下已经生成Makefile.in,编辑找到链接运行出,屏蔽掉。比如本例中屏蔽掉home/li/src/Makefile.in的189行:

    #   $(li_LINK) $(li_OBJECTS) $(li_LDADD) $(LIBS)

    其它类似问题都做同样处理。

     

    各个目标之间的依赖处理

    编译的时候,可能会遇到依赖问题。所谓依赖问题,例如以下:

          A → B

          B → C

          …...

    A依赖B, B依赖C,那么在生成目标A的时候,就须要将B和C同一时候告知A。在本样例中,生成目标hello的时候须要li.o,wang.o,zhang.o目标,所以在终于链接的时候须要将这些目标链接进去。

    如今有个问题我没解决,假设编译目标文件(而非终于的可运行文件)的时候,假设存在上面的依赖关系,怎么处理?在这个样例project的park/public.c文件,假设里面的广播方法被某一家调用,那么这块的Makefile.am怎么写(我没搞定)?

    最后,假设因须要,或者不论什么原因改动了Makefile.am,那么须要执行automake更新makefile.in


    转载自:http://www.cnblogs.com/iTsihang 

  • 相关阅读:
    SQL Server 2008的备份和日志收缩
    Java邮件开发JavaMail(三)
    数据库连接字符串大全
    什么是 MDAC、 DA SDK、 ODBC、 OLEDB、 ADO、 RDS, 和 ADO / MD
    数据库连接字符串大全
    数据库连接字符串大全
    ConnectionString类 简体中文版
    数据库连接字符串大全
    ConnectionString类 简体中文版
    ConnectionString类 简体中文版
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/4365373.html
Copyright © 2011-2022 走看看