基于GNU的autoconf

工作流程:

autoscan→ aclocal→ autoheader→ libtoolize --automake --copy --debug --force→ automake --add-missing→ autoconf

用户需要编写的只有configure.ac(configure.in)和Makefile.am

NOTE:configure.in是旧版本的写法,虽然可以兼容,但推荐使用configure.ac

官方文档:

autoconf.pdf

automake.pdf

示例框架:

示例工程:

test_autoconf.tar.gz

代码说明:

configure.ac
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
 
AC_PREREQ([2.69])    # autoconf最低版本需求
AC_INIT([dptest], [1.0.0], [liuzhengzhong @d -power.com.cn])   # 初始化,第一个参数工程名,第二个版本号,第三个参数bugreport地址
 
DPTEST_MAJOR_VERSION=1   # 主版本号
DPTEST_MINOR_VERSION=0   # 次版本号
DPTEST_MICRO_VERSION=0   # 修订版本号
 
DPTEST_VERSION= $DPTEST_MAJOR_VERSION . $DPTEST_MINOR_VERSION . $DPTEST_MICRO_VERSION     # 1.0.0
 
AC_SUBST(DPTEST_VERSION)     # 提交宏值,以供外部Makefile.am引用
 
AC_CANONICAL_SYSTEM      # 显示--build,--host,--target
 
AM_INIT_AUTOMAKE([dptest], [1.0.0])  # 初始化automake,第一个参数工程名,第二个参数版本号
AC_CONFIG_HEADER([include/config.h])     # 设置使用autoheader自动化配置头文件
 
AC_PROG_LIBTOOL      # 检查libtool
AC_PROG_CC           # 检查C编译器
AC_PROG_CXX          # 检查CXX编译器
AC_PROG_RANLIB       # 检查ranlib,更新.a符号表用到
AC_PROG_INSTALL      # 检查install
AC_PROG_LN_S         # 检查ln -s
AC_PROG_MAKE_SET     # 检查make命令
 
AC_HEADER_STDC       # 检查std头文件
AC_HEADER_DIRENT     # 检查后面的header,追加宏定义,-DHAVE_SYS_TYPES_H -DHAVE_SYS_TIME_H
AC_CHECK_HEADERS(sys/types.h sys/ time .h)
 
AC_CHECK_DECLS([strlen, strdup])     # 检查定义
 
AC_C_CONST           # 检查编译器是否支持const关键字
AC_C_INLINE          # 检查编译器是否支持inline关键字
AC_TYPE_SIZE_T       # 如果编译器没有size_t,定义一个合适的类型
AC_HEADER_TIME       # 如果编译器同时有time.h和sys/time.h,-DTIME_WITH_SYS_TIME
AC_STRUCT_TM         # 如果time.h没有定义struct tm,-DTM_IN_SYS_TIME
 
AC_FUNC_ALLOCA       # 检查如何获取alloca
AC_FUNC_MEMCMP       # 检查memcpy函数是否可用
AC_FUNC_MMAP         # 检查mmap函数是否存在并可用
AC_FUNC_VPRINTF      # 如果存在vprintf,-DHAVE_VPRINTF
AC_CHECK_FUNCS( time  localtime )   # 检查函数是否存在
 
# 初始值
debug= "yes"
trace= "no"
video= "no"
audio= "no"
png= "yes"
 
# 以函数封装,检查是否开启debug功能
CheckDebug()   
{
     # --enable-xx使用此宏,第一个参数变量名
     # 第二个参数帮助信息,--enable-变量名 xxx
     # 第三个参数赋值
     AC_ARG_ENABLE([debug], 
                     [  --enable-debug    include debug message into library <default=yes>],
                     [debug= $enableval ])
 
     # 若取值为yes,则执行条件中的语句
     if  test  "x$debug"  "xyes" ; then
         # 把DP_DEF_DEBUG值置为1,第三个参数是帮助信息
         AC_DEFINE([DP_DEF_DEBUG], [1], [Define  if  include debug])
     fi
}
 
