如何製作「deb檔(Debian Package)」

測試環境

以下測試是在「Xubuntu 14.04 64位元」。

執行步驟

準備工作環境

建立工作環境資料夾

$ mkdir ~/Templates/build-debian-package -p

切換到工作環境資料夾

$ cd ~/Templates/build-debian-package

建立套件最上層資料夾

建立一個資料夾「try」,這個是「套件最上層資料夾」,所有的檔案都要放在這裡面

$ mkdir try -p

建立「DEBIAN」資料夾

建立「try/DEBIAN」資料夾,這個資料夾是建立「Debian Package」的依據資料夾。

$ mkdir try/DEBIAN -p

建立「control」檔

建立「try/DEBIAN/control」檔,這個檔是建立「Debian Package」的依據檔案。

$ touch try/DEBIAN/control

觀看目錄結構

觀看一下剛剛建立的目錄結構

$ tree try

會顯示

try
└── DEBIAN
    └── control

1 directory, 1 file

開始製作「Debian Package」

可以執行

$ dpkg -b try

或是執行

$ dpkg --build try

或是執行

$ dpkg-deb -b try

或是執行

$ dpkg-deb --build try

會顯示一個訊息

dpkg-deb: error: no package information in `try/DEBIAN/control'

在「control」加上「Package:」

我們先在「control」這個檔加上下面這一行

Package: try

可以用擅長的編輯器編輯。

也可以直接執行下面的指令直接產生。

$ echo 'Package: try' > try/DEBIAN/control

觀看內容

$ cat try/DEBIAN/control

會顯示

Package: try

再次執行下面指令,製作「Debian Package」

$ dpkg -b try

這時候就會顯示下面的訊息

dpkg-deb: warning: parsing file 'try/DEBIAN/control' near line 2 package 'try':
 missing description
dpkg-deb: warning: parsing file 'try/DEBIAN/control' near line 2 package 'try':
 missing maintainer
dpkg-deb: error: parsing file 'try/DEBIAN/control' near line 2 package 'try':
 missing version

在「control」加上「Version:」

我們在「control」這個檔,附加上下面這一行

Version: 0.1

可以用擅長的編輯器編輯。

也可以直接執行下面的指令直接產生。

$ echo 'Version: 0.1' >> try/DEBIAN/control

觀看內容

$ cat try/DEBIAN/control

會顯示

Package: try
Version: 0.1

再次執行下面指令,製作「Debian Package」

$ dpkg -b try

這時候就會顯示下面的訊息

dpkg-deb: warning: parsing file 'try/DEBIAN/control' near line 3 package 'try':
 missing description
dpkg-deb: warning: parsing file 'try/DEBIAN/control' near line 3 package 'try':
 missing maintainer
dpkg-deb: warning: parsing file 'try/DEBIAN/control' near line 3 package 'try':
 missing architecture
dpkg-deb: warning: ignoring 3 warnings about the control file(s)

dpkg-deb: building package `try' in `try.deb'.

並且產生一個檔,叫做「try.deb」

$ ls -1

可以看到

try
try.deb

把一些欄位補足

依據上面的提示訊息,把「architecture」「description」「maintainer」這幾個欄位補足吧

執行下面的指令

echo 'Architecture: all' >> try/DEBIAN/control
echo 'Description: This is a test package.' >> try/DEBIAN/control
echo 'Maintainer: developer <developer@hell.heaven>' >> try/DEBIAN/control

觀看內容

$ cat try/DEBIAN/control

會顯示

Package: try
Version: 0.1
Architecture: all
Description: This is a test package.
Maintainer: developer <developer@hell.heaven>

再次執行下面指令,製作「Debian Package」

$ dpkg -b try

這時候就會顯示下面的訊息

dpkg-deb: building package `try' in `try.deb'.

觀看「deb檔」的訊息

執行

$ dpkg -I try.deb

會顯示

 new debian package, version 2.0.
 size 594 bytes: control archive=241 bytes.
     127 bytes,     5 lines      control
 Package: try
 Version: 0.1
 Architecture: all
 Description: This is a test package.
 Maintainer: developer <developer@hell.heaven>

執行

$ dpkg -f try.deb

會顯示

Package: try
Version: 0.1
Architecture: all
Description: This is a test package.
Maintainer: developer <developer@hell.heaven>

執行

$ dpkg -c try.deb

會顯示(以下的「user/user」會依據你的「帳號」和「所屬群組」而定)

drwxrwxr-x user/user           0 2015-05-06 15:57 ./

測試安裝

執行

$ sudo dpkg -i try.deb

會顯示

[sudo] password for user:

輸入正確密碼,按下「Enter」

會顯示下面的訊息

Selecting previously unselected package try.
(Reading database ... 947302 files and directories currently installed.)
Preparing to unpack try.deb ...
Unpacking try (0.1) ...
Setting up try (0.1) ...

觀看安裝到系統的狀況

執行

$ dpkg -l try

會顯示

Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name                         Version             Architecture        Description
+++-============================-===================-===================-==============================================================
ii  try                          0.1                 all                 This is a test package.

執行

dpkg --get-selections | grep try

會顯示

...略...
try                                             install

執行

$ dpkg -s try

會顯示

Package: try
Status: install ok installed
Maintainer: developer <developer@hell.heaven>
Architecture: all
Version: 0.1
Description: This is a test package.

觀看「/var/lib/dpkg/status」的紀錄

$ cat /var/lib/dpkg/status | grep 'Package: try' -A 5

會顯示

