FROG項(xiàng)目培訓(xùn)文檔系列之02
Portage軟件管理
本章內(nèi)容包括:
1.Portage簡介
2.Portage tree
3.Overlay
4.emerge 操作
5.equery
6.ebuild 文件
7.Eclass
8.ebuild 中軟件包依賴
上一章節(jié)我們提到了gentoo軟件管理的一些基本概念,本章我們來詳細(xì)介紹。
1.Portage簡介
Portage是Gentoo Linux的軟件管理方案。Portage也是Gentoo在軟件包管理方面最矚目的創(chuàng)新。它所具有的高度靈活性以及其他大量的特性,使其經(jīng)常被認(rèn)為是Linux中最好用的軟件包管理工具。Portage system完全用Python和Bash寫成。由于它們均為腳本語言,所以Portage對(duì)于用戶而言也就是完全可見的。
為獲得Gentoo Linux的最新軟件,只需要輸入一個(gè)命令:
? ? ? ? emerge --sync
這個(gè)命令告訴Portage到因特網(wǎng)更新本地的Portage樹。
Portage也是一套軟件包編譯和安裝系統(tǒng)。輸入
? ? ? ?emerge packagename
Portage將自動(dòng)會(huì)為你編譯出一個(gè)滿足你需要的這個(gè)軟件包,并根據(jù)你的硬件進(jìn)行優(yōu)化和確認(rèn)你想要和不想要的特性。
Portage也可以保持你的系統(tǒng)保持最新。只需要輸入一個(gè)命令,
? ? ? ? emerge -uDN world
你將會(huì)使你想要的軟件都自動(dòng)更新一次。
大多數(shù)在Portage中的程式都是以源碼形式存在,用戶可以通過emerge命令來進(jìn)行程序的安裝。從程序的下載、編譯、到安裝、更新完成。Portage有不同的ebuild,超過10,000個(gè),ebuild包含了用來描述如何編譯、安裝和設(shè)定程式的解釋資料。用Portage最大的好處就是Portage會(huì)按照ebuid的描述,會(huì)一手包辦從下載至安裝的所有程序,用戶也可以透過設(shè)定檔 make.conf 對(duì)編譯作優(yōu)化設(shè)定,編譯到已優(yōu)化的程式。
與portage相關(guān)的幾個(gè)目錄:
/usr/lib/portage:? ? ? ? portage程序所在位置,各種portage的行為,皆可通過閱讀程序來獲知
/usr/portage:? ? ? ? ? ? portage tree 官方數(shù)據(jù)庫本地同步目錄
/usr/portage/distfiles:包文件下載目錄,可在當(dāng)前沒有emerge操作進(jìn)行中時(shí)刪除
/var/lib/portage:? ? ? ? 某個(gè)系統(tǒng)信息記錄位置,例如world列表文件
/var/db/pkg:? ? ? ? ? ? ? 系統(tǒng)中安裝的軟件包信息
/var/cache/edb:? ? ? ? 主要臨時(shí)存放依賴關(guān)系信息,可以刪除
2.Portage tree
當(dāng)我們談到軟件包的時(shí)候,我們通常指的是Portage樹為Gentoo用戶提供的包的名稱。Portage樹是ebuilds文件的集合,這些文件包含了Portage管理工具維護(hù)軟件(安裝,搜索,查詢, ...)時(shí)所需要的所有信息,并被默認(rèn)的放置在/usr/portage目錄中。
我們?cè)诎惭b Gentoo 時(shí),一個(gè)必須的步驟是下載一個(gè) Portage 樹的鏡像包,解包后通常安置于 /usr 目錄(即?/usr/portage),之后每次執(zhí)行?emerge --sync?時(shí),便會(huì)根據(jù)官方遠(yuǎn)程網(wǎng)站上的 Portage 樹來更新你本地的 Portage 樹。
Portage 樹有四層結(jié)點(diǎn):
第1層根結(jié)點(diǎn)便是?/usr/portage?目錄
第2層結(jié)點(diǎn)是軟件包所屬分類目錄
第3層結(jié)點(diǎn)是軟件包的名稱目錄
第4層葉子結(jié)點(diǎn)則是 ebuild 文件以及其他輔助性文件或目錄
以?gnome-shell-3.12.2.ebuild?文件為例,它在 Portage 樹中的完整路徑是:
?/usr/portage/gnome-base/gnome-shell/gnome-shell-3.12.2.ebuild
對(duì)于我們期望的軟件包,如果 Portage 樹沒有提供針對(duì)它的 ebuild 文件,那么我們需要自己動(dòng)手豐衣足食。一般是不建議將我們所寫的 ebuild 文件放在 Portage 樹中的,因?yàn)樗鼈兛赡軙?huì)在?emerge --sync?期間被沖刷(比如被官方的同名文件替換)。每當(dāng)您要求Portage對(duì)系統(tǒng)中的軟件包執(zhí)行一些操作的時(shí)候,它會(huì)以系統(tǒng)中的ebuilds文件作為基礎(chǔ)。
3.Overlay
Portage 樹支持一種被稱為 Overlay 的技術(shù)。簡單來說,就是我們可以另行建立一棵新的 Portage 樹,這棵樹的規(guī)模雖然比官方的 Portage 樹小很多,但是 Portage 樹的管理系統(tǒng)可以將這棵新的 Portage 樹與官方 Portage 樹『合并』。如果新的 Portage 樹中某些結(jié)點(diǎn)與官方的 Portage 樹存在重疊,那么 Portage 樹的管理系統(tǒng)會(huì)以前者覆蓋后者,因此我們新建的 Portage 樹通常被直呼為『Overlay』
建立自己的 Overlay
假設(shè)在?/usr/local?目錄中創(chuàng)建自己的 Overlay,約定俗成的方式是:
mkdir -p /usr/local/portage
需要將 Overlay 路徑告知 Portage 管理系統(tǒng),即在?/etc/make.conf?文件中添加以下代碼:
PORTDIR_OVERLAY="/usr/local/portage"
比如當(dāng)前海思平臺(tái)的overlay設(shè)置如下
為了讓我們的 Overlay 能夠被 Portage 管理系統(tǒng)所接受,需要在?/usr/local/portage?中創(chuàng)建?metadata?子目錄,并在該目錄內(nèi)添加內(nèi)容為?masters = gentoo?的?layout.conf?文件即:
mkdir? /usr/local/portage/metadata
echo "masters = gentoo" > /usr/local/portage/metadata/layout.conf
最后,還需要在?`/usr/local/portage?中創(chuàng)建?profiles?子目錄,并在該目錄內(nèi)添加?repo_name?文件。我們可以在這份文件中設(shè)置 Overlay 名稱,只需將 Overlay 名稱寫入該文件即可。例如,我將我的 Overlay 命名為?garfileo:
echo "garfileo" > /usr/local/portage/profiles/repo_name
今后就在這個(gè) Overlay 中學(xué)習(xí) ebuild 文件的編寫。
4.emerge 操作
emerge是Portage系統(tǒng)的命令行接口,主要用于軟件包的安裝、升級(jí)、卸載。emerge可以自動(dòng)處理依賴關(guān)系、更新portage樹、更新已安裝的軟件包。
? ? 語法:? emerge [選項(xiàng)] [動(dòng)作] [ebuild | tbz2file | file | @set | atom] ...
"ebuild"
? 必須是一個(gè)有效的Portage包目錄名(可以不帶類別與版本信息),比如:"portage"或"python"
? 當(dāng)然也可以帶上類別與版本信息,例如:"sys-apps/portage"或"=python-2.2.1-r2"
? 還可以是一個(gè)實(shí)際的文件名,例如:/usr/portage/app-admin/python/python-2.2.1-r2.ebuild
"set"
? ? 是一組特定軟件包集合的代稱。目前有三個(gè)set總是可用:selected, system, world 。
? ? selected 包含用戶手動(dòng)安裝的軟件包集合(/var/lib/portage/world)
? ? ? ? ? ? ? ? ? ? 及其依賴的軟件包集合(/var/lib/portage/world_sets)。
? ? system 表示系統(tǒng)正常運(yùn)行所必須的一組軟件包(基本系統(tǒng)/最小系統(tǒng))。
? ? world 表示 selected 與 system 的合集
"atom"
? 描述了你要安裝的軟件包的一個(gè)限定范圍,比如
? “>=dev-lang/python-2.2-1-r2”? 大于等于2.2-1-r2的最新可用版本
“
? "tbz2file"
一個(gè)有效的tbz2文件,創(chuàng)建于ebuild-.ebuild 或者emerge --buildpkg
1).更新Portage樹
通常我們使用rsync命令來更新Portage樹,它是一個(gè)快速的增量性的文件傳輸工具。另外emerge命令為rsync命令提供了一個(gè)相當(dāng)簡單的前端。
emerge --sync
emerge-webrsync命令會(huì)自動(dòng)將最新的Portage快照下載并安裝到您的系統(tǒng)中
2).軟件的查詢
例如要查找<軟件包名稱>的軟件:
emerge --search <軟件包名稱>
而如果要通過軟件的描述來查找相應(yīng)的軟件,您可以使用--searchdesc?(或者簡寫為?-S) 開關(guān):
emerge --searchdesc <軟件包名稱>
emerge --S <軟件包名稱>
3).軟件的安裝
要安裝<軟件包名稱>:
emerge <軟件包名稱>
因?yàn)樵S多應(yīng)用程序互相依賴,試圖安裝其中任何一個(gè),可能將會(huì)要求同時(shí)安裝其所依賴的其他相關(guān)軟件。無需擔(dān)心,Portage可以很好地處理軟件包間的依賴問題。當(dāng)您安裝某個(gè)軟件的時(shí)候,您可以加上--pretend開關(guān),以便觀察Portage將會(huì)同時(shí)安裝哪些軟件。例如:
emerge --pretend <軟件包名稱>
當(dāng)您要求Portage安裝一個(gè)軟件,必要時(shí)它會(huì)自動(dòng)從internet下載相應(yīng)的源代碼包并默認(rèn)將其保存在/usr/portage/distfiles目錄中,然后將源代碼包解壓縮,編譯并安裝軟件。
如果您僅僅希望Portage將源代碼包下載到本地而不安裝它們,在emerge命令后加上--fetchonly的選項(xiàng):
emerge --fetchonly <軟件包名稱>
4).查找已安裝軟件的文檔
許多軟件包中包含有自己的文檔,有些時(shí)候doc的USE標(biāo)記決定了軟件包中的自帶文檔是否會(huì)被安裝到本地。您可以通過
emerge -vp <軟件包名稱>
命令來檢查是否存在doc?USE標(biāo)記。
emerge -vp alsa-lib
? ? ? [ebuild? N? ? ] media-libs/alsa-lib-1.0.14_rc1? -debug +doc 698 kB
軟件包安裝結(jié)束后文檔通常會(huì)存放在/usr/share/doc目錄下以軟件包名命名的子目錄中
5).軟件的移除
當(dāng)您想把一個(gè)軟件包從系統(tǒng)中移除的時(shí)候,使用
emerge --unmerge <軟件包名稱>
命令執(zhí)行完成后,除了那些在安裝軟件包后您修改過的配置文件,Portage將會(huì)移除此軟件包安裝到您系統(tǒng)中的所有文件。保留這些修改過的配置文件是為了便于您今后再次使用同一個(gè)軟件包.
Portage將不會(huì)檢查您要?jiǎng)h除的包是否仍被其他的包依賴。但是當(dāng)您要?jiǎng)h除一個(gè)可能破壞您系統(tǒng)的重要的軟件包時(shí),它還是會(huì)給予警告。
當(dāng)您從系統(tǒng)中移除一個(gè)軟件包時(shí),之前那些為了滿足其依賴關(guān)系而自動(dòng)被一并安裝的軟件包將會(huì)被保留。如果想讓Portage移除現(xiàn)在可以移除的相關(guān)軟件包,可以使用
emerge --depclean
6).更新您的系統(tǒng)
要保持您系統(tǒng)在最佳狀態(tài)您需要定期的更新您的系統(tǒng)。由于Portage只能檢查本地Portage樹中已有的ebuilds文件,因此您首先應(yīng)該更新您的Portage樹。
emerge --sync
當(dāng)您的Portage樹更新后,您可以用
emerge --update world
命令來更新系統(tǒng)。
我們還會(huì)使用--ask開關(guān)來控制Portage顯示它要更新的軟件包列表,并讓您決定是否繼續(xù)更新。
emerge --update --ask world
Portage接下來會(huì)查找您已經(jīng)安裝的軟件包是否有更新版本,但它只會(huì)核對(duì)那些您已經(jīng)明確地安裝過的軟件包(也就是在/var/lib/portage/world文件中列出的包),并不會(huì)完整去的檢查與這些軟件產(chǎn)生依賴關(guān)系的包是否也需要更新。
如果您想更新系統(tǒng)中的每個(gè)軟件包(包括依賴包),那就加上--deep參數(shù):
emerge --update --deep world
5.equery
equery是Gentoo?linux系統(tǒng)軟件包相關(guān)信息查詢工具,它可查看系統(tǒng)已安裝包的信息。是一個(gè)查詢Gentoo系統(tǒng)中的軟件包,文件和USE標(biāo)簽狀態(tài)信息的工具
使用equery命令之前需要安裝此工具:?emerge?gentoolkit
詳細(xì)請(qǐng)參考官方網(wǎng)站: https://wiki.gentoo.org/wiki/Equery
1. 列出所有已安裝包:
equery list package_name
equery l package_name
2. 查看已安裝包裝了哪些內(nèi)容:
equery files package_name
equery f package_name
3. 查看一個(gè)程序foo隸屬于哪個(gè)包:
equery belongs foo
equery b foo
4. 查看哪些包直接依賴于package_name:
equery depends package_name
equery d package_name
5. 查看已安裝包用了哪些USE:
equery uses package_name
equery u package_name?
USE:
一個(gè)軟件不只包含軟件本身,還包括其組件,如文檔,插件,GUI支持等。
USE就是用來標(biāo)記是否要安裝軟件的同時(shí)安裝這些組件。
臨時(shí)USE :
USE="-Java" emerge seamonkey
USE="python" LINGUAS="en zh_CN" emerge postgresql-server ?
6.ebuild 文件
An?ebuild?is a specialized?bash?script which automates?compilation?and?installation?procedures for software packages. The format was created by the?Gentoo Linux?project for use in its?Portage?software management system.Each version of an application or package in the Portage repository has a specific ebuild script written for it. The script is used by the?emerge?tool, also created by the Gentoo Linux project, to calculate any dependencies of the desired software installation, download the required files (and?patch?them, if necessary), configure the package (based on "USE flag" settings), compile, and perform a?sandboxed?installation (in?/var/tmp/portage/[ebuild name]/image/?by default). Upon successful completion of these steps, the installed files are merged into the live system, outside the sandbox.
若要在 Gentoo 中安裝一個(gè)軟件包,通常要定義如何進(jìn)行軟件源代碼包的下載、解包、打補(bǔ)丁、編譯、安裝以及合并。為了實(shí)現(xiàn)對(duì)軟件包進(jìn)行細(xì)微的定制,還需要定義一些有用的元數(shù)據(jù)(即 USE 旗標(biāo))、補(bǔ)丁文件以及一些操控軟件包編譯與安裝的過程。
Gentoo 是通過 GNU Bash shell 腳本來定義這一切,這種腳本就是所謂的 ebuild 文件。
emerge 與 ebuild 聯(lián)系
簡單的說就是?emerge?這個(gè) Python 腳本會(huì)調(diào)用?ebuild.sh?這個(gè) Bash 腳本,讓后者去執(zhí)行 ebuild 文件定義的軟件包的下載、編譯及安裝過程
ebuild.sh?所操控的軟件包安裝過程是在一個(gè)沙箱(Sandbox)中進(jìn)行的。這一過程結(jié)束后,emerge?腳本需要將沙箱中的成果轉(zhuǎn)移到真實(shí)世界,即?/?目錄。
寫一個(gè)非常簡單的 ebuild 文件
假設(shè)在?app-misc?這個(gè)分類中有一個(gè)名為?hello-world?的軟件包,現(xiàn)在我們要為這個(gè)軟件包的 1.0 版的安裝寫一份 ebuild 文件。
注意:軟件包的分類名并不是隨意的,它必須要與?/usr/portage?中的某個(gè)子目錄名一致。
1).首先在 Overlay 中建立軟件包所在的分支:
? mkdir -p /usr/local/portage/app-misc/hello-world
可從?/usr/portage/header.txt?文件中復(fù)制一份 ebuild 文件默認(rèn)的文件頭,即:
# Copyright 1999-2014 Gentoo Foundation# Distributed under the terms of the GNU General Public License v2# $Header: $
只不過是一些 Bash 腳本注釋形式的文件描述信息而已,但它們是必須的??梢灾苯訉?/usr/portage/header.txt?文件復(fù)制為?hello-world-1.0.ebuild?文件,這樣便可獲得一個(gè)含有上述內(nèi)容的空 ebuild 文件。
ebuild 文件的名稱必須符合 Portage 所認(rèn)可的格式,即:
軟件包名稱-版本號(hào).ebuild
cp /usr/portage/header.txt /usr/local/portage/app-misc/hello-world/hello-world-1.0.ebuild
2).為這份 ebuild 文件增加以下內(nèi)容:
SLOT="0"
有關(guān)SLOT:
通過使用Portage,一個(gè)軟件的不同版本可以共存于一個(gè)系統(tǒng)中。Gentoo的Portage使用一種我們稱之為SLOT的技術(shù)來實(shí)現(xiàn)這種并存。一個(gè)ebuild為它自身的版本聲明了一個(gè)確切的SLOT。具有不同SLOT的同一軟件的ebuild可以共存于同一個(gè)系統(tǒng)中。軟件包可以擁有不同的ebuilds,里面分別有SLOT="1"和SLOT="2"的標(biāo)志。
這樣,我們便建立了一份最為簡單的 ebuild 文件。
3).接下來生成一份簽名文件
cd /usr/local/portage/app-misc/hello-world
ebuild ./hello-world-1.0.ebuild manifest
若簽名成功,會(huì)在 ebuild 文件同一目錄中生成一份名為?Manifest?的文件。將來發(fā)布這份 ebuild 文件時(shí),需要將數(shù)字簽名文件一起發(fā)出,這樣他人便可以驗(yàn)證這份 ebuild 是不是我們做的。因?yàn)榉浅S锌赡芪覀冊(cè)谙蚺笥褌儼l(fā)送 ebuild 文件的過程中會(huì)被壞人攔截,然后篡改 ebuild 文件。由于 ebuild 是可被系統(tǒng)執(zhí)行的腳本,因此很有可能變成『病毒』。因此,ebuild 文件的數(shù)字簽名非常有必要。不過,這里為了簡單起見,沒有涉及如何用自己的密鑰實(shí)現(xiàn)對(duì) ebuild 的簽名,所得?Manifest?文件僅僅是為了讓 ebuild 能夠被 Portage 管理系統(tǒng)所認(rèn)可。
4).繼續(xù)向這份 ebuild 加入一些內(nèi)容:
# Copyright 1999-2014 Gentoo Foundation# Distributed under the terms of the GNU General Public License v2# $Header: $ EAPI="5"SLOT="0"DESCRIPTION="A classical example to use when starting on something new."HOMEPAGE="http://wiki.gentoo.org/index.php?title=Basic_guide_to_write_Gentoo_Ebuilds" LICENSE="MIT"KEYWORDS="~alpha ~amd64 ~arm ~hppa ~ia64 ~ppc ~ppc64 ~s390 ~sh ~sparc ~x86"
基本上就是在原來那份最簡單的 ebuild 文件的基礎(chǔ)上增加了幾個(gè)變量:
EAPI:Portage 系統(tǒng)已經(jīng)為我們編寫了許多有用的 Bash 函數(shù),將?EAPI?的值設(shè)為?5?表示我們要用目前最新的 Bash 函數(shù)。這個(gè)變量必須要在 ebuild 文件頭之后進(jìn)行設(shè)定。
DESCRIPTION:這個(gè)變量存儲(chǔ)了軟件包的簡介信息。
HOMEPAGE:定義了軟件包的項(xiàng)目主頁。
LICENSE:定義了?軟件包所使用的許可證,例如 LGPL,GPL V2,GPL V3,MIT 等。
KEYWORDS:如果你期望軟件包能夠安裝在你的機(jī)器上,那么?KEYWORDS?變量的值必須要包含你在?/etc/make.conf?中所設(shè)定的?ACCEPT_KEYWORDS?值。
一旦改動(dòng)了 ebuild 文件內(nèi)容,那么必須重新生成?Manifest?文件:
ebuild ./hello-world-1.0.ebuild manifest
現(xiàn)在便可以使用?emerge?命令安裝這個(gè)軟件包
5). ebuild 加入SRC_URI
在一個(gè)遙遠(yuǎn)的地方,真的存在著?hello-world 的源碼包。我們只要通過 ebuild 文件將這個(gè)源碼包的位置告訴?ebuild.sh?腳本,ebuild.sh?便會(huì)不遠(yuǎn)萬里將其擒來。所以,我們需要在?hello-world-1.0.ebuild?文件中添加以下內(nèi)容:
SRC_URI="http://dev.gentoo.org/~tomwij/files/wiki/hello-world-1.0.tar.gz"
SRC_URI?這個(gè)變量便是存儲(chǔ)源碼包的下載地址的
在重新生成?Manifest?時(shí),ebuild.sh?便會(huì)自動(dòng)將源碼包下載到?/usr/portage/distfiles?目錄,并為這個(gè)源碼包也生成一個(gè)數(shù)字簽名存儲(chǔ)在?Manifest?文件中。
6). ebuild 加入源碼編譯安裝過程
既然有了?hello-world?的源碼包,那么下一步就該思考如何在 ebuild 文件中定義這個(gè)源碼包的編譯過程了。不過,解開剛才下載的hello-world-1.0.tar.gz?包看一下,發(fā)現(xiàn)包里只有一份 Bash 腳本?hello-world,其內(nèi)容為:
#!/bin/shecho "Hello world!"
所以,這個(gè)源碼包就沒必要編譯了,直接安裝到系統(tǒng)中即可。
我們?cè)?ebuild 文件中獲得了第一次編寫 ebuild 函數(shù)的機(jī)會(huì)。在現(xiàn)有的?hello-world-1.0.ebuile?的文件中繼續(xù)添加以下內(nèi)容:
src_install() {
? ? dobin hello-world
}
src_install?是?ebuild.sh?腳本能夠識(shí)別并執(zhí)行的函數(shù)名。也就是說,從?ebuild.sh?腳本的角度來看,你若想讓我替你將軟件包安裝至系統(tǒng)中,那么你必須得按照我的習(xí)慣來。我的習(xí)慣就是在你提供給我的 ebuild 文件中尋找?src_install?這個(gè)函數(shù),如果有這個(gè)函數(shù),我就執(zhí)行它,否則我就什么也不做。這就是?ebuild.sh?與 ebuild 文件之間達(dá)成的一個(gè)約定。
現(xiàn)在我們?cè)?ebuild 文件中向?ebuild.sh?提供了?src_install?這個(gè)函數(shù)。這個(gè)函數(shù)只包含一條命令:dobin hello-world?。這個(gè)命令的意思是為?hello-world?這個(gè)腳本設(shè)置可執(zhí)行權(quán)限,然后將其安裝至系統(tǒng)默認(rèn)的可執(zhí)行文件目錄中,即?/usr/bin?目錄。
src_install?只是?ebuild.sh?與 ebuild 文件之間眾多約定函數(shù)中的一個(gè)而已,并且這些約定函數(shù)是順次被?ebuild.sh?執(zhí)行的,如下圖所示:
這里存在一個(gè)問題,hello-world?這個(gè) Bash 腳本是包含在?hello-world-1.0.tar.gz?這個(gè)包內(nèi)的,而我們只在?hello-world-1.0.ebuild?文件中定義了?src_install?函數(shù),那么?hello-world-1.0.tar.gz?何時(shí)被解包的呢?
這個(gè)問題的答案是,Portage 管理系統(tǒng)中已經(jīng)為這些約定的函數(shù)定義了默認(rèn)行為。比如,用于為源碼包解包的?src_unpack?函數(shù),其默認(rèn)的定義是:
src_unpack() {
? ? if [ "${A}" != "" ]; then? ? ? ? unpack ${A}? ? fi}
如果在 ebuild 文件中沒有重新定義?src_unpack?函數(shù),那么?ebuild.sh?便會(huì)按照上面圖示的管線調(diào)用默認(rèn)的?src_unpack?函數(shù)。所以?hello-world?腳本得以從?hello-world-1.0.tar.gz?中解出。
7.Eclass
Eclass 是通過 Bash 腳本對(duì)主流的項(xiàng)目構(gòu)建工具進(jìn)行封裝,便于在 ebuild 文件中調(diào)用項(xiàng)目構(gòu)建工具。只有懂得如何應(yīng)用這些項(xiàng)目構(gòu)建工具,方能具備 ebuild 來控制它們。
以安裝oce軟件包為例
獲取 GIT 倉庫中的源代碼
上文談到只需在 ebuild 文件中定義?SRC_URI?變量,ebuild.sh?腳本便可以根據(jù)?SRC_URI?的值自動(dòng)下載源碼包?,F(xiàn)在我們面臨的問題是如何從 Git 倉庫的服務(wù)器端遷出軟件包源碼,這時(shí)?SRC_URI?便無效了,需定義?EGIT_REPO_URI?這個(gè)變量,其值為 git 倉庫地址。
即使在 ebuild 中定義了?EGIT_REPO_URI,ebuild.sh?也不知道應(yīng)該如何處理這個(gè)變量。因?yàn)楦鶕?jù)?EGIT_REPO_URI?的值從 git 倉庫遷出源碼的函數(shù)是在?/usr/portage/eclass/git-2.eclass?中定義的,因此為了能夠讓?ebuild.sh?調(diào)用這個(gè)函數(shù),需要使用?inherit?函數(shù)。
inherit?就類似于 C 語言的?#include,可以載入?/usr/portage/eclass?中的 Eclass 文件。
下面這個(gè) ebuild 文件足以從 github 服務(wù)器上遷出 oce軟件包源碼。
# Copyright 1999-2014 Gentoo Foundation# Distributed under the terms of the GNU General Public License v2# $Header: $EAPI=5inherit git-2DESCRIPTION="This project aims at gathering patches/changes/improvements from the OCC community over the latest release"HOMEPAGE="https://github.com/tpaviot/oce"EGIT_REPO_URI="git://github.com/tpaviot/oce.git"LICENSE="LGPL"SLOT="0"KEYWORDS="~amd64"
CMake 編譯環(huán)境的配置
ebuild.sh?可以通過?/usr/portage/eclass/cmake-utils.elcass?中定義的一些函數(shù)來調(diào)用 CMake 完成源碼的編譯與安裝,但是必須事先使用?inherit?載入?cmake-utils.eclass
由于?inherit?函數(shù)支持多個(gè)參數(shù),因此可將上文中的?inherit?行修改為:
inherit git-2 cmake-utils
這樣便使得?ebuild.sh?具備了操控 CMake 的能力。
默認(rèn)的 CMake 構(gòu)建環(huán)境是將?/usr/local?作為源碼編譯結(jié)果的安裝目錄的前綴。如果是手動(dòng)編譯安裝 oce,那么?/usr/local?這個(gè)目錄前綴似乎并不壞。但是現(xiàn)在我們是要讓 Portage 來管理 oce的安裝與卸載,如果不使用?/usr?作為目錄前綴,給人的感覺是太不嚴(yán)肅了。因此,必須要將 oce安裝到?/usr?目錄中。要做到這一點(diǎn),需要修改 oce的 CMake 默認(rèn)的安裝目錄前綴。
cmake-utils.eclass?的參考文檔中給出了修改 CMake 默認(rèn)構(gòu)建環(huán)境的標(biāo)準(zhǔn)做法,即:
src_configure() {
? ? ? ? local mycmakeargs=(
? ? ? ? ? ? -DOCE_INSTALL_PREFIX=/usr
? ? ? ? )
? ? ? ? cmake-utils_src_configure
}
在?mycmakeargs?這個(gè) Bash 數(shù)組中給出我們期望的編譯選項(xiàng)即可。由于我們的目的僅僅是想修改 oce默認(rèn)的安裝目錄前綴,因此只需在?mycmakeargs?中給出?OCE_INSTALL_PREFIX?變量的定義,至于?OCE_INSTALL_PREFIX?這個(gè)變量的來歷,需要懂得一些 CMake 的知識(shí)。
安裝oce
首先需要?jiǎng)?chuàng)建?/usr/local/portage/sci-libs/oce?這個(gè)分類目錄,然后在該目錄中添加?oce-9999.ebuile?文件,內(nèi)容如上一節(jié)所述。
之所以使用?9999?這個(gè)版本號(hào),并不是出于中國對(duì)數(shù)字?9?的迷戀,而是用它來表示一個(gè)最新的版本號(hào)。也就是說,gentoo 開發(fā)者認(rèn)為正常的軟件版本號(hào)很少會(huì)大于這個(gè)數(shù)字,因此你安裝的?9999?版本便不會(huì)被小于這個(gè)版本號(hào)的同一軟件包覆蓋。
然后使用生成?oce-9999.ebuild?的簽名文件:
? cd /usr/local/portage/sci-libs.oce
? ? ebuild ./oce-9999.ebuild manifest
剩下的事情就是編譯安裝 OCE 的源碼包了,即:
? emerge -avt oce
上面這個(gè)命令做了很多工作:
從 github 服務(wù)器遷出 OCE 源代碼;
在?/var/tmp/portage?目錄開辟 OCE 的編譯環(huán)境,即沙盒(Sandbox);
在沙盒中編譯 OCE 源碼,并將編譯結(jié)果復(fù)制到沙盒中指定的安裝目錄;
將沙盒中的安裝目錄中的文件按照目錄結(jié)構(gòu)復(fù)制到?/?目錄。
這一切的工作,都是在 ebuild 文件的指示下進(jìn)行的。
8.ebuild 中軟件包依賴
如何在 ebuild 文件中設(shè)定軟件包的幾種常規(guī)性依賴:
隱性的系統(tǒng)依賴
在 Gentoo 中,所有的軟件包在編譯及運(yùn)行時(shí)期都會(huì)存在一種隱性的依賴,被依賴的軟件包都居于?system?這個(gè)軟件包集中。這個(gè)軟件包集在安裝 Gentoo 期間便落地生根,與 Gentoo 系統(tǒng)共存亡,所以它們就變成了 Gentoo 軟件包的隱性依賴。
若想看一下這些幕后的英雄,下面這條命令可使之浮出水面:
emerge --pretend @system
軟件包構(gòu)建期依賴
在 ebuild 文件中,可以通過?DEPEND?這個(gè)變量來指定在解包、打補(bǔ)丁、編譯以及安裝軟件包過程中的依賴。大部分軟件包在構(gòu)建期間均需要一些程序庫的頭文件與庫文件,如果系統(tǒng)中沒有安裝相應(yīng)的程序庫,那么就無法在系統(tǒng)中構(gòu)建這些軟件包。
軟件包運(yùn)行時(shí)依賴
將軟件源碼包的編譯結(jié)果安裝到系統(tǒng)中后,可以將此刻的狀態(tài)視為軟件已經(jīng)安裝至系統(tǒng)中,但是在運(yùn)行軟件的期間,可能還是需要其他軟件包的支持,這就是軟件包運(yùn)行時(shí)依賴。這種依賴,也是大部分 Linux 發(fā)行版都致力解決的問題。
在 ebuild 文件中,RDEPEND?這個(gè)變量用于指定軟件包運(yùn)行時(shí)依賴。
如果確定軟件包的運(yùn)行時(shí)依賴與構(gòu)建期依賴相同,那么直接將?DEPEND?的值賦于?RDEPEND?變量即可。
9999.ebuild 文件中?,F(xiàn)在,完整的 oce-9999.ebuild 內(nèi)容如下:
# Copyright 1999-2014 Gentoo Foundation# Distributed under the terms of the GNU General Public License v2# $Header: $EAPI=5
inherit git-2 cmake-utils
DESCRIPTION="This project aims at gathering patches/changes/improvements from the OCC community over the latest release"HOMEPAGE="https://github.com/tpaviot/oce"EGIT_REPO_URI="git://github.com/tpaviot/oce.git"LICENSE="LGPL"SLOT="0"KEYWORDS="~amd64"DEPEND="media-libs/ftgl
? ? ? ? virtual/glu
? ? ? ? virtual/opengl
? ? ? ? x11-libs/libXmu"RDEPEND="${DEPEND}"src_configure() {
? ? local mycmakeargs=(
? ? ? ? ? -DOCE_INSTALL_PREFIX=/usr
? ? )
? ? cmake-utils_src_configure
}
Gentoo 升級(jí)系統(tǒng)的標(biāo)準(zhǔn)步驟
#emerge --sync????? //升級(jí)整個(gè)portage目錄
#emerge portage?????//如果不是最新的portage,需要按提示執(zhí)行此操作
#emerge python?????//如果不是最新的python,需要按提示執(zhí)行此操作
#/usr/sbin/update-python?????//執(zhí)行完emerge python后執(zhí)行此操作
#emerge -avuDN world??????//按照 /var/lib/portage/world 文件下的包,重新構(gòu)建整個(gè)系統(tǒng)
?參數(shù)說明:??--ask (-a)? 控制Portage顯示它要更新的軟件包列表,并讓您決定是否繼續(xù)更新
????????????????--verbose (-v) 在屏幕上輸出完整的文件列表
????????????????--update (-u) 更新包的最佳版本
????????????????--deep (-D)? 更新系統(tǒng)中的每個(gè)軟件包
????????????????--newuse (-N) USE標(biāo)記變更后,要使Portage檢查USE標(biāo)記的變動(dòng)是否導(dǎo)致
????????????????????????????需要安裝新的軟件包或者將現(xiàn)有的包重新編譯
#emerge -av --depclean?????//清除不需要(孤立)的軟件包
#revdep-rebuild?????//gentoolkit包里面的一個(gè)軟件,用來檢查系統(tǒng)的依賴關(guān)系是否都滿足,
????????????????????????????自動(dòng)安裝沒有滿足關(guān)系的包
#dispatch-conf?????//更新系統(tǒng)的配置文件
#emerge -e world?????//本地重新編譯整個(gè)系統(tǒng),USE標(biāo)記變化不大時(shí)不需執(zhí)行
?參數(shù)說明:?--emptytree (-e)??