# 以函数封装,检查是否开启trace功能
CheckTrace()   
{
     # --enable-xx使用此宏,第一个参数变量名
     # 第二个参数帮助信息,--enable-变量名 xxx
     # 第三个参数赋值
     AC_ARG_ENABLE([trace], 
                     [  --enable-trace    include trace message into library <default= no >], 
                     [trace= $enableval ])
 
     # 若取值为yes,则执行条件中的语句
     if  test  "x$trace"  "xyes" ; then
            # 把DP_DEF_TRACE值置为1,第三个参数是帮助信息
         AC_DEFINE([DP_DEF_TRACE], [1], [Define  if  include trace])  
     fi
}
 
# 以函数封装,检查是否开启video模块
CheckVideo()   
{
     # --enable-xx使用此宏,第一个参数变量名
     # 第二个参数帮助信息,--enable-变量名 xxx
     # 第三个参数赋值
     AC_ARG_ENABLE([video], 
                     [  --enable-video    include video <default= no >],  
                     [video= $enableval ])
 
     # 若取值为yes,则执行条件中的语句
     if  test  "x$video"  "xyes" ; then   
         # 把DP_DEF_VIDEO值置为1,第三个参数是帮助信息
         AC_DEFINE([DP_DEF_VIDEO], [1], [Define  if  include video])  
         # 赋值路径给SUBSYS_DIRS,此处路径相对于调用SUBSYS_DIRS的Makefile.am
         SUBSYS_DIRS= "$SUBSYS_DIRS video"   
         # 赋值库名给DRIVERS,此处路径相对于调用DRIVERS的Makefile.am
         DRIVERS= "$DRIVERS video/libvideo.la"   
     fi
}
 
# 以函数封装,检查是否开启audio模块
CheckAudio()   
{
     # --enable-xx使用此宏,第一个参数变量名
     # 第二个参数帮助信息,--enable-变量名 xxx
     # 第三个参数赋值
     AC_ARG_ENABLE([audio], 
                     [  --enable-audio    include audio <default= no >],  
                     [audio= $enableval ])
 
     # 若取值为yes,则执行条件中的语句
     if  test  "x$audio"  "xyes" ; then   
         # 把DP_DEF_AUDIO值置为1,第三个参数是帮助信息
         AC_DEFINE([DP_DEF_AUDIO], [1], [Define  if  include audio])  
         # 赋值路径给SUBSYS_DIRS,此处路径相对于调用SUBSYS_DIRS的Makefile.am
         SUBSYS_DIRS= "$SUBSYS_DIRS audio"   
         # 赋值库名给DRIVERS,此处路径相对于调用DRIVERS的Makefile.am
         DRIVERS= "$DRIVERS audio/libaudio.la"   
     fi
}
 
# 以函数封装,检查是否链接libpng
CheckPng() 
{
     # --enable-xx使用此宏,第一个参数变量名
     # 第二个参数帮助信息,--enable-变量名 xxx
     # 第三个参数赋值
     AC_ARG_ENABLE([png],   
                     [  --enable-png      include libpng <default=yes>],
                     [png= $enableval ])  
 
     # 若取值为yes,则执行条件中的语句
     if  test  "x$png"  "xyes" ; then 
         # 检查库中是否有指定函数,第一个参数库名
         # 第二个参数指定函数名
         # 第三个参数,若存在,则执行
         # 第四个参数,若不存在,则执行,此处会中断configure
         AC_CHECK_LIB([png],        
                         [png_check_sig],   
                         [SYSTEM_LIBS= "$SYSTEM_LIBS -lpng" ],
                         [AC_MSG_FAILURE([ "can not find libpng" ],[0])]) 
         # 把DP_DEF_PNG值置为1,第三个参数是帮助信息
         AC_DEFINE([DP_DEF_PNG], [1], [Define  if  include libpng])   
     fi
}
 
# 以函数封装,检查使用哪个平台
CheckPlatform()
{
     # --with-xx使用此宏,第一个参数变量名
     # 第二个参数帮助信息,--with-变量名 xxx
     AC_ARG_WITH([platform],
                     [  --with-platform=X1/X3/X5/X7/none])  
 
     # 注意中间变成下划线
     case  "$with_platform"  in   
     X1)
         # 若选择X1,则执行,此处仅打印,可根据实际情况添加
         AC_MSG_NOTICE( "select platform X1" )
     ;;
     X3)
         # 若选择X3,则执行,此处仅打印,可根据实际情况添加
         AC_MSG_NOTICE( "select platform X3" )
     ;;
     X5)
         # 若选择X5,则执行,此处仅打印,可根据实际情况添加
         AC_MSG_NOTICE( "select platform X5" )
     ;;
     X7)
         # 若选择X7,则执行,此处仅打印,可根据实际情况添加
         AC_MSG_NOTICE( "select platform X7" )
     ;;
     esac
}
 
