gbs 构建

通过使用“gbs build'指令,开发者可以在本地编译源码和生成rpm包。 关于查看gbs build的相关指令说明,用这个命令:gbs build --help。

$ gbs build -h

gbs build工作流程

输入gbs build命令

gbs build包含下面几个部分:

  • git工程源码
  • 本地或远程的二进制rpm仓库
  • build工程配置信息(宏,标志等)

其中二进制的rpm仓库包含所有二进制的rpm包,这些rpm包用来创建chroot环境和构建包,这些包可以由本地或远程来生成,就像tizen release和snapshot仓库一样。 本地仓库支持两种类型:

  • 拥有repodata存在的标准仓库
  • 包含RPM包的目录。 GBS将会在这个目录下找到所有的RPM包

配置一个仓库请参考配置文件。

构建流程

gbs build的输入和输出都是仓库。 :所有在输出仓库(默认情况下:~/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-ROOT/locals/repos/'。 如果你想修改这个输入仓库的位置,可以使用‘--buildroot’来指定。 gbs build生成的repo目录默认为'~/GBS-ROOT',它将影响编译的结果,所以,务必确保它没有包含旧的或者没必要的RPM包。 在编译过程中,你可以通过在gbs build后面加上 '--clean-repos'选项来清空本地的repos。 针对不同的设备,这里建议用户使用不同的gbs build根目录。 有几种方法:

  • 默认情况下,gbs build会在〜/GBS-ROOT/目录下输出文件。
  • 如果存在TIZEN_BUILD_ROOT环境变量,${TIZEN_BUILD_ROOT}将会用于输出的根目录。
  • 如果gbs build后面加上-B选项,那么-B选项后面所指定的目录将会作为生成的根目录,即使${TIZEN_BUILD_ROOT}存在。

gbs build的输出

GBS输出的根目录结构:

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构建示例(基本用法)

  1. 编译单个包
$ cd package1
$ gbs build -A i586
  1. 针对不同硬件平台架构编译包
$ gbs build -A armv7l      #build package for armv7l
$ gbs build -A i586        #build package for i586
  1. 删除旧的gbs build输出根目录。 如果修改了repo,必须指定该选项。比如切换到另一个release repo。
$ gbs build -A armv7l --clean
  1. 编译时指定commit ID。
$ gbs build -A armv7l --commit=<COMMIT_ID>
  1. --overwrite选项重新编译

如果你之前已经编译过,并想重新编译,--overwrite应该被指定,而且会使用之前生成的包,不会跳过。

$ gbs build -A i586 --overwrite

如果你改变了commit或者使用了--include-all选,那么即使不指定--overwrite选项也会自动重新编译。

  1. 输出调试信息
$ gbs build -A i586 --debug
  1. 建立本地仓库。 你可以通过修改.gbs.conf文件或者输入命令行的方式来配置本地仓库。
$ gbs build -R /path/to/repo/dir/ -A i586

8. 如build根目录已经备好了,那么可能使用--noinit进行离线编译。 使此选项,gbs将不会连接远程的repo,将跳过解析和检查repo,并且初始化build环境。 rebuild将会直接用来编译包。 如下所示:

$ gbs build -A i586           # build first and create build environment
$ gbs build -A i586 --noinit  # use --noinit to start building directly
  1. 使用--include-all,编译所有未提交修改的文件

例如,git树包含一个修改了的文件和两个新增加的文件:

$ git status -s
M ail.pc.in
?? base.repo
?? main.repo
  • 编译时不带--include-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
  • 编译时带上--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]
  • 当使用了--include-all选项,可以用.gitignore文件指定忽略哪些文件。 如果你想修改忽略的一些文件,你可以更新你的.gitignore文件即可。 例如:
$ cat .gitignore
.*
*/.*
*.pyc
*.patch*

增量构建

增量概念

从gbs0.10开始,gbs build通过指定 '--incremental'选项开始支持增加构建。 这种模式的设计是为了开发喝验证单个包。 目的并不是为了替换标准模式。 在这种模式下,同一时间只允许同一个包创建。 这种模式在多个步骤中会设置构建环境,构建结束时将在chroot构建环境下挂载包含包的本地git树。 :由于gbs会挂载你的本地git树到build根目录,因此在移除build根目录时得非常小心。 在移除build根目录之前,你需要确认你已经手动卸载它了。 这样做的好处是:

  1. 构建环境使用最终新的源码,即使修改了部分内容也不必重新配置构建环境。
  2. Git源树会成为构建源。 在Git仓库中做任何修改,都将通过调用构建脚本来只构建这些修改的源文件。
  3. 如果由于某种原因构建失败了,在你解决了这个问题之后,它将从原先失败的地方开始继续构建,而不必从头开始。

