找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 4387|回复: 1

GNU Autotools (autoconf, automake, libtool, etc.) 自动化编译 (1)

[复制链接]
发表于 2012-2-14 23:09:22 | 显示全部楼层 |阅读模式

个人还是推荐使用cmake,更胜一筹!

0. 操作平台: Linux

1. 软件包安装(Debian)

yes | sudo apt-get install gcc make autoconf automake libtool

2. 从一个例子谈起。
    2.0 完整拷贝如下代码直接在终端执行或者保存为auto-example.sh,添加执行权限执行。或者参考2.1~2.5逐步执行。
  1. echo "create directory ..."
  2. echo_exit()
  3. {
  4.         echo "ERROR: $@"
  5.         exit 1
  6. }
复制代码
# 1.
  1. mkdir hello && cd hello || echo_exit "mkdir hello or cd hello failed"
  2. cat > hello.c <<EOF || echo_exit "generates hello.c failed"
  3. #include <stdio.h>
  4. int main()
  5. {
  6.     printf("hello auto-tools!\n");
  7.     return 0;
  8. }
  9. EOF
复制代码
# 2.
  1. cat > Makefile.am << EOF || echo_exit "generates Makefile.am failed"
  2. bin_PROGRAMS = hello
  3. hello_SOURCES = hello.c
  4. EOF
复制代码
# 3.
  1. cat > configure.ac << EOF || echo_exit "generates configure.ac failed"
  2. #                                               -*- Autoconf -*-
  3. # Process this file with autoconf to produce a configure script.
  4. AC_PREREQ([2.67])
  5. AC_INIT([hello], [1.0], [yygcode@gmail.com])
  6. AM_INIT_AUTOMAKE([-Wall -Werror foreign])
  7. AC_CONFIG_SRCDIR([hello.c])
  8. AC_CONFIG_HEADERS([config.h])
  9. # Checks for programs.
  10. AC_PROG_CC
  11. # Checks for libraries.
  12. # Checks for header files.
  13. # Checks for typedefs, structures, and compiler characteristics.
  14. # Checks for library functions.
  15. AC_CONFIG_FILES([Makefile])
  16. AC_OUTPUT
  17. EOF
