Convert FLAC to MP3
这个文档 ABS - The Arch Build System 提供了一份良好的用于制作和修改 Arch Linux 软件包所需工具和文件的总览。如果你只想要定制或重新编译一个已经存在的软件包，这里应该已经提供了足够的信息。但是，如果你想要制作一个新的软件包，你还需要一些额外的指南。这个文档假定你已经事先阅读并掌握了 ABS 的描述。
pacman -Up <package file> 命令将其安装。
PKGBUILD 文件包含 所有 用于制作一个软件包所需的指令，这些指令以能够被 bash 识别的的格式存在(don't worry if that little tidbit of clue doesn't help you)。 ABS 条目中描述了这里使用的变量，但是最重要的也是最让人迷惑的变量在这里recapped。为了开始制作一个新的包，你应该首先创建一个空的目录，最好取名为
/var/abs/local/<PKGNAME>。这样的话，它可以很好的统一到统一的 ABS 树，但如果你没有同步该树的话，cvsup 不会接触(touch)它。进入你新建的目录，创建
- pkgname: 将这个变量设置为你的包的名字。按照惯例，你应该使用小写字母。最好包的名字与你所在的工作目录的名字相同，当然也与你将要下载的包含源程序的 tar.gz 文件名相同，但这并不是必须的。
- pkgver: 设置包的版本。它可以包含字母、数字和点，但不能有连字符。它由你打包的程序使用的版本系统决定（主版本.次版本.漏洞修复版本、major.日期等）。另外，在大多数情况下，你可以遵循源代码包的文件名的一部分的版本，以便后续步骤变得更为简单和灵活。还要注意：如果包的作者在其版本编号方案中使用了短横，请用下划线替代它。('0.99-10' => '0.99_10')
- pkgrel: 这个变量从 1 开始，你每重新发布一次，其值将增加 1 ，它的目的是区分一个包的同一版本的连续构建。有时候第一次发布的包有问题或错误。当你第二次发布这个包时，你将
pkgrel变量加 1 ，这样 pacman 知道它需要重新安装。当这个包又发布了一个新的 版本 时，你将
- pkgdesc: 该变量为该包的简短的描述，通常应该少于 76 个字符。通常并需要重复程序的名字。
OpenGL accelerated X server优于
xgl is a OpenGL...。
- arch: 该变量应该为架构的名称，通常为 'i686' ，它描述的是该 PKGBUILD 文件能够使用的架构。你可以在构建过程中使用
- url: 该变量为程序的官方站点的地址，这样有兴趣的人可以由此获得更多的信息。
- license: 许可的类型，如果你不知道，请将其写成 'unknow' 。
- depends: 该变量为在该程序能够运行前所必须安装的一系列包的名字的序列，用空格分开每个包名。这些包名可以用单引号引起来，以避免可能的 shell quoting 的问题，并且该序列必须用圆括号括起来。有时，一个程序需要一个最低版本的依赖；在这种情况下，请将数学上的 "大于 或 等于" 运算符，并将这些运算符也放在引号里。这里是一个添加 glibc 包的依赖的实例，slang 库的版本至少应为 1.8.0 ：
- makedepends: 该变量为只是在打包过程中需要而在安装后的*使用*过程中并不需要的包的名字的序列。举例：
- provides: 该变量为因为即将构建的包提供了相同的作用而变得不再需要的包的名字的序列。
- conflicts: 该变量为安装该包后会产生问题的包的名字的序列。
- replaces: 该变量为即将构建的包可以替代的陈旧的包的名字的序列。
- source: 该变量为构建该包所需文件的序列，至少应包含程序源的地址，在大多数情况下是一个完整的用双引号引起来的 http 或 ftp 地址。 这里的
PKGBUILD放在同一目录即可，然后将补丁的文件名添加在 source 的序列中。任何你在此添加的路径为相对于
- md5sums: 源文件的 md5 检查值，用空格分开，并用引号引起来。当 source 序列中的所有文件都存在时，每个文件的 md5 计算值将自动产生并于这里提供的值对照，这些值的顺序应与 source 序列中的顺序相同. 同时，源文件本身的顺序并不重要，重要的是与 md5sums 的顺序一致，因为
makepkg不会猜测 md5sums 属于哪个源文件，所以如果他们不能匹配，则会开始报错，这样可以防止下载错误或程序被篡改。你可以在包含
makepkg -g命令简单的得到 md5sums (在你将源序列正确的设置后) 。
makepkg -g >>PKGBUILD将生成这些 sums 并将其附在
到目前为止，你只是把与包有关的 meta-信息 设置好了；到哪去下载源代码，包的名字是什么等。下一步是补充如何实际 编译和安装 你将打包的程序的指令。
Using the source
Now you should download the source tarball, extract it, and note all commands needed to compile and install it. The contents of the
build() function in your
PKGBUILD will do nothing but run exactly these steps again, with a little glue to pack everything up once compilation is done.
Now you probably need to edit the contents of the build() function in the
PKGBUILD. This function uses common shell commands in the bash syntax. The basic purpose of this function is to automatically compile the programs and create a
pkg directory to install the program to, allowing
makepkg to pack it all up easily without having to pick all interesting files from your "live" filesystem.
The build() function
Usually the first step in the build function is to change into one of the directories created by uncompressing the source files. You can use the
$startdir variable to do this (it refers to the directory that contains the
PKGBUILD). You may also use the $pkgname and $pkgver variables that you set earlier. For example, depending on the name of the directory that was uncompressed by makepkg, the first command in your build function might be
cd $startdir/src/$pkgname-$pkgver, which happens to be a very common case unless the program's author is a very, very evil person.
Compiling the programs is the more difficult part. I will assume you managed to compile the program successfully "by hand" here, as all imaginable steps to do this cannot possibly be covered here. That's what the program's author is supposed to write README and INSTALL files for after all.
Now that you are in that directory, you need to issue whatever commands it takes to compile the files. In simple cases, you may simply use
./configure; make, although there are dozens of variations including
ant build or issuing the actual
gcc commands to compile the packages.
Good thing is, if you already managed to compile the package manually, you basically only need to list the commands you used here, and things should work out just fine. Since many packages like to install their files relative to the
/usr/local directory, but Arch Linux prefers using just
/usr, you probably want to supply a parameter to the configure script or the make command to take care of this. The prototype
PKGBUILD serves as an example for that. It might work differently, though; Again, your mileage may vary.
The next step in the
build() function is to put the compiled files in a place where
makepkg can scoop them up to create a package. This directory is the
pkg directory. It is supposed to imitate the root of your filesystem to the program's installation procedure. Any files that should be installed in a directory in the root of your filesystem should go in the
pkg directory under the same directory structure (ie. if you want to install the file
/usr/bin, it should be placed in
$startdir/pkg/usr/bin). Fortunately, only a few programs require the user to copy dozens of files manually, but they supply some kind of installation procedure instead which is supposed to do that automatically, often invoked by running "make install". It's critical, however, that you find out how to tell this installation procedure that it's supposed to stuff all it's nifty files not into your /, but into
$startdir/pkg/ instead! Otherwise you'll end up with an empty package file, and the binaries of the program you installed "correctly" added to your system already. Most of the time you'll have to supply the prefix parameter to the "make install" call as shown in the prototype, but it's very well possible that the program you're packaging expects an altogether different approach, but here are some hints:
- Sometimes the
configurescript accepts a prefix property that tells where the files should be installed. You might use
./configure --prefix=$startdir/pkg/usrin such configuration, for example.
- Sometimes there is a
PREFIXoption to append to a
make installcommand. This is sometimes set as a variable, and sometimes set in the command. In worse cases you have to edit the Makefile(s) (or ant build/properties files if the project uses ant) with sed or a patch you'd have to create yourself.
- There might be other sorts of install scripts that allow you to specify where the program should be installed.
- In some cases, the program expects to be run from a single directory. Often it is wise to simply copy these to
As you might have guessed already, that's the part where actual knowledge and experience becomes a necessity. It helps a lot if you browse over the
PKGBUILD files in the ABS tree, as those are tested and contain a few tricks that might prove valuable.
More often that not, the installation routine of the program will take care to create any subdirectories below the
pkg/ directory. If it does not, however, you'll get a lot of errors during the install stage as files are copied to nonexistent subdirectories. In that case you'll have to create the needed subdirectories by adding the appropriate
mkdir commands in the
build() function before running the installation procedure. The actual directory structure is package dependent, of course; some programs need to place files in
/usr while others might need to use
/opt. Most will need to create several directories. You can do all of this with the
mkdir -p $startdir/pkg/OTHER/DIRS/AS/NEEDED command, where OTHER/DIRS/AS/NEEDED represent directories at the root of the filesystem.
Testing the PKGBUILD
As you are writing the
build() function, you will want to test your changes frequently to ensure there are no bugs. You can do this using the
makepkg command in the directory containing the
PKGBUILD. With a properly formatted
PKGBUILD, this will create a package, but with a broken or unfinished one it will throw an error. Hopefully it will be a descriptive error!
makepkg finished successfully, it will place a shiny new file called $pkgname-$pkgver.pkg.tar.gz in your working directory. This is a pacman package and can be installed with the
pacman -U and
pacman -A options, or added to a local or web based repository. Note that just because a package file was built it doesn't mean it works! It might conceivably contain only the directory structure and no files whatsoever if, for example, you specified a prefix improperly. You can use pacman's query functions to display a list of files contained in the package and the dependencies it requires, and compare those with what you consider as correct. "pacman -Qlp <package file>" and "pacman -Qip <package file>" do the trick.
If the package looks sane, that's all you need to do. However, if you plan on releasing the package or PKGBUILD, it is imperative that you check and double check and re-double-check the contents of the depends array. This should contain a list of all packages that need to be installed in order for your package to work. You only need to list first level depends in the depends array. That is, you do not need to list packages that your program depends on if other packages that your program depends on are already listed.
gtk2 depends on
glib2. Like most open source C programs, it also requires
glibc to be installed. However,
glibc does not need to be listed as a dependency for
gtk2 because it is a dependency for
glib2 is already listed in
There are some tools you can use to check dependencies, including Jason Chu's famous
namcap program (
pacman -Sy namcap), and the more arcane
ldd program. Check the man pages for these programs and the links at the end of this document for more information. You should also scour the program's documentation and website (some nice developers have a page called "dependencies" that helps a lot).
Testing the package
Also make sure that the package binaries actually run flawlessly! It's really annoying to release a package that contains all necessary files, but dumps core because of some obscure configuration option that doesn't quite work well with the rest of the system. If you're only going to compile packages for your own system, though, you don't need to worry too much about this quality assurance step, as you're the only person suffering from mistakes after all.
To sum it all up
- Download the source tarball of the program you want to package up
- Try compiling the package and installing it into an arbitrary directory
- Copy over the prototype
/var/abs/PKGBUILD.protoand rename it to
PKGBUILDin a temporary working directory
- Edit the PKGBUILD according to the needs of your package
makepkgand see whether the resulting package is built correctly
- If not, repeat the last two steps
- ABS - The Arch Build System
- makepkg man page
- about dependencies
- makepkg tutorial
- PKGBUILD Help
- Arch CVS & SVN PKGBUILD guidelines
- Before you can automate the package building process, you should have done it manually at least once unless you know exactly what you're doing in advance, in which case you would not be reading this in the first place. Unfortunately, although a good bunch of program authors stick to the 3-step build cycle of "./configure; make; make install", this is not always the case, and things can get real ugly if you have to apply patches to make everything work at all. Rule of thumb: If you can't get the program to compile from the source tarball, and make it install itself to a defined, temporary subdirectory, you don't even need to try packaging it. There isn't any magic pixie dust in
makepkgthat makes source problems go away.
- In a few cases, the packages are not even available as source and you have to use something like
sh installer.runto get it to work. You will have to do quite a bit of research (read READMEs, INSTALL instructions, man pages, perhaps ebuilds from gentoo or other package installers, possibly even the MAKEFILEs or source code) to get it working. In some really bad cases, you have to edit the source files to get it to work at all. However,
makepkgneeds to be completely autonomous, with no user input. Therefore if you need to edit the Makefiles, you may have to bundle a custom patch with the
PKGBUILDand install it from inside the
build()function, or you might have to issue some
sedcommands from inside the
- Note that just because a package file was built it doesn't mean it works! It might conceivably contain only the directory structure and no files whatsoever if, for example, you specified a prefix improperly. You can use pacman's query functions to display a list of files contained in the package and the dependencies it requires, and compare those with what you consider as correct. "pacman -Qlp <package file>" and "pacman -Qip <package file>" do the trick.