Makefile&Spec文件的简单案例

MakeFile:

(感觉用在编译go程序简直就是大材小用, 编译生成的是一个静态可执行文件,除了glibc外没有其他外部依赖,机器上只需要一个基础的系统和必要的管理、监控工具,完全不需要操心应用所需的各种包、库的依赖关系,大大减轻了维护的负担。)

简单案例展示:
//.PHONY是一个伪目标,可以防止在Makefile中定义的只执行命令的目标和工作目录下的实际文件出现名字冲突,
//另一种是提交执行makefile时的效率。
.PHONY:all build install clean uninstall bin test upgrade  upload testcase

//定义需要用到的全局变量
PROJECT_PATH=$(PWD)               //将当前目录作为项目的目录
NAME=sdns-agent                   //软件的名字
FULL_NAME=$(PROJECT_PATH)/$(NAME) //编译出软件二进制可执行文件名字放置的绝对路径 
SRC_PATH=$(PROJECT_PATH)/agent    //源码目录
FTP=127.0.0.1                     //编译完之后上传ftp保存
X86=x86_64                        //rpm包放置的路径
AAA=$(shell git pull)
VERSION=$(shell git describe --tags |awk -F '-' '{printf $$1 }') //软件的版本号
RELEASE_NUM=$(shell git describe --tags |awk -F '-' '{printf $$2 }')//发布号
if eq ($(RELEASE_NUM), )
    RELEASE_NUM=0
endif

//定义make的标签,分标签执行相关的操作,使用方式make + 标签名 就可以执行标签下的命令

//直接使用make命令时会执行的默认标签
all: clean uninstall build install

testcase: 
    cd $(SRC_PATH); go test
    cd $(PROJECT_PATH)

bin: 
    //先进入源码目录,使用godep进行编译
    cd $(SRC_PATH); godep go build -o $(FULL_NAME) 
    -ldflags "-X main.gitVersion=$(VERSION)_$(RELEASE_NUM)"
    //出源码目录,进入项目目录
    cd $(PROJECT_PATH) 

test: bin
    $(FULL_NAME) -loglevel=Debug -setlogger=console

build: clean bin
     //_name 软件的名字 _sourcedir  项目的目录 _rpmdir rpm打包的目录  _version 软件的版本号
     //使用rpmbuild工具进行打包,方便存储使用安装。
    rpmbuild -bb --define '_name $(NAME)' --define '_sourcedir $(PROJECT_PATH)' 
    --define '_rpmdir $(PROJECT_PATH)' --define '_version $(VERSION)'
    --define '_release_num $(RELEASE_NUM)' -bs rpm.spec

install: build 
    yum install $(X86)/$(NAME)*.rpm -y

upgrade: build 
    yum upgrade $(X86)/$(NAME)*.rpm -y

clean://打包之前先清理
    rm -rf $(X86)      //rpm包放置的路径
    rm -rf $(NAME)     //软件编译之后的名字

uninstall:
    yum remove $(NAME) -y

upload: build
    lftp $(FTP) -uharbor,123456 -e "ls;cd $(NAME)/;mrm *;mput $(X86)/*.rpm;exit"

spec文件中内置的变量

查阅rpm常用路径 rpm --showrc>/usr/rpmShowrc.txt
Macros mimicking autoconf variables(RPM中内部宏变量,可以直接使用)
%{_sysconfdir}        /etc
%{_prefix}            /usr
%{_exec_prefix}       %{_prefix}
%{_bindir}            %{_exec_prefix}/bin
%{_lib}               lib (lib64 on 64bit systems)
%{_libdir}            %{_exec_prefix}/%{_lib}
%{_libexecdir}        %{_exec_prefix}/libexec
%{_sbindir}           %{_exec_prefix}/sbin
%{_sharedstatedir}    /var/lib
%{_datadir}           %{_prefix}/share
%{_includedir}        %{_prefix}/include
%{_oldincludedir}     /usr/include
%{_infodir}           /usr/share/info
%{_mandir}            /usr/share/man
%{_localstatedir}     /var
%{_initddir}          %{_sysconfdir}/rc.d/init.d

RPM directory macros
%{_topdir}            %{getenv:HOME}/rpmbuild
%{_builddir}          %{_topdir}/BUILD
%{_rpmdir}            %{_topdir}/RPMS
%{_sourcedir}         %{_topdir}/SOURCES
%{_specdir}           %{_topdir}/SPECS
%{_srcrpmdir}         %{_topdir}/SRPMS
%{_buildrootdir}      %{_topdir}/BUILDROOT

简单spec文件案例

为了方便观看,使用了虚线将各个部分分割开来。

