从源码包构建.deb文件的备忘

源码包是什么

我们知道ubuntu有别于gentoo之一的特点就是,gentoo是基于源码包安装的系统,而ubuntu是基于二进制的。我们执行一个apt-get install foo安装包命令时,apt从对应的apt source源地址下载一个二进制包-以.deb为后缀名的文件到/var/cache/apt/archives下,再用dpkg工具安装它们。这些.deb文件都是包的维护者在某台build machine上build之后放上去的,而与foo.deb对应的源码包,一般都是指三个文件的一个集合:foo.orig.gz, foo.dsc, foo.diff.gz. foo.orig.gz是该软件的原始源码,通常取自于git,svn或sourceforge,可以把它看作是中立的,和Linux发行版无关的源码。foo.diff.gz包含了将一份原始源码加工、改造为debian系安装包的非功能性的补丁文件,或许同时也包括一些功能性的修补源码bug的补丁。foo.dsc是一个包描述文件,它是一些ubuntu上的源码包处理工具如dpkg-source的输入。foo.diff.gz和foo.dsc扮演meta package的角色。一般来说,一个或者多个二进制包都对应一份源码包(因为多个二进制包可能由同一个源码产生),source.list的deb-src标鉴说明了可以通过apt-get从哪些网络地址获取源码包.

为什么从源码包生成软件

既然已经有了二进制包,为什么有时候还要从源码包来生成软件?因为二进制包毕竟是在别人的build machine上生成的,自然产生的二进制依赖也是基于维护人的环境。假如你想使用一个软件的更高版本,可能是因为高版本修订了当前使用版本的某个bug,或者想看看新的更省电的feature,当你把该软件高版本的apt source源添加到了source.list,然后使用apt-get update; apt-get install foo=high_version时,你发现apt-get抱怨很多运行时依赖得不到满足;而不得不把Ubuntu的整个release version升级,其实,你想做的只是升级这个软件包而已,发行版其他的部分仍然想保留已经使用了很久的版本,那这时从源码包构建软件就是必须的了。这里我个人就经历过这样的例子,在12.04LTS系统里,cairo-dock这个软件是有bug的,如果要升级,就得升级发行版,因为新的cairo-dock依赖新的xserver stack,而新的xserver stack牵涉的东西太多,那么就得升级发行版,当采用官方的源把xserver stack升级到最新版时,发现它已经帮你默认采用xmir了…天,我只是想用一个新版本的cairo-dock而已,并不想升级我的内核,libc,更不想用什么mir。这时我只有从网上下载更新版本的cairo-dock的源码包来构建,当然在构建过程中,必然会发先cairo-dock确实有些依赖不被当前的xserver stack所满足(比如用了更新的api或者数据结构都变了),那这时你就只有再把满足依赖的xserver stack包下下来编译(是一个递归收敛的过程),有可能要调整默认的编译参数(比如build最新的xserver core时把xmir disable掉)这个过程当然不容易,但做多了有经验后再碰到类似问题就相对容易多了。你也许会说从源码构建很简单啊,不就是git clone源码仓库然后./configure; make; make install吗?但这种构建方式只会产生二进制文件,不会产生二进制.deb包,操作系统的包管理器只有通过.deb包安装,它才知道用户安装过这个程序,有哪些二进制文件属于这个”包”等,这样不管以后的升级,卸载,替换等都有踪可循,如果直接从源码构建,那你以后要卸载它怎么办?你还记得它的源码放在哪里吗?它是用make uninstall卸载的还是其他什么命令?一些目录甚至可能是写死的,并且,如果你的软件包含一些库会被其他软件依赖,那么包管理器也可以通过包数据库为这些依赖提供线索,如果直接使用源码构建软件,那相当于你机器上的软件依赖链条出现了断裂,这会影响后续软件的安装卸载管理。

