ifdex: 一個由 ESR 出品的給代碼考古學家的工具
Eric Raymond 寫了一個工具,用來幫助那些無畏的“代碼考古學家們”理解“古代”代碼的結構。它叫做 ifdex ,它的背后有一段故事,拿起你的 Fedora 和趕牛的鞭子,讓我講給你聽……
在開發 NTPsec 早期, 我們就決定替換它的構建系統——它是如此的難于理解和修改——嚴重的拖慢了我們的開發進度。
古老的 autoconf 構建方式就像一個恐怖的爬行動物,而 NTP 更是一個極端的例子。不完善的宏技術定義了太多的配置符號,為了掌握這些接口,即使你查看了 config.h 也無濟于事。尤其是當你要做一些大的修改時,這更是一個問題!
我們的一個伙計 Amar Takhar,是 waf 構建系統的專家,當他初步提出遷移的想法時得到了我的積極響應。幾個月之后,他就做出了一些 waf 功能,雖然還未完成,但是已經至少可以生成用于實際測試的二進制了。
這里我說“未完成”的意思是,代碼里面還有一些 waf 構建絕不會設置的 #define 。很多人絕對不會碰那些 autoconf 構建的東西,而另外一些人則不。那些從來用不到的配置開關迷失在大堆的系統頭文件和編譯器設置的 #define 條件中。
我這里說的不是幾個或幾十個,我最終統計出了有超過 670 個不同的 #define 用在 #if/#ifdef/#ifndef/#elif 條件中,而這些條件,如 John D. Bell 指出的那樣,有 2430 個之多。我需要一些辦法來檢查它們并分成不同的類型:有的來自系統頭文件、有的是配置開關,以及其它的……
所以我寫了一個分析器,它可以對代碼樹解析每個編譯時條件的符號,然后將它們分成單純的列表或 GCC 類的文件/行錯誤信息,你可以用 Emacs 的編譯模式逐個分析。
為了降低干擾,它掌握著一個條件符號的長列表(大概200個),這些可以忽略掉。比如像 __GNUC__ 符號是 GCC 預定義,而 O_NONBLOCK 宏用于幾種系統調用等等。
這些符號分成幾組,你可以使用命令行選項分別忽略它們。所以,如果你希望忽略列表中所有標準的 POSIX 宏而想看到操作系統相關的任何東西,那就可以做到了。
另外一個重要的功能是你可以構造你自己的排除列表及注釋。這樣當我探索 NTP 編譯條件的黑暗森林時,所構造的越來越大的排除列表就代表了我已經了解了的條件符號。最終(我希望)未知符號的報告將縮減為空,那么我就已經了解了所有配置開關的確切意義了。
目前為止,我已經搞定了它們之中的 300 個,還有 373 個。這是我用我的漂亮工具在一周內完成的主要工作。噢,從來沒有人說過代碼考古是如此的容易。
最后, ifdef 的主頁是: http://www.catb.org/esr/ifdex/ ,代碼庫在這里: https://gitlab.com/esr/ifdex 。希望你用的上。