錯誤: 空 %file 檔案 /home/user/rpmbuild/BUILD/xxxx-0.1/debugsourcefiles.list
你看錯誤的裡邊有一個%file
,這是使用spec檔案構建時的一個命令階段,用於列出檔案以生成對應的rpm包。
我們查詢rpm的宏定義,發現了一行程式碼%files debugsource -f debugsourcefiles.list
,debugsource包要使用debugsourcefiles.list檔案,而debugsourcefiles.list是空的,所以出現了相應的錯誤。
原始碼包經過構建後,除了生成spec中指定的包外,還會生成額外的debuginfo和debugsource包,noarch架構除外。
debugsourcefiles.list是由find-debuginfo生成的。
生成的檔案內容為空有以下幾個原因:
1 編譯的目標並未生成任何動態庫和可執行檔案。
2 編譯時未給編譯器加可偵錯選項,比如gcc的-g
選項。
3 有些開發者在構建檔案的install階段執行了strip,剝除了偵錯資訊。
如果不想生成額外的debuginfo和debugsource包,可以在rpmbuild命令列指定--nodebuginfo
,也可以在spec檔案的開頭加上%define debug_package %{nil}
。
如果只是不想生成debugsource,還繼續生成debuginfo,可以在spec檔案的開頭加上%define _debugsource_template %{nil}
。
如果不想生成debuginfo,還繼續生成debugsource?別折騰了,這樣做沒意義。
但是如果本意是想生成的,卻遇到了以上的問題,那就往下看,瞭解一下find-debuginfo的原理。
建立臨時目錄 /tmp/find-debuginfo.XXXXXX,XXXXXX為亂數。
然後在$RPM_BUILD_ROOT查詢檔案屬性中有not stripped
標誌的檔案,將結果寫到臨時目錄的primary檔案內。使用了下邊的一段程式碼。
可以看到查詢條件,只要檔案許可權中owner、group、other任意一個可執行,並且屬性中有not stripped
就滿足要求。
touch "$temp/primary"
find "$RPM_BUILD_ROOT" ! -path "${debugdir}/*.debug" -type f \
\( -perm -0100 -or -perm -0010 -or -perm -0001 \) \
-print | LC_ALL=C sort |
file -N -f - | sed -n -e 's/^\(.*\):[ ]*.*ELF.*, not stripped.*/\1/p' |
xargs --no-run-if-empty stat -c '%h %D_%i %n' |
while read nlinks inum f; do
if [ $nlinks -gt 1 ]; then
var=seen_$inum
if test -n "${!var}"; then
echo "$inum $f" >>"$temp/linked"
continue
else
read "$var" < <(echo 1)
fi
fi
echo "$nlinks $inum $f" >>"$temp/primary"
done
對所有寫入primary的檔案,逐個進行處理,這裡使用了多執行緒,指令碼中每個執行緒是一個run_job函數,ran_job其本質執行的是do_file函數。
比如使用了8個執行緒,執行緒0是run_job0,run_job0將自己處理過的檔案寫入elfbins.0,將提取的資訊寫入debugsources.0,將處理結果寫入res.0。
然後再將多個執行緒處理產生的多個elfbins和debugsources檔案進行合併,顧名思義,debugsources裡邊記錄著偵錯原始檔的名稱和型別。
debugsourcefiles.list | debugsource包的列表檔案。記錄所有偵錯原始檔(就是程式碼檔案)將要被安裝到系統的路徑,一般是/usr/src/debug/%{packagename}-%{version}-%{release}.%{dist}.%{arch} 。 |
debugfiles.list | debuginfo包的列表檔案。記錄所有的偵錯檔案將要被安裝的路徑,就是未被stripped 的檔案,每個檔案一條記錄。 |
debuglinks.list | |
debugsources.list | 記錄所有偵錯用原始碼檔案的名稱和型別。原始碼檔案的偵錯型別可以是<internal> 、<built-in> 、<__thread_local_inner macros> 等。 |
elfbins.list | 記錄所有的可偵錯的可執行程式,不包括動態庫,每個檔案一條記錄。 |
我們再來看看run_job執行緒內都做了些什麼?
run_job執行緒內呼叫了do_file函數,do_file函數使用了debugedit命令對單個檔案進行偵錯資訊處理。