工作流程:
autoscan→ aclocal→ autoheader→ libtoolize --automake --copy --debug --force→ automake --add-missing→ autoconf
用户需要编写的只有configure.ac(configure.in)和Makefile.am
NOTE:configure.in是旧版本的写法,虽然可以兼容,但推荐使用configure.ac
官方文档:
示例框架:
示例工程:
代码说明:
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)
|