注:本文從: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包含以下幾個部分:
- git工程源碼
- 本地或遠程的二進制的rpm倉庫
- build工程配置信息(宏,標誌等)
其中二進制的rpm倉庫包含所有二進制的rpm包,這些rpm包用來創建chroot環境和RPM包,RPM包可以是由本地或遠程來生成,就像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