其实不管是什么linux的发行版本,都需要一个软件包管理器,负责将用户需要的软件从源代码转换成二进制程序。无论是早期的rpm、yum、apt、emerge还是pacman都是这个原理,但是具体细节呢。manjaro是基于arch的,也是使用了makepkg 工具,它会按照 PKGBUILD 文件生成一个二进制包。有些时候,makepkg 还需要 install 文件(主要用来显示提示信息、备份用户设置等)和其他的配置文件。PKGBUILD 中包含了安装使用一个软件需要的所有信息。下面是 dwm(一个非常非常简捷、高效的窗口管理器)的 PKGBUILD 文件:
1、PKGBUILD 文件,以typora为例子
1 # Maintainer: Jonathan Duck <duckbrain30@gmail.com> 2 3 # Expiremental System electron package, set ELECTRON env to electron 4 pkgname=typora 5 pkgver=0.9.98 6 pkgrel=1 7 pkgdesc="Typora will give you a seamless experience as both a reader and a writ er." 8 arch=('x86_64') 9 filename="${pkgname}_${pkgver}_amd64.deb" 10 license=('custom:"Copyright (c) 2015 Abner Lee All Rights Reserved."') 11 url="https://typora.io/" 12 depends=('libxss') 13 optdepends=( 14 'noto-fonts-emoji: Or some other emoji font to see emojis' 15 'pandoc: Import/export for extra file formats') 16 source=("https://typora.io/linux/$filename") 17 sha512sums=('a004ef3b336df25f4181927b864aa2fbee6f857b9afbe675e75b271dd9a8173e80 c7dca56e8074103908d78084370a0be082da2c96aea612bcb10751b5227cba') 18 19 if [[ ! -z $ELECTRON ]]; then 20 depends+=($ELECTRON) 21 source+=(typora.js) 22 sha512sums+=('8ce47de8b0d0ab4b0323ee4c19a4daaf313513700d8c191faab299bfa21aa ba9b55cbcf945914103e5f53607228fec3411a83aea8007b192616ad845a3af5c98') 23 fi 24 25 package() { 26 bsdtar -xf data.tar.xz -C "$pkgdir/" 27 rm -rf "$pkgdir/usr/share/lintian/" 28 chmod 4755 "$pkgdir/usr/share/typora/chrome-sandbox" 29 sed -i '/Change Log/d' "$pkgdir/usr/share/applications/typora.desktop" 30 find "$pkgdir" -type d -exec chmod 755 {} \; 31 if [[ ! -z $ELECTRON ]]; then 32 appdir="${pkgdir}/usr/share/typora" 33 mv "${appdir}" tmp/ 34 mv tmp/resources/app "${appdir}" 35 rm -rf tmp/ 36 install -Dm755 "typora.js" "${pkgdir}/usr/bin/typora" 37 fi 38 }
文件比较简单,包含了软件包的包名、版本号、包描述、包文件名、包的许可证、包的url地址、包依赖等等
2、编译部分通过Makefile文件,以typora为例子:
1 2 # This will update the checksums and build the package 3 all: 4 updpkgsums 5 makepkg --printsrcinfo > .SRCINFO 6 makepkg -sr 7 8 # This will do the same as all, but will install it to the local system as well 9 install: 10 updpkgsums 11 makepkg --printsrcinfo > .SRCINFO 12 makepkg -sri 13 14 system: 15 ELECTRON=electron makepkg -sr 16 17 # This will update PKGBUILD with the latest version and build the package 18 update: 19 sed 's/^pkgver=.*$$/pkgver=$(shell $(MAKE) versions | tail -n 1)/' -i PKGBU ILD 20 sed 's/^pkgrel=.*$$/pkgrel=1/' -i PKGBUILD 21 $(MAKE) 22 23 # This will list the versions available in the Ubuntu repository 24 versions: 25 curl -s https://www.typora.io/linux/Packages | perl -n -e '/^Version: (.*)- [0-9]+$$/ && print "$$1\n"' | sort -V | uniq 26 27 # This will remove the files downloaded and created in the build process 28 clean: 29 rm -rf pkg src typora_*.deb typora-*.pkg.tar 30 31 publish: 32 git add . 33 git commit -m "Update to version $(shell $(MAKE) versions | tail -n 1)" 34 git push 35 git push aur master
编译的过程”这个部分,很多代码都和我们在 shell 里编译的命令一样。Archlinux 不要求用户学习太多新的东西,PKGBUILD 很容易理解,因为里面都是基本的 shell 命令。把PKGBUILD,dwm.install 和 config.h(dwm 比较特殊,config.h 包含所有的配置信息,所以要在编译之前提供。其他的软件大多依靠外部的配置文件,像是 .bashrc 等)放在一个新的目录里之后。我们执行:
makepkg命令 目录里出现了一些新的东西,包括:dwm-4.7-1-x86_64.pkg.tar.gz dwm-4.7.tar.gz 两个文件,还有两个目录srcpkg通过比较这些文件、目录里的内容和 PKGBUILD,你就会明白 makepkg 到底做了些什么:
- 根据 source 里的内容下载了源代码文件 dwm-4.7.tar.gz;
- 通过 md5 验证码确定下载的源代码文件和 PKGBUILD 的作者使用的是一致的;
- 把源代码文件解压缩到 ./src/package/pkgver;
- 按照 build() 里的内容编译源代码,并把编译好的内容放在 ./pkg 里;
- 在 ./pkg 里加上其他的一些信息,包括 .PKGINFO 和 .INSTALL,也就是 dwm.install 的拷贝;
- 把 ./pkg 里面的内容打包形成 dwm-4.7-1-x86_64.pkg.tar.gz。
那么,我们有了一个 .pkg.tar.gz 这样一个二进制包之后,我们要如何安装呢?我们要使用这样一个命令:
pacman -U dwm-4.7-1-x86_64.pkg.tar.gz
这个命令又完成了那些事情呢?
- 首先,二进制包被解压缩;
- 按照 .INSTALL 的内容执行一定的命令;
- 二进制包里面的内容会被拷贝到相应的目录(你注意到二进制包内的目录结构了吗?);
- 在 /var/lib/pacman/local 这个目录中建立 dwm-4.7-1 这样一个目录;
- 这个目录里包含了四个文件 depends、desc、files 和 install;
- depends 记录了 dependency,desc 是软件说明,files 记录了每一个安装到系统上的文件的路径,install 就是 .INSTALL 的拷贝。
从这以后,pacman 正是通过检查 /var/lib/pacman/local 里的内容来管理软件包的。比如说,在执行 pacman -R dwm 的过程中,pacman 首先在 /var/lib/pacman/local 找到了 dwm-4.7-1 这个目录,然后根据 files 的内容删除已安装的内容。Dependency 也是通过 depends 计算的。
OK!我已经解释了 PKGBUILD 的基本结构和 makepkg 的过程。
基本上是两步:从 PKGBUILD 到 .pkg.tar.gz 包,再从二进制包安装到系统。这样一种办法有很多好处。首先,PKGBUILD 非常方便用户交流。我的一个 PKGBUILD 如果编译成功了,就可以给别人用。PKGBUILD 的内容一目了然,不但有助于学习,也再不用担心木马的问题了。
另外,我通过一个小例子展现 Archlinux 的灵活性在哪里。比如,我要对 dwm 有自己的设置,也就是自己的 config.h,那我应该怎么做呢?我会做如下的事情:
- 编辑 config.h,另存为 myconfig.h;
- 编辑 PKGBUILD,把所有的 config.h 替换为 myconfig.h;
- 把 pkgrel 变成 2。
之后通过 makepkg,我会得到一个文件 dwm-4.7-2-x8664.pkg.tar.gz,这个和原来的 dwm-4.7-1-x8664.pkg.tar.gz 可以区别开。我可以安装 dwm-4.7-2-x8664.pkg.tar.gz,如果有问题我还可以通过 pacman -U dwm-4.7-1-x8664.pkg.tar.gz 来安装原来的二进制包。我还可以用同样的办法生成一系列的 .pkg.tar.gz 包,这在软件的安装调试过程中非常有用。你理解了 makepkg 和 PKBGUILD,安装软件会更加灵活。
参考:https://www.jianshu.com/p/1b48ef4bc2ba