复制代码
  1. # 4.
  2. autoreconf --install || echo_exit "autoreconf --install failed"
  3. # 5.
  4. ./configure && make || echo_exit "configure or make failed"
  5. # 6.
  6. make dist && make distcheck || echo_exit "make dist && make distcheck failed"
  7. echo "All Do Over Success"
  8.     2.1 创建hello目录和源代码hello.c:          ~$ mkdir hello && cd hello
  9. ~$ cat > hello.c <<EOF
  10. #include <stdio.h>
  11. int main()
  12. {
  13.     printf("hello auto-tools!\n");
  14.     return 0;
  15. }
  16. EOF    2.2 创建 Makefile.am
  17. ~$ cat > Makefile.am << EOF
  18. bin_PROGRAMS = hello
  19. hello_SOURCES = hello.c
  20. EOF    2.3 用 autoscan 生成configure.ac的模板configure.scan
  21. ~$ autoscan
  22. ~$ cat configure.scan
  23. #                                               -*- Autoconf -*-
  24. # Process this file with autoconf to produce a configure script.
  25. AC_PREREQ([2.67])
  26. AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
  27. AC_CONFIG_SRCDIR([hello.c])
  28. AC_CONFIG_HEADERS([config.h])
  29. # Checks for programs.
  30. AC_PROG_CC
  31. # Checks for libraries.
  32. # Checks for header files.
  33. # Checks for typedefs, structures, and compiler characteristics.
  34. # Checks for library functions.
  35. AC_CONFIG_FILES([Makefile])
  36. AC_OUTPUT      
  37. 需要修改configure.scan的不问内容并保存为configure.ac。为了方便,直接用如下指令生成configure.ac:
  38. ~$ cat > configure.ac << EOF
  39. #                                               -*- Autoconf -*-
  40. # Process this file with autoconf to produce a configure script.
  41. AC_PREREQ([2.67])
  42. AC_INIT([hello], [1.0], [yygcode@gmail.com])
  43. AM_INIT_AUTOMAKE([-Wall -Werror foreign])
  44. AC_CONFIG_SRCDIR([hello.c])
  45. AC_CONFIG_HEADERS([config.h])
  46. # Checks for programs.
  47. AC_PROG_CC
  48. # Checks for libraries.
  49. # Checks for header files.
  50. # Checks for typedefs, structures, and compiler characteristics.
  51. # Checks for library functions.
  52. AC_CONFIG_FILES([Makefile])
  53. AC_OUTPUT
  54. EOF      可以看出,只是修改了AC_INIT行,并添加了AM_INIT_AUTOMAKE行。
  55.     2.4 使用autoreconf直接生成可执行configure并执行编译:
  56. ~$ autoreconf --install
  57. configure.ac:6: installing `./install-sh'
  58. configure.ac:6: installing `./missing'
  59. Makefile.am: installing `./depcomp'
  60. ~$ ./configure
  61. checking for a BSD-compatible install... /usr/bin/install -c
  62. checking whether build environment is sane... yes
  63. checking for a thread-safe mkdir -p... /bin/mkdir -p
  64. checking for gawk... gawk
  65. checking whether make sets $(MAKE)... yes
  66. checking for gcc... gcc
  67. checking whether the C compiler works... yes
  68. checking for C compiler default output file name... a.out
  69. checking for suffix of executables...
  70. checking whether we are cross compiling... no
  71. checking for suffix of object files... o
  72. checking whether we are using the GNU C compiler... yes
  73. checking whether gcc accepts -g... yes
  74. checking for gcc option to accept ISO C89... none needed
  75. checking for style of include used by make... GNU
  76. checking dependency style of gcc... gcc3
  77. configure: creating ./config.status
  78. config.status: creating Makefile
  79. config.status: creating config.h
  80. config.status: executing depfiles commands
  81. ~$ make
  82. make  all-am
  83. make[1]: Entering directory `/tmp/hello'
  84. gcc -DHAVE_CONFIG_H -I.     -g -O2 -MT hello.o -MD -MP -MF .deps/hello.Tpo -c -o hello.o hello.c
  85. mv -f .deps/hello.Tpo .deps/hello.Po
  86. gcc  -g -O2   -o hello hello.o  
  87. make[1]: Leaving directory `/tmp/hello'
  88. ~$ ./hello
  89. hello auto-tools!
  90.     2.5生成发行包并检测完整性:
  91. ~$ make dist && make distcheck
  92. /bin/sh ./config.status --recheck
  93. running CONFIG_SHELL=/bin/sh /bin/sh ./configure --no-create --no-recursion
  94. checking for a BSD-compatible install... /usr/bin/install -c
  95. checking whether build environment is sane... yes
  96. checking for a thread-safe mkdir -p... /bin/mkdir -p
  97. checking for gawk... gawk
  98. checking whether make sets $(MAKE)... yes
  99. checking for gcc... gcc
  100. checking whether the C compiler works... yes
  101. checking for C compiler default output file name... a.out
  102. checking for suffix of executables...
  103. checking whether we are cross compiling... no
  104. checking for suffix of object files... o
  105. checking whether we are using the GNU C compiler... yes
  106. checking whether gcc accepts -g... yes
  107. checking for gcc option to accept ISO C89... none needed
  108. checking for style of include used by make... GNU
  109. checking dependency style of gcc... gcc3
  110. configure: creating ./config.status
  111. /bin/sh ./config.status
  112. config.status: creating Makefile
  113. config.status: creating config.h
  114. config.status: config.h is unchanged
  115. config.status: executing depfiles commands
  116. { test ! -d "hello-1.0" || { find "hello-1.0" -type d ! -perm -200 -exec chmod u+w {} ';' && rm -fr "hello-1.0"; }; }
  117. test -d "hello-1.0" || mkdir "hello-1.0"
  118. test -n "" \
  119.         || find "hello-1.0" -type d ! -perm -755 \
  120.                 -exec chmod u+rwx,go+rx {} \; -o \
  121.           ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
  122.           ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
  123.           ! -type d ! -perm -444 -exec /bin/sh /tmp/hello/install-sh -c -m a+r {} {} \; \
  124.         || chmod -R a+r "hello-1.0"
  125. tardir=hello-1.0 && /bin/sh /tmp/hello/missing --run tar chof - "$tardir" | GZIP=--best gzip -c >hello-1.0.tar.gz
  126. { test ! -d "hello-1.0" || { find "hello-1.0" -type d ! -perm -200 -exec chmod u+w {} ';' && rm -fr "hello-1.0"; }; }
  127. { test ! -d "hello-1.0" || { find "hello-1.0" -type d ! -perm -200 -exec chmod u+w {} ';' && rm -fr "hello-1.0"; }; }
  128. test -d "hello-1.0" || mkdir "hello-1.0"
  129. test -n "" \
  130.         || find "hello-1.0" -type d ! -perm -755 \
  131.                 -exec chmod u+rwx,go+rx {} \; -o \
  132.           ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
  133.           ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
  134.           ! -type d ! -perm -444 -exec /bin/sh /tmp/hello/install-sh -c -m a+r {} {} \; \
  135.         || chmod -R a+r "hello-1.0"
  136. tardir=hello-1.0 && /bin/sh /tmp/hello/missing --run tar chof - "$tardir" | GZIP=--best gzip -c >hello-1.0.tar.gz
  137. { test ! -d "hello-1.0" || { find "hello-1.0" -type d ! -perm -200 -exec chmod u+w {} ';' && rm -fr "hello-1.0"; }; }
  138. case 'hello-1.0.tar.gz' in \
  139.         *.tar.gz*) \
  140.           GZIP=--best gzip -dc hello-1.0.tar.gz | /bin/sh /tmp/hello/missing --run tar xf - ;;\
  141.         *.tar.bz2*) \
  142.           bzip2 -dc hello-1.0.tar.bz2 | /bin/sh /tmp/hello/missing --run tar xf - ;;\
  143.         *.tar.lzma*) \
  144.           lzma -dc hello-1.0.tar.lzma | /bin/sh /tmp/hello/missing --run tar xf - ;;\
  145.         *.tar.xz*) \
  146.           xz -dc hello-1.0.tar.xz | /bin/sh /tmp/hello/missing --run tar xf - ;;\
  147.         *.tar.Z*) \
  148.           uncompress -c hello-1.0.tar.Z | /bin/sh /tmp/hello/missing --run tar xf - ;;\
  149.         *.shar.gz*) \
  150.           GZIP=--best gzip -dc hello-1.0.shar.gz | unshar ;;\
  151.         *.zip*) \
  152.           unzip hello-1.0.zip ;;\
  153.         esac
  154. chmod -R a-w hello-1.0; chmod a+w hello-1.0
  155. mkdir hello-1.0/_build
  156. mkdir hello-1.0/_inst
  157. chmod a-w hello-1.0
  158. test -d hello-1.0/_build || exit 0; \
  159.         dc_install_base=`CDPATH="${ZSH_VERSION+.}:" && cd hello-1.0/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
  160.           && dc_destdir="${TMPDIR-/tmp}/am-dc-$/" \
  161.           && am__cwd=`pwd` \
  162.           && CDPATH="${ZSH_VERSION+.}:" && cd hello-1.0/_build \
  163.           && ../configure --srcdir=.. --prefix="$dc_install_base" \
  164.              \
  165.           && make  \
  166.           && make  dvi \
  167.           && make  check \
  168.           && make  install \
  169.           && make  installcheck \
  170.           && make  uninstall \
  171.           && make  distuninstallcheck_dir="$dc_install_base" \
  172.                 distuninstallcheck \
  173.           && chmod -R a-w "$dc_install_base" \
  174.           && ({ \
  175.                (cd ../.. && umask 077 && mkdir "$dc_destdir") \
  176.                && make  DESTDIR="$dc_destdir" install \
  177.                && make  DESTDIR="$dc_destdir" uninstall \
  178.                && make  DESTDIR="$dc_destdir" \
  179.                     distuninstallcheck_dir="$dc_destdir" distuninstallcheck; \
  180.               } || { rm -rf "$dc_destdir"; exit 1; }) \
  181.           && rm -rf "$dc_destdir" \
  182.           && make  dist \
  183.           && rm -rf hello-1.0.tar.gz \
  184.           && make  distcleancheck \
  185.           && cd "$am__cwd" \
  186.           || exit 1
  187. checking for a BSD-compatible install... /usr/bin/install -c
  188. checking whether build environment is sane... yes
  189. checking for a thread-safe mkdir -p... /bin/mkdir -p
  190. checking for gawk... gawk
  191. checking whether make sets $(MAKE)... yes
  192. checking for gcc... gcc
  193. checking whether the C compiler works... yes
  194. checking for C compiler default output file name... a.out
  195. checking for suffix of executables...
  196. checking whether we are cross compiling... no
  197. checking for suffix of object files... o
  198. checking whether we are using the GNU C compiler... yes
  199. checking whether gcc accepts -g... yes
  200. checking for gcc option to accept ISO C89... none needed
  201. checking for style of include used by make... GNU
  202. checking dependency style of gcc... gcc3
  203. configure: creating ./config.status
  204. config.status: creating Makefile
  205. config.status: creating config.h
  206. config.status: executing depfiles commands
  207. make[1]: Entering directory `/tmp/hello/hello-1.0/_build'
  208. make  all-am
  209. make[2]: Entering directory `/tmp/hello/hello-1.0/_build'
  210. gcc -DHAVE_CONFIG_H -I. -I..     -g -O2 -MT hello.o -MD -MP -MF .deps/hello.Tpo -c -o hello.o ../hello.c
  211. mv -f .deps/hello.Tpo .deps/hello.Po
  212. gcc  -g -O2   -o hello hello.o  
  213. make[2]: Leaving directory `/tmp/hello/hello-1.0/_build'
  214. make[1]: Leaving directory `/tmp/hello/hello-1.0/_build'
  215. make[1]: Entering directory `/tmp/hello/hello-1.0/_build'
  216. make[1]: Nothing to be done for `dvi'.
  217. make[1]: Leaving directory `/tmp/hello/hello-1.0/_build'
  218. make[1]: Entering directory `/tmp/hello/hello-1.0/_build'
  219. make[1]: Nothing to be done for `check'.
  220. make[1]: Leaving directory `/tmp/hello/hello-1.0/_build'
  221. make[1]: Entering directory `/tmp/hello/hello-1.0/_build'
  222. make[2]: Entering directory `/tmp/hello/hello-1.0/_build'
  223. test -z "/tmp/hello/hello-1.0/_inst/bin" || /bin/mkdir -p "/tmp/hello/hello-1.0/_inst/bin"
  224.   /usr/bin/install -c hello '/tmp/hello/hello-1.0/_inst/bin'
  225. make[2]: Nothing to be done for `install-data-am'.
  226. make[2]: Leaving directory `/tmp/hello/hello-1.0/_build'
  227. make[1]: Leaving directory `/tmp/hello/hello-1.0/_build'
  228. make[1]: Entering directory `/tmp/hello/hello-1.0/_build'
  229. make[1]: Nothing to be done for `installcheck'.
  230. make[1]: Leaving directory `/tmp/hello/hello-1.0/_build'
  231. make[1]: Entering directory `/tmp/hello/hello-1.0/_build'
  232. ( cd '/tmp/hello/hello-1.0/_inst/bin' && rm -f hello )
  233. make[1]: Leaving directory `/tmp/hello/hello-1.0/_build'
  234. make[1]: Entering directory `/tmp/hello/hello-1.0/_build'
  235. make[1]: Leaving directory `/tmp/hello/hello-1.0/_build'
  236. make[1]: Entering directory `/tmp/hello/hello-1.0/_build'
  237. make[2]: Entering directory `/tmp/hello/hello-1.0/_build'
  238. test -z "/tmp/hello/hello-1.0/_inst/bin" || /bin/mkdir -p "/tmp/am-dc-8010//tmp/hello/hello-1.0/_inst/bin"
  239.   /usr/bin/install -c hello '/tmp/am-dc-8010//tmp/hello/hello-1.0/_inst/bin'
  240. make[2]: Nothing to be done for `install-data-am'.
  241. make[2]: Leaving directory `/tmp/hello/hello-1.0/_build'
  242. make[1]: Leaving directory `/tmp/hello/hello-1.0/_build'
  243. make[1]: Entering directory `/tmp/hello/hello-1.0/_build'
  244. ( cd '/tmp/am-dc-8010//tmp/hello/hello-1.0/_inst/bin' && rm -f hello )
  245. make[1]: Leaving directory `/tmp/hello/hello-1.0/_build'
  246. make[1]: Entering directory `/tmp/hello/hello-1.0/_build'
  247. make[1]: Leaving directory `/tmp/hello/hello-1.0/_build'
  248. make[1]: Entering directory `/tmp/hello/hello-1.0/_build'
  249. { test ! -d "hello-1.0" || { find "hello-1.0" -type d ! -perm -200 -exec chmod u+w {} ';' && rm -fr "hello-1.0"; }; }
  250. test -d "hello-1.0" || mkdir "hello-1.0"
  251. test -n "" \
  252.         || find "hello-1.0" -type d ! -perm -755 \
  253.                 -exec chmod u+rwx,go+rx {} \; -o \
  254.           ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
  255.           ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
  256.           ! -type d ! -perm -444 -exec /bin/sh /tmp/hello/hello-1.0/install-sh -c -m a+r {} {} \; \
  257.         || chmod -R a+r "hello-1.0"
  258. tardir=hello-1.0 && /bin/sh /tmp/hello/hello-1.0/missing --run tar chof - "$tardir" | GZIP=--best gzip -c >hello-1.0.tar.gz
  259. { test ! -d "hello-1.0" || { find "hello-1.0" -type d ! -perm -200 -exec chmod u+w {} ';' && rm -fr "hello-1.0"; }; }
  260. make[1]: Leaving directory `/tmp/hello/hello-1.0/_build'
  261. make[1]: Entering directory `/tmp/hello/hello-1.0/_build'
  262. test -z "hello" || rm -f hello
  263. rm -f *.o
  264. rm -f *.tab.c
  265. test -z "" || rm -f
  266. test . = ".." || test -z "" || rm -f
  267. rm -f config.h stamp-h1
  268. rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
  269. rm -f config.status config.cache config.log configure.lineno config.status.lineno
  270. rm -rf ./.deps
  271. rm -f Makefile
  272. make[1]: Leaving directory `/tmp/hello/hello-1.0/_build'
  273. { test ! -d "hello-1.0" || { find "hello-1.0" -type d ! -perm -200 -exec chmod u+w {} ';' && rm -fr "hello-1.0"; }; }
  274. ===========================================
  275. hello-1.0 archives ready for distribution:
  276. hello-1.0.tar.gz
  277. ===========================================
复制代码

3. 一般项目并不是简单的一个.c文件。通常包括多个(嵌套的)目录。并且需要执行差异化的编译和安装,下一篇文章示范如何在一个实际项目中应用autotools。

作者:cppgp 发表于2012-2-14 17:40:22 原文链接


发表于 2012-2-16 09:46:41 | 显示全部楼层
autotools入门,写个简单的程序,用起来很简单,但想深入还是有些难度的,主要是资料太少,大部分都是讲解单个工程的。
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-4-29 03:53 , Processed in 0.011600 second(s), 6 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表