讓gcc每次編譯都輸出相同的二進制文件

假設有一個靜態(tài)庫二進制文件,由于某種原因,庫里沒帶版本信息,但又想知道它是哪個版本的。那只能重新編譯各個版本,然后將生成的文件與這個庫進行二進制對比。本來是期望同一個版本的代碼,多次編譯出來的文件,應該是二進制完全一致的,但實際上,即使是同一個版本的代碼,每次編譯出來的結(jié)果或多或少都有一些差異。因此,只能選擇差異最小的,認為這個庫就是該版本。
從編譯器的角度出發(fā),相同的代碼在相同的環(huán)境下編譯,是要求產(chǎn)生完全一致的結(jié)果的。不能說這次編譯,把代碼段A放在代碼段B之前,下次編譯又把代碼段A放在代碼段B之后。同樣的,不能說這次編譯把某條語句優(yōu)化成匯編指令A,下次編譯又把該條語句優(yōu)化成匯編指令B。
其實,相同版本代碼在相同環(huán)境下編譯出不同的結(jié)果,差異的往往是時間戳,build-id等信息。為了每次編譯都得到相同的結(jié)果,可以比較一下每次編譯結(jié)果的差異,看看差異具體是在哪些段,然后分別針對處理。
從目前的測試來看,動態(tài)庫是比較好的,每次編譯產(chǎn)生的結(jié)果基本都是一致的,差異的地方是因為代碼里使用了 __TIME__等編譯宏。靜態(tài)庫稍微復雜一些,有差異是因為ar引入了時間戳和uid,pid,解決辦法是對ar使用-D選項(use zero for timestamps and uids/gids)。對內(nèi)核驅(qū)動文件(ko)的處理相對來說麻煩一些。它產(chǎn)生差異是因為build-id的引入,每次編譯.note.gnu.build-id段都會不同。本來把--build-id=none傳給鏈接器(-Wl,--build-id=none)應該是可以解決這個問題的。但在交叉編譯的環(huán)境下,這樣指定好像是無效的,.note.gnu.build-id段還是照樣產(chǎn)生。想來應該是這里的指定被內(nèi)核里的相關(guān)配置覆蓋了,沒有生效。最終的解決辦法是,修改內(nèi)核頂層目錄的Makefile,注釋掉了下面兩行:

KBUILD_LDFLAGS_MODULE += $(LDFLAGS_BUILD_ID)
LDFLAGS_vmlinux += $(LDFLAGS_BUILD_ID)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容