本文是 Tizen 系统的 gbs build 的用法的中英文对照版,主要内容为如何使用 gbs build 命令
Reference: https://source.tizen.org/documentation/reference/git-build-system/usage/gbs-build
gbs build
PUBLISHED 19 Oct 2014
By using ‘gbs build’, the developer can build the source code and generate rpm packages locally. For instructions on using the build subcommand, use this command: gbs build –help
开发者可使用gbs build在本地编译源代码然后生成RPM包。使用命令 gbs build –help 可以获取关于子命令 build 的帮助指南
$ gbs build -h
gbs build workflow (gbs build 工作流程)
Input of gbs build (gbs build的输入)
Below is the input for gbs build:
以下是 gbs build 所需输入:
git project(s) which contains rpm packaging files
包含rpm packing文件的git项目
binary rpm repositories (remote or local)
二进制rpm包仓库
project build configurations (macros, flags, etc)
项目编译配置,宏定义、标志位等
The binary rpm repositories contain all the binary rpm packages which are used to create the chroot environment and build packages, which can be remote, like tizen release or snapshot repositories, or local repository. Local repository supports two types:
二进制rpm包仓库包含所有rpm包,这些rpm包可以用来创建chroot环境和编译软件包。包仓库可以是远程的或者是本地的,远程的如Tizen的发布或快照仓库,本地仓库支持两种类型,如下:
A standard repository with repodata exists
带repodata的标准仓库
A normal directory contains RPM packages. GBS will find all RPM packages under this directory.
包含RPM包的普通目录,GBS可以在此目录下找到所有的RPM包
Please refer to Configuration File part to configure a repository.
请参考配置文件来配置一个软件包仓库
Build workflow (编译流程)
The input and output of gbs build are all repositories.
gbs build的输入和输出都是仓库
Note: All the rpm packages under the output repository (by default, ~/GBS-ROOT/local/repos/<VERSION>/) will be used when building packages. That is, all the packages under the output repository will be applied to the build environment, so make sure the output repository is clean if you don’t want this behavior.
注意:输出仓库(默认为~/GBS-ROOT/local/repos/<VERSION>/)下所有的rpm包将会被用于编译,如果你不希望使用这些包,请清理掉输出仓库中的rpm包。
Here’s the basic gbs build workflow
gbs build的基本流程
____________________
| | ___________
| Source Code (GIT) |---->| | _________________________
|____________________| | | | |
____________________ | | | Local repository of |
| | | | | |
| Build config |---->| GBS build |---->| |
|____________________| | | | |
____________________ | | | build RPM packages |
| | | | |(~/GBS-ROOT/local/repos/)|
|Binary repositories | | | |_________________________|
|in GBS conf |---->|___________| |
|(Remote or Local) | ^ |
|____________________| |________________________|
From the above diagram, we can see the input and input are all repositories and the output repository located at ‘~/GBS-ROOT/locals/repos/‘ by default. You can change the repo path by using ‘–buildroot’ to specify a different build root.
输出仓库默认为:~/GBS-ROOT/local/repos,可以通过 –buildroot 指定build root来改变仓库路径。
Local repos in gbs build root (‘~/GBS-ROOT’ by default) will affect build results, so you must make sure that repos don’t contains old or unnecessary RPM packages. While running gbs build, you can specify ‘–clean-repos’ to clean up local repos, which gbs created, before building. We recommend that gbs users set different gbs build root directories for different profiles. There are several ways:
gbs build root下的本地仓库会影响编译结果,所以你必须要保证仓库里没有旧的软件包或者无关的软件包。在编译的时候可以用 –clean-repos 选项在实际编译前清理 gbs 创建的本地仓库。建议 gbs 使用者针对不同的场景设置不同的 build root 目录。可以使用以下方法:
By default, the GBS build will put all output files under ~/GBS-ROOT/.
GBS build默认会把所有的输出文件都放在 ~/GBS-ROOT/ 里
If the environment variable TIZEN_BUILD_ROOT exists, ${TIZEN_BUILD_ROOT} will be used as output top dir
如果存在环境变量 TIZEN_BUILD_ROOT,其值 $(TIZEN_BUILD_ROOT) 将会作为 build root
If -B option is specified, then the specified directory is used, even if ${TIZEN_BUILD_ROOT} exists
如果使用 -B 选项,那么就其参数将作为 build root ,即使环境变量 $(TIZEN_BUILD_ROOT) 存在
Output of gbs build (gbs build 输出)
Structure of a GBS build root directory
GBS build root的目录结构
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 # meta data used by gbs
GBS Build Examples (Basic Usage) (GBS Build示例,基本用法)
1 Build a single package.
编译单个包
$ cd package1
$ gbs build -A i586
2 Build a package for different architectures.
为不同的架构编译包
Note: Supported architectures include: x86_64, i586, armv6l, armv7hl, armv7l, aarch64, mips, mipsel.
注意:支持的架构有: x86_64, i586, armv6l, armv7hl, armv7l, aarch64, mips, mipsel.
$ gbs build -A armv7l #build package for armv7l
$ gbs build -A i586 #build package for i586
3 Make a clean build by deleting the old build root. This option must be specified if the repo has been changed, for example, changed to another release.
删除旧的build root,全新编译。当软件包仓库有变化时,必须使用这个选项,比如改成使用另一个发行版的软件仓库时.
$ gbs build -A armv7l --clean
4 Build the package with a specific commit.
为特定提交编译包
$ gbs build -A armv7l --commit=<COMMIT_ID>
5 Use –overwrite to trigger a rebuild.
用–overwrite触发一次重新编译
If you have already built before, and want to rebuild, –overwrite should be specified, or the packages will be skipped.
如果以前已经编译过,并且想重新编译,应该使用–overwrite,否则已经编过的包会被跳过
$ gbs build -A i586 --overwrite
If you change the commit or specify –include-all option, it will always rebuild, so –overwrite is not needed.
如果有新提交或者带选项–include-all,则GBS总是会重新编译,此时滴必要使用–overwrite
6 Output the debug info.
输出调试信息
$ gbs build -A i586 --debug
7 Build against a local repository. You can config the local repo at .gbs.conf file or through the command line.
$ gbs build -R /path/to/repo/dir/ -A i586
8 Use –noinit to build package in offline mode.
使用 –noinit 选项,在离线模式下编译
–noinit option can only be used if build root is ready. With –noinit option, gbs will not connect the remote repo, and skip parsing & checking repo and initialize build environment. rpmbuild will be used to build the package directly. Here’s an example:
在build root准备好的情况下,可以使用选项 –noinit。使用 –noinit 选项时,gbs不会连接远程仓库并且会跳过解析/检查仓库和初始化编译环境,直接使用rpmbuild编译包.
重要:此选项可用于快速编译
$ gbs build -A i586 # build first and create build environment
$ gbs build -A i586 --noinit # use --noinit to start building directly
9 Build with all uncommitted changes using –include-all.
使用 –include-all 选项编译所有的未提交的改动
重要,此选项为常用选项,当用户本地有修改又没有提交时,经常需要使用此选项用于测试新代码
For example, the git tree contains one modified file and two extra files:
例如,git目录中包含一个改动的文件和二个新加的文件
$ git status -s
M ail.pc.in
?? base.repo
?? main.repo
Build without the –include-all option
不用–include-all编译
Builds committed files only. All the modified files, which are not committed nor added, will NOT be built:
仅编译已提交的文件。所有未提交或未添加到版本控制的文件都不会被编译:
$ 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
Build with the –include-all option builds all the files
使用–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]
Use .gitignore to ignore specific files, when using the –include-all option.
当使用–incldue-all时可以用.gitignore来忽略特定的文件
If you want to ignore some files types, you can update your .gitignore. For example:
如果要想忽略某类型文件可以修改.gitignore,例如:
$ cat .gitignore
.*
*/.*
*.pyc
*.patch*
Incremental build
增量编译
Incremental Concept
增量的概念
Starting from gbs 0.10, the gbs build subcommand supports building incrementally, which can be enabled by specifying the ‘–incremental’ option.
从gbs 0.10开始,gbs build就支持增量式的编译,通过指定–incremental选项来启用。
This mode is designed for development and verification of single packages. It is not intended to replace the standard mode. Only one package can be built at a time using this mode.
这种模式主要用来开发和验证单个软件包,不是用来替代标准的编译模式。在此模式下,一次只能编译一个包。
This mode will set up the build environment in multiple steps, finishing by mounting the local Git tree of a package in the chroot build environment.
这种模式分成多步来设置编译环境,把本地的软件包的Git目录绑定到chroot的编译目录后就完成了。
Note: Because gbs will mount your git tree to the build root, be very careful when you remove your build root. You need to make sure you’ve already umounted the source tree manually before you remove it.
注意:因为gbs会把git目录绑定到buid root,所以当要删除build root时要非常小心,删除前要确定已经手动地把源码解绑定。
This has the following benefits:
这种模式有以下优点:
The build environment uses the latest source code and changes to source do not trigger a new build environment (in the chroot).
编译环境可以使用最新的源代码,并且代码的改动不会修改编译环境
The Git source tree becomes the source of the builds. Any change made in the Git repository followed by invocation of the build script will build the changed sources
git目录变成了编译的源目录,只要在git中的任何改动之后,调用编译命令,就可以编译改动过的源代码
If the build fails for some reason, the build script will continue from the spot where it has failed, once the code has been changed to fix the problem causing the failure.
编译失败后,一旦导致编译失败的错误被修正,编译脚本会从先前失败的地方接着编译
This mode is, in many ways, similar to traditional code development, where changes are made to sources, followed by running make to test and compile the changes. However, it enables development using the build environment of the target, instead of the host OS.
从不同的方面说,这种模式类似于传统的代码开发:修改代码然后运行make编译改动。不同的地方在于,增量编译使用编译环境而不是宿主机器的操作系统
This method has some limitations, mostly related to packaging and how the sources are maintained. Among others, it depends on how the RPM spec file is composed:
这种模式有一些限制,都是关于打包和代码的管理。尤其是依赖于RPM的spec文件
It does not support patches in the spec file. All source has to be maintained as part of the Git tree
不支持spec文件中的patches,所有的源码必须是git目录的一部分
It requires a clean packaging workflow. Exotic workflows in the spec files might not work well, because this mode expects the following model:
需要一个整洁的打包流程。spec文件中的极特殊的流程可能不会有效,因为这种模式预期以下模型:
- Code preparation (%prep) (代码准备)
- Code building (%build) (代码编译)
- Code installation (%install) (代码安装)
Because we run the %build section every time, if the %build script has configuration scripts (auto-tools), binaries might be regenerated, causing a complete build every time. To avoid this, you are encouraged to use the following macros, which can be overridden using the –no-configure option:
因为每次都运行编译部分,如果%build脚本有自动配置脚本,二进制文件会被重新生成,导致每次都完全编译。为了避免这样情况发生,推荐使用下面的宏,这些宏能够用–no-configure选项来覆盖
- %configure: runs the configure script with pre-defined paths and options.
- %reconfigure: regenerates the scripts and runs %configure
- %autogen: runs the autogen script
Example
In this example, we use dlog source code. First, we need to build with –incremental, then just modify one source file, and trigger the incremental build again. We will see that only modified source code has been compiled during the incremental build.
$ 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
From the buildlog, we can see that only log.c has been re-compiled. That’s the incremental build behavior.
–noinit option can be used together with –incremental to make a build more quickly, like:
$ gbs build --incremental --noinit
Limitations of Incremental Build
增量编译的限制
Incremental build doesn’t support all packages. Here are some limitations:
增量编译不支持所有的包。一些限制如下:
Incremental build currently supports building only a single package. It doesn’t support building multiple packages in parallel
只支持单个包
The tarball’s name in the spec file should be %{name}-%{version}.{tar.gz|tar.bz2|zip|…}, otherwise GBS can’t mount source code to build the root correctly
spec文件中的压缩包名字必须是%{name}-%{version}.{tar.gz|tar.bz2|zip|…},否则GBS无法正确把源码绑定到build root中
%prep section should only contains %setup macro to unpack tarball, and should not contains other source code related operations, such as unpack another source, apply patches, etc.
%prep部分应该仅包含用于解圧压缩包的%setup宏,而不应该含有对源代码的其他操作,比如解压其他源码或打patch等都不允许
Multiple packages build (dependency build) (多包编译)
Multiple package build has been supported since gbs 0.10. If packages have dependencies on each other, gbs will build packages in the correct order calculated by dependency relationship. Previously built out RPMs will be used to build the following packages that depend on them, which is the dependency build.
从gbs 0.10开始就支持多包编译。如果包有相互的依赖,gbs会计算出它们之间的关系然后按正确的顺序来编译。作为依赖编译,先前编译出的RPM包会用来编译后面的有依赖需求的包
Examples:
1 Build all packages under a specified package directory
编译指定目录下的所有的包
$ mkdir tizen-packages
$ cp package1 package2 package3 ... tizen-packages/
$ gbs build -A i586 tizen-packages # build all packages under tizen-packages
2 Build multiple packages in parallel with –threads
使用–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
3 Select a group of packages to be built
选择编译一组包
The –binary-from-file option specifies a text file that contains a name list of RPM packages to be built. The format in the text file is one package per line.
The –binary-list option specifies a list in which the package names are separated by comma.
When the number of packages is small, thus the packages can be clearly presented in command line, it is recommended to use the –binary-list option for simplicity.
$ gbs build -A i586 --binary-from-file=/path/to/packages.list
$ gbs build -A i586 --binary-list=<pkg1>,<pkg2>
4 Exclude certain packages.
排除某些包
The –exclude option specifies a list in which the names of packages to be ignored are separated by comma. The –exclude-from-file option specifies a text file that contains a name list of packages to be ignored.
$ 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 Build packages based on dependencies.
基于依赖来编译包
The –deps option enables GBS to build specific packages, together with all the related packages on which they depend.The –rdep option enables GBS to build specific packages, together with all the related packages that depend on them.
The specific packages can be included by the –binary-from-file option or the –binary-list option, and be excluded by the –exclude option or the –exclude-from-file option.
These two options are compatible. When added at the same time, besides the specific packages, GBS will build not only the related packages on which they depend, but also all the related packages that depend on them.
$ 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
Other useful options (其他有用的选项)
Install extra packages to build root
安装额外的包到build root中
–extra-packs=
$ gbs build --extra-packs=vim,zypper,gcc,gdb ...
Keep all packages in build root
保留所有build root中的包
Generally, gbs build will remove unnecessary packages in build root. While transferring to build another package, you can use –keep-packs to keep all unnecessary packages, and just install missing build required packages. This option can be used to speed up build multiple packages.
通常情况下,gbs build会把build root中的不需要的包删除掉。当要编译另外的包时可以使用–keep-packs选项来保留不再需要的包而只安装缺失的依赖包。这个选项可以加速多个包的编译。
重要:重要选项,可以节省编译时间
$ gbs build --keep-packs
–keep-packs can be used to create one build root for building multiple packages. Once the build root is ready, you can use –noinit to build these packages quickly.
–keep-packs选项可以用来为多个包创建一个build root。一旦build root准备好,就可以用 –noinit 选项来快速的编译这些包
重要:–keep-packs 配合 –noinit,可以节省编译时间
$ gbs build pkg1/ --keep-packs -A i586
$ gbs build pkg2/ --keep-packs -A i586
$ gbs build pkg3/ --keep-packs -A i586
Now, the build root (~/GBS-ROOT/local/scratch.i586.0) is ready for building pkg1, pkg2, and pkg3. You can use –noinit to build them offline, and don’t need waste time to check repo updates and build root.
$ gbs build pkg1 --noinit
$ gbs build pkg2 --noinit
$ gbs build pkg3 --noinit
Fetch the project build conf and customize build root (for Advanced Users) (高级用户,获取项目的编译配置和定制build root)
Project build conf describes the project build configurations for the project, including pre-defined macros/packages/flags in the build environment. In Tizen releases, the build conf is released together with the released repo. You can find an example at: http://download.tizen.org/releases/daily/trunk/ivi/latest/builddata/xxx-build.conf
gbs build will fetch the build conf automatically
Starting from gbs 0.7.1, by default, gbs will fetch the build conf from a remote repo, if you specify the remote Tizen repo, and then store it in your temp environment. Here’s the build log:
$ 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>:
build the package using your own project build conf, using the -D option
You can save it and modify it, and then use it for your purposes:
cp /var/tmp/<user>-gbs/tizen2.0.conf ~/tizen2.0.conf
$ gbs build -A i586 -D ~/tizen2.0.conf
If you need to customize the build config, refer to: http://en.opensuse.org/openSUSE:Build_Service_prjconf
Reference: https://source.tizen.org/documentation/reference/git-build-system/usage/gbs-build