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

来源:互联网 发布:sql 字段累加 编辑:程序博客网 时间:2024/06/05 17:01

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

目录结构:

 |- 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 文件

root@ubuntu:/home/zlk/workspace/sample/lib# touch Makefile.amroot@ubuntu:/home/zlk/workspace/sample/lib# 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的后缀名

root@ubuntu:/home/zlk/workspace/sample/lib# autoscanroot@ubuntu:/home/zlk/workspace/sample/lib# lsautoscan.log  configure.scan  hello.c  Makefile.am  root@ubuntu:/home/zlk/workspace/sample/lib# mv configure.scan configure.acroot@ubuntu:/home/zlk/workspace/sample/lib# 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

root@ubuntu:/home/zlk/workspace/sample/lib# aclocalroot@ubuntu:/home/zlk/workspace/sample/lib# autoconfroot@ubuntu:/home/zlk/workspace/sample/lib# autoheaderroot@ubuntu:/home/zlk/workspace/sample/lib# automake --add-missingroot@ubuntu:/home/zlk/workspace/sample/lib# ./configure root@ubuntu:/home/zlk/workspace/sample/lib# makeroot@ubuntu:/home/zlk/workspace/sample/lib# lsaclocal.m4      config.h.in    configure.ac  hello.o       Makefile.amautom4te.cache  config.log     depcomp       install-sh    Makefile.incompile         config.status  hello.c       libmyhello.a  missingconfig.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 并修改其内容

root@ubuntu:/home/zlk/workspace/sample/src# autoscanroot@ubuntu:/home/zlk/workspace/sample/src# lsautoscan.log  configure.scan  main.c  Makefile.amroot@ubuntu:/home/zlk/workspace/sample/src# mv configure.scan configure.acroot@ubuntu:/home/zlk/workspace/sample/src# vim configure.ac 

这里写图片描述

主要修改如下:

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

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

root@ubuntu:/home/zlk/workspace/sample/src# aclocalroot@ubuntu:/home/zlk/workspace/sample/src# autoconfroot@ubuntu:/home/zlk/workspace/sample/src# autoheaderroot@ubuntu:/home/zlk/workspace/sample/src# automake --add-missingroot@ubuntu:/home/zlk/workspace/sample/src# ./configure root@ubuntu:/home/zlk/workspace/sample/src# makeroot@ubuntu:/home/zlk/workspace/sample/src# ./mainHello Mr.Sandmanroot@ubuntu:/home/zlk/workspace/sample/src# make installroot@ubuntu:/home/zlk/workspace/sample/src# make cleanroot@ubuntu:/home/zlk/workspace/sample/src# make distroot@ubuntu:/home/zlk/workspace/sample/src# lsaclocal.m4      config.h       configure     main-1.0.tar.gz  Makefile.inautom4te.cache  config.h.in    configure.ac  main.c           missingautoscan.log    config.log     depcomp       Makefile         stamp-h1compile         config.status  install-sh    Makefile.amroot@ubuntu:/home/zlk/workspace/sample/src# 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:ApplicationsLicense:GPLURL:http://blog.csdn.net/qq_15437629/article/details/77587588Source:sample.tar.gzBuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)%descriptionmy test rpm%preptar -xzvf $RPM_SOURCE_DIR/sample.tar.gz%buildcd $RPM_BUILD_DIR/sample/src./configuremake%installcd $RPM_BUILD_DIR/sample/srcmake install%cleanrm -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