从源码包构建的备忘

  • 用dpkg-source -x

    foo.dsc从foo.orig.gz和foo.diff.gz创建工作目录foo:一份发行版中立的源码目录,加上一个debian目录以及目录下的meta文件,就构成了一份可以生成二进制deb包的源码工作目录。其实从apt-get

    source抓下来的目录,已经是通过dpkg-source -x解压过的了。dpkg-source

    -x所做的主要事情就是1.解压;2.把foo.diff.gz里的patch打到原始文件上。生成的foo目录下的源文件,都已经是打过deb源码包里的patch了的。

  • 在foo目录下,执行dpkg-buildpackage -us

    -uc构建包。-us和-uc参数是不做签名,适合于本地构建本地使用的情况。这个命令的输出有两个,一个是二进制deb包,另一个是源码包,为什么这里还要生成源码包?因为你可能改动某些文件,那么会生成新的diff.gz来记录所有你针对原始源码的改动,不管发布还是保存更改都更方便,下一次你只需要在生成的新的.dsc文件上执行dpkg-source -x就可以产生一个一模一样的源码了。如果你什么都没改动,那么新产生的源码包同你构建所来源的源码包是一样的。你也可以用参数-b和-S来控制这次构建只产生二进制包或者只产生源码包。

  • 两个最重要的meta文件,debian/control和debian/rules。control文件决定了哪些二进制包将从这份源码目录中构建,一个源码目录往往是好几个二进制包的输入源。你不想生成哪个屏蔽它就行。二进制包的运行时依赖关系也在包的声明中可见,并且control文件也声明了构建过程中的依赖,不过可以给dpkg-buildpackage传-d参数来忽略构建依赖。
  • debian/rules文件其实就是个Makefile,你可以执行make -f debian/rules target来单独执行某个目标。rules文件里基本上都是对debhelper脚本函数的调用,像是dh_*这样的函数,它们负责大部分的构建过程。常用的clean, install目标在rules文件中也有,有些基于源码包的Makefile上所做的事情如make clean需要通过make -f debian/rules clean来代替。
  • 和传统意义的Make过程有点不一样的就是,默认状态下,每次dpkg-buildpackage,其实都是把从configure.ac生成configure脚本,到生成Makefile,到构建source,到安装binary都做一遍,哪怕你并没有改过configure.ac,或者改过源代码.c文件,假如构建失败了,就需要尝试改动源代码重新构建,有时候需要反复尝试这个过程直到构建成功,如果包很大的话那需要花费的时间就很长,这时传入-nc参数可以让dpkg-buildpackage保留当前的构建结果,就像传统的make一样只会从出错的地方重新开始。当然,当对源代码的改动终止后,最后还是需要再执行一遍不带-nc参数的命令”dpkg-buildpackage -us -uc”来重新完全构建一遍,否则在生成源码包时可能会出错。
  • dpkg-buildpackage不用担心它会自动改变你的源文件(即通过dpkg-source

    -x产生的文件),当然前提是你确实改动的是”源”文件,比如是configura.ac而不是configure,是dkms.conf.in而不是dkms.conf。

  • 构建软件时做得最多的事就是根据自己系统的需求调整./configure参数了吧,比如–enable–xxx或者–disable-xxx,在rules文件中,通过带override前缀的target可以起到为默认的target定制参数的目的,如override_dh_auto_xconfigure:
  • 对源码包有修改最好通过dch -i来生成一个新的changelog文件,每个change item的title部分都是表示这次change的最新版本号,dpkg-buildpackage的输出二进制包的版本号其实就是从changelog里提取的(不是写在control文件里的)。
时间: 2024-08-24 09:47:55

从源码包构建.deb文件的备忘的相关文章

dockerfile用源码包构建tomcat服务

一.说明 centos基于docker官方镜像来制作的,用tomcat源码包生成的镜像,本环境中tomcat安装目录位于:/usr/local/,jdk安装目录位于:/usr/,如果你使用dockerfile buid此镜像,你要提前下载好jdk.tomcat源码包,在此文本中用的版本为apache-tomcat-8.0.24.jdk1.8.0_131,并且还配置了服务器的时间区,里面#号为注释掉的内容可以不用管它. 二.Dockerfile FROM centos:latest MAINTAI

Linux服务篇之十二:源码包构建LAMP服务器

