automake编写完整的项目---静态库+可执行文件+rpm包

在 Unix 上写过程序的人尤其是用 C 来开发程序的人一般都遇到过 Makefile,用 make 来开发和编译程序的确很方便,可是要写出一个 Makefile 就不那么简单了。GNU Autoconf 及Automake 这两个软件就是帮助程序开发者轻松产生 Makefile 文件的。现在的 GNU 软件如 Apache, MySQL Minigui 等都是利用 Autoconf,Automake实现自动编译的。用户只要使用 “./configure”, “make”, “make install” 就可以把程序安裝到系统中。

具体地:

1、configure,这一步一般用来生成 Makefile,为下一步的编译做准备,你可以通过在 configure 后加上参数来对安装进行控制,比如代码: ./configure –prefix=/usr 意思是将该软件安装在 /usr 下面,执行文件就会安装在 /usr/bin (而不是默认的 /usr/local/bin),资源文件就会安装在 /usr/share(而不是默认的/usr/local/share)。同时一些软件的配置文件你可以通过指定 –sys-config= 参数进行设定。有一些软件还可以加上 –with、–enable、–without、–disable 等等参数对编译加以控制,你可以通过允许 ./configure –help 察看详细的说明帮助。

2、make,这一步就是编译,大多数的源代码包都经过这一步进行编译(当然有些perl或python编写的软件需要调用perl或python来进行编译)。如果 在 make 过程中出现 error ,你就要记下错误代码(注意不仅仅是最后一行),然后你可以向开发者提交 bugreport(一般在 INSTALL 里有提交地址),或者你的系统少了一些依赖库等,这些需要自己仔细研究错误代码。

3、make insatll,这条命令来进行安装(当然有些软件需要先运行 make check 或 make test 来进行一些测试),这一步一般需要你有 root 权限(因为要向系统写入文件)

4、最后,可以运行make clean删除临时文件;make distclean:除了清除可执行文件和目标文件外,把configure所产生的Makefile也清除掉。

下面介绍详细使用步骤。

目录结构:

 |- sample
	 |-  src :    存放源代码文件 main.c
	 |-  lib :    存放生成库文件 hello.c
	 |-  include: 存放库中头文件 hello.h

main.c:

#include "hello.h"

int main()
{
	char* s = "Mr.Sandman";
	hello(s);
 
	return 0;
}

hello.c

#include <stdio.h>

void hello(char* str)
{
	printf("Hello %s\n",str);
}

hello.h

void hello(char* str);

生成静态库:

1. 编写lib/Makefile.am 文件

# touch Makefile.am
# vim Makefile.am

这里写图片描述

第一行AUTOMAKE_OPTIONS 是Automake 的选项。设置为foreign 时,Automake 会用一般软件的标准来检查。如果不加这句,在执行Automake 时,会检查目录下是否存在标准GNU软件中应具备的文件,例如’NEWS’、‘AUTHOR’、 ‘ChangeLog’ 等文件,需要在autoconf之前,先执行touch NEWS README AUTHORS ChangeLog 来生成对应文件。

第二行表示用来生成静态库的源文件。前缀为libmyhello_a_,对应静态库名为libmyhello.a。

第三行noinst 表示生成的静态库,不需要make install ,直接指定它的位置和名字就可以使用。

2 执行autoscan 生成configure.scan 文件,将它重命名为configure.ac 并修改其内容

注:修改原因为autoconf只能识别configure.ac的后缀名

# autoscan
# ls
autoscan.log  configure.scan  hello.c  Makefile.am  
# mv configure.scan configure.ac
# vim configure.ac 

这里写图片描述

主要修改如下:

  • 修改AC_INIT([软件名], [版本编号], [])
  • 增加AM_INIT_AUTOMAKE,防止报错
  • 增加 AC_PROG_RANLIB,因为使用了静态库

另外:

  • AC_PROG_CC 检查系统可用的C 编译器,若源代码是用C 写的就需要这个宏。
  • AC_OUTPUT([Makefile]) 用于设置 configure 所产生的文件,若是Makefile ,configure 便会把它检查出来的结果填充到Makefile.ac 文件后产生合适的 Makefile。 后面的FILE 是一个Makefile 的输出列表

3.依次执行下列指令,在lib目录下生成了静态库libmyhello.a

# aclocal
# autoconf
# autoheader
# automake --add-missing
# ./configure 
# make
# ls
aclocal.m4      config.h.in    configure.ac  hello.o       Makefile.am
autom4te.cache  config.log     depcomp       install-sh    Makefile.in
compile         config.status  hello.c       libmyhello.a  missing
config.h        configure      hello.c~      Makefile      stamp-h1

生成可执行文件:

1. 编写src/Makefile.am 文件

