autoconf、automake以及rpm包的制作過程
第一步:
在root下建立目錄hello-cxf-1.0,然后在該目錄下新建子目錄src和doc(doc幾乎存放一些文檔,但在這里暫時為空)。
#mkdir hello-cxf-1.0
#cd hello-cxf-1.0
#mkdir src
#mkdir doc
第二步:
在src目錄下編輯文件main.c
#cd src
#vi main.c
#include <stdio.h>
int main(void)
{
printf("this is hello-cxf-1.0 testing!\n");
return 0;
}
第三步:
回到hello-cxf-1.0目錄下,編輯configure.ac(或者叫做configure.in)和Makefile.am文件。
configure.ac的例子:
AC_PREREG(2.59)
#AC_INIT(FULL-PACKAGE-NAME, VERSION,BUG-REPORT-ADDRESS)
AC_INIT(hello-cxf,1.0)
AM_INIT_AUTOMAKE([foreign])
AC_CONFIG_SRCDIR([src/main.c])
AC_CONFIG_HEADER([src/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_CONFIG_FILES([Makefile
src/Makefile
doc/Makefile
])
AC_OUTPUT
其中,
1.可以通過運行 autoscan(生成configure.ac的模板文件) , 自動創建兩個文件: autoscan.log configure.scan,修改configure.scan的文件名為configure.in或者configure.ac,
2.最簡單的configure.ac必須包含的AC_INIT (package, version, [bug-report], [tarname])、AC_CONFIG_FILES([files])、AC_OUTPUT三個宏,有用到automake的話,則必須添加 AM_INIT_AUTOMAKE和AC_PROG_CC宏。automake一般是要用到的,因為生成的configure會根據 Makefile.in生成Makefile文件,而Makefile.in可以有automake生成。
Makefile.am文件要在當前目錄,子目錄都個建一份,如下:
Hello-cxf-1.0目錄下Makefile.am的例子:
AUTOMAKE_OPTIONS=foreign
SUBDIRS = src doc
Src目錄下Makefile.am的例子:
bin_PROGRAMS = hello-cxf
hello_cxf_SOURCES = main.c
#hello_cxf_LDADD = -lpthread
#hello_cxf_debug_LDADD= -lpthread-debug
#SUBDIRS = lib
Doc目錄下的Makefile.am是個空的。
注意:
Makefile.am就是一系列變量的定義。Makefile的語法:變量名 = 變量值。
Makefile.am的編寫
1. 需要生成Makefile的目錄下都要編寫一個Makefile.am
2. 頂層(項目)目錄的Makefile.am,可能會包含AUTOMAKE_OPTIONS = foreign 1.4這樣一句。
3. 如果當前目錄有其它子目錄,子目錄中也要生成makefile,則要包含
SUBDIRS = 子目錄…,例如:SUBDIRS = src doc
4. 對于不需要安裝,但是需要一起打包發布的文件,則在當前目錄的Makefile.am中可以添加一句:EXTRA_DIST = 發布的文件,例如:EXTRA_DIST = purge.conf purge
5. Makefile.am中的變量名,有統一的命名機制,一般是:安裝目錄_主變量。
6. 安裝目錄。
有些標準的安裝目錄可以直接使用。例:bin_PROGRAMS = hello,表示hello將被安裝在$(prefix)/bin目錄下。但是這些標準安裝目錄可能不夠使用,因此我們可以自己定義所需要的安裝目錄。安裝目錄一般是省略’dir’的,例如:
htmldir = $(prefix)/html
html_DATA = automake.html
就表示automake.html將被安裝在$(prefix)/html目錄下。這里DATA是主變量,稍后說明。
對于不安裝的文件,變量名的目錄變量可寫為noinst。
7. 主變量。常見的主變量有:`PROGRAMS'、`LIBRARIES'、 `LISP'、`SCRIPTS'、`DATA'、 `HEADERS'、`MANS'和`TEXINFOS'。這些主變量說明了生成的對象類型。例如,主變量PROGRAMS 保存了需要被編譯和連接的程序的列表。
8. Makefile.am的例子。
目錄結構:
purge-1.2
|―·doc
| |-purge.conf
| |-Makefile.am
|-·src
| |-purge.h
| |-thread.h
| |-…
| |-list.h
| |-debug.c
| |-fun.c
| |-list.c
| |-main.c
| |-map.c
| |-parseconf.c
| |-purge.c
| |-thread.c
| |-Makefile.am
|-hello-0.1.0.spec
|-configure.ac
|-Makefile.am
各目錄下的Makefile.am文件可以編寫如下:
purge-1.2目錄:vi Makefile.am
AUTOMAKE_OPTIONS = foreign 1.4
SUBDIRS = src doc
doc目錄:vi Makefile.am
EXTRA_DIST = purge.conf
src目錄:vi Makefile.am
bin_PROGRAMS = purge
purge_SOURCES = main.c purge.c fun.c list.c \
parseconf.c thread.c debug.c map.c
purge_LDADD = -lpthread
說明:
a) 在Makefile.am也可以定義變量如:
ALL_SOURCE = main.c purge.c fun.c list.c parseconf.c thread.c debug.c map.c
purge_SOURCES = $( ALL_SOURCE)
b) 名字中除了字母、數字和下劃線之外的所有字符都將用下劃線代替。例如,如果你的程序被命名為sniff-glue,那么派生出的變量名將是 sniff_glue_SOURCES,而不是sniff-glue_SOURCES;庫liblob.a的’_SOURCES’變量對應的變量名 為’liblob_a_SOURCES’,而不是’liblob.a_SOURCES’。
9. 注:共享庫必須被安裝,所以不允許使用 `noinst_LTLIBRARIES'和`check_LTLIBRARIES'。
10. Makefile.am中configure輸出變量的使用。
在configure.ac中通過宏AC_SUBST引出的變量在Makefile.am中就能被使用到。
例子:
在configure.ac中定義如下:
if test -z "$CACHE_ICP_PORT"; then
CACHE_ICP_PORT="3130"
fi
AC_SUBST(CACHE_ICP_PORT)
在Makefile.am中通過@CACHE_ICP_PORT@格式就能引用變量CACHE_ICP_PORT。
例子:DEFAULT_ICP_PORT = @CACHE_ICP_PORT@
第四步:
運行 aclocal, 它根據configure.ac或者configure.in生成一個“aclocal.m4”文件和一個緩沖文件夾autom4te.cache,該文件主要處理本地的宏定義。
在hello-cxf-1.0目錄下運行aclocal。
#aclocal
#ls
第五步:
運行 autoconf, 根據configure.ac和aclocal.m4生成configure腳本。
#autoconf
#ls
第六步:
運行 autoheader,它負責生成config.h.in文件。該工具通常會從“acconfig.h”文件中復制用戶附加的符號定義。即 autoheader根據configure.ac,運行m4,生成config.h.in(該文件名由 AC_CONFIG_HEADER([src/config.h])的定義而定)
#autoheader
#ls
第七步:
使用automake根據Makefile.am和aclocal.m4生成Makefile.in文件,在這里使用選項“—adding- missing”可以讓automake自動添加有一些必需的腳本文件,如depcomp,install-sh, missing等。
#automake –adding-missing
第八步:
運行./configure根據makefile.in和config.h.in(如果有的話)生成makefile和config.h(如果有 config.h.in)文件,及config.status,config.log用于記錄檢測到的一些狀態。即通過運行自動配置設置文件 configure,把Makefile.in變成了最終的Makefile。
#./configure
#ls
其中,autoreconf 相當于連續執行aclocal autoconf autoheader automake --add-missing。
第九步:
運行 make,對配置文件Makefile進行測試一下。
#make
….
#ls
#ls src/
可以看到,在src文件下面生成了main.c的輸出文件hello-cxf。
第十步:
運行生成的文件hello-cxf
#./src/hello-cxf
this is hello-cxf-1.0 testing!
注意:
Makefile文件
自動生成的Makefile文件常用幾個命令如下:
make all - 生成程序、庫、文檔等,等同于make,根據Makefile編譯原始碼,連接,生成目標文件,可執行文件。
make install - 安裝
make install-strip -安裝,去除調試符號
make uninstall - 卸載
make clean - 清除臨時文件,make all 的反過程,即清除上次的make命令所產生的object文件(后綴為“.o”的文件)及可執行文件。
make dist - 創建發布包:PACKAGE-VERSION.tar.gz.
rpm 打包過程如下:
make:根據Makefile編譯原始碼,連接,生成目標文件,可執行文件。
第一步:
創建發布包,運行make dist命令
#make dist
#ls
// 生成hello-cxf-1.0.tar.gz
注:make dist
產生發布軟件包文件(即distribution package)。這個命令將會將可執行文件及相關文件打包成一個tar.gz壓縮的文件用來作為發布軟件的軟件包。
他會在當前目錄下生成一個名字類似“PACKAGE-VERSION.tar.gz”的文件。PACKAGE和VERSION,是我們在configure.in中定義的AM_INIT_AUTOMAKE(PACKAGE, VERSION)。
第二步:
#make distcheck
注意:
make distcheck-生成發布軟件包并對其進行測試檢查,以確定發布包的正確性。這個操作將自動把壓縮包文件解開,然后執行configure命令,并且執行make,來確認編譯不出現錯誤,最后提示你軟件包已準備好,能發布了。
make distclean-類似make clean,但同時也將configure生成的文件全部刪除掉,包括Makefile。
第三步:
我用的是as4.0,首先查看一下/usr/src/redhat/目錄下面是否有BUILD RPMS SOURCES SPECS SRPMS這些子目錄,如果沒有,則創建。
把上一步生成的hello-cxf-1.0.tar.gz包復制到/usr/src/redhat/SOURCES/目錄下:
#cp hello-cxf-1.0.tar.gz /usr/src/redhat/SOURCES/
第四步:
編輯將應用程序打包(package)必須的配置文件spec文件。
我的hello-cxf-1.0.spec配置文件為:
%define _name hello-cxf
%define _ver 1.0
%define _rel 1.0
Summary:It's a hello-cxf program
Name: %{_name}
Version: 1.0
Release: %{_rel}
License: Copyright
Group:Amusements/Games
Source: %{_name}-%{_ver}.tar.gz
BuildRoot: /var/tmp/hello-cxf-1.0-root
%description
print Hello-cxf world
%prep
%setup -q
#tar zxf %{_name}-%{_ver}.tar.gz
%build
./configure
make
%install
rm -rf %{buildroot}
make DESTDIR="$RPM_BUILD_ROOT" install
%post
echo "OK, Hello is already installed for you!"
%postun
echo "OK, Hello is already uninstalled for you!"
echo "Thanks for using!"
%clean
rm -rf $RPM_DUILD_ROOT
%files
%defattr(-,root,root)
/usr/local/bin/hello-cxf
%changelog
第五步:
#rpmbuild -ba hello-cxf-1.0.spec
rpmbuild讀入spec文件上的配置信息,自動生成rpm包。
第六步:
安裝:rpm -ivh name-version-release.architecture.rpm (由剛rpmbuild -bb ×××.spec生成的rpm安裝包)
可以先查看一下再/usr/src/redhat/RPMS/i386目錄下是否已經生成了rpm包。
# cd /usr/src/redhat/RPMS/
# ls
athlon i386 i486 i586 i686 noarch
# ls i386/
hello-cxf-1.0-1.0.i386.rpm hello-cxf-debuginfo-1.0-1.0.i386.rpm
# rpm –ivh hello-cxf-1.0-1.0.i386.rpm
第七步:
運行#hello-cxf即可
# hello-cxf
this is hello-cxf-1.0 testing!
注意:
rpm文件命名規則:name-version-release.architecture.rpm
name指軟件名,version軟件 版本,release發布版本,architecture表示該rpm包適用的平臺(指cpu),典型的有:src, noarch, i386, i686,ppc64,x86_64,ia64,sparc64。其中src, noarch這兩種適用各種平臺,i386, i686(32位),x86_64(64位),這三種比較常見。
rpm常用的命令:
安裝:rpm -ivh name-version-release.architecture.rpm
升級:rpm –Uvh name-version-release.architecture.rpm
卸載:rpm -e name ;rpm -e name-version ;rpm -e name-version-release
版本查詢:rpm -q name
其它命令:
rpm -qi name 詳細信息查詢
rpm -qpl name-version-release.architecture.rpm rpm文件列表(該rpm包將安裝的文件)
rpm -qa 已經安裝的所有rpm包。
rpm -ivh --nodeps name-version-release.architecture.rpm 中-nodeps選項可以忽略對其它rpm軟件包的依賴。
rpm -qf filename查看該文件屬于哪個rpm包。
rpmbuid常用命令
rpmbuild -bb|-bs|-ba ×××.spec
rpmbuild -tb|-ts|-ta ×××.tar.gz //spec文件在tar.gz中
-bb 和 -tb打包成二進制包
-bs 和 -ts 打包成源碼包
-ba 和 -ta打包成二進制包和源碼包