前段時間試着用了用Autotools,當時覺得不錯想寫一篇小的記錄的,結果忙呀忙呀就拖到現在了……暑假裡想重新寫一篇,結果居然已經通通忘光了……是故現在決定速度動工,謹防以後自己又忘了……
本文也是一篇較好的Autotools教學文,市面上的版本不是太片面就是長到難以靜心看下去……這篇會包括頭檔案的處理,簡單的庫檔案檢測,制作靜态庫等,對于一般的DIYer應該夠用了吧~
又及:我假定您是一個基礎的*nix使用者,對gcc的CLI使用較純熟,或者退而求其次……至少要懂得Wiki,Google或者RTFM……
感謝
http://www.gnu.org/software/automake/manual/html_node/index.html
http://www.gnu.org/software/autoconf/manual/html_node/index.html
http://www.freesoftwaremagazine.com/books/autotools_a_guide_to_autoconf_automake_libtool
在我困惑的時候提供解答,并遵守GFDL1.3 || cc-by-sa2.0,少量撷取了圖檔資源。
本文遵循 GFDL1.3 && cc-by-sa3.0 釋出。
首先上三幅流程圖:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicGcq5iZzAzYyYWYmFDM2YjYiRWNjVzN1YmYkZzLc1WZ0l2LcNWaw9CXwkTOxU2cy9Ga5xmZh9CXt92YuUHZpFmYuM3b09GawlGavw1LcpDc0RHaiojIsJye.jpg)
看不太懂沒關系,這些隻是要你對autotools的運作流程有個大概的印象。前面提到的諸多User-provided data files中,隻有configure.ac和Makefile.am是要自己手工寫成的。後者包含了tarball的編譯順序,前者包含預檢測./configure的檢查要求。(本文中,前者将利用autoscan的自動補全功能改寫而成)
簡單的說,GNU Autotools的使用步驟
生成時:
1.在各個目錄中寫出Makefile.am
2.利用autoscan獲得configure.scan作為模闆
3.改寫configure.scan,重命名為configure.ac
4.依次運作aclocale,autoheader,autoconf,獲得configure腳本
5.運作automake (automake -a)獲得Makefile.in檔案
測試時:
6.嘗試./configure,檢查輸出的傳回值有否和預期相悖之處,若有,檢視config.in檔案,跳回第3步
7.嘗試make,檢查error和warning,檢查輸出的傳回值有否和預期相悖之處,若有,跳回第1步
8.嘗試make distcheck,檢查是否有檔案找不到的報錯,若有,則為Makefile.am錯誤,跳回第1步
9.運作一次autoreconf,touch所有配置檔案時間,記錄到Changelog中
10.再次make distcheck,確定無誤
11.複制至其他計算機(不同發行版最佳),嘗試編譯一次,檢查相容性和configure依賴腳本工作良好
12.釋出
以下是一個例子和具體的操作過程。
$ENV = 2.6.32 x86_64 GNU/Linux, make 3.81, autoconf 2.65, automake 1.11.1, m4 1.4.13, perl 5.10.1
[email protected]:~/test$ ls -R
.:
include lib Makefile.am src
./include:
foo.h Makefile.am
./lib:
Makefile.am test.cpp test.h
./src:
foo.cpp main.cpp Makefile.am
tarball可以在我的網盤下載下傳,如果想自己一步一步體驗的可以删掉除了源檔案外的其他一切檔案自己嘗試,不過強烈推薦看一下源碼的内容(總共隻有不到50行),明白其中用到的各個功能
http://www.uushare.com/user/aflyhorse/file/3349455
切入正題。
首先,具體講每個Makefile.am的寫法(這個隻能純手工……)。
./Makefile.am
AUTOMAKE_OPTIONS = foreign -Wall -Werror
SUBDIRS = lib include src
首行表示編譯選項。foreign指本釋出包不是按照GNU規範的(否則automake将不勝其煩的要求AUTHOR,README,CHANGELOG等檔案);-Wall和-Werror都是為gcc準備的,表示嚴格顯示編譯錯誤
SUBDIRS當然表示的是子檔案夾,将按順序編譯,是以請先放庫檔案,最後放可執行檔案
./lib/Makefile.am
noinst_LIBRARIES = libtest.a
libtest_a_SOURCES = test.cpp test.h
noinst_字首表示不安裝的(一般隻有開發軟體才會安裝靜态庫),如果是要安裝的,則用lib_字首。動态庫用_LTLIBRARIES表示,不過我還不會用libtool呢……
之後就是列舉庫的所需編譯檔案了
./include/Makefile.am
noinst_HEADERS = foo.h
這裡表示不安裝的頭檔案。在automake中,如果沒有在Makefile.am中列舉出來的檔案在dist的時候是不會包含在tarball裡的(額外的不相關文檔用EXTRA_标記)。通常頭檔案應該被列舉到對應的binary的$(binary)_SOURCES裡去,但是這個特殊的僅有頭檔案的檔案夾隻能以這個形式編寫Makefile
需要安裝的頭檔案用include_字首标示
./src/Makefile.am
bin_PROGRAMS = hello
hello_SOURCES = main.cpp foo.cpp ../include/foo.h ../lib/test.h
hello_LDADD = $(top_builddir)/lib/libtest.a -lm
hello_CPPFLAGS = -I$(top_srcdir)
bin_PROGRAMS表示我們應該生成的binary有以下幾個(偷懶,隻寫了一個),$(binary)_SOURCES則列舉需要的檔案(和gcc指令行單個編譯方式一樣要包括頭檔案),$(binary)_LDADD說明額外的庫
我們用到了cmath,是故要加上-lm指令,額外的再加上我們編譯出的臨時庫檔案
$(top_srcdir)和$(top_builddir)都是自解釋的,額外指令可以放到$(binary)_CPPFLAGS裡,比如對源檔案頂層目錄的包含
OK,Makefile寫完,接下來
[email protected]:~/test$ autoscan
[email protected]:~/test$ vi configure.scan
lunarsh[email protected]:~/test$ mv configure.scan configure.in
[email protected]:~/test$ cat configure.in
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.65])
AC_INIT([hello], [1.0.0], [http://hi.baidu.com/aflyhorse1990/])
AC_CONFIG_SRCDIR([lib/test.h])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE
# Checks for programs.
AC_PROG_CXX
AC_PROG_CC
AC_PROG_RANLIB
# Checks for libraries.
# FIXME: Replace `main' with a function in `-lm':
AC_CHECK_LIB([m], [sqrt])
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_CHECK_FUNCS([sqrt])
AC_CONFIG_FILES([Makefile
include/Makefile
lib/Makefile
AC_OUTPUT
其中你要修改的就是AC_INIT中的安裝包名和版本号,然後在此段最後加一句AM_INIT_AUTOMAKE來提供automake接口;之後是在第二段添加AC_PROG_RANLIB以提供靜态庫ar的檢查機制。FIXME中,由于我用了libm.a(數學庫)中的sqrt函數,需要把AC_CHECK_LIB後面的main換成sqrt。
[email protected]:~/test$ aclocal
[email protected]:~/test$ autoheader
[email protected]:~/test$ autoconf
[email protected]:~/test$ automake
此時,目錄檔案結構将如下所示:
[email protected]:~/test$ ls -R
.:
aclocal.m4 config.h.in depcomp lib missing
autom4te.cache configure include Makefile.am src
autoscan.log configure.ac install-sh Makefile.in
./autom4te.cache:
output.0 output.1 requests traces.0 traces.1
./include:
foo.h Makefile.am Makefile.in
./lib:
Makefile.am Makefile.in test.cpp test.h
./src:
foo.cpp main.cpp Makefile.am Makefile.in
之後就可以./configure後make distcheck打包了,看了這麼一長串的輸出,是不是很有成就感呀~啊!唔……大牛請繞道或輕拍……倫家@$&(*#^Q*(#&q$&@#q#&(*#)_$w*(e#……
這是最後的tarball結構:
[email protected]:~/test/hello-1.0.0$ ls -R
.:
aclocal.m4 configure depcomp install-sh Makefile.am missing
config.h.in configure.ac include lib Makefile.in src
./include:
foo.h Makefile.am Makefile.in
./lib:
Makefile.am Makefile.in test.cpp test.h
./src:
foo.cpp main.cpp Makefile.am Makefile.in