% This file was generated with po4a. Translate the source file.
%
\documentclass[10pt,final]{beamer}
\mode<presentation> \usetheme{debian}

\usepackage{debiantutorial.zh_CN} \usepackage[UTF8]{ctex} 

\hypersetup{bookmarks}
\title{Debian打包教程}
\author[]{Lucas Nussbaum\\{\small\texttt{packaging-tutorial@packages.debian.org}}}

\date{\footnotesize version 0.29 -- 2021-11-03} 

\begin{document}


\frame{\titlepage}

\begin{frame}{关于该教程}
  \begin{itemize}
  \item 目标：\textbf{告诉你关于Debian打包必须知道的知识}
    \begin{itemize}
      \hbr
    \item 修改现有软件包
      \hbr
    \item 创建你自己的软件包
	    \hbr
    \item 在Debian社区内与人交流
      \hbr
    \item 成为Debian高手
    \end{itemize}
    \br
  \item 涵盖了大部分要点，但不是全部
    \begin{itemize}
    \item 你还需要看更多的说明文档
    \end{itemize}
    \br
  \item 绝大部分内容同样适用于Debian的各个衍生版本
    \begin{itemize}
      \hbr
    \item 包括Ubuntu
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{内容概括}
  \tableofcontents[hideallsubsections]
\end{frame}

\section{介绍}

\subsection{Debian}

\begin{frame}{Debian}
	\begin{itemize}
		\item \textbf{是一款 GNU/Linux 发行版}
			\br
		\item 第一款遵循“GNU开放精神”而开发的大型发行版
			\br
		\item \textbf{非商业用途}，由超过1000名志愿者合作构建
			\br
		\item 3项主要特性：
			\begin{itemize}
				\item textbf{高质量}——技术至上主义\\ {\small\sl 尽善尽美才可发行}
					\hbr
				\item \textbf{自由}——开发者和用户以\textsl{社会契约}的方式联系在一起，\\ 共同推广1993年开始的自由软件精神
					\hbr
				\item \textbf{独立}——没有（单独一家）公司在照看Debian\\ 我们集思广益群策群力（\textsl{高行动力} + \textsl{民主决策}）
			\end{itemize}
                        \br
                \item \textbf{业余爱好者}们的理想状态：与同好们一起用爱发电
	\end{itemize}
\end{frame}

\subsection{Debian软件包}
\begin{frame}{Debian软件包}
\begin{itemize}
\item \textbf{.deb} 文件（程序文件包）
	\br
\item 可靠又方便的软件发行方式
	\br
\item 两种应用最广泛的软件包格式之一（另一种是RPM）
	\br
\item 概况：
	\begin{itemize}
		\item Debian有超过30,000个软件包\\ $\rightarrow$绝大多数可用的自由软件都被打包进了Debian！
			\hbr
		\item 覆盖12种架构，包括两款非Linux架构（Hurd; KFreeBSD）
			\hbr
		\item 同时被用于120款Debian衍生系统
	\end{itemize}
\end{itemize}
\end{frame}


\subsection{Deb软件包格式}

\begin{frame}[fragile=singleslide]{Deb软件包格式}
  \begin{itemize}
  \item \texttt{.deb} 文件：其实是一种\texttt{ar}压缩包，里面包含了以下文件：
    \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
