注:本文从:https://source.tizen.org/documentation/articles/gbs-build 翻译而来.
1 前言
通过使用gbs build指令,开发者可以在本地编译源码和生成rpm包。
通过
$ gbs build -h
指令可以查看gbs build相关的使用说明。
2 gbs build工作流程
2.1 gbs build的输入
gbs build包含以下几个部分:
- 它包含rpm包的工程
- 本地或远程的二进制的rpm仓库
- build工程配置(宏,标志等)
其中二进制的rpm仓库包含所有二进制的rpm包,这些rpm包用来创建chroot环境和生成包,生成包是可以在本地或远程来生成,就像tizen release和snapshot仓库一般。
本地仓库支持两种类型:
- 拥有repodata存在的标准仓库
- 包含rpm包的目录,GBS将会在此目录下查找所有的RPM包
有关配置文件请参考http://blog.csdn.net/flydream0/article/details/9018443
2.2 编译流程
GBS的输入和输出都是仓库。
注:所有的在输出仓库(默认情况下:~/GBS-ROOT/local/repos/<VERSION>/)下的RPM包将会在编译的过程中使用到。也就是说,编译环境对这些包都适用,因此,如果你不想这样,那么务必在编译之前清空此输出仓库。
下图是编译的流程示意图:
____________________
| | ___________
| Source Code (GIT) |---->| | _________________________
|____________________| | | | |
| | | Local repository of |
____________________ | GBS Build |---->| build RPM packages |
| | | | |(~/GBS-ROOT/local/repos/)|
|Binary repositories | | | |_________________________|
|in GBS conf |---->|___________| |
|(Remote or Local) | ^ |
|____________________| |________________________|
由上图可知,GBS的两个输入都是仓库,输出也是仓库,输出仓库默认位置在~/GBS-ROOT/locals/repos/,如果你想修改这个输出仓库位置,可以使用--buildroot'来指定。
gbs build生成的repo目录默认情况下为~/GBS-ROOT,它会影响gbs build的生成结果,因此,务必确保它没有包含过时的或没必要的RPM包。在编译过程中,你可以通过在gbs build指令后加上--clean-repos选项来指定清除repo.针对不同的profile(即不同的设备)这里建议使用不同的gbs build 根目录:
- 在默认情况下,gbs build会将所有生成的文件放入根目录~/GBS-ROOT/下。
- 如果存在TIZEN_BUILD_ROOT环境变量,那么会使用${TIZEN_BUILD_ROOT}指定的目录为输出根目录.
- 如果gbs build后面加入了-B选项,那么-B选项后面所指定的目录最终将会作为生成的根目录,即使TIZEN_BUILD_ROO环境变量同时存在的话也是如此。
2.3 gbs build的输出
gbs build输出根目录如下文件结构:
gbs output top dir
|-- local
| |-- cache # repodata and RPMs from remote repositories
| |-- repos # generated local repo top directory
| | |-- tizen # distro one: tizen
| | | |-- armv7l # store armv7l RPM packages
| | | |-- i586 # store x86 RPM packages
| | `-- tizen2.0 # build for distro two: tizen2.0
| | `-- i586 # the same as above
| |-- scratch.armv7l.0 # first build root for arm build
| |-- scratch.i586.0 # second build root for x86 build
| |-- scratch.i586.1 # third build root for x86 build
| |-- scratch.i586.2 # fourth build root for x86 build
| |-- scratch.i586.3 # fifth build root for x86 build
| | # The above build root dir can be used by gbs chroot <build root dir>
| `-- sources # sources generated for build, including tarball, spec, patches, etc.
| |-- tizen
| `-- tizen2.0
`-- meta
3 gbs build基本示例
3.1 编译单个包
$ cd package1
$ gbs build -A i586
3.2 为生成的包在编译时指定硬件平台架构
$ gbs build -A armv7l #build package for armv7l
$ gbs build -A i586 #build package for i586
3.3 删除老的gbs build输出根目录
如果修改了指定的repo,那么此选项必须使用。比如切换到另一个release repo.
$ gbs build -A armv7l --clean
3.4 在编译时指定commit ID
这个不是太明白,个人理解这个commit为一个标记,即为git commit的修订版本号,也就是编译某一个修订版本的源码。
$ gbs build -A armv7l --commit=<COMMIT_ID>
3.5 重新编译
如果你之前已经编译过,这次你想重新编译的话,那么请用如下指令:
$ gbs build -A i586 --overwrite
--overwrite选项会使用之前生成的包不会跳过,全部都重新编译。
如果你使用了--include-all和修改了commit,那么即使你不指定--overwrite选项也会自动重新编译。
3.6 输出调试打印信息
$ gbs build -A i586 --debug
3.7 使用本地仓库来编译
你可以通过配置.gbs.con文件来实现,或者通过如下指令来指令本地仓库的位置:
$ gbs build -R /path/to/repo/dir/ -A i586
3.8 使用--noinit选项来指定离线编译
如果build根目录已经准备好了,那么可能使用--noinit选项。使用此选项,将不会连接远程的repo,将跳过解析和检查repo,并且初始化build环境,rpmbuild将会直接用来build包。如下所示:
$ gbs build -A i586 # build first and create build environment
$ gbs build -A i586 --noinit # use --noinit to start building directly
3.9 build所有的源文件,即使当前包含还没有commit或新增的源文件
假如你当前修改了一个文件另外还新增加了两个其它文件,如下:
$ git status -s
M ail.pc.in
?? base.repo
?? main.repo
如上所示,ail.pc.in为修改的文件,base.repo和main.repo为新增加的文件.
3.9.1 build时不带--inclde-all选项
此时只会编译已经commit的文件,那此没有上传和新增的文件都将不会被编译。
$ gbs build -A i586
warning: the following untracked files would NOT be included: base.repo main.repo
warning: the following uncommitted changes would NOT be included: ail.pc.in
warning: you can specify '--include-all' option to include these uncommitted and untracked files.
....
info: Binaries RPM packages can be found here:
/home/test/GBS-ROOT/local/scratch.i586.0/home/abuild/rpmbuild/RPMS/
info: Done
3.9.2 build时带上--include-all选项
此时所有未上传和新增的文件都将会被编译:
$ gbs build -A i586 --include-all
info: the following untracked files would be included: base.repo main.repo
info: the following un-committed changes would be included: ail.pc.in
info: export tar ball and packaging files
...
...
[build finished]
3.9.3 使用.gitignore文件指定忽略哪些文件
如果使用--include-all选项,而此时你又想忽略一些源文件,那么此时,你可以通过.gitignore来指定哪此源文件将会被忽略。
$ cat .gitignore
.*
*/.*
*.pyc
*.patch*
4 增量构建
4.1 增量的概念
从gbs0.10开始,gbs build通过--incremental选项开始支持增加构建。
这种模式之所以这样设计,是为了开发和验证单个包。目的并不是为了替换标准模式,在这种模式下,同一时间只允许唯一一个包被构建。
这种模式在多个步骤中会设置构建环境,构建结束时将在chroot构建环境下挂载包含包的本地git树。
注:由于gbs会挂载你的本地git树到build根目录,因此在移除build根目录时得非常小心。在移除build根目录之前,你必须手动卸载它。
这样做的好处:
- 构建环境使用最终新的源码,即使修改了部分内容也不必重新配置构建环境。
- GIT源树将会成为构建源,在GIT中做任何修改,都将通过调用构建脚本来只构建这些修改的源文件。
- 如果由于某种原因构建失败了,在你解决了这个问题之后,它将从原先失败的地方开始继续构建,而不必从头开始。
这个有点像传统的make指令那样来编译修改过的源码。但是它还使能了使用构建环境来开始构建,这个构建环境是目标设备的环境,而不是主机的。
这种方法有一些限制,主要是关于打包方面和如何维护源方面。除此之外,就取决于这个RPM spec文件的组成:
- 在spec文件中不支持补丁。所有源必须做为GIT树的一部分来维护。
- 在打包过程中流程必须纯粹,在spec文件中所有外来流程将得不到很好的运转,因此模式下只支持如下模型:
- Code preparation (%prep)
- Code building (%build)
- Code installation (%install)
- %configure: 使用预定义好的路径和选项运行配置脚本。
- %reconfigure: 重新生成脚本和运行宏 %configure
- %autogen: 运行 autogen 脚本。
4.2 示例
在这个示例中,我们使用dlog源码,通过--incremental选项进行首次构建,然后只修改其中一个源文件,然后再次使用--incremental进行构建,我们将会看到此时只有被修改过的文件才会被编译。
示例如下所示:
$ cd dlog
# first build:
$ gbs build -A i586 --incremental
$ vim log.c # change code
# second build:
$ gbs build -A i586 --incremental
info: generate repositories ...
info: build conf has been downloaded at:
/var/tmp/test-gbs/tizen.conf
info: Start building packages from: /home/test/packages/dlog (git)
info: Prepare sources...
info: Retrieving repo metadata...
info: Parsing package data...
info: *** overwriting dlog-0.4.1-5.1 i586 ***
info: Next pass:
dlog
info: *** building dlog-0.4.1-5.1 i586 tizen (worker: 0) ***
info: Doing incremental build
[ 0s] Memory limit set to 10854336KB
[ 0s] Using BUILD_ROOT=/home/test/GBS-ROOT/local/scratch.i586.0
[ 0s] Using BUILD_ARCH=i686:i586:i486:i386:noarch
[ 0s] test-desktop started "build dlog.spec" at Thu Sep 13 07:36:14 UTC 2012.
[ 0s] -----------------------------------------------------------------
[ 0s] ----- building dlog.spec (user abuild)
[ 0s] -----------------------------------------------------------------
[ 0s] -----------------------------------------------------------------
[ 0s] + rpmbuild --short-circuit -bc /home/abuild/rpmbuild/SOURCES/dlog.spec
[ 0s] Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.XLz8je
[ 0s] + umask 022
[ 0s] + export LD_AS_NEEDED
[ 4s] + make -j4
[ 4s] make all-am
[ 4s] make[1]: Entering directory /home/abuild/rpmbuild/BUILD/dlog-0.4.1
[ 4s] /bin/sh ./libtool --tag=CC --mode=compile gcc -c -o log.lo log.c
[ 4s] mv -f .deps/log.Tpo .deps/log.Plo
[ 4s] /bin/sh ./libtool --tag=CC --mode=link gcc -o libdlog.la /usr/lib log.lo
[ 4s] libtool: link: gcc -shared .libs/log.o -o .libs/libdlog.so.0.0.0
[ 4s] libtool: link: ar cru .libs/libdlog.a log.o
[ 4s] libtool: link: ranlib .libs/libdlog.a
[ 4s] make[1]: Leaving directory /home/abuild/rpmbuild/BUILD/dlog-0.4.1
[ 4s] + exit 0
[ 4s] finished "build dlog.spec" at Thu Sep 13 07:36:18 UTC 2012.
[ 4s]
info: finished incremental building dlog
info: Local repo can be found here:
/home/test/GBS-ROOT/local/repos/tizen/
info: Done
如上所示,只有log.c文件才被重新编译。
--noinit选项可以与--incremental选项一起使用,以此来加快构建的速度。如下:
$ gbs build --incremental --noinit
4.3 增量构建的限制
增量构建不支持一次构建所的包。
以下是增量构建的一些限制:
- 增量构建只支持构建一个包,它不支持同时构建多个包。
- 在spec文件中的tar 包的名字必须为%{name}-%{version}.{tar.gz|tar.bz2|zip|...}这样的格式,否则gbs不能正确地将源码构建并挂载到根目录。
- %prep部分只能包含%setup宏来解包tar包,不能包含其它相关操作源码,比如解包其它源,应用补丁等。
5 构建多包
从GBS0.10开始支持构建多包。如果包与包之间存在依赖关系,GBS将会自动计算包与包之间的依赖关系,并以正确的顺序依次构建。之前构建生成的RPM包接下来将会被用来构建后续的RPM包,这种前后包之间的关系即为依赖关系。
5.1 示例
5.1.1 在指定目录下构建包
$ mkdir tizen-packages
$ cp package1 package2 package3 ... tizen-packages/
$ gbs build -A i586 tizen-packages # build all packages under tizen-packages
5.1.2 并行构建多包
此时可以使用--threads选项
# current directory have multiple packages, --threads can be used to set the max build worker at the same time
$ gbs build -A armv7l --threads=4
5.1.3 将多包以组的形式进行构建
使用选项--binary-from-file可以指定一个文本文件,这个文件描述多个包,即将在构建的多包。文本文件的格式每行表示一个包。
使用--binary-list选项将用来在命令行下指定多个包,各包的名字之间用逗号相隔。
如果构建的包比较少的话,那么比较容易在命令行下指定多包,因此建议使用--binary-list的方式。如下:
$ gbs build -A i586 --binary-from-file=/path/to/packages.list
$ gbs build -A i586 --binary-list=<pkg1>,<pkg2>
5.1.4 指定某些包为例外
选项--exclude是用来指定某些包是例外的,可以支持指定多个包例外。
选项--exclude-from-file用来指明例外的包是包含在一个文本文件里边。
如下示例:
$ gbs build -A i586 tizen-packages --exclude=<pkg1>
$ gbs build -A i586 tizen-packages --exclude=<pkg1>,<pkg2>
$ gbs build -A i586 tizen-packages --exclude-from-file=/path/to/packages.list
5.1.5 基于依赖来构建包
选项--deps用来指前当前这些指定将要构建的包所依赖的其它包也将会一起构建。
选项--rdep用来指明如果有其它包依赖当前包,那么其它包也将一起构建。
两者可以一起用,且选项--exclude,--exclude-from-file也可以一起生效。
如下示例:
$ gbs build -A i586 --binary-list=<pkg1,pkg2> --deps
$ gbs build -A i586 --binary-list=<pkg1,pkg2> --rdeps
$ gbs build -A i586 --binary-list=<pkg1,pkg2> --deps --rdeps
6 其它比较有用的选项
6.1 安装其它包到输出根目录
选项--extra-packs=<pkgs list sep by comma>用来安装其它额外的包。
$ gbs build --extra-packs=vim,zypper,gcc,gdb ...
6.2 在输出根目录下保持所有包
在通常情况下,gbs build在输出根目录下将会删除所有没有使用到或不必要的包,如果你想保持这些不必要的包或仅仅只想安装当前丢失的包,此时你可以使用--keep-packs选项。在个选项在构建多包时将会加快速度。
如下所示:
$ gbs build --keep-packs
--keep-packs选项可以用来创建输出根目录,如果输出根目录已经存在,那么可以使用选项--noinit来加快构建多包。
$ gbs build pkg1/ --keep-packs -A i586
$ gbs build pkg2/ --keep-packs -A i586
$ gbs build pkg3/ --keep-packs -A i586
此时输出根目录(~/GBS-ROOT/local/scratch.i586.0)已经存在,你可以使用--noinit选项来进行离线构建,不必要在检查repo是否更新及输出根目录上浪费时间。
如下:
$ gbs build pkg1 --noinit
$ gbs build pkg2 --noinit
$ gbs build pkg3 --noinit
7 获取构建配置文件及自定义配置(高级用户)
构建配置文件描述了构建配置信息,包含在构建环境中预定义的宏/包/标志。在tizen发布时,一般情况下它的构建配置文件将同时发布,如:http://download.tizen.org/releases/daily/trunk/ivi/latest/builddata/e174d73b3fa659f2ae5181e3a9e15dd518bf1f68c23f2c752b86affd579e9257-build.conf
7.1 gbs build将自动获取它的构建配置文件
自gbs 0.7.1起,在默认情况下,gbs将自动从远程repo获取构建配置文件。如果你指定了远程的tizen repo,那么它将存储到你的临时环境中。
如下示例:
$ gbs build -A i586
info: generate repositories ...
info: build conf has been downloaded at:
/var/tmp/<user>-gbs/tizen2.0.conf
info: generate tar ball: packaging/acpid-2.0.14.tar.bz2
[sudo] password for <user>:
7.2 指定自定义构建配置文件进行构建
你可以保存之前下载的构建配置文件,然后根据自己的需要进行修改。构建时使用-D选项来指定自已修改过的构建配置文件。
如下所示:
cp /var/tmp/<user>-gbs/tizen2.0.conf ~/tizen2.0.conf
$ gbs build -A i586 -D ~/tizen2.0.conf
如果你想知道更多有关自定义构建配置文件的相关信息,请参考:
http://en.opensuse.org/openSUSE:Build_Service_prjconf