Makefile 管理工具 — Automake and 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的时候,该工具会在工程目录下查找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相关推荐
- 使用Automake和Autoconf生成Makefile
automake 所产生的 Makefile 除了可以做到程序的自动编译和链接 外,还可以用来生成各种文档(如manual page.info文件),可以将源代码文件包装起来以供发布.所以程序源代码所 ...
- 如何用 ndctl/ipmctl 管理工具 配置不同访问模式的pmem设备
文章目录 1 PMEM 底层架构 2 PMEM 逻辑架构 3 ipmctl 创建 不同模式的 region 3.1 安装 3.2 创建AppDirect mode的region 3.3 创建 Memo ...
- 了解automake和autoconf(autoreconf)
本文转载自<例解 autoconf 和 automake 生成 Makefile 文件> 通过这篇文章可以了解auotmake和autoconf的基本工作流程,文章讲的通俗易懂,但是版本较 ...
- linux下使用automake、autoconf生成configure文件
一.生成configure过程中各文件之间的关系图 二.详细介绍 autoscan: 扫描源代码以搜寻普通的可移植性问题,比如检查编译器,库,头文件等,生成文件configure.scan,它是con ...
- 外来Slackware包管理工具[转]
http://blog.csdn.net/eroswang/archive/2007/08/11/1738766.aspx一.SWARET ---网络安装模式的实现! 1.简介: swaret可以进行 ...
- CentOS 6.0+Nagios中文版+PNP+Nagios Web管理工具nagiosQL中文版
战CentOS 6.0+Nagios中文版+PNP+Nagios Web管理工具nagiosQL中文版 2011-11-15 17:17:56| 分类: rhel_监控 | 标签: |字号大中小 ...
- 第二篇supervisor集群管理工具cesi安装详解-如何安装supervisor-cesiwebUI
第二篇supervisor集群管理工具cesi安装详解-如何安装supervisor-cesiwebUI 介绍 安装 解压 安装依赖 修改配置 注册为系统服务 启动 登录一下,发现报错了 解决方法 介 ...
- Redis 集群搭建及集群管理工具
目录 一.简介 二.架构图 三.搭建集群 3.1.下载 3.2.编译安装 3.3.配置文件修改 3.4.创建集群 四.集群管理工具redis-cli 4.1.查看集群信息 4.2.检查集群 4.3.修 ...
- 近日学习笔记:df -h和du -sh命令,查看linux版本,vbm管理工具,su命令,ssh服务升级技巧,source命令
文章目录 df -h和du -sh区别 df -h查看整个系统中文件系统的使用情况 du -sh *查看当前目录下各个文件及目录占用空间大小 查看Linux系统版本的命令: VirtualBox管理工 ...
- golang 官方依赖管理工具 dep 使用和持续集成
介绍 go dep 依赖管理工具是为应用管理代码的,go get是为GOPATH管理代码的 官方地址 官方说明为啥要统一依赖管理 dep 需要在Go 1.7及更高的版本中使用 安装 本文使用 gola ...
最新文章
- 四、redis比mysql快的原因
- ANSI C中的sizeof详解
- 【渗透技术】一个渗透测试工具人是怎样操作的
- sql server中创建链接服务器图解教程
- checkout 撤销修改_Git的4个阶段的撤销更改
- 学音视频一定要掌握这几个算法
- ffplay播放器移植VC的工程:ffplay for MFC
- BOOT.BIN文件
- 机票订票b系统的服务器,飞机订票系统分析与总结
- GraphRNN: Generating Realistic Graphs with Deep Auto-Regressive Models
- 传统语音增强——基于先验信噪比的维纳滤波语音降噪算法
- 数据分析怎么学?我画了一个导图,又找到22本书
- 医院病案管理系统MRMS源码 病案管理 医院源码
- 【阅读文献】单目视觉SLAM方法综述【4】~特征点深度获取+地图尺度控制
- 【生产优化】基于matlab遗传算法求解帐篷工序问题【含Matlab源码 2145期】
- canvas实现pc端画板
- 苹果新款笔记本_谷歌发布售价99美元的新款Wi-Fi路由器(全文)_苹果 新款MacBook Pro 13英寸_笔记本新闻...
- SOEM 源码解析 ecx_lookup_prev_sii
- 传智播客微金所项目实战移动web开发
- oracle闪回空间满的原因,处理Oracle数据库闪回区空间满的问题