实验环境:Apache服务器一台.Mysql服务器一台.PHP服务器一台 步骤一:安装Apache服务器 1.安装apr yum install gcc-c++ -y yum -y install epel-release tar zxf apr-1.5.2.tar.gz cd apr-1.5.2 ./configure --prefix=/usr/local/apr;echo $? make && make install;echo $? cd .. 2.安装apr-util yum -

Linux-什么是二进制包,源码包,RPM包,软件仓库

博文说明[前言]: 本文将通过个人口吻介绍什么是二进制包,RPM包,源码RPM包(SRPM包),源码包,以及RPM常用命令,源码rpm的安装(*.src.rpm),源码包的安装步骤知识(./configure,make,make install)相关知识. 在目前时间点[2017年6月12号]下,所掌握的技术水平有限,可能会存在不少知识理解不够深入或全面,望大家指出问题共同交流,在后续工作及学习中如发现本文内容与实际情况有所偏差,将会完善该博文内容. 本文参考文献引用链接: 1.http://m

程序包管理之源代码编译安装及rpm源码包安装

一.程序源码编译安装步骤 二.程序路径管理 三.简单源码编译安装示例 四.rpm源码包安装 一.程序源码编译安装步骤 --------------------------------------- 1.cd SOURCE_CODE    #cd到程序源码文件夹 --------------------------------------- 2../configure    #检查编译环境,对程序定制编译配置,编译前读一读README,INSTALL #常用配置参数:--prefix=安装路径,-

源码包安装和快捷的管理nginx,自定义命令管理服务

安装线上的生产服务器软件包时大多会用源码安装,这是因为源码安装可以选择最新的软件包,而Linux系统自带的软件包一般都是最稳定的版本,但不能保证是最新的.源码安装还可以自行调整编译参数,最大化地定制安装结果.相对而言,源码安装的性能是最优异的.但该源码装的软件不能使用 systemctl 管理,启动,关闭,查看状态,重启比较麻烦,现在编写一个启动脚本,可以简单快捷的管理该软件 环境Red Hat Enterprise Linux Server release 7.0 安装源码包nginx-1.8

详解CentOS7.4搭建Tomcat构建Java Web站点(内附源码包)

Java简介 Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承.指针等概念,因此Java语言具有功能强大和简单易用两个特征.Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论.Java具有简单性.面向对象.分布式.健壮性.安全性.平台独立与可移植性.多线程.动态性等特点.Java可以编写桌面应用程序.Web应用程序.分布式系统和嵌入式系统应用程序等. Tomcat简介 Tomcat是Apache软件基金会的Jakarta项目中的一

Ubuntu软件安装指南:dpkg、apt 与源码包安装

基础知识: 通常情况下,linux会这样放软件的组件(一般规范): 程序的文档->/usr/share/doc; /usr/local/share/doc 程序->/usr/share; /usr/local/share 程序的启动项->/usr/share/apps; /usr/local/share 程序的语言包->/usr/share/locale; /usr/local/share/locale 可执行文件->/usr/bin; /usr/local/bin 而有的软

第12章 安装RPM包或者安装源码包

1. 区分 rpm -qi -qf  -ql  -qa四个不同选项组合的作用?rpm -qi   //查询已经安装的某个RPM软件包的信息rpm -qf   //查询某个程序文件是由哪个RPM软件包安装的rpm -ql   //查询某个RPM软件包的所有安装文件rpm -qa   //查询所有已经安装的RPM软件包 2. rpm -qi 后面如果跟一个未安装的包名,会显示什么信息?  会提示该软件包没有安装 3. 请找出 vim 这个命令是由哪个rpm包安装来的?rpm -qf `which v

RPM 包管理与 yum安装源码包

RPM工具 RPM 是 Red HatPackage Manager 的缩写,是由Redhat所开发一款包管理程序.目前Redhat系的Linux使用rpm可以完成软件的安装.查询.卸载.升级等工作. 需要注意的是,RPM包之间存在依赖性的问题:在安装一个包的过程中可能需要安装其它包,并且其它包又有所依赖的包.所以必须先安装好所有所依赖的包后才能安装自己想要安装的包. 获取程序包的途径:优先选择系统附带的光盘或到官方的服务器下载:项目的官方站点下载. 每个rpm包名称都由"-"和&qu