這是用 latex2html 轉出來的。
目錄
- 1 autobuild 簡介
- 2 autobuild 版本
- 3 hello example C version
- 4 hello example C++ version
- 5 加入 libtool
- 6 產生兩個以上的執行檔
- 7 使用 config.h
- 8 把原始碼放到 src 的目錄裡
- 9 撰寫自己的 M4 測試
摘要:
本文件介紹如何使用 autoconf, automake, libtool 來產生編譯原始碼所需要的檔案, ex : configure, Makefile ...
1 autobuild 簡介
GNU autobuild 系統包含了 autoconf, automake, libtool。 autoconf 需要編寫 configure.ac, automake 需要編寫 Makefile.am, configure.ac 由 M4 巨集和 shell script 構成。 所以在 configure.ac 可以看到 M4 巨集和 shell script。 而 configure.ac 可以先用 autoscan 來產生一個範本 (configure.scan), 先複製成 configure.ac 再修改需要的 M4 巨集即可。automake 則是用來產生 Makefile.in, 再讓 configure 根據 Makefile.in 產生 Makefile。
libtool 則是產生 static/shared library 的 script。
2 autobuild 版本
autoscan (GNU Autoconf) 2.59 Written by David J. MacKenzie and Akim Demaille.Copyright (C) 2003 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
autoconf (GNU Autoconf) 2.59 Written by David J. MacKenzie and Akim Demaille.
Copyright (C) 2003 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
automake (GNU automake) 1.9.5 Written by Tom Tromey <tromey@redhat.com>.
Copyright 2005 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
由於各版本的 M4 巨集寫法有些差異, 以下介紹以我目前所接觸的最新版本為主, 若是之前的版本不一定適用。
3 hello example C version
這是 C 版本的 hello。 #include <stdio.h> int main() { printf("hello\n"); return 0; }
$ autoscan autom4te: configure.ac: no such file or directory autoscan: /usr/bin/autom4te failed with exit status: 1configure.scan 內容:
# Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS) AC_CONFIG_SRCDIR([hello.c]) AC_CONFIG_HEADER([config.h]) # Checks for programs. AC_PROG_CC # Checks for libraries. # Checks for header files. # Checks for typedefs, structures, and compiler characteristics. # Checks for library functions. AC_OUTPUT
$ cp configure.scan configure.ac現在我們要修改 configure.ac, 使其符合我們的需要。 首先先移除
AC_CONFIG_HEADER([config.h])
, 因為目前我們沒有用到 config.h。 加入和 automake 有關的 M4 巨集。
AM_INIT_AUTOMAKE AC_CONFIG_FILES(Makefile)
AM_INIT_AUTOMAKE
初始化 automake。 AC_CONFIG_FILES(Makefile)
會由 Makefile.in 來產生 Makefile, 而 Makefile.in 由 Makefile.am 來產生。 修改
AC_INIT
參數: AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
應該很直覺, FULL-PACKAGE-NAME ->
hello, VERSION ->
0.1, BUG-REPORT-ADDRESS ->
cname@mail.com
。 這三個參數分別為 package 的 name, 版本, bug report 到那裡。 以下為修改後的 configure.ac: # -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.59)
AC_INIT(hello, 0.1, cname@mail.com
)
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([hello.c])
#AC_CONFIG_HEADER([config.h])
# Checks for programs.
AC_PROG_CC
AC_CONFIG_FILES(Makefile)
# Checks for libraries.
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_OUTPUT
再來看看 Makefile.am bin_PROGRAMS=hello hello_SOURCES=hello.c這個更直覺, 完全不需要解釋了吧!?
再來便是執行一系列的程式來產生所需要的檔案了。
aclocal autoconf automake -a第一次執行 automake -a 會有以下的訊息:
automake: Makefile.am: required file `./NEWS' not found automake: Makefile.am: required file `./README' not found automake: Makefile.am: required file `./AUTHORS' not found automake: Makefile.am: required file `./ChangeLog' not found這是因為 automake 需要這些檔案, 而 automake 無法自動產生, 所以我們自己來產生。
$ touch NEWS README AUTHOR ChangeLog再執行 automake -a 一次。 應該就沒問題了。
執行 configure script 看看有無錯誤。
./configure make來測試看有沒有正確產生 hello, 並執行看看。
make distcheck會作一系列的測試, 並產生 hello-0.1.tar.gz, hello, 0.1 就是
AC_INIT
的前兩個參數。 可以試試看 make install make distclean這些 makefile rule。 如何? 是不是比自己寫 makfile 容易多了。
4 hello example C++ version
這是 C++ 版本的 hello。#include <iostream> int main() { using namespace std; cout << "hello" << endl; return 0; }一樣先執行 autoscan, 再把 configure.scan copy 成 configure.ac。 autoscan 會得知目前的語言是 C++ 語言, 並會產生相對應的 M4 巨集。 修改方式和 C 版本的 hello 一樣, 注意
AC_PROG_CXX
, 這會測試是否有 C++ compiler, 也就是 g++。 照著 section 3 再執行一遍, 應該可以順利成功。 由於我大部份使用 C++, 所以下面的例子全部以 C++ 為主。
5 加入 libtool
5.1 libtool 簡介
libtool 是用來產生 library 的 script, 可以用來產生 shared/static library。 由於每個系統產生 library 的方法不同, libtool 把有支援到的平台, 以同樣的方式來產生 library。 下面的命令可以產生 static/shared library。libtool --mode=link g++ -o libgraph.la svga.lo shape.lo \ geometry.lo view.lo painter.lo draw.lo color_convert.lo \ -rpath /usr/local/lib而 libtool 命令會去執行下面的 g++ 命令。
g++ -shared .libs/svga.o .libs/shape.o .libs/geometry.o \ .libs/view.o .libs/painter.o .libs/draw.o .libs/color_convert.o \ -lstdc++ -lm -lc -lgcc_s -Wl,-soname -Wl,libgraph.so.0 \ -o .libs/libgraph.so.0.0.0 (cd .libs && rm -f libgraph.so.0 && ln -s libgraph.so.0.0.0 libgraph.so.0) (cd .libs && rm -f libgraph.so && ln -s libgraph.so.0.0.0 libgraph.so) ar cru .libs/libgraph.a svga.o shape.o geometry.o view.o painter.o \ draw.o color_convert.o ranlib .libs/libgraph.a creating libgraph.la (cd .libs && rm -f libgraph.la && ln -s ../libgraph.la libgraph.la) $ exit在 autoconf, automake 加入一些 M4 巨集及變數, 便可以呼叫 libtool 來幫我們產生 library。想要單獨使用 libtool 的朋友, 請自行參考 libtool 手冊。
5.2 加入 libtool 支援
在 configure.ac 新增AC_PROG_LIBTOOL
, 就可以了。 至於 Makefile.am: bin_PROGRAMS=hello1 hello1_SOURCES=hello1.cpp hello1_LDADD=libh.la lib_LTLIBRARIES=libh.la libh_la_SOURCES=h.cpp h.h新的變數名稱有:
hello1_LDADD=libh.la lib_LTLIBRARIES=libh.la libh_la_SOURCES=h.cpp h.h
hello1_LDADD
會讓 hello1.o 和 libh.la 作 link, lib_LTLIBRARIES
會用 libtool 產生 libh.la, 會有 shared/static 兩種, 在 .lib 目錄裡。 libh_la_SOURCES
這個 library 的原始程式。 libh_la
就是將 libh.la 的 . 符號以 _
替換掉, 若是 library 檔名為 libabc.la 就以 libabc_la_SOURCES
為 Makefile.am 的變數名稱。 接著執行
aclocal autoconf libtoolize --force automake -a
libtoolize --force
會產生新的 script 檔案, config.guess config.sub ltmain.sh'以下是完整的 configure.ac
# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS) AM_INIT_AUTOMAKE AC_CONFIG_SRCDIR([hello1.cpp]) #AC_CONFIG_HEADER([config.h]) AC_PROG_LIBTOOL AC_CONFIG_FILES([Makefile]) # Checks for programs. AC_PROG_CXX # Checks for libraries. # Checks for header files. # Checks for typedefs, structures, and compiler characteristics. # Checks for library functions. AC_OUTPUT以下是完整的 Makefile.am
bin_PROGRAMS=hello1 hello1_SOURCES=hello1.cpp hello1_LDADD=libh.la lib_LTLIBRARIES=libh.la libh_la_SOURCES=h.cpp h.h所有原始碼檔案:
h.cpp hello1.cpp hello2.cpp h.hhello1.cpp hello2.cpp 是兩個含有 main 的程式檔案, h.h h.cpp 則含有一個 function 來讓 hello1.cpp hello2.cpp 呼叫, 也是構成 libh.la library 的原始程式。
6 產生兩個以上的執行檔
這很容易, 把 Makefile.am 改成bin_PROGRAMS=hello1 hello2 hello1_SOURCES=hello1.cpp hello1_LDADD=libh.la hello2_SOURCES=hello2.cpp hello2_LDADD=libh.la lib_LTLIBRARIES=libh.la libh_la_SOURCES=h.cpp h.h產生 hello2 相關的變數 (
hello2_SOURCES
, hello2_LDADD
), bin_PROGRAMS
則加入一個 hello2。以此類推就可以產生多個執行檔。 7 使用 config.h
經由 autobuild 產生的 Makefile 會產生很多的 -D 巨集定義,AC_CONFIG_HEADER([config.h])
可以產生 config.h 裡面會定義一些巨集, 而我們的程式 #if HAVE_CONFIG_H #include "config.h" #endif即可使用這些巨集定義, 而 Makefile 也不會有很多的 -DAAA -DBBB -DCCC, 可以減少 Makefile 的大小。
這是在還沒有使用
AC_CONFIG_HEADER([config.h])
所產生的 Makefile 其中的巨集定義。 DEFS = -DPACKAGE_NAME=\"FULL-PACKAGE-NAME\" -DPACKAGE_TARNAME=\"full-package-name\"
-DPACKAGE_VERSION=\"VERSION\" -DPACKAGE_STRING=\"FULL-PACKAGE-NAME\ VERSION\"
-DPACKAGE_BUGREPORT=\"BUG-REPORT-ADDRESS\" -DPACKAGE=\"full-package-name\"
-DVERSION=\"VERSION\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1
-DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1
-DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1
在使用
AC_CONFIG_HEADER([config.h])
之後, Makefile 的 DEFS 如下: DEFS = -DHAVE_CONFIG_H所有的巨集定義都在 config.h 裡了。
/* config.h. Generated by configure. */ /* config.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if you have the <dlfcn.h> header file. */ #define HAVE_DLFCN_H 1 /* Define to 1 if you have the <inttypes.h> header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the `vga' library (-lvga). */ #define HAVE_LIBVGA 1 /* Define to 1 if you have the `vgagl' library (-lvgagl). */ #define HAVE_LIBVGAGL 1 /* Define to 1 if you have the <memory.h> header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have the <stdint.h> header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the <stdlib.h> header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the <strings.h> header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the <string.h> header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the <sys/stat.h> header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the <sys/types.h> header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the <unistd.h> header file. */ #define HAVE_UNISTD_H 1 /* Name of package */ #define PACKAGE "svgalib_test" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "descent@gmail.com" /* Define to the full name of this package. */ #define PACKAGE_NAME "svgalib_test" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "svgalib_test 0.0.1" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "svgalib_test" /* Define to the version of this package. */ #define PACKAGE_VERSION "0.0.1" /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Version number of package */ #define VERSION "0.0.1" /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */執行
aclocal autoconf autoheader libtoolize --force automake -a現在要多執行一支程式: autoheader, 用來產生 config.h。
8 把原始碼放到 src 的目錄裡
建立 src 目錄, 將 source code (*.cpp, *.h) 移到 src, 將原本的 Makefile.am 也移到 src, 修改 confiure.acAC_CONFIG_FILES([Makefile src/Makefile])表示要在原始碼目錄和 src 目錄產生 Makefile, 接著在原始碼目錄新增一個 Makefile.am, 其內容為:
SUBDIRS = src執行
aclocal autoconf autoheader libtoolize --force automake -a執行 configure, 在原始碼目錄可以看見 Makefile, config.h, 而 src 目錄也會產生 Makefile。
9 撰寫自己的 M4 測試
以下的例子會檢查 svgalib 和 libjpeg 是否系統有這兩個 library。# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) AC_INIT(jpeglib_test, 0.0.1, descent@gmail.com) AM_INIT_AUTOMAKE AC_CONFIG_SRCDIR([jpeg.cpp]) AC_PROG_LIBTOOL AC_CONFIG_HEADER([config.h]) # Checks for programs. AC_PROG_CXX AC_PROG_CC AC_CONFIG_FILES([Makefile]) # Checks for libraries. #AC_CHECK_LIB([vga],main,,[echo "not find svgalib vgagl.";exit 1],) #AC_CHECK_LIB([vgagl],main,,[echo "not find svgalib vga .";exit 1],[-lvga]) AC_LANG_PUSH([C++]) ORG_LIBS="LIBS" AC_SUBST([CONFIG_SVGALIB_LIB],["-lvga -lvgagl"]) AC_MSG_CHECKING([we need to link svgalib lib]) LIBS="$CONFIG_SVGALIB_LIB $LIBS" AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[ #include <vga.h> #include <vgagl.h> ]], [[ vga_init(); int mode=G320x200x256; vga_setmode(mode); gl_setcontextvga(mode); vga_setmode(TEXT); ]] )], [CONFIG_SVGALIB_LIB="-lvga -lvgagl"; AC_MSG_RESULT(yes);], [AC_MSG_RESULT(no), CONFIG_SVGALIB_LIB="" ; exit;] ) LIBS=$ORG_LIBS #check jpeg lib AC_SUBST([CONFIG_JPEG_LIB],["-ljpeg"]) AC_MSG_CHECKING([we need to link jpeg lib]) LIBS="$CONFIG_JPEG_LIB $LIB" AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[ #include <cstdio> // this shoule before jpeg header file #include <cstdlib> // this shoule before jpeg header file #include <jpeglib.h> #include <jerror.h> ]], [[ struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; cinfo.err = jpeg_std_error (&jerr); ]] )], [CONFIG_JPEG_LIB="-ljpeg"; AC_MSG_RESULT(yes);], [AC_MSG_RESULT(no), CONFIG_JPEG_LIB=""; echo "no"; exit;] ) LIBS=$ORG_LIBS AC_LANG_POP([C++]) LIBS="$CONFIG_JPEG_LIB $CONFIG_SVGALIB_LIB" # Checks for header files. # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST # Checks for library functions. AC_OUTPUT
About this document ...
This document was generated using the LaTeX2HTML translator Version 2008 (1.71)Copyright © 1993, 1994, 1995, 1996, Nikos Drakos, Computer Based Learning Unit, University of Leeds.
Copyright © 1997, 1998, 1999, Ross Moore, Mathematics Department, Macquarie University, Sydney.
The command line arguments were:
latex2html -show_section_numbers -split 0 autobuild.tex
source file: https://github.com/descent/latex_doc/tree/master/autobuild
ref:
convert pdf to html: http://www.pdfonline.com/convert-pdf-to-html/
沒有留言:
張貼留言
使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。
我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。