Chinaunix首页 | 论坛 | 博客
  • 博客访问: 210991
  • 博文数量: 55
  • 博客积分: 1305
  • 博客等级: 中尉
  • 技术积分: 350
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-11 15:18
文章分类

全部博文(55)

文章存档

2012年(1)

2011年(54)

分类: LINUX

2011-06-08 08:56:30

小技巧:#include "/dev/stdin"Susam Pal 有篇短文 [Compiler taking input while compiling] 提到一個非常有趣的技巧,就是在 C 語言程式中去 #include "/dev/stdin" (UNIX) 或 #include "CON" (Windows),這樣就能在編譯時期,接受標準輸入作為新增的程式碼。那麼,實際的應用呢?筆者想到一種應用型態,試想,有許多成功的 open source 專案長年累積眾多開發者或貢獻者,會期望在 UI 顯示這些份清單,可能的作法有兩個:
  • 讀取某個文件檔,如 AUTHORS
  • 透過 Makefile 的修改,在編譯時期指定 -DAUTHOR_LIST="..." 之類的編譯參數
前者看來很有彈性,但可能大題小作了,不過只是字串,有必要因此開檔嗎?又,萬一多個版本共存於同一個環境,該怎麼辦呢?後者麻煩了一些,但絕對會運作,但這又額外的風險,因為我們不確定這份清單到底有多長、shell 是否能處理過長的字串。更麻煩的是,因為是編譯參數的修改,make 無法清楚得知確切的編譯時間變動,無法確保最終的字串輸出,因為即使將 'AUTHORS' 一類的檔案放入 Makefile target 的相依清單中,還是有可能面臨產生 C-style string 的方式改變而未能同步。

套用前述的技巧,則可簡潔的克服這樣的問題。以下是示範的程式碼 (list_authors.c)
#include int main() { puts( #include "/dev/stdin" ); return 0; }假設貢獻者清單放在 ../AUTHORS 這個檔案中,那我們撰寫以下 Makefile:
all: @awk '/@/{print " \"" $$_ "\\n\"" }' ../AUTHORS | \ gcc -o list_authors list_authors.c ./list_authors嘗試去編譯並執行看看,以 [] 為例:(忽略後方的 email)
./list_authors Lu-chuan Kung Kang-pen Chen Jim Huang Kan-Ru Chen Yun-Ta Tsai Kang-min Liu Weizhong Yang Kuang-che Wu Shiva Huang Jeff Chen Hong Jen Yee (PCMan) James Huang (Sea Monster) Tiberius Teng Andy Horng Caius Chance Ding-Yi Chen 簡單來說,就是把 awk 處理過的 C 字串透過 stdout,提供給需要 stdin 的 GCC,當我們編譯 list_authors.c 時,而且能確保每次編譯時,都提供最新的清單與格式 (我們當然希望這份列表能越來越長,期待更多熱血朋友的參與)。另一個潛在的好處是,目前的工作目錄中,不需要保有中間檔案,就可避免有人不慎將其放入版本控制系統中,這點非常重要,因為仍有部份版本控制系統無法有效偵測或排除新增檔案。

其他可能的應用:
  • 內嵌 firmware 的 WLAN driver: 以 Broadcom WLAN driver 來說,原本得提供一份 firmware (可動態載入) 或另一份展開為 C header file 的 firmware 形式,現在經由 build system 的修改,只要提供一份 firmware 即可
  • 編譯時期儘量包含 build host 的資訊: 不同於 Microsoft Visual Studio 系列,gcc 預設僅會將少數的資訊放入執行檔,但有時候我們會希望在 debug build 多包含一些資訊,特別是有助於 QA 分析使用
UNIX 的哲學之一: "Everything is file",再次獲得有趣的應用。
阅读(1604) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~