这里写图片描述

  • 第二行指定头文件的位置,-I 是idirafter 的缩写。…/include 指定头文件的位置,…是上 一级目录,也就是这里的example 目录。
  • 第三行指定生成可执行文件名main,在这里可执行文件生成在src 下,建议将可执行文件生成到一个特定的文件夹下,让它和源代码分开。
  • 第四行指定生成可执行文件main的源代码文件,如果main.c 在其他目录下,需要加上 完整的路径。
  • 第五行指定需要使用静态库的位置。

2. 执行autoscan 生成configure.scan 文件,将它重命名为configure.ac 并修改其内容

# autoscan
# ls
autoscan.log  configure.scan  main.c  Makefile.am
# mv configure.scan configure.ac
# vim configure.ac 

这里写图片描述

主要修改如下:

  • 修改AC_INIT([软件名], [版本编号], [])
  • 增加AM_INIT_AUTOMAKE,防止报错

3.依次执行下列指令,在src目录下生成了可执行文件main

c# aclocal
# autoconf
# autoheader
# automake --add-missing
# ./configure 
# make
# ./main
Hello Mr.Sandman
# make install
# make clean
# make dist
# ls
aclocal.m4      config.h       configure     main-1.0.tar.gz  Makefile.in
autom4te.cache  config.h.in    configure.ac  main.c           missing
autoscan.log    config.log     depcomp       Makefile         stamp-h1
compile         config.status  install-sh    Makefile.am

# rm -rf main

make install 后软件安装成功,任意目录下执行main都可运行。
make clean:清除编译产生的可执行文件及目标文件(object file,*.o)。
make distclean:除了清除可执行文件和目标文件外,把configure所产生的Makefile也清除掉
make dist:将程序和相关的档案包装成一个压缩文件以供发布。执行完在目录下会产生一个以PACKAGE-VERSION.tar.gz为名称的文件。 PACKAGE和VERSION这两个变数是根据configure.in文件中AM_INIT_AUTOMAKE(PACKAGE,VERSION)的定义。在此范例中会产生main-1.0.tar.gz的档案。
rm -rf :卸载tar软件

tar包与rpm包

上文已经得到了一个 tar包,但是,如果仅仅是上述的tar包发送给别人是无法安装使用的,因为涉及其他依赖文件,因此必须是整个目录打包:

# tar -czvf sample.tar.gz sample

具体安装方式为:

# tar -zxvf sample.tar.gz //解压
# cd sample/src/
# ./configure
# make
# make install
# make clean

显然每次安装都得编译,怎么办呢?那就根据我们的需求制作RPM包吧,相当于windows下的exe,可以直接安装。

用rpmbuild制作rpm包:

  1. 创建/root/rpmbuild/目录
  2. 在/root/rpmbuild/目录下创建以下5个子目录:
    BUILD 源代码解压后的存放目录
    RPMS 制作完成后的RPM包存放目录,里面有与平台相关的子目录
    SOURCES 收集的源材料,补丁的存放位置
    SPECS SPEC文件存放目录
    SRMPS 存放SRMPS生成的目录
  3. 将sample.tar.gz放在 /root/rpmbuild/SOURCES/目录下
  4. 在 /root/rpmbuild/SPECS/目录下编写 main.spec文件,具体内容在后面介绍
  5. 在 /root/rpmbuild/目录下执行:
    rpmbuild -ba SPECS/main.spec
  6. 在/root/rpmbuild/RPMS/x86_64/下将生成二进制rpm包
    在/root/rpmbuild/SRPMS/下将生成含源码的rpm包
  7. 显示rpm包详细信息,执行:
    rpm -qpi sample-1.0.0-1.src.rpm
安装:rpm -ivh sample-1.0.0-1.src.rpm --force
查看:rpm -qa|grep main  
卸载:rpm -e

针对本用例编写的main.spec文件如下:

Group:Applications
License:GPL
URL:http://blog.csdn.net/qq_15437629/article/details/77587588
Source:sample.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)

%description
my test rpm

%prep
tar -xzvf $RPM_SOURCE_DIR/sample.tar.gz

%build
cd $RPM_BUILD_DIR/sample/src
./configure
make

%install
cd $RPM_BUILD_DIR/sample/src
make install

%clean
rm -rf $RPM_BUILD_DIR

%files
%defattr(-,root,root,-)
%doc

%changelog

下面来说说其中最最重要的spec的格式:

vi tengine.spec 
 
### 0.define section               #自定义宏段,这个不是必须的 
### %define nginx_user nginx       #这是我们自定义了一个宏,名字为nginx_user值为nginx,%{nginx_user}引用 
 
### 1.The introduction section      #介绍区域段 
 
Name:           tengine            #名字为tar包的名字 
Version:        1.4.2              #版本号,一定要与tar包的一致哦 
Release:        1%{?dist}          #释出号,也就是第几次制作rpm 
Summary:        tengine from TaoBao  #软件包简介,最好不要超过50字符 
 
