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的时候,该工具会在工程目录下查找Makefile.am文件,有该文件的目录下会自动生成相应的Makefile文件。当然也可以后期手动添加。一般的生成顺序是:

1> 根据工程结构,在需要生成Makefile的目录下创建Makefile.am文件。

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

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

这里有三类Makefile.am,现在分类介绍其在整个工程目录中实现的功能。

家目录下的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工具提供工程下各个子目录的路径。在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工具会自动查找工程目录,包括子目录,在发现有Makefile.am存在的目录下为即将创建的Makefile指明工程路径。当然,可以根据自己的需要,指定该文件,如下。

修改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])

在工程目录下创建: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文件。

配置

配置工程安装和运行环境,通过该步骤可以向工程传递配置和安装信息等,最后生成Makefile。

编译

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

问题探讨

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

这根据自己系统当前安装的工具而定,你可以将这些链接重新指向automake安装目录下的相应文件,也可以将automake安装目录下的文件拷贝到工程目录。但是考虑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目标,所以在最终链接的时候需要将这些目标链接进去。

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

最后,如果因需要,或者任何原因修改了Makefile.am,那么需要运行automake更新makefile.in

Makefile 管理工具 — Automake and Autoconf相关推荐

  1. 使用Automake和Autoconf生成Makefile

    automake 所产生的 Makefile 除了可以做到程序的自动编译和链接 外,还可以用来生成各种文档(如manual page.info文件),可以将源代码文件包装起来以供发布.所以程序源代码所 ...

  2. 如何用 ndctl/ipmctl 管理工具 配置不同访问模式的pmem设备

    文章目录 1 PMEM 底层架构 2 PMEM 逻辑架构 3 ipmctl 创建 不同模式的 region 3.1 安装 3.2 创建AppDirect mode的region 3.3 创建 Memo ...

  3. 了解automake和autoconf(autoreconf)

    本文转载自<例解 autoconf 和 automake 生成 Makefile 文件> 通过这篇文章可以了解auotmake和autoconf的基本工作流程,文章讲的通俗易懂,但是版本较 ...

  4. linux下使用automake、autoconf生成configure文件

    一.生成configure过程中各文件之间的关系图 二.详细介绍 autoscan: 扫描源代码以搜寻普通的可移植性问题,比如检查编译器,库,头文件等,生成文件configure.scan,它是con ...

  5. 外来Slackware包管理工具[转]

    http://blog.csdn.net/eroswang/archive/2007/08/11/1738766.aspx一.SWARET ---网络安装模式的实现! 1.简介: swaret可以进行 ...

  6. CentOS 6.0+Nagios中文版+PNP+Nagios Web管理工具nagiosQL中文版

    战CentOS 6.0+Nagios中文版+PNP+Nagios Web管理工具nagiosQL中文版 2011-11-15 17:17:56|  分类: rhel_监控 |  标签: |字号大中小  ...

  7. 第二篇supervisor集群管理工具cesi安装详解-如何安装supervisor-cesiwebUI

    第二篇supervisor集群管理工具cesi安装详解-如何安装supervisor-cesiwebUI 介绍 安装 解压 安装依赖 修改配置 注册为系统服务 启动 登录一下,发现报错了 解决方法 介 ...

  8. Redis 集群搭建及集群管理工具

    目录 一.简介 二.架构图 三.搭建集群 3.1.下载 3.2.编译安装 3.3.配置文件修改 3.4.创建集群 四.集群管理工具redis-cli 4.1.查看集群信息 4.2.检查集群 4.3.修 ...

  9. 近日学习笔记:df -h和du -sh命令,查看linux版本,vbm管理工具,su命令,ssh服务升级技巧,source命令

    文章目录 df -h和du -sh区别 df -h查看整个系统中文件系统的使用情况 du -sh *查看当前目录下各个文件及目录占用空间大小 查看Linux系统版本的命令: VirtualBox管理工 ...

  10. golang 官方依赖管理工具 dep 使用和持续集成

    介绍 go dep 依赖管理工具是为应用管理代码的,go get是为GOPATH管理代码的 官方地址 官方说明为啥要统一依赖管理 dep 需要在Go 1.7及更高的版本中使用 安装 本文使用 gola ...

最新文章

  1. 四、redis比mysql快的原因
  2. ANSI C中的sizeof详解
  3. 【渗透技术】一个渗透测试工具人是怎样操作的
  4. sql server中创建链接服务器图解教程
  5. checkout 撤销修改_Git的4个阶段的撤销更改
  6. 学音视频一定要掌握这几个算法
  7. ffplay播放器移植VC的工程:ffplay for MFC
  8. BOOT.BIN文件
  9. 机票订票b系统的服务器,飞机订票系统分析与总结
  10. GraphRNN: Generating Realistic Graphs with Deep Auto-Regressive Models
  11. 传统语音增强——基于先验信噪比的维纳滤波语音降噪算法
  12. 数据分析怎么学?我画了一个导图,又找到22本书
  13. 医院病案管理系统MRMS源码 病案管理 医院源码
  14. 【阅读文献】单目视觉SLAM方法综述【4】~特征点深度获取+地图尺度控制
  15. 【生产优化】基于matlab遗传算法求解帐篷工序问题【含Matlab源码 2145期】
  16. canvas实现pc端画板
  17. 苹果新款笔记本_谷歌发布售价99美元的新款Wi-Fi路由器(全文)_苹果 新款MacBook Pro 13英寸_笔记本新闻...
  18. SOEM 源码解析 ecx_lookup_prev_sii
  19. 传智播客微金所项目实战移动web开发
  20. oracle闪回空间满的原因,处理Oracle数据库闪回区空间满的问题

热门文章

  1. _itoa_s替换 itoa
  2. 阅读underscore源码笔记
  3. C#.NET软件项目中程序开发外包经验分享【从接包者转变为发包者】
  4. 生鲜电商之毒,食行生鲜模式虽好、恐也难解
  5. input 禁止 复制 粘贴 剪切 操作
  6. 爬虫入门到精通-headers的详细讲解(模拟登录知乎)
  7. 一道容易栽坑的有趣的面试题(关于js,定时器,闭包等)
  8. SpringMVC一路总结(一)
  9. Utils工具方法集插件详解
  10. Linux tree 命令乱码