这种模式,在很多方面,类似于传统的代码开发,当改变了,运行make指令后只测试和编译所更改的部分。 但是,这个构建环境是目标设备的构建环境,而不是主机的。 该方法具有一定的局限性,主要涉及打包和如何维护源方面。 除此之外,它取决于RPM spec文件的组成:

  1. 在spec文件中不支持补丁。 所有的源必须作为Git树的一部分来维护。
  2. 在打包过程中需要一个干净的环境。 在spec文件中所有的外来流程将不能很好的工作,因为这个模式只支持如下模型:
    1. 代码编写 (%prep)
    2. 代码构建(%build)
    3. 代码安装 (%install)
  3. 因为每次运行build部分时,如果build脚本文件已经配置了脚本(auto-tools),那么每次在构建结束时将重新生成二进制文件。 为了避免如此,你可以使用下面这些宏,这个宏是可以用覆盖的:
    1. %configure: 使用预定义好的路径和选项运行配置脚本。
    2. %reconfigure: 重新生成脚本和运行宏 %configure
    3. %autogen: 运行 autogen 脚本。

示例

在这个例子,我们使用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文件才被重新编译。 这就是增量构建行为。 这是增量构建当前的一个限制。 项可以与选项起使用,以此来加快构建的速度,如下:

$ gbs build --incremental --noinit

增量构建的限制

增量构建不支持所有的包。 这里有一些限制:

  • 增量构建目前只支持构建一个包。 它不支持同时构建多个软件包。
  • 在spec文件中tar包的名字应该为%{name}-%{version}.{tar.gz|tar.bz2|zip|...},否则GBS不能正确地将源码构建并挂载到根目录。
  • %prep部分应该只包含%setup宏来解压tar包,并且不应该包含其他源代码相关的操作,比如解包其它源,应用补丁等。

构建多包

从gbs0.10开始支持多包构建。 如果包与包之间存在依赖关系,gbs将会计算包与包之间的依赖关系,以正确的顺序依次构建包。 之前构建生成的RPM包接下来将会被用来构建后续的RPM包,这种前后包之间的关系即为依赖关系。 例:

  1. 在指定目录下构建所有包
$ mkdir tizen-packages
$ cp package1 package2 package3 ... tizen-packages/
$ gbs build -A i586 tizen-packages # build all packages under tizen-packages
  1. 用--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
  1. 将多包以组的形式构建

使用选项--binary-from-file可以指定一个文本文件,这个文件包含了将要构建的RPM包的名称列表。 文本文件的格式是每行表示一个包。 使用--binary-list选项将用来指定多个包的列表,各包的名字之间用逗号相隔。 如果构建的包比较少的话,那么比较容易在命令行下指定多包。 这里推荐使用--binary-list选项的方式。

$ gbs build -A i586 --binary-from-file=/path/to/packages.list
$ gbs build -A i586 --binary-list=<pkg1>,<pkg2>
  1. 排除某些包。 使--exclude选项指定的多个包的列表是被忽略的,其中包的名称以逗号分隔。 选项用来指明例外的包是包含在一个文本文件里边。
$ 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
  1. 构建基于依赖关系的软件包。 选--deps用来指前当前这些指定将要构建的包依赖的其它包也将会一起构建。选项--rdep用来指明如果有其它包依赖当前包,那么其它包也将一起构建。          使用--binary-from-file选项或 --binary-list选项,指定的包将被包含进去,使用--exclude选项或--exclude-from-file选项,指定的包将被排除在外。 这两个选项是兼容的。 当同时加上两个选项时,除了特定的包,GBS将不仅编译他们依赖的相关包,而且依赖他们的相关包也会被编译。
$ 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

其它有用的选项

安装其他包到build根目录

选项--extra-packs=<pkgs list sep by comma>用来安装其它额外的包。

$ gbs build --extra-packs=vim,zypper,gcc,gdb ...

在build根目录下保持所有包

般来说,gbs编译时将移除根目录下所有不必要的包。 如果你想保持这些不必要的包或仅仅只想安装当前丢失的包,此时你可以使用选项。 在个选项在构建多包时将会加快速度。

$ 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

此时,构建pkg1, pkg2, and pkg3的输出根目录(~/GBS-ROOT/local/scratch.i586.0)已经存在。 你可以使用--noinit选项来进行离线构建,不必要在检查repo是否更新及输出根目录上浪费时间。

$ gbs build pkg1 --noinit
$ gbs build pkg2 --noinit
$ gbs build pkg3 --noinit

获取项目构建配置和自定义构建配置(针对高级用户)

构建配置文件描述了构建配置信息,包含在构建环境中预定义的宏/包/标志。 在tizen发布时,构建配置文件也将一同发布。 你可以在下面找到例子

  • 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>:
  • 使用自定义配置文件构建包

您可以保存和修改之前的配置文件,然后根据自己的目的应用:

cp /var/tmp/<user>-gbs/tizen2.0.conf ~/tizen2.0.conf
$ gbs build -A i586 -D ~/tizen2.0.conf

在gbs0.17以及更高的版本上已经支持在.gbs.conf文件中自定义修改。 更多的信息请参考配置文件。 如果你需要自定义配置文件,请参考:http://en.opensuse.org/openSUSE:Build_Service_prjconf

 

#next_pages_container { width: 5px; hight: 5px; position: absolute; top: -100px; left: -100px; z-index: 2147483647 !important; }