//设置变量
%global _summary             summary
%global _source              sdns-agent 
%global _source_upgrade      sdns-agent-upgrade
%global _description         "sdns-agent"
------------------------------------------
//设置变量
Name: %_name                        //通过rpmbuild命令传递过来的数据
Version: %_version                  //通过rpmbuild命令传递过来的数据
Release: %_release_num%{?dist}
Summary: %_summary
Group: GPL
License: 1
URL: http://www.letv.com
//源码包的目录
Source0: %_source                 
//在rpmbuild中的路径, _tmppath====tmp
BuildRoot:  %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) 
--------------------------------------------
BuildRequires: rpm-build   //打rpm包需要rpmbuild命令
Requires: rpm-build        //依赖的软件包
------------------------------------------ 
//rpm打包从上往下依次执行相关的标签
%description        //项目描述
%_description
------------------------------------------ 
//全局变量,build时的目录
%global _build_dir %{name}-%{version}-%{release}.letv    
----------------------------------------- 
%prep              
//与准备阶段  先进入rpm的根目录,这个可以在rpm的配置文件中设置,
// /letv/rpmbuild/作为根目录,则下面会有这些目录,BUILD/     BUILDROOT/ RPMS/      SOURCES/   SPECS/     SRPMS/
rm -rf %{_build_dir}
//(sdns-agent-%_version-0.el7.centos.letv 作为我们项目的build目录)
mkdir %{_build_dir}     
-----------------------------------------
/**
其实在Makefile中已经进行了编译,这里只是将文件从源码位置拷贝到/rpmbuild/BUILD相关位置然后进行打包,
install阶段将会从这个BUILD目录拷贝需要安装的文件到BUILDROOT中
**/
%build   
pushd %{_build_dir}                         
mkdir -p {script,conf,sysconfig}                  
cp %{_sourcedir}/%{_source} .                     
cp %{_sourcedir}/script/%{_source_upgrade} .     
cp %{_sourcedir}/script/%{_source} script/       
cp %{_sourcedir}/conf/%{_source}.conf conf/      
cp %{_sourcedir}/sysconfig/%{_source} sysconfig/  
popd

-----------------------------------------------------------------------------------
//此时的目录还是上次的目录,/letv//rpmbuild/BUILD
buildroot: 是用于测试安装的目录./letv/rpmbuild/BUILDROOT
rpmbuild会在buildroot目录下执行spec文件的install段,模拟将来rpm包在客户机上的安装过程.
这样,通过观察buildroot目录下的文件即目录结构,你就可以看到将来rpm包将会在客户机上安装哪些文件.
*/
%install
rm -rf %{buildroot}                                             
mkdir -p  %{buildroot}/%{_sbindir} %{buildroot}/%{_initrddir}   
mkdir -p %{buildroot}/%{_sysconfdir}/%{_source}/conf             
mkdir -p %{buildroot}/%{_sysconfdir}/sysconfig                  
cp %{_build_dir}/%{_source} %{buildroot}/%{_sbindir}           
cp %{_build_dir}/%{_source_upgrade} %{buildroot}/%{_sbindir}   
cp %{_build_dir}/script/%{_source} %{buildroot}/%{_initrddir}   
cp %{_build_dir}/conf/%{_source}.conf %{buildroot}/%{_sysconfdir}/%{_source}/conf
cp %{_build_dir}/sysconfig/%{_source} %{buildroot}/%{_sysconfdir}/sysconfig   
chmod a+x %{buildroot}/%{_sbindir}/*
chmod a+x %{buildroot}/%{_initrddir}/*
---------------------------------------------------------------------------------------
//这一节所描述的内容表示在完成包建立的工作之后,自动执行此节下的脚本进行附加的清除工作
%clean
rm -rf %{buildroot}
---------------------------------------------------------------------------------------
%files
%defattr(-,root,root,-)                                    //设置权限
%{_sbindir}/%{_source}                                     // /usr/sbin/sdns-agent
%{_sbindir}/%{_source_upgrade}
%{_initrddir}/%{_source}
%config(noreplace) %{_sysconfdir}/%{_source}/conf/*
%config(noreplace) %{_sysconfdir}/sysconfig/%{_source}

----------------------------------------------------------------------------------------
%changelog
* Tue May 19 2015 Letv Engineering <GCP@letv.com> - 0.1
- Hello World!
----------------------------------------------------------------------------------------
 一个文件被%config(noreplace)指令配置。
此时包含如下情况:
该文件在新的rpm包里相对之前的rpm有变化,且在本地没有被修改过。
此时执行rpm -Uvh xxxx时,新rpm包里的该文件会替换旧的文件。(旧文件被删除)
该文件在新的rpm包里相对之前的rpm有变化,且在本地被修改过。
此时执行rpm -Uvh xxxx时,旧文件保持不变,新rpm包里的该文件并重命名为xx.rpmnew,例如/etc/redis/redis.conf.rpmnew
该文件在新的rpm包里相对之前的rpm没有变化,且在本地没有被修改过。
此时执行rpm -Uvh xxxx时,新rpm包里的该文件会替换旧的文件。(旧文件被删除)
该文件在新的rpm包里相对之前的rpm没有变化,且在本地被修改过。
此时执行rpm -Uvh xxxx时,新rpm包里的该文件不会覆盖旧的文件,旧文件保持不变。
总结如下:
如果一个文件在%files段没有被%config%config(noreplace)指令配置;则执行rpm -Uvh时,该文件会无条件被新文件替换。
无论一个文件有没有被%config%config(noreplace)指令配置,只要改文件在本地没有被编辑过,则执行rpm -Uvh时,该文件会被新文件替换。
一个被%config%config(noreplace)指令配置的文件,如果被编辑过,那么在rpm更新时,如果新的rpm包中该文件没有修改,则该文件不会被新rpm包中的文件替换,之前做的编辑依然有效。
一个被%config指令配置的文件,如果被编辑过,且新的rpm包中该文件有修改,则该文件会被重命名为xx.rpmsave, 新文件会替代原文件。
一个被%config(noreplace)指令配置的文件,如果被编辑过,且新的rpm包中该文件有修改,则该文件不会被新的rpm包中的文件替换,之前做的编辑依然有效;但新rpm包中的同名文件会被重命名为xx.rpmnew.
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值