Group:          System Environment/Daemons  #组名,可以通过less /usr/share/doc/rpm-4.8.0/GROUPS 选择合适组 
License:        GPLv2                       #许可,GPL还是BSD等  
URL:            http://laoguang.blog.51cto.com   #可以写一个网址 
Packager:       Laoguang <ibuler@qq.com> 
Vendor:         TaoBao.com 
Source0:        %{name}-%{version}.tar.gz   
#定义用到的source,也就是你收集的,可以用宏来表示,也可以直接写名字,上面定义的内容都可以像上面那样引用 
#patch0:            a.patch                 #如果需要补丁,依次写 
BuildRoot:      %_topdir/BUILDROOT         
#这个是软件make install 的测试安装目录,也就是测试中的根,我们不用默认的,我们自定义,
#我们可以来观察生成了哪此文件,方便写file区域 
BuildRequires:  gcc,make                           #制作过程中用到的软件包 
Requires:       pcre,pcre-devel,openssl,chkconfig  #软件运行需要的软件包,也可以指定最低版本如 bash >= 1.1.1 
%description                                       #软件包描述,尽情的写吧 
It is a Nginx from Taobao.                         #描述内容 
 
###  2.The Prep section 准备阶段,主要目的解压source并cd进去 
 
%prep                                              #这个宏开始 
%setup -q                                          #这个宏的作用静默模式解压并cd 
#%patch0 -p1                                       #如果需要在这打补丁,依次写 
 
###  3.The Build Section 编译制作阶段,主要目的就是编译 
%build 
./configure \                                      #./configure 也可以用%configure来替换 
  --prefix=/usr \                                  #下面的我想大家都很熟悉 
  --sbin-path=/usr/sbin/nginx \ 
  --conf-path=/etc/nginx/nginx.conf \ 
  --error-log-path=/var/log/nginx/error.log \ 
  --http-log-path=/var/log/nginx/access.log \ 
  --pid-path=/var/run/nginx/nginx.pid  \ 
  --lock-path=/var/lock/nginx.lock \ 
  --user=nginx \ 
  --group=nginx \ 
  --with-http_ssl_module \ 
  --with-http_flv_module \ 
  --with-http_stub_status_module \ 
  --with-http_gzip_static_module \ 
  --http-client-body-temp-path=/var/tmp/nginx/client/ \ 
  --http-proxy-temp-path=/var/tmp/nginx/proxy/ \ 
  --http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ \ 
  --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi \ 
  --http-scgi-temp-path=/var/tmp/nginx/scgi \ 
  --with-pcre 
make %{?_smp_mflags}          #make后面的意思是:如果就多处理器的话make时并行编译 
 
###  4.Install section  安装阶段 
%install                                
rm -rf %{buildroot}                #先删除原来的安装的,如果你不是第一次安装的话 
make install DESTDIR=%{buildroot} 
#DESTDIR指定安装的目录,而不是真实的安装目录,%{buildroot}你应该知道是指的什么了 
 
###  4.1 scripts section #没必要可以不写 
%pre        #rpm安装前制行的脚本 
if [ $1 == 1 ];then    #$1==1 代表的是第一次安装,2代表是升级,0代表是卸载 
        /usr/sbin/useradd -r nginx 2> /dev/null  ##其实这个脚本写的不完整
fi 
%post       #安装后执行的脚本 
 
%preun      #卸载前执行的脚本 
if [ $1 == 0 ];then 
        /usr/sbin/userdel -r nginx 2> /dev/null 
fi 
%postun     #卸载后执行的脚本 
 
###  5.clean section 清理段,删除buildroot 
 
%clean 
rm -rf %{buildroot} 
     
###  6.file section 要包含的文件 
%files  
%defattr (-,root,root,0755)   #设定默认权限,如果下面没有指定权限,则继承默认 
/etc/           #下面的内容要根据你在%{rootbuild}下生成的来写     
/usr/ 
/var/ 
     
###  7.chagelog section  改变日志段 
%changelog 
*  Fri Dec 29 2012 laoguang <ibuler@qq.com> - 1.0.14-1 
- Initial version 

备注:
rpm -Uvh升级时执行顺序

 1、执行新包spec文件中 %pre 段.
 2、安装新包的相关依赖包.
 3、执行新包spec文件中的 %post 段.
 4、执行旧包spec文件中的 %preun 段.
 5、删除新包中不需要的旧文件。
 6、执行旧包spec文件中的 %postun 段.

当进行不同操作的时候,会传递不同的参数给段,完整的参数传递及释义如下:

%pre和%post段
当传递的第一个参数为1时,表示新安装一个rpm包。
当传递的第一个参数为2时,表示升级一个已经存在的包。
 
%preun和%postun段
当传递的第一个参数为0时,表示删除一个包。
当传递的第一个参数为1时,表示更新一个包。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值