# 调用前面封装的函数
{  
  CheckPlatform
  CheckDebug
  CheckTrace
  CheckVideo
  CheckAudio
  CheckPng
}
 
# 检查库中是否有指定函数,第一个参数库名
# 第二个参数指定函数名
# 第三个参数为空时,若函数存在,则自动-lpthread
# 第四个参数,若不存在,则执行,此处会中断configure
AC_CHECK_LIB([pthread],
                 [pthread_create],  
                 [],    
                 [AC_MSG_FAILURE([ "error test pthread" ],[0])])  
 
# 提交宏值,以供外部Makefile.am引用
AC_SUBST(SUBSYS_DIRS)  
AC_SUBST(DRIVERS)     
 
# 若第二个参数的结果为TRUE,提交第一个参数的宏值为TRUE
AM_CONDITIONAL(DP_DEF_AUDIO, test  "x$audio"  "xyes" )  
AM_CONDITIONAL(DP_DEF_VIDEO, test  "x$video"  "xyes" )
 
# ./configure -h时,对齐
AS_HELP_STRING 
 
# 指定自动生成文件,路径相对于顶层路径
# 根据顶层路径下的dptest.pc.in生成dptest.pc
# 根据顶层路径下的Makefile.in生成Makefile
# 根据顶层路径下的src/Makefile.in生成src/Makefile
# 根据顶层路径下的src/video/Makefile.in生成src/video/Makefile
# 根据顶层路径下的src/audio/Makefile.in生成src/audio/Makefile
AC_OUTPUT(         
dptest.pc          
Makefile           
src/Makefile       
src/video/Makefile 
src/audio/Makefile 
)
Makefile.am
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 最宽松的规则,否则会检查工程目录下的NEWS,ChangeLog等文件
AUTOMAKE_OPTIONS=foreign
 
# 当前目录
PROJECT_PATH=$(shell /bin/pwd)
 
# 头文件路径
AM_CFLAGS = -I$(PROJECT_PATH)/include
AM_CPPFLAGS = -I$(PROJECT_PATH)/include
 
# make install的路径
dptest_includedir = $(includedir)/dptest
# make install需要安装的头文件
dptest_include_HEADERS = $(PROJECT_PATH)/include/main.h
 
# 子目录,路径相对于当前Makefile.am的路径
SUBDIRS = src
src/Makefile.am
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 取configure.ac中SUBSYS_DIRS的值作为子目录
SUBDIRS =  @SUBSYS_DIRS @
 
# 生产的可执行文件名,并会跟随make install安装到安装目录
bin_PROGRAMS = dptest
 
# 源文件
SRC_FILES = main.c
# 头文件
HDR_FILES = main.h
 
# 以可执行文件名作为前缀
dptest_SOURCES = $(SRC_FILES) $(HDR_FILES)
# 指定链接库
dptest_LDADD =  @DRIVERS @
# 指定依赖
dptest_DEPENDENCIES =  @DRIVERS @
src/audio/Makefile.am
1
2
3
4
5
6
7
8
9
10
11
12
13
# 源文件
SRC_FILES = audio.c
# 头文件
HDR_FILES = audio.h
 
# 版本号
DPTESTLDFLAGS = -release $(DPTEST_VERSION)
 
# 库名,并且会跟随make install安装到安装目录
lib_LTLIBRARIES = libaudio.la
# 注意前缀
libaudio_la_SOURCES=$(SRC_FILES) $(HDR_FILES)
libaudio_la_LDFLAGS=$(DPTESTLDFLAGS)
src/video/Makefile.am
1
2
3
4
5
6
7
8
9
10
# 库名,并且不会跟随make install安装到安装目录
noinst_LTLIBRARIES = libvideo.la
 
# 源文件
SRC_FILES = video.c
# 头文件
HDR_FILES = video.h
 
# 注意前缀
libvideo_la_SOURCES=$(SRC_FILES) $(HDR_FILES)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值