跳轉至: ,
打包
通用打包指南 - 命名指南 - Spec 文件指南 -
OBS 打包互助問答 - 打包黑名單
什么是 spec(配置規范文件)?RPM 編譯過程的核心是處理 .spec 文件。它說明了軟件包怎樣被配置,補綴哪些補丁,安裝哪些文件,被安裝到哪里,在安裝該包之前或之后需要運行那些系統級別的活動。它必須手寫,但更簡單的辦法是拿來他人寫好的,在此基礎上修改。RPM 自身對于你能在 spec 文件中做什么沒有太多限制,所以你可以搞的很復雜。本指南試圖減少一些特殊區域的差異以使它易于維護。
目錄
請叫我瑪嘎學姐
Email: i@.su
Blog:
IRC:
Wiki
Build
Talk: i#.su
: @
噗浪: @
模板幫助
通用指南
所有的 spec 文件必須易讀。如果其他的打包者看不懂你的 spec 文件,他們就不可能去復核你的包或者與你協作。
Spec 模板
當你從零開始打包一個軟件的時候,你應該基于 spec 模板來寫你的 spec 文件,(參見 )。下面是一個針對名為 我的軟件 的軟件包的基本配置:
# 添加開發工具源 sudo zypper -p http://download.opensuse.org/repositories/devel:/tools/openSUSE_12.1 -v in osc rpmdevtools # 定位到你的項目文件夾 cd .../MYPROJECT # 在構建服務官網上注冊你的包 osc mkpac MYPACK # 定位到你的軟件包根目錄 cd MYPACK # 用wget下載你的軟件包的源代碼 wget http://upstream.example.org/source/.../MYPACK-1.0.tar.gz # 使用 rpmdev 工具生成你的軟件包的 spec 模板文件 rpmdev-newspec -t lib MYPACK (或者直接使用 vi MYPACK.spec 即可。項目文件夾下的任何空白 spec 文件都會被模板自動填充) # 生成軟件更新日志 osc vc # 編輯你的spec文件 vi MYPACK.spec # 之后可以用: # osc build 編譯 # osc ci 掃描文件改動并上傳到構建服務器
請把你的注意力從 spec 文件的格式和組織方式上移開,盡可能的順著這個模板一步一步往下填。這么做不是因為我們認為這是唯一正確的寫 spec 文件的方法,而是讓在你提問的時候,幫助你的那個人能更方便的定位錯誤和很快就明白你試圖做什么:-)。
針對特殊編程語言的特殊 spec 文件也可以被特殊的工具制作出來,例如 或者 -。想了解更多就去瞧瞧:
Spec 文件的編碼
如果不需要使用 ASCII字符集以外的字符,那就不用關心 spec 文件的編碼。如果使用了 ASCII 字符集以外的字符,請把 spec 文件以 UTF-8 編碼保存。如果不確定一個字符是不是屬于 ASCII 字符集,請參見: ACII字符地圖。
Spec 文件的授權
由于一些法律上的原因,spec 文件必須有一個授權說明的頭部。請注意,如果你不寫,開放式構建服務就會把它自己默認的加給你。如果這不是你想要的那樣子,你可以參考下面的模板寫你自己的。
# # spec file for package python-$FOO # # Copyright (c) $CURRENT_YEAR $YOUR_NAME_WITH_MAIL_ADDRESS # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed # upon. The license for this file, and modifications and additions to the # file, is the same license as for the pristine package itself (unless the # license for the pristine package is not an Open Source License, in which # case the license is the MIT License). An "Open Source License" is a # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. # Please submit bugfixes or comments via http://bugs.opensuse.org/ #
#中文版 # # # 軟件包 軟件包名寫這里 的 spec 文件 # 版權所有 (c) 年份寫這里 你的名字 你的電郵 # # 第三方修訂者擁有對本文件的任何修正和增補的版權,除非他們宣布放棄。這份文件本身的授權, # 修復和增補的授權,都和軟件包的授權相同(除非軟件包不是以開源協議發布,例如MIT協議)。 # 開源協議是一種遵守開源行動制定的開源定義的授權許可。 # 請通過 http://bug.opensuse.org 提交錯誤報告和評論。 #
宏
請使用宏而不是硬編碼的文件夾名 (可用宏請參見 打包指南之打包慣例:RPM宏). 在 : 或者 Patch: 行使用宏是高手的象征。有些人認為在 : 行不使用宏會更加易讀。另一些人喜歡用宏,這樣升級版本的時候他們就不用手動改這里了。兩種都可以,但請統一風格并書寫正確。如果你需要查看包含宏的字符串背后的真實內容的話,你可以使用rpm命令。例如,查看 : 背后的真實內容,你可以用:
rpm -q --specfile foo.spec --qf "$(grep -i ^Source foo.spec)\n"
注意:以上方法對于 %name 和 % 都可用,但是用戶自定的宏可能會失敗。
宏 vs RPM 變量
在 spec 文件中有兩種定義編譯根目錄和優化參數的風格。
宏風格 變量風格
編譯根目錄
%
$
優化參數
%
$
兩者都是正確的,最終解析成的也是同樣的值,但打包者應該選取一種風格并持續的在打包生涯中使用。混用,本身是合法的,但是從與其他人互動和易用性的角度看,是不應該在 中這么用的。
RPM 變量在包含它的命令腳本執行前被解析。由于 sh 的執行是臭名狼籍的慢,因此%-宏應該優先考慮,此外你其實已經使用了宏 % ,所以也不得不把其他的都寫成宏,因為上面那些是沒有 RPM 變量來替代的。
條件依賴
這章是 討論 - 貢獻重寫的,因為英文版是直接復制 的,而 的 Koji 構建服務是要上傳 SRPM 和 spec 文件的,對 來講 SRPM 就驢唇不對馬嘴了。
詳情見 RPM 條件依賴,這是目前互聯網上最詳細的資料。
報頭
以下是對 spec 文件報頭的要求。
命名 / 版本信息
見 包命名指南。
元數據標簽概要()標簽描述()標簽
描述是在概要的基礎上的展開。在描述標簽里不要收納任何安裝說明樣子的東西,它不是用戶手冊。如果軟件包要求手動配置或有其他重要說明要告之用戶,在軟件文檔里告訴他們。覺得有必要的話可以添加一個 .SUSE 或其他類似的文件。另外請確保你的描述每行不超過70個字符(受 YaST 軟件管理器在使用 庫進行高級終端處理時描述窗口的大小所限,不是指你在圖形界面打開的那個 YaST,是你 DVD 安裝時的那個字符界面的 YaST) 。描述也不該超出合理的長度,多于20行可能就太多了。
軟件包的描述應該輔助并使用戶不用安裝其他類似的軟件包就找到對的符合他目的的包。這里才是更詳細的告知用戶一個軟件的功能的地方。它應該包含更多的軟件特性的信息和與其他類似特性的軟件包的不同之處。如果一個包有可能破壞用戶的安裝,那描述就應該明確警告這個包的潛在風險和副作用。
請放下你的個人喜好,在概要和描述中使用美式英語的拼寫吧。出于對整個 RPM 數據庫大小的考慮,RPM 的 spec 文件只包含了英語版本的概要和描述。不靠譜的本地化是由 YaST 來控制的。
2011年夏天之后,描述結尾部分的軟件作者列表再也不應該被收納進來了。我們使用了一個獨立的 文件來給他們表功。如果上游的源代碼包沒有這部分,你可以創建一個,然后像下面這樣寫:
Source2: AUTHORS ... %setup cp?%{S:2} . <= 這個縮寫值得學習,全文是?%{SOURCE2},最后那個.表示當前文件夾,也就是?%{buildroot} ... %files %doc AUTHORS
概要或描述標簽中用到商標
打包者應該注意在概要或描述中使用商標的方式。下面是幾條需要遵守的規則:
如果你不確定的話,問問自己,有沒有可能讓別人誤以為這個包是官方版?如果還有猶豫,干脆就把商標從你的表述中去掉。
依賴關系 運行依賴
RPM 有超級牛力去自動尋找函數庫和諸如 Perl 模塊的運行間依賴關系。簡單說,別重造輪子此文檔有宏是什么意思,這活兒交給 RPM 就好。通常沒有必要去單獨列示像 : 這樣的字段,RPM 發現你依賴了 包的共享庫就會自動幫你選取這個運行依賴。
如果你的包分成了幾個子包,那么子包需要用 :%name =% 代碼來請求對主包的附帶版本號的運行依賴。
-devel 子包需要明確的依賴這些開發工程包做了軟鏈接的共享庫所在的庫包,例如 -devel 需要 : =%, =%
小提示: 在 %files 字段中只有 .0.473.1.so 這樣的名稱最全的庫文件才應該被放到 %{name}-libs / lib%{name}? 這樣的共享庫包中,其他的 .0.so, .0.473.so 這樣的文件大部分都是做的軟鏈接,應該放到 -devel 開發工程包中。
前期依賴
軟件包不應該使用 標簽。曾幾何時,在查找依賴關系時的循環里 用來在 RPM 決定安裝順序時 “獲得” 一些普遍的運行依賴(那時 RPM 處理能力不強,包也不標準,你運行時依賴 , 但是你想編譯發生就需要一些基礎系統包比如 這種,等它一個一個依賴解決到這個層面是很慢的)。現在這個標簽再也用不到了。
編譯依賴
不同于運行依賴 ,編譯依賴 是沒有自動查找程序的。你必須單獨列出你的軟件包成功編譯所需要的包。寫個好的編譯依賴會節省所有開發者和測試者的時間,因為他們不用再去手動查找缺失的編譯依賴。這也保證了編譯是可再生的,輸出的包是永遠有相同特性的。例如,如果編譯依賴里沒有 -devel 包的話, 腳本,就有可能找不到 PNG 圖像的支持。通過這樣的代碼 : -devel (或者 11.4 之后才有的: : (),在沒有安裝 -devel 編譯依賴時,你可以讓編譯拋錯并中止。
對于我們打包者來說,最重要的字段就是編譯依賴 ,但由于它的手動屬性,留給我們的方法不多,如果不是修補他人 spec 文件里的編譯依賴的話,試錯是唯一通向成功的路:
如果到這里依然行不通,如果你是程序員(碼農),那就是你大顯神通的時候了; 如果不是,就當是進行了一場心靈的旅行吧,報個 Bug,重新上路。畢竟,漫漫長路,最美總是在路上不是咩?針對 宏嵌套 的 OBS 警告
條件編譯依賴僅限于簡單的變量。RPM 一般通過這樣的%if 表達式來支援復雜的構造:
%if 0%(test "%something" = "enabled" && echo 1)
(上面是一個有兩層宏嵌套的例子,第一層是 0%(),第二層是%。)
但是當評估編譯依賴的時候,構建服務的 RPM 解析器是運行在一個 宏嵌套展開 被禁止的環境中的。你會看到這樣子的警告:
Warning: spec file parser line 109: can't expand?%(...)
下面這個例子只使用了一個簡單變量,因此和 編譯依賴 兼容:
%if?! 0%?have_own_mpfr BuildRequires: mpfr-devel %endif
豁免情況
不需要把下列包或者他們的依賴作為 ,因為他們出現的太頻繁了。它們已經被作為開放構建服務的最小化編譯環境被預裝了。之所以構建服務禁用了 % 宏,原因就在于此。你可以用此命令得到這個列表:
osc meta : | egrep '^(:|:|:)'
Preinstall: aaa_base acl attr bash coreutils diffutils Preinstall: filesystem fillup glibc grep insserv libacl libattr Preinstall: libbz2-1 libgcc%{gcc_version} libxcrypt m4 libncurses5 pam Preinstall: permissions libreadline6 rpm sed tar zlib libselinux1 Preinstall: liblzma5 libcap2 libpcre0 Preinstall: libpopt0 libelf1 liblua5_1 Required: gcc gcc%{gcc_version} glibc perl rpm tar patch Support: autoconf automake binutils bzip2 gcc gcc%{gcc_version} Support: gettext-runtime glibc libtool perl rpm zlib Support: libncurses5 Support: libaudit1 cpio cpp cpp%{gcc_version} cracklib cvs Support: file findutils gawk gdbm gettext-tools Support: glibc-devel glibc-locale groff gzip info less Support: libbz2-devel libdb-4_8 Support: libstdc++%{gcc_version} Support: udev Support: libxcrypt libzio Support: linux-glibc-devel make man netcfg Support: net-tools pam-modules patch perl-base sysvinit-tools Support: texinfo timezone util-linux libmount1 login Support: libgomp%{gcc_version} libuuid1 psmisc Support: terminfo-base update-alternatives pwdutils build-mkbaselibs Support: brp-check-suse post-build-checks rpmlint-Factory Support: build-compare Support: libunwind libunwind-devel
依賴沖突
會盡可能的去自動避免包之間的依賴沖突。但不幸的是,目前還達不到完全自動避免。 的依賴沖突政策詳見: 依賴沖突。
文件依賴
除了依賴包,RPM 還賜予了你依賴文件的能力,但這種既懶惰又不標準的能力即使不會讓你深陷泥潭,也會抹殺掉你大部分的創造力。盡量使用:
只要有可能性,你都要去避免依賴 /etc, /bin, /sbin, /usr/bin, 或者 /usr/sbin 以外的文件。依賴這些文件夾以外的文件要求 (和其他使用“軟件源”這種方式的依賴解決工具,其實就是命令行的軟件在線安裝工具啦)去下載和解析一個龐大的 XML 文件,在里面查找你依賴的文件所在的包。通過依賴包而不是依賴文件的方式來幫助依賴解決工具避免這個過程會節省最終用戶大把的時間。
很多時候,其他一些技術上的考慮會壓倒這些考慮。一個特殊例子就是安裝路徑在 %// 的包。在本例中,授權你包中的某個特殊的小瀏覽器程序作為這個文件夾的所有者(通過 %files 宏的子宏 %dir),會給你拖上一大堆不需要的包,至少 那一堆就躲不過。兩害相權取其輕,下載一堆包還是下載一個大 XML 文件并占用點處理器運算時間,相信請求這個文件夾作為文件依賴會是更好的選擇。
補丁
所有 spec 文件中提到的補丁都應該在最上面有一條說明它們狀態的評論。詳見 打包指南之補丁 頁面。
預備處理 (%prep)
以下是對 spec 文件的預備處理標簽的要求
%setup 消音
你應該傳送 -q 參數給 %setup 宏。這會顯著減少編譯日志文件的輸出,尤其是源代碼包會解壓出一堆文件的時候。
編譯 (%build)
以下是針對 spec 文件的編譯章節的規則
編譯器參數
用來編譯軟件包的編譯器應該尊重系統 RPM 配置中設定的可用編譯器參數。現實點說就是 C,C++ 和 編譯器應該尊重 % 宏(等價 RPM 變量: $)。尊重的意思是說在軟件包編譯時使用此宏/變量對應的真實內容作為編譯器實際使用的參數。如果理由夠充分,附加額外參數,重定義覆蓋一些參數以及過濾這些參數中的一部分都是允許的,但這么做之前應該再三思量并把理由注釋進 spec 文件,尤其是當你要覆蓋或過濾參數的時候。
并行 make
可能的話, 應該這樣調用 make:
make?%{?_smp_mflags}
通常這都會加快編譯,尤其是在有對稱多處理器(即雙核心/四核心)的機器上。這比 %{?jobs:-j%jobs} 更受歡迎,因為它允許使用交叉編譯參數,make -lN,而不是通過多線程編譯參數硬性指定線程 -jN。然而,請務必確認,你的軟件包可以 干凈的 這么編譯,因為有些作者的 不支持并行編譯,或者這么做會搞壞你的依賴關系。
如果源代碼包不支持并行編譯的話,請在 spec 文件中用注釋提示這點,并且最好用 -j1 參數,這樣其他人用 grep 命令會方便的知道該包不支持并行編譯。
安裝 (%)
以下是對 spec 文件中安裝章節的規則:
因為 是以一個非特權用戶運行的(就是最常見的那個 # no root for build),運行 make 的時候必須不能試圖去擁有文件的所有權(無論是直接使用 chown 命令,還是利用這樣的命令如, -o root)。文件的所有權應該在下面的 %files 部分來設定。
原版 RPM 的宏包和 SUSE 的 rpm 包里面帶的宏包提供了兩種名字相近所以特別愛混淆的安裝宏:
# 在原版 RPM 的宏包中: # 這種模擬方法套用了現在的 autotools 里面的?%configure: %make_install 相當于 make install DESTDIR=%{?buildroot} #------------------------------------------------------------------------------ # 這種模擬方法是為了和老的不支持 DESTDIR 或者用 DESTDIR 會崩潰的包兼容 %makeinstall \ 相當于 make \\\ prefix=%{?buildroot:%{buildroot}}%{_prefix} \\\ exec_prefix=%{?buildroot:%{buildroot}}%{_exec_prefix} \\\ # 為什么叫模擬呢,因為真正的 make install 是在命令行里面用的。 [...]
SUSE 的 rpm 的宏包,在 /usr/lib/rpm/ 里,把上面兩種都重新定義為其實是一回事的宏了(因此不再支持老的 方式了):
%make_install make install DESTDIR=%{?buildroot} %makeinstall make DESTDIR=%{?buildroot:%{buildroot}} install
因此,你最好用且只用 %。
移除編譯根目錄
把在 % 的頭部使用 rm -rf%{} 或 rm -rf $ 標記為“壞的寫法”:
?%install rm -rf $RPM_BUILD_ROOT mkdir -p $RPM_BUILD_ROOT/usr/... 或 make install
為什么呢?
一般是在 /var/tmp,你造成了一個“競速危機”,把自己暴露給同一臺計算機上的本地攻擊者,他可能控制你的賬戶(甚至是根賬戶,如果你用它編譯的話)。最好在% 章節完全不要用 "rm -rf $",而是依靠%clean 來做。
如果一定要做,使用:
?%install rm -rf $RPM_BUILD_ROOT mkdir $RPM_BUILD_ROOT mkdir -p $RPM_BUILD_ROOT/usr ... or make install
這樣如果攻擊者想要用他自己的磁盤鏈接來替換你的 的話,"mkdir $" 會出錯,整個編譯也會中斷。
PS:“競速危機”是指你馬上要做的事依賴前一個你發起卻管不了過程的事的返回結果,如果有人在結果出來前偽造了一個結果給你,你要做的事實際上幫助了攻擊者釣魚。意即你前一件事的運行時間必須和偽造結果所需的時間賽跑。
清理 (%clean)
%clean 章節,如果有的話,會在 RPM 二進制包和 RPM 源碼包生成后運行。在開放構建服務上這是沒必要的,因為無論如何用來編譯這個包的 環境或虛擬化環境都會被抹去。 通常不支持在已有環境中編譯軟件包。(cf. bnc# c4)從 rpm-4.7/.3 開始, 如果 %clean 字段在 spec 文件中沒有的話,rpm 會默認使用 "%clean: rm -Rf%"。
很早以前,在 %clean 刪除一些包前會檢測 %{} 不是 /。 這在 中也不需要了。
代碼片段 (%post* /%pre*)
這里是關于 spec 文件中 “代碼片段” 章節的規則。使用代碼片段應該慎之又慎。只有在合情合理的情況下才使用它。一些常見的代碼片段被歸檔在:: .
代碼片段的運行依賴 ()
你的包必須聲明你在代碼片段中使用的任何東西。表示法如下:
Requires(pre): ... Requires(post): ...
注意: 和 (pre) 的內容不能有相同的部分,即 (pre) 要求的包只用在%pre 章節,也即它是“代碼片段”的依賴而不是包的依賴。如果有相同,會造成編譯成功的 .log (本地編譯會產生在 /var/tmp/build-root/home///OTHER, 開放構建服務官網點擊""字樣后在編譯日志“”的最后一章就是它的內容,也可以點擊源名稱如”“后看到生成的二進制 RPM 包和源代碼 SRPM 包,最下面的下載鏈接就是 .log,另外不同的源會生成不同的 .log)里產生一個 (依賴冗余) 警告。
只允許針對特定目錄寫代碼片段
根據下標,包編譯指令 (%prep, %build, %, %check 和 %clean) 里只允許變動 (創建、修改、刪除) %, %, % 和有效的臨時位置如 /tmp, /var/tmp (或 rpm 編譯過程設定的 $ (valid?) 或 %) 中的文件。
/tmp, /var/tmp, $,%{} %{} %{}
%prep
是
是
否
%build
是
是
否
%
是
是
是
%check
是
是
否
%clean
是
是
是
上表中規則不管你用什么用戶編譯都必須被遵守。
文件 (%files)
這里是針對 spec 文件的“文件”章節的規則。 沿襲了 文件系統層級標準 對文件系統布局的安排。該標準定義了文件應該被放置在系統的哪個位置,任何對該標準的背離都應該在 spec 文件中注釋并解釋為什么這么做是合理的。
所有權
您的軟件包應該擁有在 % 章節安裝的全部文件。軟件包不能擁有已經被其他軟件包擁有的文件。這里的經驗法則是第一個安裝的軟件包應該擁有其他包可能依賴的文件。如果你認為你有充分的理由去擁有一個其他軟件包已擁有的文件,那么請在軟件包提交到工廠版的復核請求里指出它。
文件夾的擁有權比文件的擁有權稍微復雜一點。盡管經驗法則是相同的:擁有你的軟件包在安裝過程中創建的全部文件夾此文檔有宏是什么意思,不要擁有你的軟件包依賴的軟件包的文件夾,在一些特殊情況下,多個軟件包擁有同一個文件夾也是可以的。這些特例如下:
你的軟件包依賴的軟件包提供的文件夾可能在該依賴包的后續版本中提供不同的文件夾,但你的軟件包仍會使用原來提供的文件夾。一個普遍的例子是 Perl 模塊。假設 perl-A-B 依賴 perl-A 并且把文件安裝到 /usr/lib/perl5//5.8.8/i386-linux--multi/A/B. Perl 基礎軟件包保證了它會擁有 /usr/lib/perl5//5.8.8/i386-linux--multi ,只要它還與 5.8.8 版本兼容,但未來升級 perl-A 依賴包的時候可能會擁有并安裝文件到 /usr/lib/perl5//5.9.0/i386-linux--multi/A. 這時 perl-A-B 軟件包就需要去擁有 /usr/lib/perl5//5.8.8/i386-linux--multi/A 和 /usr/lib/perl5//5.8.8/i386-linux--multi/A/B 以便保持合理的所有權。 多個軟件包都安裝了文件到一個常見文件夾中,但這些文件互不依賴。一個例子:
Foo-Animal-EMu 把文件放到 /usr/share/Foo/Animal/Emu Foo-Animal-Llama 把文件放到 /usr/share/Foo/Animal/Llama
兩個包互不依賴。沒有其中一個軟件包需要另一個軟件包去擁有 /usr/share/Foo/ 文件夾的情況。在這種情況下,它們都必須宣稱擁有 /usr/share/Foo/ 文件夾。
無論如何,我們都不能讓系統中出現無人擁有的文件夾。詳情見 /.
一個 軟件包必須不能在 %files 列表里包含任何的冗余文件,冗余文件不但指一個文件被打包了兩次或以上(在兩個或多個子軟件包中),還指文件內容上的雷同。可以使用 %% (需要添加 : ) 來巧妙的通過硬鏈接來清理冗余文件。
權限
文件權限必須妥善設定,例如可執行文件需要給它設定執行權限。每個 %files 章節必須包括一行 %(...)。下面是默認的設定:
%files %defattr(-,root,root)
如果你沒有一個非常好的原因去背離它,你應該對你軟件包中所有的 %files 章節使用 %(-,root,root) 設定。
訪問授權 (SUID bits)
待修正 本章節基于“試錯”法寫作,還沒有找到任何有關于此的文檔。
在 下面,安全相關的權限是通過 /etc/* 來處理的。軟件包特有的權限可以通過在 /etc/.d/ 里放文件來定義。閱讀 /etc/* 的例子來取得這部分知識。
如果你想要創建一個需要設定用戶和組權限的程式,你應該如下去做:
由于上面所說的包含一些不顯著的細節,下面給出一個簡化的例子:
[...] Source2: permissions Source3: permissions.easy Source4: ?%{name}-rpmlintrc [...] Requires(post): permissions [...] %install [...] mkdir -p?%{buildroot}%{_sysconfdir}/permissions.d/ install -m 644?%{S:2}?%{buildroot}%{_sysconfdir}/permissions.d/%{name} install -m 644?%{S:3}?%{buildroot}%{_sysconfdir}/permissions.d/%{name}.easy %if 0%{?suse_version} >= 1120 %verifyscript %verify_permissions?-e?%{_bindir}/mysuidprogram %endif %post %if 0%{?set_permissions:1} > 0 ?%set_permissions?%{name} %else ?%run_permissions %endif %files %defattr(-,root,root,-) [...] %verify(not user group mode)?%attr(0711,root,root)?%{_bindir}/mysuidprogram [...]
這至少對你 私人車庫 下的軟件包是適宜的。
文檔 文件
任何分發的源代碼中附帶的相關文檔都應該被附加到軟件包中去。不相關的文檔包括像“編譯指南”,無處不在的寫有一般編譯指南的 文件,和給非 Linux 系統的文檔,比如 .MSDOS。另外還需注意你應該把文檔放在哪個子軟件包,例如 API 文檔歸屬于 -devel 子軟件包,而不應該是主軟件包。或者如果有好多文檔,那可以考慮把它們單獨切分為一個子文檔包。在這種情況下,推薦使用 *-doc 作為子軟件包名, 作為 Group 標簽的值。
還有,如果一個軟件包包含了一些 %doc 的東西,它必須不能影響程式的運行環境。簡單說:如果它在 %doc 里,那么即使它沒有程序也必須能運行。
配置 文件
配置文件必須在軟件包中被標記為配置文件。這里的經驗法則是,如果你大膽猜測單純使用簡單的 % 會破壞東西,那么就用 %() 來替換它。換句話講,當軟件包升級需要覆蓋本地配置文件中的更改時請一定三思而后行。一個不使用 %() 的例子是當一個軟件包的配置文件更改過以至于新版本的包不能和它一起工作了的時候。無論何時使用 % ,最好在 spec 文件里加注簡短注釋說明為什么那樣子做。
不能在 /usr 目錄下使用 % 或者 %()。 在 中 /usr 是約定俗成的不放配置文件的。
開發 文件
如果被打包的程式包含只用于開發的文件,這些文件就應該被放到一個 -devel 子包里去。下面舉例說明什么類型的文件應該放到 -devel 中去:
包含 (.pc) 文件的軟件包必須初始化 : pkg- 以便于能夠自動加上運行依賴 : pkg-。
區域和語言 文件
包含了一個 RPM 宏變量叫做 %. 這個宏變量可以通過名稱來定位所有屬于你的軟件包的區域和語言文件,并且把這個列表寫進一個文件。你稍后可以用那個文件來導入它們到“文件”章節。% 應該在你的 spec 文件的 % 章節運行,運行次序應該在所有的文件已經被安裝到 %{} 之后。使用 % 可以使得 spec 文件更加簡明,并且繞開了容易犯的打包錯誤。
%{_datadir}/locale/ar/LC_MESSAGES/%{name}.mo %{_datadir}/locale/be/LC_MESSAGES/%{name}.mo %{_datadir}/locale/cs/LC_MESSAGES/%{name}.mo %{_datadir}/locale/de/LC_MESSAGES/%{name}.mo %{_datadir}/locale/es/LC_MESSAGES/%{name}.mo ...
這樣的內容,打包變得更容易了。
非 ASCII 文件名
包含非 ASCII 字符的文件名必須編碼為 UTF-8. 因為沒有方法來識別文件名的編碼,對所有文件名使用同一種編碼是讓用戶可以正常讀文件名的最好辦法。如果上游提供了不使用 UTF-8 編碼的文件名,你可以使用類似 軟件包里的 在 % 部分轉換文件名。
可執行庫 文件夾 ()
文件系統層級標準 并沒有提供任何“可執行庫”文件夾, 但是 軟件包可以在那里存放恰當的文件。可執行庫文件夾 (在 上被重定義到/usr/lib) 可以作為設計目的是由“其他程序”而不是“用戶”來執行的可執行文件的目錄。
rpm 包含了一個可執行庫文件夾的宏變量, %{}。強烈建議打包者在一個軟件包特定的子文件夾中存放可執行庫文件,例如 %{}/%{name}。
修訂日志 (%)
每次你修訂了軟件包,你必須添加一條修訂日志。這對于不管是記錄軟件包歷史,還是讓用戶、依賴你的包的打包者和“客服人員”能夠輕松的定位到你做出的修訂,都是蠻重要的。
OBS 使用一個單獨的文件來記錄軟件包修訂。這個文件像 spec 文件一樣,但它的后綴是 . 而不是 .spec。(實際上最終編譯發生時會自動使用一個 的工具把 . 寫入到 .spec 的% 章節)
修訂日志條目必須以時間順序排列。新的修訂日志條目在老的之上,因此最上面一條是最近期的一條。如果一個軟件包已經在官方源里“注冊”了那么就不允許再修正之前的修訂日志條目了。
修訂日志單行不允許超過 80 個字節,跟% 描述的規定相同,這是因為超出的部分在命令行顯示時會被 略去。
在修訂日志中的條目遵守如下結構:
------------------------------------------------------------------- Tue Apr 22 20:54:26 UTC 2011 - your@email.com - bullet point 1 * bullet point 1.1 with long long long description * bullet point 1.2 - bullet point 2 with long long long description * bullet point 2.1
修訂日志文件中的補丁應該遵守 補丁指南 (尤其是“縮寫”部分,因為 OBS 會自動鏈接格式正確的 bug 縮寫到 網址,便于 審核者調閱)。
還需要注意這里的“修訂日志”針對的是軟件包的修訂,而不僅僅是 spec 文件的修訂。因此僅僅像 deb 軟件包那樣無節操的使用一句 1.0 是堅決不能允許的。
------------------------------------------------------------------- Tue Apr 22 20:54:26 UTC 2011 - your@email.com - updated version 2.0 (或者 initial package 1.0) // 上游修訂日志 * many bug fixes ┓ * new feature 1 ┫-- (從軟件包歸檔中的 ChangeLog/News 以及上游網站的 * new feature 2 ┛ commit log/release notes 等信息中尋找) - regenerated patch #1, #3 against latest source. -- 關于補丁 - fixed categories in desktop file. -- 關于其他 Source,沒有可不寫 - add Requires for?%{name}-%{version} -- 關于 spec 的修訂 - License changes to GPL-3.0+ -- 關于授權協議的修訂,注明原因,沒有可不寫 * Upstream update
關于上游修訂日志:
- update version 2.0 * details see ChangeLog
或者是上游網站,例如:
- update version 2.0 * details see https://is.gd/blabla
關于 spec 文件的修訂:
最后,善意的提醒大家,. 是通過命令行 osc vc 命令或網頁的 new 按鈕來自動生成的,不要用 vi 創建文件然后自己畫線哦。