Package: try
Status: install ok installed
Maintainer: developer <developer@hell.heaven>
Architecture: all
Version: 0.1
Description: This is a test package.

觀看「/var/lib/dpkg/available」的紀錄

$ cat /var/lib/dpkg/available | grep 'Package: try' -A 5

會顯示

Package: try
Maintainer: developer <developer@hell.heaven>
Architecture: all
Version: 0.1
Size: 594
Description: This is a test package.

觀看「try」這個套件,安裝了哪些檔案在系統上

$ dpkg -L try

會顯示

/.

加入一個檔案

產生一個「try.txt」。

$ touch > try/try.txt

然後編寫內容

$ echo hi > try/try.txt

觀看一下目前的目錄結構

$ tree

會顯示

.
├── try
│   ├── DEBIAN
│   │   └── control
│   └── try.txt
└── try.deb

2 directories, 3 files

然後執行

$ dpkg -b try

執行安裝

$ sudo dpkg -i try.deb

會顯示

(Reading database ... 947302 files and directories currently installed.)
Preparing to unpack try.deb ...
Unpacking try (0.1) over (0.1) ...
Setting up try (0.1) ...

觀看「try」這個套件,安裝了哪些檔案在系統上

$ dpkg -L try

會顯示

/.
/try.txt

觀看「/」底下,是否有「try.txt」這個檔

ls /try.txt -l

會顯示

-rw-rw-r-- 1 user user 3 May  6 18:38 /try.txt

也就是「try」會對應到「/」,「try」底下有哪些檔案,就會裝到「/」底下,「DEBIAN」這個資料夾則是例外。

檔案命名

剛利用「dpkg -b try」製作「Debian Package」,會產生一個「try.deb」檔。

然後也可以有不同的方式

先產生一個 [build]的資料夾,可以隨意命名,不見得要叫「build」

$ mkdir build

觀看一下目前的檔案結構

$ tree

顯示

.
.
├── build
├── try
│   ├── DEBIAN
│   │   └── control
│   └── try.txt
└── try.deb

3 directories, 3 files

執行下面的指令

dpkg -b try build

會顯示下面的訊息

$ dpkg-deb: building package `try' in `build/try_0.1_all.deb'.

也就是會在「build」這個資料夾,產生「try_0.1_all.deb」, 格式是「Package_Version_Architecture.deb」。 也就是依據剛剛的「try/DEBIAN/control」裡面設定的資料來命名的。 當「dpkg -b try」後面接「資料夾」參數時候,就會依照這樣的規則去命名。

更多的命名規則可以執行下面的指令

$ man dpkg-deb

會看到其中有一段

       -b, --build directory [archive|directory]
              Creates a debian archive from the filesystem tree stored in directory. directory must have a DEBIAN subdirectory,  which
              contains  the  control  information  files such as the control file itself. This directory will not appear in the binary
              package's filesystem archive, but instead the files in it will be put in the binary package's control information area.

              Unless you specify --nocheck, dpkg-deb will read DEBIAN/control and parse it. It will check it  for  syntax  errors  and
              other problems, and display the name of the binary package being built.  dpkg-deb will also check the permissions of the
              maintainer scripts and other files found in the DEBIAN control information directory.

              If no archive is specified then dpkg-deb will write the package into the file directory.deb.

              If the archive to be created already exists it will be overwritten.

              If the second argument is a directory then dpkg-deb will write to the  file  package_version_arch.deb,  or  package_ver‐
              sion.deb  if  no Architecture field is present in the package control file. When a target directory is specified, rather
              than a file, the --nocheck option may not be used (since dpkg-deb needs to read and parse the package  control  file  to
              determine which filename to use).

control欄位說明文件

執行下面的指令,就可以看到control的欄位說明

$ man deb-control

可以看到

REQUIRED FIELDS
       Package: package-name
              The value of this field determines the package name, and is used to generate file names by most installation tools.

       Version: version-string
              Typically, this is the original package's version number in whatever form the program's author uses. It may also include
              a Debian revision number (for non-native packages). The exact format and sorting algorithm  are  described  in  deb-ver‐
              sion(5).

       Maintainer: fullname-email
              Should  be in the format `Joe Bloggs <jbloggs@foo.com>', and is typically the person who created the package, as opposed
              to the author of the software that was packaged.

       Description: short-description
               long-description
              The format for the package description is a short brief summary on the first line (after the "Description"  field).  The
              following  lines  should  be used as a longer, more detailed description. Each line of the long description must be pre‐
              ceded by a space, and blank lines in the long description must contain a single '.' following the preceding space.

OPTIONAL FIELDS

    ...略...

       Architecture: arch|all
              The  architecture  specifies  which  type  of  hardware  this package was compiled for. Common architectures are `i386',
              `m68k', `sparc', `alpha', `powerpc' etc. Note that the all option is meant for packages that are  architecture  indepen‐
              dent. Some examples of this are shell and Perl scripts, and documentation.

    ...略...

不過我測試安裝的時候,「Architecture」應該是必填,不然會出錯。

還有執行 「dpkg -l try」會出現四個欄位, 「Name」「Version」「Architecture」「Description」。 「Architecture」在其中之一。

更多參考

這篇我主要是因為閱讀了「這篇」後的「啟發」,

不然現在的工具都是在上面架上一層。

先了解這基本的原理後, 再來了解,更多的工具的使用, 還有怎麼重新編譯「Source Package」。

還有「DEBIAN」底下的其他檔的功用。

control
conffiles
preinst
postinst
prerm
postrm
triggers

另外附上最近發現的影片