$ ar tv wget_1.12-2.1_i386.deb
rw-r--r-- 0/0      4 Sep  5 15:43 2010 debian-binary
rw-r--r-- 0/0   2403 Sep  5 15:43 2010 control.tar.gz
rw-r--r-- 0/0 751613 Sep  5 15:43 2010 data.tar.gz
    \end{lstlisting} \begin{itemize}
    \item \texttt{debian-binary}: deb文件格式的版本，\texttt{"2.0\textbackslash{}n"}
    \item \texttt{control.tar.gz}: 软件包的元数据(metadata)，包括\\ {\small
\texttt{\textbf{control}, md5sums, (pre|post)(rm|inst), triggers, shlibs},
\ldots}
    \item \texttt{data.tar.gz}: 软件包的数据文件
    \end{itemize}
    \br
  \item 你可以手动创建你自己的 \texttt{.deb} 文件\\ {\footnotesize
\url{http://tldp.org/HOWTO/html\_single/Debian-Binary-Package-Building-HOWTO/}}
    \br
  \item 但大家一般不这么做
  \end{itemize}
  \br
  \centerline{\textbf{此教程会教你：如何用Debian的方式创建Debian软件包}}
\end{frame}

\subsection{你需要准备的工具}
\begin{frame}{你需要准备的工具}
  \begin{itemize}
  \item Debian（或Ubuntu）操作系统（且你有root权限）
    \br
  \item 某些软件包：
    \begin{itemize}
    \item \textbf{build-essential}:
包含了在开发机上使用的依赖包（不需要逐一把这些依赖包在你软件包的命令控制参数\texttt{Build-Depends:}里列出来）
      \begin{itemize}
      \item 也包含了\textbf{dpkg-dev}的依赖包。\textbf{dpkg-dev}里有基本的Debian专用打包工具。
      \end{itemize}
      \hbr
    \item \textbf{devscripts}: 里面有很多对Debian维护者很有用的脚本。
    \end{itemize}
  \end{itemize}

  \br
  之后还会提到很多其他工具，譬如 \textbf{debhelper}, \textbf{cdbs}, \textbf{quilt},
\textbf{pbuilder}, \textbf{sbuild}, \textbf{lintian},
\textbf{svn-buildpackage}, \textbf{git-buildpackage}, \ldots\\ 
在你需要的时候可以安装它们。
\end{frame}

\subsection{通用打包流程}
\begin{frame}{通用打包流程}
  \begin{center}
    \begin{tikzpicture}[
      node1/.style={shape=rectangle,draw=rouge,fill=debianbackgroundblue,thick},
      arr/.style={very thick}, command/.style={text=rouge,font=\ttfamily}, ]
      
      \node[node1] (www) at (0, 0) {网页}; \node[node1] (us) at (2.5, 0) {上游源代码};
\node[node1] (da) at (-2.5, 0) {Debian源镜像}; \node[node1] (sp) at (0, -2)
{源码包}; \draw[arr,<-,dashed,thick] (sp) -- (2.5,-2) node[right=0cm,text
width=2.98cm,text centered,font=\small\sl] {至此绝大部分人工操作完成}; \node[node1]
(bin) at (0, -4) {一个或若干个程序包}; \draw[arr,<-,dashed,thick] (bin) -- (3.5,-4)
node[right,text centered,font=\small\ttfamily\sl] {.deb\normalfont};
\draw[arr,->] (us) -- (sp) node[pos=0.5,right,command] {dh\_make};
\draw[arr,->] (da) -- (sp) node[pos=0.5,left,command] {apt-get source};
\draw[arr,->] (www) -- (sp) node[pos=0.5,left,command] {dget}; \draw[arr,->]
(sp) -- (bin) node[pos=0.5,right,text width=6cm] {\textttc{debuild}
(用\textttc{lintian}构建或测试) 或 \textttc{dpkg-buildpackage}}; \draw[arr,->]
(bin) -- (1,-6) node[pos=0.5,right] {安装 (\textttc{debi})};
\draw[transparent] (bin) -- (-1,-6) node[pos=0.5,left,opaque] {上传
(\textttc{dput})}; \draw[arr,->,rounded corners] (bin) -- (-1,-6) --
(-4.5,-6) -- (-4.5,0) -- (da); \useasboundingbox (-4,-6) rectangle (6,0); \end{tikzpicture}
  \end{center}
\end{frame}

\subsection{重构dash}
\begin{frame}{范例：重构dash}
\begin{enumerate}
\item 安装构建dash需要的软件包，以及devscripts\\ {\texttt{sudo apt-get build-dep dash}\\ (需要在
\texttt{/etc/apt/sources.list})} 文件里加上\texttt{deb-src}的相关地址内容\\ 
{\texttt{sudo apt-get install -{}-no-install-recommends devscripts
fakeroot}}
  \hbr
\item 新建工作目录文件夹，并进入\\ \texttt{mkdir /tmp/debian-tutorial ; cd
/tmp/debian-tutorial}
  \hbr
\item 获取 \texttt{dash} 的源码包\\ \texttt{apt-get source dash}\\ {\small （需要在
\texttt{/etc/apt/sources.list} 文件里加上\texttt{deb-src}的相关地址内容）}
  \hbr
\item 构建软件包\\ {\texttt{cd dash-*\\ debuild -us -uc}} ~~~(\texttt{-us -uc}
指不将软件包标记为GPG)

  \hbr
\item 检查命令是否正常运作
	\begin{itemize}
		\item  上级目录下应该会出现几个新的 \texttt{.deb} 文件
	\end{itemize}
    \hbr
\item 查看 \texttt{debian/} 目录
	\begin{itemize}
		\item 打包完成后的软件包位于此目录
	\end{itemize}
\end{enumerate}
\end{frame}

\section{创建源码包}
\subsection{源码包基础}
\begin{frame}{源码包}
  \begin{itemize}
  \item 一个源码包可以生成若干个程序文件包\\ {\small 例如 \texttt{\bfseries libtar}
源代码可以生成\texttt{\bfseries libtar0} 和 \texttt{\bfseries libtar-dev} 程序文件包} \hbr
  \item 两种软件包：（如果不确定是哪种，选非原生）
    \begin{itemize}
      \small
    \item 原生软件包：专为Debian定制开发的软件(\textsl{dpkg}, \textsl{apt})
    \item 非原生软件包：在Debian之外开发的软件
    \end{itemize}
    \hbr
  \item 主要文件: \texttt{.dsc}（元数据）
    \hbr
  \item 与源码格式版本相关的其他文件
    \begin{itemize}
    \item 1.0或3.0（原生）：\texttt{package\_version.tar.gz}
      \hbr
    \item 1.0（非原生）：
      \begin{itemize}
      \item \texttt{pkg\_ver.orig.tar.gz}: 上游源代码
      \item \texttt{pkg\_debver.diff.gz}: 专为Debian准备的更新补丁
      \end{itemize}
      \hbr
    \item 3.0（quilt）
      \begin{itemize}
      \item \texttt{pkg\_ver.orig.tar.gz}: 上游源代码
      \item \texttt{pkg\_debver.debian.tar.gz}: 包含Debian补丁的压缩包
      \end{itemize}
    \end{itemize}
  \end{itemize}
  \hbr
  详见 \texttt{dpkg-source(1)}
\end{frame}

\begin{frame}[fragile=singleslide]{源码包范例（wget\_1.12-2.1.dsc）}
  \begin{lstlisting}[basicstyle=\ttfamily\small]
Format: 3.0 (quilt)
Source: wget
Binary: wget
Architecture: any
Version: 1.12-2.1
Maintainer: Noel Kothe <noel@debian.org>
Homepage: http://www.gnu.org/software/wget/
Standards-Version: 3.8.4
Build-Depends: debhelper (>> 5.0.0), gettext, texinfo,
 libssl-dev (>= 0.9.8), dpatch, info2man
Checksums-Sha1: 
 50d4ed2441e67[..]1ee0e94248 2464747 wget_1.12.orig.tar.gz
 d4c1c8bbe431d[..]dd7cef3611 48308 wget_1.12-2.1.debian.tar.gz
Checksums-Sha256: 
 7578ed0974e12[..]dcba65b572 2464747 wget_1.12.orig.tar.gz
 1e9b0c4c00eae[..]89c402ad78 48308 wget_1.12-2.1.debian.tar.gz
Files: 
 141461b9c04e4[..]9d1f2abf83 2464747 wget_1.12.orig.tar.gz
 e93123c934e3c[..]2f380278c2 48308 wget_1.12-2.1.debian.tar.gz
\end{lstlisting}
\end{frame}

\subsection{获取源码包}
\begin{frame}{从现成源码包中获取}
  \begin{itemize}
  \item 从Debian源代码库里获取
    \begin{itemize}
    \item \texttt{apt-get source \textsl{package}}
    \item \texttt{apt-get source \textsl{package=version}}
    \item \texttt{apt-get source \textsl{package/release}}
    \end{itemize}
    (需要在\texttt{sources.list}文件里加上\texttt{deb-src}的相关地址内容)
    \br
  \item 从互联网上获取：
    \begin{itemize}
    \item \texttt{dget \textsl{url-to.dsc}}
    \item \texttt{dget
http://snapshot.debian.org/archive/debian-archive/\\20090802T004153Z/debian/dists/bo/main/source/web/\\ 
wget\_1.4.4-6.dsc}\\ (\href{http://snapshot.debian.org/}{\ttfamily
snapshot.d.o} 提供了自2005年起Debian的所有软件包)
    \end{itemize}
    \br
  \item 从（已声明的）版本控制系统中获取：
    \begin{itemize}
    \item \texttt{debcheckout \textsl{package}}
    \end{itemize}
    \br
  \item 下载完毕后，用该命令解压缩：\texttt{dpkg-source -x \textsl{file.dsc}}
  \end{itemize}
\end{frame}

\subsection{创建基础源码包}
\begin{frame}{创建基础源码包}
  \begin{itemize}
  \item 下载上游源代码\\ （\textsl{上游源代码} = 软件开发者提供的源代码）
    \hbr
  \item 将源代码包重命名为\texttt{<\textsl{source\_package}>\_<\textsl{upstream\_version}>.orig.tar.gz}\\ 
(例如: \texttt{simgrid\_3.6.orig.tar.gz})
    \hbr
  \item 解压缩
    \hbr
  \item 重命名目录为\texttt{<\textsl{source\_package}>-<\textsl{upstream\_version}>}\\ 
(例如: \texttt{simgrid-3.6})
    \hbr
  \item \texttt{cd \texttt{<\textsl{source\_package}>-<\textsl{upstream\_version}>}
\&\& dh\_make}\\ (利用 \textbf{dh-make} 软件包)
    \hbr
  \item 如果要用其他的\texttt{dh\_make}命令来处理某些特定的源码包种类，还需要安装对应的软件包，如\textbf{dh-make-perl},
\textbf{dh-make-php}, \ldots \hbr
  \item 这时\texttt{debian/} 目录就会被创建，里面有一大堆文件
  \end{itemize}
\end{frame}

\subsection{debian/ 目录下的文件}
\begin{frame}{debian/ 目录下的文件}
  所有的打包工作都应该通过修改\texttt{debian/} 目录下的文件来进行
  \hbr
  \begin{itemize}
  \item 主要文件：
    \begin{itemize}
    \item \textbf{control}——软件包的元数据（依赖包，之类）
    \item \textbf{rules}——规定了如何构建软件包
    \item \textbf{copyright}——软件包的版权信息
    \item \textbf{changelog}——Debian软件包的更新历史记录
    \end{itemize}
    \hbr
  \item 其他文件：
    \begin{itemize}
    \item 兼容文件
    \item 监测文件
    \item dh\_install* 的保存目录\\ {\small *.dirs, *.docs, *.manpages, \ldots}
    \item 维护脚本\\ {\small *.postinst, *.prerm, \ldots}
    \item 源码/格式
    \item 补丁/ ——如果你需要修改上游源代码
    \end{itemize}
    \hbr
  \item 有几个文件使用基于RFC 8222的格式（邮件header格式）
  \end{itemize}
\end{frame}

\begin{frame}[fragile=singleslide]{debian/changelog}
  \begin{itemize}
  \item Debian打包更新历史记录
  \item 列出软件包的当前版本
  \begin{center}
    \begin{tikzpicture}
	    \draw (0,0) node[above right] {\large 1.2.1.1-5}; \draw
[decorate,decoration={brace}] (2,0) -- (1.45,0) node[at start,below,text
width=1.6cm,text centered] {\small Debian 版本}; \draw
[decorate,decoration={brace}] (1.4,0) -- (0,0) node[midway,below,text
width=1.6cm,text centered] { \small 上游版本};
\end{tikzpicture}
\end{center}


	  \item 手动编辑或使用\textttc{dch}命令
  \begin{itemize}
	  \item 为新发行的软件创建更新日志：\textttc{dch -i}
  \end{itemize}
  \item 自动关闭Debian或Ubuntu bug的特殊字符：\\ Debian: \texttt{Closes:~\#595268}; Ubuntu:
\texttt{LP:~\#616929}
  \item 安装在 \texttt{/usr/share/doc/\textit{package}/changelog.Debian.gz}
  \end{itemize}
  \seprule
  \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
mpich2 (1.2.1.1-5) unstable; urgency=low

  * Use /usr/bin/python instead of /usr/bin/python2.5. Allow
    to drop dependency on python2.5.  Closes: #595268
  * Make /usr/bin/mpdroot setuid. This is the default after
    the installation of mpich2 from source, too. LP: #616929
    + Add corresponding lintian override.

 -- Lucas Nussbaum <lucas@debian.org>  Wed, 15 Sep 2010 18:13:44 +0200
\end{lstlisting}
\end{frame}

\begin{frame}[fragile=singleslide]{debian/control}
  \hbr
  \begin{itemize}
  \item 软件包metadata
    \begin{itemize}
    \item 源码包的元数据
    \item 从源代码构建出来的每个程序文件包的元数据
    \end{itemize}
    \hbr
  \item 软件包名称，分类，优先级，维护者，上传者，build依赖包，本体依赖包，描述介绍，主页，\ldots \hbr
  \item 说明文档： Debian 政策 第5章\\ 
\url{https://www.debian.org/doc/debian-policy/ch-controlfields}
  \end{itemize}
  \seprule
\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
Source: wget
Section: web
Priority: important
Maintainer: Noel Kothe <noel@debian.org>
Build-Depends: debhelper (>> 5.0.0), gettext, texinfo,
 libssl-dev (>= 0.9.8), dpatch, info2man
Standards-Version: 3.8.4
Homepage: http://www.gnu.org/software/wget/

Package: wget
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: retrieves files from the web
 Wget is a network utility to retrieve files from the Web
\end{lstlisting}
\end{frame}

\begin{frame}{架构(Architecture)：全部(all)或任意(any)}
  有两种程序文件包：
  \hbr
  \begin{itemize}
  \item 每种Debian架构上有不同内容的软件包
    \begin{itemize}
    \item 例如：C 语言编程
    \item \texttt{debian/control} 文件内\texttt{Architecture:\ any}
      \begin{itemize}
      \item 或者，仅在某几种架构下可用：\\ \texttt{Architecture:\ amd64 i386 ia64 hurd-i386}
      \end{itemize}
    \item buildd.debian.org：会在你上传软件包时自动为你构建所有其他架构
    \item 命名为 \texttt{\textsl{package}\_\textsl{version}\_\textsl{architecture}.deb}
    \end{itemize}
    \br
  \item 所有架构下内容都相同的软件包
    \begin{itemize}
    \item 举例：Perl 函数库
    \item \texttt{debian/control} 文件内\texttt{Architecture:\ all}
    \item 命名为 \texttt{\textsl{package}\_\textsl{version}\_\textbf{all}.deb}
    \end{itemize}
  \end{itemize}
  \br
  一个源码包可以生成既有\texttt{Architecture:\ any} 程序 又有\texttt{Architecture:\ all}
程序的文件包。
\end{frame}

\begin{frame}[fragile=singleslide]{debian/rules}
  \hbr
  \begin{itemize}
  \item 用于编译源代码生成文件(Makefile)
    \br
  \item 用于构建Debian软件包的接口
    \br
  \item 说明文档在 Debian 政策，章节4.8\\ {\small
\url{https://www.debian.org/doc/debian-policy/ch-source\#s-debianrules}}
    \br
  \item 用到的目标参数：
    \begin{itemize}
    \item \texttt{build, build-arch, build-indep}: 这几项包括了所有配置 和编译方法。
      \hbr
    \item \texttt{binary, binary-arch, binary-indep}: 构建程序文件包
      \begin{itemize}
      \item \texttt{dpkg-buildpackage} 命令可以调用参数 \texttt{binary} 来构建所有的 软件包，也可以调用参数
\texttt{binary-arch} 只构建 \texttt{Architecture:~any} 的软件包
      \end{itemize}
      \hbr
    \item \texttt{clean}: 清除源目录下的文件
    \end{itemize}
  \end{itemize}
\end{frame}

\subsection{打包助手}
\begin{frame}{打包助手——debhelper}
  \begin{itemize}
  \item 你可以直接在 \texttt{debian/rules} 文件里写shell代码
  \item 更好的打包实操方法（大多数软件包都用此方法）：使用\textsl{打包助手}
  \item 最流行的打包助手：\textbf{debhelper}（98\% 的软件包用它打包）
  \item 目标：
    \begin{itemize}
    \item 归纳出用标准打包工具完成打包任务时适用于所有软件包的通用操作
    \item 一次性解决所有软件包中共同存在的打包bug
    \end{itemize}{\footnotesize dh\_installdirs, dh\_installchangelogs, dh\_installdocs,
dh\_install, dh\_installdebconf, dh\_installinit, dh\_link, dh\_strip,
dh\_compress, dh\_fixperms, dh\_perl, dh\_makeshlibs, dh\_installdeb,
dh\_shlibdeps, dh\_gencontrol, dh\_md5sums, dh\_builddeb, \ldots}
    \begin{itemize}
    \item 调用 \texttt{debian/rules}
    \item 可以使用命令行参数或者修改 \texttt{debian/} 目录内的文件来进行配置
    \end{itemize}{\footnotesize \ttfamily \textsl{package}.docs, \textsl{package}.examples,
\textsl{package}.install, \textsl{package}.manpages, \ldots} \hbr
  \item 特定软件包种类的第三方助手：\textbf{python-support}, \textbf{dh\_ocaml}, \ldots \hbr
  \item \texttt{debian/compat}: Debhelper compatibility version
	  \begin{itemize}
		  \item Defines precise behaviour of dh\_*
		  \item New syntax: \texttt{Build-Depends: debhelper-compat (= 13)}
	  \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}[fragile=singleslide]{用到 debhelper 的 debian/rules 文件写法 (1/2)}
  \begin{lstlisting}[basicstyle=\ttfamily\footnotesize,escapeinside=\{\}]
#!/usr/bin/make -f

# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1

build: 
        $(MAKE)
        #docbook-to-man debian/packagename.sgml > packagename.1

clean: 
        dh_testdir
        dh_testroot
        rm -f build-stamp configure-stamp
        $(MAKE) clean
        dh_clean 

install: build
        dh_testdir
        dh_testroot
        dh_clean -k 
        dh_installdirs
        # Add here commands to install the package into debian/packagename.
        $(MAKE) DESTDIR=$(CURDIR)/debian/packagename install
\end{lstlisting}
\end{frame}

\begin{frame}[fragile=singleslide]{用到 debhelper 的 debian/rules 文件写法（2/2）}
  \begin{lstlisting}[basicstyle=\ttfamily\footnotesize,escapeinside=\{\}]

# Build architecture-independent files here.
binary-indep: build install

# Build architecture-dependent files here.
binary-arch: build install
        dh_testdir
        dh_testroot
        dh_installchangelogs 
        dh_installdocs
        dh_installexamples
        dh_install
        dh_installman
        dh_link
        dh_strip
        dh_compress
        dh_fixperms
        dh_installdeb
        dh_shlibdeps
        dh_gencontrol
        dh_md5sums
        dh_builddeb

binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install configure
\end{lstlisting}
\end{frame}

\begin{frame}[fragile=singleslide]{CDBS}
  \hbr
  \begin{itemize}
  \item 即使用了debhelper，打不同的包依然有许多重复劳动
    \hbr
  \item 需要更进一步的归纳通用操作的助手软件
    \begin{itemize}
    \item 例如：用 \texttt{./configure \&\& make \&\& make install} 或者 CMake构建
    \end{itemize}
    \hbr
  \item CDBS:
    \begin{itemize}
    \item 出现在2005年，基于进阶 \textsl{GNU make} 功能
    \item 说明文档: \texttt{/usr/share/doc/cdbs/}
    \item 支持 Perl, Python, Ruby, GNOME, KDE, Java, Haskell, \ldots
    \item 但也有人很讨厌它：
      \begin{itemize}
      \item 有时候会让自定义软件包构建变得困难：\\ “\textsl{搞得人头昏脑胀 的文件生成和环境变量}”
      \item 比普通的debhelper要慢（这是对\texttt{dh\_*}的大量无效调用导致的）
      \end{itemize}
    \end{itemize}
  \end{itemize}
  \seprule
      \begin{lstlisting}[basicstyle=\ttfamily\footnotesize,escapeinside=\{\}]
#!/usr/bin/make -f
include /usr/share/cdbs/1/rules/debhelper.mk
include /usr/share/cdbs/1/class/autotools.mk

# add an action after the build
build/mypackage::
    /bin/bash debian/scripts/foo.sh
      \end{lstlisting}
\end{frame}

\begin{frame}[fragile=singleslide]{Dh（也叫Debhelper 7，或 dh7）}
  \begin{itemize}
  \item 在2008年以\textsl{CDBS killer}的名义被公布
    \hbr
  \item \textbf{dh} 命令调用\texttt{dh\_*}
    \hbr
  \item 简易的 \textsl{debian/rules} 文件，仅仅列出覆盖内容
    \hbr
  \item 比CDBS更容易定制
    \hbr
  \item 说明文档: man手册 (\texttt{debhelper(7)}, \texttt{dh(1)}) + DebConf9 的幻灯片文档\\ 
\url{http://kitenet.net/~joey/talks/debhelper/debhelper-slides.pdf}
  \end{itemize}
  \seprule
    \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
#!/usr/bin/make -f
%:
    dh $@

override_dh_auto_configure:
     dh_auto_configure -- --with-kitchen-sink

override_dh_auto_build:
     make world

    \end{lstlisting}
\end{frame}

\begin{frame}{经典debhelper vs CDBS vs dh}
  \hbr
  \begin{itemize}
  \item 份额比例：\\ 经典debhelper：15\% \hskip 1em CDBS:15\% \hskip 1em dh：68\%
    \hbr
  \item 我该学用哪个？
    \begin{itemize}
    \item 最好全学一点
    \item 你得先搞懂debhelper才能用好dh和CDBS
    \item 你可能需要修改CDBS软件包
    \end{itemize}
    \hbr
  \item 打包新软件用哪个?
    \begin{itemize}
	    \item \textbf{dh} (份额比例不断上升的不二选择)
	    \item See \url{https://trends.debian.net/\#build-systems}
    \end{itemize}
  \end{itemize}
  
  \hbr


\end{frame}

\section{构建与测试软件包}
\subsection{构建软件包}
\begin{frame}{构建软件包}
  \begin{itemize}
  \item \textttc{apt-get build-dep mypackage}\\ 安装
\textsl{build-dependencies}（构建依赖库） (如果该包已经在Debian源内)\\ 或者
\textttc{mk-build-deps -ir} (如果该包还没被上传过)
    
    \br
  \item \textttc{debuild}: 使用 \texttt{lintian} 构建、测试，使用GPG签名
    \br
  \item 也可以直接调用 \textttc{dpkg-buildpackage}
    \begin{itemize}
    \item 通常使用命令 \texttt{dpkg-buildpackage -us -uc}
    \end{itemize}
    \br
  \item 尽可能在干净而精简的系统环境中构建软件包
    \begin{itemize}
    \item \textttc{pbuilder} -- 在 \textsl{chroot}\\中构建软件包的助手
不错的说明文档：\url{https://wiki.ubuntu.com/PbuilderHowto}\\ (优化:
\textttc{cowbuilder} \textttc{ccache} \textttc{distcc})
      \hbr
    \item \textttc{schroot} 和 \textttc{sbuild}: 用于Debian构建后台 \\ (不如 \texttt{pbuilder}
简单，但允许使用LVM快照 \\ 详见：\url{https://help.ubuntu.com/community/SbuildLVMHowto} )
    \end{itemize}
    \br
  \item 生成 \texttt{.deb} 文件和 \texttt{.changes} 文件
    \begin{itemize}
    \item \texttt{.changes}: 说明构建了哪些东西；上传软件包的时候用到
    \end{itemize}
  \end{itemize}
\end{frame}
\subsection{安装和测试软件包}
\begin{frame}{安装和测试软件包}
  \begin{itemize}
  \item 在本机安装软件包: \textttc{debi} (查看 \texttt{.changes} 来 了解要安装哪些东西) \br
  \item 列出软件包内容：\texttt{{\color{rouge}debc} ../mypackage<标签>.changes} \br
  \item 与一版本的软件包进行对比：\\ \texttt{{\color{rouge}debdiff} ../mypackage\_1\_*.changes
../mypackage\_2\_*.changes}\\ 或者直接对比源代码\\ \texttt{{\color{rouge}debdiff}
../mypackage\_1\_*.dsc ../mypackage\_2\_*.dsc}\\
    \br
  \item 用 \texttt{lintian} (静态检测工具)检查软件包:\\ \texttt{{\color{rouge}lintian}
../mypackage<标签>.changes}\\ \texttt{lintian -i}: 反馈更多错误信息 \\ \texttt{lintian
-EviIL +pedantic}: 显示更多问题\br
  \item 把软件包上传到Debian (\textttc{dput}) (需要配置) \br
  \item 用 \textttc{reprepro} 或 \textttc{aptly} 管理个人Debian档案库\\ 说明文档:
\url{https://wiki.debian.org/HowToSetupADebianRepository}
  \end{itemize}
\end{frame}
\section{实操练习环节1：修改grep软件包}
\begin{frame}{实操练习环节1：修改grep软件包}
  \begin{enumerate}
  \item 访问 \url{http://ftp.debian.org/debian/pool/main/g/grep/} 并下载 2.12-2版本的grep软件包
    \begin{itemize}
		   \item 如果源码包没有自动解包，用 \texttt{dpkg-source~-x~grep\_*.dsc} 命令解包
    \end{itemize}

  \item 查看 \texttt{debian/} 目录下的文件。
    \begin{itemize}
    \item 		此源码包生成了多少个程序文件包？
    \item 		此软件包用了哪个打包助手？
    \end{itemize}
    \hbr
  \item 构建软件包
    \hbr
  \item 现在我们要修改这个软件包。添加一条更新记录并且增加一位版本号。
    \hbr
  \item 然后停用perl-regexp的支持（这是 \texttt{./configure} 里的一条选项）
    \hbr
  \item 重构软件包
    \hbr
  \item 用debdiff对比原版和新版软件包的区别
    \hbr
  \item 安装新构建的软件包
  \end{enumerate}
\end{frame}

\section{进阶打包知识}
\subsection{debian/copyright}
\begin{frame}[fragile=singleslide]{debian/copyright}
  \hbr
  \begin{itemize}
  \item 源代码和打包的版权及证书信息
  \item 以前都是写成文本文件
  \item 现在用的可被机器识别的格式:
{\small\url{https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/}}
  \end{itemize}
  \seprule
  \begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: X Solitaire
Source: ftp://ftp.example.com/pub/games

Files: *
Copyright: Copyright 1998 John Doe <jdoe@example.com>
License: GPL-2+
 This program is free software; you can redistribute it
 [...]
 .
 On Debian systems, the full text of the GNU General Public
 License version 2 can be found in the file
 `/usr/share/common-licenses/GPL-2'.

Files: debian/*
Copyright: Copyright 1998 Jane Smith <jsmith@example.net>
License:
 [LICENSE TEXT]
\end{lstlisting}
\end{frame}



\subsection{修改上游源代码}
\begin{frame}{修改上游源代码}
  常用于：
  \begin{itemize}
  \item 修复bug或添加Debian专属定制内容
    \hbr
  \item 从新的上游版本回注（backport）各种修复
  \end{itemize}
  \br
  有几种方法
  \begin{itemize}
  \item 直接修改文件
    \begin{itemize}
    \item 简单
    \item 但不能追踪和记录各种更新
    \end{itemize}
    \hbr
  \item 使用补丁系统
    \begin{itemize}
    \item 简化了将更新提交到上游源代码的操作
    \item 与其他衍生系统分享你的修复内容
    \item 让更多人知道你的更新\\ \url{http://patch-tracker.debian.org/} (暂不可用)
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{补丁系统}
  \begin{itemize}
  \item 原则：更新以补丁形式存储在 \texttt{debian/patches/}
    \br
  \item 在构建中实装或卸装
    \br
  \item 以前：几种实现方式—— \textsl{simple-patchsys} (\textsl{cdbs}), \textsl{dpatch},
\textbf{\textsl{quilt}}
    \begin{itemize}
  \item 每一种都支持两个 \texttt{debian/rules} 目标参数：
    \begin{itemize}
    \item \texttt{debian/rules patch}: 实装所有补丁
    \item \texttt{debian/rules unpatch}: 卸装所有补丁
    \end{itemize}
	  \hbr
  \item 更多说明文档：\url{https://wiki.debian.org/debian/patches}
  \end{itemize}
  \br
  \item \textbf{包含内建补丁系统的新源码包格式：3.0（quilt）}
  \begin{itemize}
  \item 推荐使用这个方案
	  \hbr
  \item 你得先学用一下 \textsl{quilt}\\ 
\url{https://perl-team.pages.debian.net/howto/quilt.html}
    \hbr
  \item 补丁工具在 \texttt{devscripts}: \texttt{edit-patch}
  \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}[fragile=singleslide]{补丁说明文档}
  \begin{itemize}
	  \item 补丁开头要有标准的头标（header）
    \br
  \item 说明文档在 DEP-3— 补丁标签引导\\ \url{http://dep.debian.net/deps/dep3/}
  \end{itemize}
  \vfill
\seprule
  \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
Description: Fix widget frobnication speeds
 Frobnicating widgets too quickly tended to cause explosions.
Forwarded: http://lists.example.com/2010/03/1234.html
Author: John Doe <johndoe-guest@users.alioth.debian.org>
Applied-Upstream: 1.2, http://bzr.foo.com/frobnicator/revision/123
Last-Update: 2010-03-29

--- a/src/widgets.c
+++ b/src/widgets.c
@@ -101,9 +101,6 @@ struct {
\end{lstlisting}
\end{frame}

\subsection{安装或移除过程中的操作}
\begin{frame}{安装或移除过程中的操作}
  \begin{itemize}
  \item 仅仅解压缩软件包通常是不够的
    \hbr
  \item 新建/移除系统用户，开始/停止服务，管理马甲命令（ \textsl{alternatives}）
    \hbr
  \item 用维护脚本（ \textsl{maintainer scripts}）完成\\ \texttt{preinst, postinst, prerm,
postrm}
    \begin{itemize}
	    \item  debhelper可以生成通用操作的重复脚本
    \end{itemize}
    \hbr
  \item 说明文档：
    \begin{itemize}
    \item Debian 政策说明, 第6章 \\ {\footnotesize
\url{https://www.debian.org/doc/debian-policy/ch-maintainerscripts}}
      
      \hbr
    \item Debian 开发者手册, 第6.4章 \\ {\scriptsize
\url{https://www.debian.org/doc/developers-reference/best-pkging-practices.html}}
      \hbr
    \item {\footnotesize
\url{https://people.debian.org/~srivasta/MaintainerScripts.html}}
    \end{itemize}
    \br
  \item 用户指引
    \begin{itemize}
    \item 需要用 \textbf{debconf} 做好用户指引
      \hbr
    \item 说明文档: \texttt{debconf-devel(7)} (\texttt{debconf-doc} package)
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}[fragile=singleslide]{监测上游版本}
  \begin{itemize}
  \item 在 \texttt{debian/watch} 文件中指定监测目标 (详见 \texttt{uscan(1)})
    \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
version=3

http://tmrc.mit.edu/mirror/twisted/Twisted/(\d\.\d)/ \
  Twisted-([\d\.]*)\.tar\.bz2
    \end{lstlisting}
    \br
  \item 有网站会自动追踪上游软件的新版本， 且会通过控制台通知维护者，譬如 \url{https://tracker.debian.org/} 和
\url{https://udd.debian.org/dmd/}
    \br
  \item \texttt{uscan}: 手动检查命令
    \br
  \item \texttt{uupdate}: 尝试将你的软件包更新到最新的上游版本
  \end{itemize}
\end{frame}

\subsection{用版本控制系统打包（SVN, Git）}
\begin{frame}[fragile=singleslide]{用版本控制系统打包}
  \begin{itemize}
  \item 有些工具可以帮你在打包工作中管理分支版本（branch）和标签：\\ \texttt{svn-buildpackage},
\texttt{git-buildpackage}
    \hbr
  \item 例如：\texttt{git-buildpackage}
    \begin{itemize}
    \item \texttt{upstream} 分支会通过 \texttt{upstream/\textsl{version}} 标签追踪上游版本
    \item \texttt{master} 分支用于追踪Debian软件包
    \item \texttt{debian/\textsl{version}} 标签用于每次上传
    \item \texttt{pristine-tar} 分支用于重构上游压缩包
    \end{itemize}
    文档:
\url{http://honk.sigxcpu.org/projects/git-buildpackage/manual-html/gbp.html}
    \hbr
  \item \texttt{Vcs-*} \texttt{debian/control} 文件里用于定位软件仓库的代码块
	  \begin{itemize}
		\item \url{https://wiki.debian.org/Salsa}
	\end{itemize}
\end{itemize}
  \begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
Vcs-Browser: https://salsa.debian.org/debian/devscripts
Vcs-Git: https://salsa.debian.org/debian/devscripts.git
  \end{lstlisting}
  \begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
Vcs-Browser: https://salsa.debian.org/perl-team/modules/packages/libwww-perl
Vcs-Git: https://salsa.debian.org/perl-team/modules/packages/libwww-perl.git
  \end{lstlisting}
  \begin{itemize}
  \item VCS-交互接口: \texttt{debcheckout}, \texttt{debcommit}, \texttt{debrelease}\\
    \begin{itemize}
	    \item     \texttt{debcheckout grep} $\rightarrow$ 检查来自Git的源码包 
    \end{itemize}
\end{itemize}
\end{frame}

\subsection{回注（Backport）软件包}
\begin{frame}{回注（Backport）软件包}
  \begin{itemize}
  \item 目标：在老系统版本里使用新版软件包\\ 例如，在 Debian\textsl{stable} 分支使用 Debian \textsl{unstable}
分支的\textsl{mutt} 软件包
	\br
  \item 通用方法：
	  \begin{itemize}
		\item 直接从 Debian unstable（开发）分支里照搬源码包
		\hbr
		\item 修改并构建使之正常用于Debian stable（稳定）分支
		\begin{itemize}
			\item 有时候没啥必要（不用改动代码）
			\item 有时候很麻烦
			\item 有时候不可能（有很多不可用的依赖库）
		\end{itemize}
	\end{itemize}
	\br
   \item 有些软件包回注是由以下这个Debian项目来提供和支持的 \\ \url{http://backports.debian.org/}
\end{itemize}
\end{frame}



\section{维护Debian软件包}
\subsection{Debian档案库和分支}
\begin{frame}{Debian档案库和分支}
  \begin{center}
	  \resizebox{\textwidth}{!}{
    \begin{tikzpicture}[
	    people/.style={shape=ellipse,draw,thick},
      suite/.style={shape=rectangle,draw},
	    devel/.style={fill=red!30!white},
	    test/.style={fill=orange!30!white},
	    prod/.style={fill=green!30!white,node distance=2cm},
	    internal/.style={},
	    old/.style={fill=gray!30!white},
	    veryold/.style={fill=gray!70!white},
      arr/.style={very thick},
	    uploads/.style={decorate,decoration={snake,amplitude=.4mm,segment length=2mm,post length=1mm}},
	    migrations/.style={};
	    command/.style={text=rouge,font=\ttfamily},
	    legend/.style={font=\small}
	    ]
      
      \draw node[suite,prod] (sec) {security}; \draw node[suite,prod,right=of sec]
(su) {stable-updates}; \draw node[suite,prod,right=of su] (st) {stable};
\draw node[suite,old,node distance=0.3cm,below=of st] (os) {oldstable};
\draw node[suite,veryold,node distance=0.3cm,below=of os] (ar)
{archive.d.o}; \draw node[suite,prod,right=of st] (bp) {backports}; \draw
node[suite,test] (spu) at ($(su) + (-0.6,2.5)$) {stable-proposed-updates};
\draw node[suite,internal] (sn) at ($(st) + (-1.8,1.4)$) {stable-new}; \draw
node[suite,test,node distance=1.5cm,above=of st] (te) {testing}; \draw
node[suite,devel,above=of te] (sid) {unstable}; \draw node[suite,devel]
(exp) at ($(sid) + (2.5,0.5)$) {experimental}; \draw node[suite,devel] (tpu)
at ($(te)!0.5!(sid) + (2.5,0)$) {testing-proposed-updates}; \draw
node[people,above=of sid] (dd) {开发者}; \draw node[people,node
distance=3cm,left=of dd] (secteam) {安全团队}; \draw[arr,uploads,->] (dd) --
(sid); \draw[arr,uploads,->] (dd) -- (exp); \draw[arr,uploads,->,bend
right=8] (dd) to (tpu); \draw[arr,uploads,->] (secteam) -- (sid);
\draw[arr,uploads,->] (secteam) -- (sec); \draw[arr,uploads,->] (dd) to
(spu); \draw[arr,uploads,->] plot [smooth, tension=0.75] coordinates {
(dd.east) ($(exp.north east)+(0.1,0.1)$) ($(tpu.east)+(0.2,0)$)  ($(bp.north
east) + (-0.4,0)$) }; \draw[arr,migrations,->] (tpu) -- (te);
\draw[arr,migrations,->] (sid) -- (te); \draw[arr,migrations,->] (te) --
(st) node [midway,align=left,midway,right,font=\footnotesize] {稳定版\\ 发行};
\draw[arr,migrations,->] (sec) -- (sn); \draw[arr,migrations,->] (sn) to
node [pos=0.2] (spulabel) {} (st); \draw
node[font=\footnotesize,align=right] at ($(spulabel) + (-0.4,-0.45)$) {稳定版
\\ 小数点 \\ 更新}; \draw[arr,migrations,->] (spu) to (sn);
\draw[arr,migrations,->] (spu) -- (su); \draw[arr,migrations,->] (st) --
(os); \draw[arr,migrations,->] (os) -- (ar); \coordinate (legend) at
(-2,-1); \draw[arr,uploads,->] (legend) -- ($(legend) + (0.7,0)$) node
[right,legend] {软件包上传}; \coordinate[node distance=1.1em,below=of legend]
(legend2); \draw[arr,migrations,->] (legend2) -- ($(legend2) + (0.7,0)$)
node [right,legend] {软件包在不同分支间迁移}; \coordinate[node distance=1.5em,below=of
legend2] (legend3); \draw node[right,suite,devel,legend] (ldev) at (legend3)
{开发分支}; \draw node[node distance=0.1cm,right=of ldev,suite,test,legend]
(ltest) {测试分支}; \draw node[node distance=0.1cm,right=of
ltest,suite,internal,legend] (lint) {内部版本}; \draw node[node
distance=0.1cm,right=of lint,suite,prod,legend] (lprod) {成品分支}; \draw
($(legend.north west) + (-0.1,0.25)$) rectangle ($(lprod.south east) +
(0.1,-0.1)$); \draw node[font=\bf,red!70!white,align=center] (tnext) at
($(te.east) + (2,-0.1)$) {准备发行 \\ 下个版本}; \draw
node[font=\bf,green!70!black,align=center] (tsrm) at ($(sec.north east) +
(1,1)$) {稳定版\\发行\\管理}; \pgfdeclarelayer{background}
\pgfdeclarelayer{foreground} \pgfsetlayers{background,main,foreground}
\begin{pgfonlayer}{background}
	    \fill[red!10!white] plot [smooth cycle,tension=0.55] coordinates {
($(sid.north west) + (-0.1,0.1)$) ($(exp.north east)+(0.1,0.1)$)
($(tpu.south east)+(0.1,-0.1)$) ($(tnext.south) + (0.6,0)$) ($(te.south
west) + (0.1,-0.1)$)  }; \fill[green!10!white] plot [smooth
cycle,tension=0.55] coordinates { ($(spu.north west) + (-0.1,0.1)$)
($(spu.north east)+(0.1,0.1)$) ($(sn.north east)+(0.1,0.1)$) ($(st.north
east) + (0.1,0.5)$) ($(bp.north east) + (0.1,0.1)$)  ($(bp.south east) +
(0.1,-0.1)$) ($(sec.south west) + (-0.1,-0.1)$)  };
\end{pgfonlayer}

    \end{tikzpicture}
	  }
  \end{center}
	\begin{flushright}
		\tiny 该图参考 Antoine Beaupr\'e
的图表绘制。\url{https://salsa.debian.org/debian/package-cycle}~~~~~~~~~~~~
	\end{flushright}
\end{frame}

\begin{frame}{开发分支}
		\begin{itemize}
			\item 新的软件包版本一般都上传到 \textbf{unstable} (\textbf{sid}) 分支
				\hbr
			\item \textbf{unstable}（开发）分支中的软件在符合一定标准（例如在开发分支运行了10天且没有回滚过版本） 后会从
\textbf{unstable} 分支迁移到 \textbf{testing}（测试）分支
				\hbr
			\item 也可以把新软件包上传到
				\begin{itemize}
					\item \textbf{experimental}（实验）分支（用于某些\textsl{实验性} 的软件包，
如某个还没有确定将用于替换当前unstable分支版本的新版本）
						\hhbr
					\item \textbf{testing-proposed-updates}（用于测试的更新）分支, 不经过\textbf{unstable} 直接更新到
\textbf{testing} 分支（很少这么做） 
				\end{itemize}
		\end{itemize}
\end{frame}

\begin{frame}{冻结和发行}
	\begin{itemize}
					\item 在发行周期中的某个时间点，发行团队会 \textsl{freeze} （冻结）testing 分支: 停止软件在 \textbf{unstable} 和
\textbf{testing} 分支间的自动迁移，改为人工审核
						\br
		\item 当发行团队认为\textbf{testing} 分支已经足够完善，可以对外发行时：
			\begin{itemize}
				\item \textbf{testing} 分支变为新的\textbf{stable} （稳定）分支
					\hhbr
				\item 同时，原来的\textbf{stable}分支成为\textbf{oldstable}（旧稳定）分支
					\hhbr
				\item 不再提供支持的发行版则归入 \texttt{archive.debian.org}
			\end{itemize}
			\br
		\item 详见 \url{https://release.debian.org/}
	\end{itemize}
\end{frame}

\begin{frame}{稳定版的分支和管理}
	\begin{itemize}
		\item 我们使用若干分支来发行稳定版软件包
			\hhbr
			\begin{itemize}
				\item \textbf{stable}: 主分支
					\hbr
				\item 安全团队在\texttt{security.debian.org} 网站提供\textbf{security} 分支更新， 同时也会向订阅
\texttt{debian-security-announce} 的邮件列表推送更新通知
					\hbr
				\item \textbf{stable-updates}: 与安全无关但很紧急的更新（等不到下一次小数点更新）:
杀毒软件数据库，时区调整相关的软件包，等等。向订阅 \texttt{debian-stable-announce} 的邮件列表推送通知
					\hbr
				\item \textbf{backports}: 从 \textbf{testing} 分支回注的新上游版本
			\end{itemize}
			\hbr
		\item \textbf{stable} 分支通常每几个月会进行一次 \textsl{stable point releases}
（小数点更新）(一般就是修修bug)
			\hhbr
			\begin{itemize}
				\item 随下一次小数点更新一起更新的软件包会被上传到 \textbf{stable-proposed-updates} 分支，并且由发行团队审核
			\end{itemize}
			\hbr
		\item \textbf{oldstable} 旧稳定版的分支系列保持不变
	\end{itemize}
\end{frame}

\subsection{几种为Debian做贡献的方式}
\begin{frame}{几种为Debian做贡献的方式}
  \begin{itemize}
  \item \textbf{最糟糕的} 的贡献方式：
    \begin{enumerate}
    \item 打包你自己的应用
    \item 放进Debian
    \item 不管了
    \end{enumerate}
    \br
  \item \textbf{更好的}贡献方式：
	  \begin{itemize}
		  \item 加入打包团队
    \begin{itemize}
    \item 许多专注于打包的团队需要人手
    \item 团队列表 \url{https://wiki.debian.org/Teams}
    \item 这也是向高手们请教学习的绝佳途径
    \end{itemize}
    \br
\item 认领现有的未维护软件包（\textsl{orphaned packages} 遗弃软件包）
    \br
  \item 为Debian提供新软件
    \begin{itemize}
    \item 请务必只提供足够有趣/有用的软件，拜托
    \item 注意是不是已经有类似软件被打包上传过了？
    \end{itemize}
  \end{itemize}

  \end{itemize}
\end{frame}

\subsection{认领遗弃软件包}
\begin{frame}{认领遗弃软件包}
      \hbr
  \begin{itemize}
    \item Debian里有很多未维护软件包
    \hbr
  \item 详细的列表+当前状态：\url{https://www.debian.org/devel/wnpp/}
    \hbr
  \item 你可以在自己系统里安装这两个包来查看： \texttt{wnpp-alert}\\ 或 \texttt{how-can-i-help}
    \hbr
  \item 不同的软件包状态
    \begin{itemize}
		    \small
    \item \textbf{O}rphaned: 遗弃：该软件包无人维护\\ 可以直接认领
      \hbr
    \item \textbf{RFA}: \textbf{R}equest \textbf{F}or \textbf{A}dopter 求认领\\ 
现维护者正在找人接盘，有人接盘前会继续维护。\\ 可以直接认领，记得认领前给现维护者写一封邮件告知
      \hbr
    \item \textbf{ITA}: \textbf{I}ntent \textbf{T}o \textbf{A}dopt 打算认领\\ 有人想要认领某软件包\\ 
你可以去帮他!
      \hbr
    \item \textbf{RFH}: \textbf{R}equest \textbf{F}or \textbf{H}elp 求帮忙\\ 维护者想要找人一起维护
    \end{itemize}
    \hbr
  \item 有一些未维护软件包还没有被检测到 \arr 尚未被遗弃
    \hbr
  \item 如果你不确定, 可以询问 \texttt{debian-qa@lists.debian.org} \\ 或
\texttt{irc.debian.org} 的\texttt{\#debian-qa} 频道
  \end{itemize}
\end{frame}

\begin{frame}[fragile=singleslide]{认领软件包：范例}
\begin{lstlisting}[basicstyle=\ttfamily\footnotesize,escapeinside=\{\}]
From: You <you@yourdomain>
To: 640454@bugs.debian.org, control@bugs.debian.org
Cc: Francois Marier <francois@debian.org>
Subject: ITA: verbiste -- French conjugator

retitle 640454 ITA: verbiste -- French conjugator
owner 640454 !
thanks

Hi,

I am using verbiste and I am willing to take care of the package.

Cheers,

You
\end{lstlisting}

\begin{itemize}
\item 记得联系一下上任维护者（特别是该软件包处于RFA状态而不是遗弃状态时），这是礼貌
\item 最好也能联系一下上游开发者
\end{itemize}
\end{frame}

\subsection{把你的软件包放进Debian}
\begin{frame}{把你的软件包放进Debian}
\begin{itemize}
\item 你不需要获得任何官方身份就能直接上传你的软件包到Debian
	\begin{enumerate}
		\item 用 \texttt{reportbug wnpp} 来提交 \textbf{ITP} (\textbf{I}ntent \textbf{T}o
\textbf{P}ackage 有意向打包) 的bug
			\hbr
		\item 准备好源码包
			\hbr
		\item 找一个肯帮你上传软件包的Debian Developer（DD—Debian开发者）
	\end{enumerate}
\br
\item 官方身份（如果你已经是一个熟练的软件包维护者）：
	\begin{itemize}
		\item \textbf{Debian Maintainer (DM——Debian维护者):}\\ 有权上传你自己的 软件包\\ 详见
\url{https://wiki.debian.org/DebianMaintainer}
			\hbr
		\item \textbf{Debian Developer (DD——Debian开发者):}\\ Debian 项目成员；有权投票或上传任何软件包
	\end{itemize}
\end{itemize}
\end{frame}

\begin{frame}{在找人上传前你需要检查的事项}
\begin{itemize}
	\item Debian \textbf{极重视软件质量}
\hbr
\item 通常，\textbf{维护者们都非常忙}
\begin{itemize}
\item 在找人上传前务必确保你的软件包已经准备妥当
\end{itemize}
\hbr
\item 要检查的事项：
\begin{itemize}
\item 不要遗漏构建依赖库： 确保你的软件包是在干净的 \textsl{sid} \textsl{chroot} 环境里构建的
\begin{itemize}
\item 推荐使用 \texttt{pbuilder}
\end{itemize}
\hbr
\item 为你的软件包运行一下 \texttt{lintian -EviIL +pedantic}
\begin{itemize}
\item 修复Error错误和各种其他问题
\end{itemize}
\hbr
\item 当然还要做好各种延申测试
\end{itemize}
\hbr
\item 有问题就求助
\end{itemize}
\end{frame}

\subsection{哪里可以求助？}
\begin{frame}{哪里可以求助？}
	\hbr
  你可能需要的帮助：
  \begin{itemize}
  \item 针对你的疑问给出建议和解答，以及代码审核
  \item 在你准备好软件包后替你上传
  \end{itemize}
  \hbr
  你可以通过以下方式求助：
  \begin{itemize}
	  \item \textbf{各打包团队的成员}
    \begin{itemize}
    \item 打包团队列表：\url{https://wiki.debian.org/Teams}
    \end{itemize}
    \hbr
  \item \textbf{Debian 导师组}（如果你的软件包没有团队接）
    \begin{itemize}
    \item \url{https://wiki.debian.org/DebianMentorsFaq}
    \item 邮件列表：\url{debian-mentors@lists.debian.org}\\ {\small (正好也是个学习的好途径)}
    \item IRC聊天: \texttt{irc.debian.org} 上的\texttt{\#debian-mentors} 频道 
    \item \url{http://mentors.debian.net/}
    \item 说明文档：\url{http://mentors.debian.net/intro-maintainers}
    \end{itemize}
    \hbr
  \item \textbf{本地化团队邮件列表} (以你的母语求助)
    \begin{itemize}
  \item \texttt{debian-devel-\{french,italian,portuguese,spanish\}@lists.d.o}
  \item 完整列表：\url{https://lists.debian.org/devel.html}
  \item 或者用户列表：\url{https://lists.debian.org/users.html}
  \end{itemize}
  \end{itemize}
\end{frame}

\subsection{更多说明文档}
\begin{frame}{更多说明文档}
  \begin{itemize}
  \item Debian 开发者圈子\\ \url{https://www.debian.org/devel/}\\ {\small
很多Debian开发方面的资源链接}
    \hbr
  \item Debian维护者指南\\ \url{https://www.debian.org/doc/manuals/debmake-doc/}
    \hbr
  \item Debian 开发者手册\\ \url{https://www.debian.org/doc/developers-reference/}\\ 
{\small 主要内容是关于Debian自身发展，但也有一些极好的打包实操 (part 6)}
    \hbr
  \item Debian 政策\\ \url{https://www.debian.org/doc/debian-policy/}\\
    
    {\small \begin{itemize} \item \small 这是每个软件包都必须达到的硬性要求 \item \small
针对Perl，Java，Python，\ldots 都有专用条款 \end{itemize}}
    \hbr
    
  \item Ubuntu 打包指南\\ \url{https://packaging.ubuntu.com/html/}
  \end{itemize}
\end{frame}

\subsection{Debian 维护者查询面板}
\begin{frame}{Debian 维护者查询面板}
  \begin{itemize}
	  \item \textbf{源码包中心}:\\ \url{https://tracker.debian.org/dpkg}
    \br
  \item \textbf{维护者/团队中心：}: Developer's Packages Overview (DDPO——开发者软件包概览)\\ 
\url{https://qa.debian.org/developer.php?login=pkg-ruby-extras-maintainers@lists.alioth.debian.org}
    \br
  \item \textbf{待办事项表：}: Debian Maintainer Dashboard (DMD——Debian维护者查询面板)\\ 
\url{https://udd.debian.org/dmd/}
  \end{itemize}
\end{frame}

\begin{frame}{使用Debian Bgu追踪系统（BTS）}
\begin{itemize}
\item 非常独特的bug管理方式
\begin{itemize}
\item 用web接口查看bug
\item 用Email接口更新bug
\end{itemize}
\hbr
\item 给bug添加相关信息：
	\begin{itemize}
		\item 发邮件给 \texttt{123456@bugs.debian.org} (不包括bug提交者，你得手动抄送给
\texttt{123456-submitter@bugs.debian.org})
	\end{itemize}
\hbr
\item 更新bug状态：
\begin{itemize}
\item 给 \texttt{control@bugs.debian.org} 发邮件
\item 命令行接口：在\texttt{devscripts} 里用\texttt{bts}命令
\item 说明文档：\url{https://www.debian.org/Bugs/server-control}
\end{itemize}
\hbr
\item 报告bug：用 \texttt{reportbug}
\begin{itemize}
\item 一般使用本地邮件服务器：安装 \texttt{ssmtp} 或者 \texttt{nullmailer}
\item 或者用 \texttt{reportbug -\@-template}, 然后 (手动) 发给
\texttt{submit@bugs.debian.org}
\end{itemize}
\end{itemize}
\end{frame}

\begin{frame}{使用BTS（bug追踪系统）：范例}
\begin{itemize}
\item 发邮件给bug和提交者：\\ 
\url{https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=680822\#10}
\hbr
\item 更改标签和更新严重程度：\\ 
\url{https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=680227\#10}
\hbr
\item 分配任务，更新严重度，重命名 \ldots: \\ 
\url{https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=680822\#93}
\begin{itemize}
	\item \texttt{notfound}, \texttt{found}, \texttt{notfixed}, \texttt{fixed}
是给\textbf{version-tracking}（版本追踪）提供的标签\\ 详见
\url{https://wiki.debian.org/HowtoUseBTS\#Version\_tracking}
\end{itemize}
\hbr
\item 使用用户标签：\url{https://bugs.debian.org/cgi-bin/bugreport.cgi?msg=42;bug=642267}\\ 
详见 \url{https://wiki.debian.org/bugs.debian.org/usertags}
\hbr
\item BTS说明文档：
\begin{itemize}
\item \url{https://www.debian.org/Bugs/}
\item \url{https://wiki.debian.org/HowtoUseBTS}
\end{itemize}
\end{itemize}
\end{frame}

\subsection{对Ubuntu更感兴趣？}
\begin{frame}{对Ubuntu更感兴趣？}
  \begin{itemize}
  \item Ubuntu主要管理与Debian的差异部分
    \br
  \item Ubuntu并不关注特定的软件包，\\ 而是与Debian团队合作 
    \br
  \item 通常情况下，推荐将新软件包先上传到Debian\\ 
\url{https://wiki.ubuntu.com/UbuntuDevelopment/NewPackages}
    \br
  \item 还有个更好的方案：
    \begin{itemize}
    \item 加入Debian团队然后负责与Ubuntu沟通
      \hbr
    \item 协助降低两者差异性，收集整理Launchpad里的bug
      \hbr
    \item 用好Debian的多种工具：
      \begin{itemize}
      \item 开发者软件包概览（Developer’s packages overview)里的Ubuntu部分
      \item 软件包追踪系统(Package Tracking System)里的Ubuntu内容
      \item 通过PTS收取launchpad的bugmail邮件
      \end{itemize}
    \end{itemize}
  \end{itemize}
\end{frame}

\section{结论}
\subsection{结论}
\begin{frame}{结论}
  \begin{itemize}
  \item 虽然你已经对Debian打包有了一个完整的大致印象
    \br
  \item 但你还需要阅读更多说明文档
    \br
  \item 最好的打包实操方法经过了多年的优化
    \begin{itemize}
    \item 如果不确定，就用\textbf{dh} 打包助手，以及\textbf{3.0 (quilt)}格式
    \end{itemize}
  \end{itemize}
  \vfill
  \centerline{\large 反馈： \textbf{packaging-tutorial@packages.debian.org}}
\end{frame}

\subsection{合规信息}
\begin{frame}{合规信息}

  版权所有 \copyright 2011--2019 Lucas Nussbaum -- lucas@debian.org
  \br

  {\small \textbf{该文档为自由软件}: 你可以随意传播/修改(以你自己的观点): \hbr \begin{itemize} \item
GNU General Public License（GPL——GNU通用公共证书）条款， 由Free Software
Foundation出版，在第三版或更新的后续版本中都有。\\ \url{http://www.gnu.org/licenses/gpl.html}
\br \item Creative Commons Attribution-ShareAlike 3.0 未发布证书条款。\\ 
\url{http://creativecommons.org/licenses/by-sa/3.0/} \end{itemize} }
\end{frame}

\subsection{为该教程做出贡献}
\begin{frame}{为该教程做出贡献}
	\begin{itemize}
		\item 贡献方式：
			\begin{itemize}
				\item{\small \texttt{apt-get source packaging-tutorial}}
					\hbr
				\item  {\small \texttt{debcheckout packaging-tutorial}}
					\hbr
				\item  {\small \texttt{git clone\\ 
https://salsa.debian.org/debian/packaging-tutorial.git}}
					\hbr
				\item {\small \url{https://salsa.debian.org/debian/packaging-tutorial}}
					\hbr
				\item {\small 已知bugs: \url{bugs.debian.org/src:packaging-tutorial}}
			\end{itemize}
			\br
		\item 提供反馈：
			\begin{itemize}
				\item \href{mailto:packaging-tutorial@packages.debian.org}{\textbf{\texttt{mailto:packaging-tutorial@packages.debian.org}}}
				\begin{itemize}
					\item{\small 还需要在教程里添加哪些内容？}
				\item {\small 还有哪些内容需要优化？}
				\end{itemize}
					\hbr
				\item{\small \texttt{reportbug packaging-tutorial}}
			\end{itemize}
	\end{itemize}
\end{frame}

\section{更多实操练习环节}

\subsection{实操练习环节2：打包GNUjump}
\begin{frame}{实操练习环节2：打包GNUjump}
	\begin{enumerate}
		\item 下载GNUjump 1.0.8 \url{http://ftp.gnu.org/gnu/gnujump/gnujump-1.0.8.tar.gz}
			\br
		\item 创建Debian软件包
			\begin{itemize}
				\item 安装构建依赖库，用于构建软件包
				\item 修复bug
				\item 获得基础工作包
				\item 填写\texttt{debian/control}和其他文件
			\end{itemize}
			\br
		\item 开搞
	\end{enumerate}
\centerline{\includegraphics[width=5cm]{figs/gnujump.png}}
\end{frame}

\begin{frame}[fragile=singleslide]{实操练习环节2：打包GNUjump（提示）}
	\begin{itemize}
		\item 要获得基础工作包，使用\texttt{dh\_make}
		\item 刚上手的话，可以先建一个\textsl{1.0} 格式的源码包，比\textsl{3.0 (quilt)}
简单一点（在\texttt{debian/source/format}里修改格式）
		\item 要搜索缺失的构建依赖库，可以找到缺失文件，使用 \texttt{apt-file} 来查找缺失软件包
		\item 如果你遇到错误：
\begin{lstlisting}[basicstyle=\ttfamily\tiny]
/usr/bin/ld: SDL_rotozoom.o: undefined reference to symbol 'ceil@@GLIBC_2.2.5'
//lib/x86_64-linux-gnu/libm.so.6: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
Makefile:376: recipe for target 'gnujump' failed
\end{lstlisting}
			你需要在关联命令行后加上 \texttt{-lm} ：\\ 编辑 \texttt{src/Makefile.am} 并将
\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
gnujump_LDFLAGS = $(all_libraries)
\end{lstlisting}
					替换为以下内容
\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
gnujump_LDFLAGS = -Wl,--as-needed
gnujump_LDADD = $(all_libraries) -lm
\end{lstlisting}
				然后运行 \texttt{autoreconf -i}
	\end{itemize}
\end{frame}

\subsection{实操练习环节3：打包Java库}
\begin{frame}{实操练习环节3：打包Java库}
\begin{enumerate}
	\item  快速浏览以下打包Java的说明文档：
		\begin{itemize}
		\item \url{https://wiki.debian.org/Java}
      \hbr
		\item \url{https://wiki.debian.org/Java/Packaging}
      \hbr
		\item \url{https://www.debian.org/doc/packaging-manuals/java-policy/}
      \hbr
		\item \texttt{/usr/share/doc/javahelper/tutorial.txt.gz}
		\end{itemize}
		\br
	\item 从\url{http://moepii.sourceforge.net/} 下载IRClib
		\br
	\item 打包
\end{enumerate}
\end{frame}

\subsection{实操练习环节4：打包Ruby库（Gem）}
\begin{frame}{实操练习环节4：打包Ruby库（Gem）}
\begin{enumerate}
	\item 快速浏览以下打包Ruby的说明文档：\\
		\begin{itemize}
		\item \url{https://wiki.debian.org/Ruby}
      \hbr
		\item \url{https://wiki.debian.org/Teams/Ruby}
      \hbr
		\item \url{https://wiki.debian.org/Teams/Ruby/Packaging}
      \hbr
		\item \texttt{gem2deb(1)}, \texttt{dh\_ruby(1)} (在\texttt{gem2deb} 软件包里)
		\end{itemize}
		\hbr
	\item 将\texttt{peach} 库创建成基础Debian源码包：\\ \texttt{gem2deb peach}
	\hbr
	\item 把它优化成合格的Debian软件包
\end{enumerate}
\end{frame}

\subsection{实操练习环节5：打包Perl模组}
\begin{frame}[fragile=singleslide]{实操练习环节5：打包Perl模组}
\begin{enumerate}
	\item 快速浏览以下打包Perl的说明文档：
		\begin{itemize}
		\item \url{https://perl-team.pages.debian.net}
      \hbr
		\item \url{https://wiki.debian.org/Teams/DebianPerlGroup}
      \hbr
		\item \texttt{dh-make-perl(1)}, \texttt{dpt(1)} (在\texttt{pkg-perl-tools} 软件包里)
		\end{itemize}
		\hbr
	\item 将 \texttt{Acme} 的CPAN发行版创建成基础Debian源码包：\\ \verb|dh-make-perl --cpan Acme|
	\hbr
	\item 把它优化成合格的Debian软件包
\end{enumerate}
\end{frame}

\section{实操练习环节解答}

\begin{frame}
	\begin{center}
		解答\\[0.5em] 实操练习环节
	\end{center}
\end{frame}


\subsection{实操练习环节1：修改grep软件包}

\begin{frame}{实操练习环节1：修改grep软件包}
\begin{enumerate}
  \item 访问 \url{http://ftp.debian.org/debian/pool/main/g/grep/} 并下载 2.12-2版本的grep软件包

	\item 查看 \texttt{debian/} 目录下的文件。
		\begin{itemize}
			\item 		此源码包生成了多少个程序文件包？
			\item 		此软件包用了哪个打包助手？
		\end{itemize}
    \hbr
	\item 构建软件包
    \hbr
	\item 现在我们要修改这个软件包。添加一条更新记录并且增加一位版本号。
    \hbr
	\item 然后停用perl-regexp的支持（这是 \texttt{./configure} 里的一条选项）
    \hbr
	\item 重构软件包
    \hbr
	\item 用debdiff对比原版和新版软件包的区别
    \hbr
	\item 安装新构建的软件包
\end{enumerate}
\end{frame}

\begin{frame}{获取源代码}
\begin{enumerate}
  \item 访问 \url{http://ftp.debian.org/debian/pool/main/g/grep/} 并下载 2.12-2版本的grep软件包
\end{enumerate}
\begin{itemize}
	\item 用dget命令下载\texttt{.dsc} 文件：\\ {\small \texttt{dget
http://cdn.debian.net/debian/pool/main/g/grep/grep\_2.12-2.dsc}}
		\hbr
	\item 如果你的Debian版本里的 \texttt{deb-src} 有2.12-2版的 \texttt{grep} (可以在
\url{https://tracker.debian.org/grep} 查询)，你可以：\texttt{apt-get source
grep=2.12-2}\\ 或 \texttt{apt-get source grep/release}
(例如\texttt{grep/stable})\\ 或者，干脆直接：\texttt{apt-get source grep}
	\hbr
	\item \texttt{grep}源码包由以下三个文件构成
		\begin{itemize}
			\item \texttt{grep\_2.12-2.dsc}
			\item \texttt{grep\_2.12-2.debian.tar.bz2}
			\item \texttt{grep\_2.12.orig.tar.bz2}
		\end{itemize}
		这是典型的"3.0 (quilt)"格式。
	\hbr
\item 如果有需要可以解压缩源码文件\\ \texttt{dpkg-source -x grep\_2.12-2.dsc}
\end{itemize}
\end{frame}

\begin{frame}{查看一下各个文件，然后构建软件包}
	\begin{enumerate}
			\setcounter{enumi}{1}
	\item 查看\texttt{debian/} 下的文件
		\begin{itemize}
			\item 		此源码包生成了多少个程序文件包？
			\item 		此软件包用了哪个打包助手？
		\end{itemize}
	\end{enumerate}
	\hbr
	\begin{itemize}
		\item 根据\texttt{debian/control}，该源码包只生成了一个程序文件包，名为 \texttt{grep}.
			\hbr
		\item 根据\texttt{debian/rules}， 该软件包用\textsl{经典} debhelper 打包，而没有用\textsl{CDBS} 或
\textsl{dh}。可以发现在\texttt{debian/rules} 里调用了大量\texttt{dh\_*}命令。
	\end{itemize}
	\hbr
	\begin{enumerate}
			\setcounter{enumi}{2}

		\item 构建软件包
	\end{enumerate}
	\hbr
	\begin{itemize}
		\item 先用\texttt{apt-get build-dep grep} 命令获取构建依赖库
		\item 再用 \texttt{debuild} 或 \texttt{dpkg-buildpackage -us -uc}命令（耗时约1 分钟）
	\end{itemize}
\end{frame}

\begin{frame}{编辑更新日志}
	\begin{enumerate}
			\setcounter{enumi}{3}

	\item 现在我们要修改这个软件包。添加一条更新记录并且增加一位版本号。
	\end{enumerate}
	\hbr
	\begin{itemize}
		\item \texttt{debian/changelog} 是个文本文件。你可以手动编辑并添加条目。
	\hbr
		\item  或者你也可以用\texttt{dch -i}来添加条目并打开编辑器
	\hbr
		\item 姓名和邮件可以通过环境变量 \texttt{DEBFULLNAME} 和 \texttt{DEBEMAIL} 来定义
	\hbr
		\item 做完这些再重构一下软件包：这样新版本的软件包就构建好了
	\hbr
		\item 软件包的版本号使用规则在Debian政策 5.6.12章节有详细阐述。\\ 
\url{https://www.debian.org/doc/debian-policy/ch-controlfields}
	\end{itemize}
\end{frame}

\begin{frame}{停用Perl regexp支持并重构}
	\begin{enumerate}
			\setcounter{enumi}{4}

	\item 然后停用perl-regexp的支持（这是 \texttt{./configure} 里的一条选项）
	\item 重构软件包
	\end{enumerate}
	\hbr
	\begin{itemize}
	  \item 用\texttt{./configure -{}-help}命令查看: 停用Perl regexp的选项是
\texttt{-{}-disable-perl-regexp}
	\hbr
		\item 编辑 \texttt{debian/rules}文件，找到\texttt{./configure} 所在行
	\hbr
		\item 在命令后添加\texttt{-{}-disable-perl-regexp}
	\hbr
		\item 用\texttt{debuild} 或 \texttt{dpkg-buildpackage -us -uc} 命令重构
	\end{itemize}
\end{frame}

\begin{frame}{对比和测试软件包}
	\begin{enumerate}
			\setcounter{enumi}{6}

	\item 用debdiff对比原版和新版软件包的区别
	\item 安装新构建的软件包
	\end{enumerate}
	\hbr
	\begin{itemize}
		\item 对比程序文件包：\texttt{debdiff ../*changes}
	\hbr
		\item 对比源码包：\texttt{debdiff ../*dsc}
	\hbr
		\item 安装新构建的软件包: \texttt{debi}\\ 或 \texttt{dpkg -i ../grep\_<TAB>}
	\hbr
		\item \texttt{grep -P foo} 已经失效！
	\end{itemize}
\br
重装上一版本的软件包：
\begin{itemize}
	\item \texttt{apt-get install -{}-reinstall grep=2.6.3-3} \textit{(= 上个版本)}
\end{itemize}
\end{frame}

\subsection{实操练习环节2：打包GNUjump}
\begin{frame}{实操练习环节2：打包GNUjump}
\begin{enumerate}
	\item 下载GNUjump 1.0.8 \url{http://ftp.gnu.org/gnu/gnujump/gnujump-1.0.8.tar.gz}
		\br
	\item 创建Debian软件包
		\begin{itemize}
			\item 安装构建依赖库，用于构建软件包
			\item 获得基础工作包
			\item 填写\texttt{debian/control}和其他文件
		\end{itemize}
		\br
	\item 开搞
\end{enumerate}
\centerline{\includegraphics[width=5cm]{figs/gnujump.png}}
\end{frame}

\begin{frame}[fragile=singleslide]{具体步骤\ldots}
\begin{itemize}
	\item \texttt{wget http://ftp.gnu.org/gnu/gnujump/gnujump-1.0.8.tar.gz}
		\hbr
	\item \texttt{mv gnujump-1.0.8.tar.gz gnujump\_1.0.8.orig.tar.gz}
		\hbr
	\item \texttt{tar xf gnujump\_1.0.8.orig.tar.gz}
		\hbr
	\item \texttt{cd gnujump-1.0.8/}
		\hbr
	\item \texttt{dh\_make -f ../gnujump-1.0.8.tar.gz}
	\begin{itemize}
		\item \small 当前软件包类型：单程序文件（暂时）
	\end{itemize}
\end{itemize}
\begin{lstlisting}[basicstyle=\ttfamily\small]
gnujump-1.0.8$ ls debian/
changelog           gnujump.default.ex   preinst.ex
compat              gnujump.doc-base.EX  prerm.ex
control             init.d.ex            README.Debian
copyright           manpage.1.ex         README.source
docs                manpage.sgml.ex      rules
emacsen-install.ex  manpage.xml.ex       source
emacsen-remove.ex   menu.ex              watch.ex
emacsen-startup.ex  postinst.ex
gnujump.cron.d.ex   postrm.ex
\end{lstlisting}
\end{frame}

\begin{frame}[fragile=singleslide]{具体步骤\ldots (2)}
\begin{itemize}
	\item 查看\texttt{debian/changelog}, \texttt{debian/rules},
\texttt{debian/control}\\ （由\textbf{dh\_make}自动填写）
		\hbr
	\item \texttt{debian/control}文件内容：\\ \texttt{Build-Depends: debhelper (>=
7.0.50~), autotools-dev}\\ 用\textsl{build-dependencies} = 构建所需软件包名称
的格式列出构建依赖库
		\hbr
	\item 尝试用\texttt{debuild}的“像xx一样”功能构建软件包（得益于\textbf{dh}的神奇功能）
		\begin{itemize}
			\item 然后添加构建依赖库，开始构建
			\item 提示：用\texttt{apt-cache search} 和\texttt{apt-file}命令查找软件包 
			\item 例如：
\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
checking for sdl-config... no
checking for SDL - version >= 1.2.0... no
[...]
configure: error: *** SDL version 1.2.0 not found!
\end{lstlisting}
$\rightarrow$ 将\textbf{libsdl1.2-dev}添加到构建依赖库并安装。
		\hbr
	\item 如果可以尽量用\textbf{pbuilder}在干净的系统环境里构建。
		\end{itemize}
\end{itemize}
\end{frame}

\begin{frame}[fragile=singleslide]{具体步骤\ldots (3)}
	\begin{itemize}
		\item 用到的构建依赖库有 \texttt{libsdl1.2-dev, libsdl-image1.2-dev, libsdl-mixer1.2-dev}

		\item 接下来你大概又会遇到如下错误：
	\end{itemize}
	\begin{lstlisting}[basicstyle=\ttfamily\tiny]
	/usr/bin/ld: SDL_rotozoom.o: undefined reference to symbol 'ceil@@GLIBC_2.2.5'
	//lib/x86_64-linux-gnu/libm.so.6: error adding symbols: DSO missing from command line
	collect2: error: ld returned 1 exit status
	Makefile:376: recipe for target 'gnujump' failed
	\end{lstlisting}
	\begin{itemize}
		\item 这个问题是bitrot产生的：gnujump没有跟着调整文件连接
		\item 如果你用的是源码格式版本\textbf{1.0}，你可以直接改上游源代码。
			\begin{itemize}
				\item 编辑 \texttt{src/Makefile.am}，将
\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
gnujump_LDFLAGS = $(all_libraries)
\end{lstlisting}
					替换为以下内容
\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
gnujump_LDFLAGS = -Wl,--as-needed
gnujump_LDADD = $(all_libraries) -lm
\end{lstlisting}
				\item 然后运行 \texttt{autoreconf -i}
			\end{itemize}
	\end{itemize}
\end{frame}

\begin{frame}[fragile=singleslide]{具体步骤\ldots (4)}
\begin{itemize}
	\item 如果你用的是源码格式版本 \textbf{3.0 (quilt)}，就用 \texttt{quilt} 命令制作补丁文件。（详见
\url{https://wiki.debian.org/UsingQuilt}）
\begin{itemize}
\item \texttt{export QUILT\_PATCHES=debian/patches}
\item \texttt{mkdir debian/patches}\\ \texttt{quilt new linker-fixes.patch}\\ 
\texttt{quilt add src/Makefile.am}\\
\hbr
\item 编辑 \texttt{src/Makefile.am}，将
\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
gnujump_LDFLAGS = $(all_libraries)
\end{lstlisting}
替换为以下内容
\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
gnujump_LDFLAGS = -Wl,--as-needed
gnujump_LDADD = $(all_libraries) -lm
\end{lstlisting}
\hbr
\item \texttt{quilt refresh}
	\hbr
	\item 因为修改了
\texttt{src/Makefile.am}，所以在构建时要调用一下autoreconf。用\texttt{dh}命令可以自动调用，将\texttt{debian/rules}里的\texttt{dh}调用代码块从：\texttt{dh
\$\@ -{}-with autotools-dev}\\ 改成：\texttt{dh \$\@ -{}-with autotools-dev
-{}-with autoreconf}
		\hbr
\end{itemize}
\end{itemize}
\end{frame}


\begin{frame}[fragile=singleslide]{具体步骤\ldots (5)}
\begin{itemize}
	\item 现在软件包已经能正常构建了
		\hbr
	\item 用\texttt{debc} 列出所生成的软件包内容，用\texttt{debi}安装并测试。
		\hbr
	\item 用\texttt{lintian}测试软件包
		\begin{itemize}
			\item 虽然不是必须，但强烈推荐上传到Debian的软件包都是\textsl{lintian-clean}（lintian测试无误）的
		\hbr
			\item 更多问题可以用\texttt{lintian -EviIL +pedantic} 命令列出来
		\hbr
			\item 几条提醒：
				\begin{itemize}
					\item 将\texttt{debian/}里不需要的文件删掉
		\hbr
					\item 填写\texttt{debian/control}
						\hbr
					\item 修改\texttt{dh\_auto\_configure} 来将可执行文件安装到\texttt{/usr/games} 
		\hbr
					\item 利用\textsl{hardening} compiler flags（硬化编译器标识）增加安全性。\\ 
详见\url{https://wiki.debian.org/Hardening}
				\end{itemize}
		\end{itemize}
\end{itemize}
\end{frame}

\begin{frame}{具体步骤\ldots (6)}
		\begin{itemize}
	\item 将你的软件包与Debian中现有的软件包进行对比
		\begin{itemize}
			\item 你的软件包在所有架构下统一地将data数据文件分离到了另一个软件包里（$\rightarrow$ 节约了Debian档案库的空间）
				\hbr
			\item 你的软件包装有.desktop文件（用于GNOME/KDE菜单）并将其整合进了Debian菜单
				\hbr
			\item 你的软件包用补丁修复了几个小问题
		\end{itemize}
\end{itemize}
\end{frame}

\subsection{实操练习环节3：打包Java库}
\begin{frame}{实操练习环节3：打包Java库}
\begin{enumerate}
	\item  快速浏览以下打包Java的说明文档：
		\begin{itemize}
		\item \url{https://wiki.debian.org/Java}
      \hbr
		\item \url{https://wiki.debian.org/Java/Packaging}
      \hbr
		\item \url{https://www.debian.org/doc/packaging-manuals/java-policy/}
      \hbr
		\item \texttt{/usr/share/doc/javahelper/tutorial.txt.gz}
		\end{itemize}
		\br
	\item 从\url{http://moepii.sourceforge.net/} 下载IRClib
		\br
	\item 打包
\end{enumerate}
\end{frame}

\begin{frame}{具体步骤\ldots}
\begin{itemize}
	\item \texttt{apt-get install javahelper}
		\hbr
	\item 创建基础源码包：\texttt{jh\_makepkg}
		\begin{itemize}
			\item 库
			\item 空
			\item 默认免费编译器/运行环境
		\end{itemize}
		\hbr
	\item 查看并修正\texttt{debian/*}
		\hbr
	\item \texttt{dpkg-buildpackage -us -uc} 或 \texttt{debuild}
		\hbr
	\item \texttt{lintian}, \texttt{debc}, 等等
		\hbr
	\item 将你的结果与\texttt{libirclib-java}源码包进行对比
\end{itemize}
\end{frame}

\subsection{实操练习环节4：打包Ruby库（Gem）}
\begin{frame}{实操练习环节4：打包Ruby库（Gem）}
\begin{enumerate}
	\item 快速浏览以下打包Ruby的说明文档：\\
		\begin{itemize}
		\item \url{https://wiki.debian.org/Ruby}
      \hbr
		\item \url{https://wiki.debian.org/Teams/Ruby}
      \hbr
		\item \url{https://wiki.debian.org/Teams/Ruby/Packaging}
      \hbr
		\item \texttt{gem2deb(1)}, \texttt{dh\_ruby(1)} (在\texttt{gem2deb} 软件包里)
		\end{itemize}
		\hbr
	\item 将\texttt{peach} 库创建成基础Debian源码包：\\ \texttt{gem2deb peach}
	\hbr
	\item 把它优化成合格的Debian软件包
\end{enumerate}
\end{frame}

\begin{frame}{具体步骤\ldots}
\texttt{gem2deb peach}:
\begin{itemize}
\item 从rubygems.org下载gem库
\item 创建合适的.orig.tar.gz压缩文件，然后解压缩
\item 基于gem库的元数据初始化一个Debian源码包
	\begin{itemize}
		\item 命名为\texttt{ruby-\textsl{gemname}}
	\end{itemize}
\item 尝试构建Debian程序文件包（可能会失败）
\end{itemize}
\br
\texttt{dh\_ruby} (包含在 \textsl{gem2deb}内) 命令可以完成Ruby专属任务：
\begin{itemize}
	\item 为每个Ruby版本构建C语言扩展
	\item 把文件复制到目标目录
	\item 更新可执行脚本的shebang开头
	\item 运行\texttt{debian/ruby-tests.rb}, \texttt{debian/ruby-tests.rake}, 或
\texttt{debian/ruby-test-files.yaml}, 里定义地测试，以及其他各项检测
\end{itemize}
\end{frame}

\begin{frame}[fragile=singleslide]{具体步骤\ldots (2)}
优化生成的软件包：
\begin{itemize}
	\item 运行\texttt{debclean}清理源码结构，查看\texttt{debian/}。
		\hbr
	\item \texttt{changelog} 和 \texttt{compat}必须准确无误
		\hbr
	\item 编辑\texttt{debian/control}：优化\texttt{Description}
		\hbr
	\item 基于上游文件编写正确的\texttt{copyright}版权文件
		\hbr
	\item 构建软件包
		\hbr
	\item 将你的软件包与Debian档案库的\texttt{ruby-peach}软件包进行对比
\end{itemize}
\end{frame}

\subsection{实操练习环节5：打包Perl模组}
\begin{frame}[fragile=singleslide]{实操练习环节5：打包Perl模组}
\begin{enumerate}
	\item 快速浏览以下打包Perl的说明文档：
		\begin{itemize}
		\item \url{https://perl-team.pages.debian.net}
      \hbr
		\item \url{https://wiki.debian.org/Teams/DebianPerlGroup}
      \hbr
		\item \texttt{dh-make-perl(1)}, \texttt{dpt(1)} (在\texttt{pkg-perl-tools} 软件包里)
		\end{itemize}
		\hbr
	\item 将 \texttt{Acme} 的CPAN发行版创建成基础Debian源码包：\\ \verb|dh-make-perl --cpan Acme|
	\hbr
	\item 把它优化成合格的Debian软件包
\end{enumerate}
\end{frame}

\begin{frame}[fragile=singleslide]{具体步骤\ldots}
\verb|dh-make-perl --cpan Acme|:
\begin{itemize}
\item 从CPAN下载压缩包
\item 创建合适的.orig.tar.gz压缩文件，然后解压缩
\item 基于分发文件的元数据初始化一份Debian源码包
	\begin{itemize}
		\item 命名为 \texttt{lib\textsl{distname}-perl}
	\end{itemize}
\end{itemize}
\end{frame}

\begin{frame}[fragile=singleslide]{具体步骤\ldots (2)}
优化生成的软件包：
\begin{itemize}
	\item 确保\texttt{debian/changelog}, \texttt{debian/compat},
\texttt{debian/libacme-perl.docs}, 和 \texttt{debian/watch} 文件都准确无误
		\hbr
	\item 编辑 \texttt{debian/control}: 优化 \texttt{Description}, 删除 底下的自动模板代码
		\hbr
	\item 编辑 \texttt{debian/copyright}: 删除顶上的样板代码，在\texttt{Files:\hspace{0.3em}*}
那节添加版权年份
\end{itemize}
\end{frame}


\section*{翻译}
\begin{frame}{翻译}
 本教程由Nessaj Wang 翻译为简体中文
 \hbr

 若您想对翻译内容提出意见，请发邮件至
 \href{mailto:debian-l10n-chinese@lists.debian.org}{\texttt{<debian-l10n-chinese@lists.debian.org>}}.
\end{frame}
\end{document}
