前言
這段時間總是在和openwrt打交道,之前也零零散散地寫過一點,還是希望能有點體系。還記得我剛看到源代碼的時候,覺得無從下手.我想從Makefile的整個執行過程入手,搞清楚編譯源代碼的幾個小時中,到底發生了哪些故事.
本文是這個系列的第一篇.主要講一下我對openwrt整個目錄結構的理解.我們將源代碼從官方下載而來的目錄稱之為原始目錄,將編譯后生成的目錄稱之為生成目錄,分兩部分介紹各個目錄.
原始目錄
下載源碼后,源文件如下圖所示,下面我們來一一解釋;
1. scripts
存放了一些腳本,使用了bash,python,perl等多種腳本語言.編譯過程中,用於第三方軟件包管理的feeds文件也是在這個目錄當中.在編譯過程中,使用到的腳本也統一放在這個目錄中.
2. tools
編譯時,主機需要使用一些工具軟件,tools
里包含了獲取和編譯這些工具的命令.軟件包里面有Makefile文件,有的還包含了patch.每個Makefile當中都有一句$(eval $(call HostBuild))
,這表明編譯這個工具是為了在主機上使用的.
3. config
存放着整個系統的配置文件
4. docs
包含了整個宿主機的文件源碼的介紹, 里面還有Makefile為目標系統生成docs.使用make -C docs/
可以為目標系統生成文檔.
5. toolchain
嵌入式的童鞋應該都知道交叉編譯鏈,這個文件中存放的就是編譯交叉編譯鏈的軟件包.包括:binutils,gcc,libc
等等.
6. target
openwrt的源碼可以編譯出各個平台適用的二進制文件,各平台在這個目錄里定義了firmware和kernel的編譯過程。
7. package
存放了openwrt系統中適用的軟件包,包含針對各個軟件包的Makefile。openwrt定義了一套Makefile模板.各軟件參照這個模板定義了自己的信息,如軟件包的版本、下載地址、編譯方式、安裝地址等。在二次開發過程中,這個文件夾我們會經常打交道.
事實上,通過./scripts/feed update -a和./scripts/feed install -a
的軟件包也會存放在這個目錄之中.
8. include
openwrt的Makefile都存放在這里。文件名為 *.mk 。這里的文件上是在Makefile里被include的,類似於庫文件.這些文件定義了編譯過程.
9. 其他
主要目錄就是前面提及的8個,剩下的是單個文件.
9.1 Makefile:
在頂層目錄執行
make
命令的入口文件.
9.2 rules.mk
定義了Makefile中使用的一些通用變量和函數
9.3 Config.in
在
include/toplevel.mk
中我們可以看到,這是和make menuconfig
相關聯的文件.
9.4 feeds.conf.default
是下載第三方一些軟件包時所使用的地址
9.5 LICENSE & README
即軟件許可證和軟件基本說明.其中README描述了編譯軟件的基本過程和依賴文件.
至此我們把原始目錄大致瀏覽了一遍,下面我們看看生成目錄.
生成目錄
在我們編譯完成后除了下載的源碼文件,多出來的部分很明顯就是編譯過程中新生成的.如下圖:
1. feeds
openwrt的附加軟件包管理器的擴展包索引目錄.有點繞,簡單來說就是下載管理軟件包的.默認的feeds
下載有packages、management、luci、routing、telephony
。如要下載其他的軟件包,需打開源碼根目錄下面的feeds.conf.default文件,去掉相應軟件包前面的#號,然后更新源:
./scripts/feeds update -a
安裝下載好的包:
./scripts/feeds install -a
2. build_dir
在前面的原始目錄中,我們提到了host工具,toolchain工具還有目標文件.openwrt將在這個目錄中展開各個軟件包,進行編譯.所以這個文件夾中包含3個子文件夾:
2.1 host
在該文件夾中編譯主機使用的工具軟件
2.2 toolchain-XXX
在該文件夾中編譯交叉工具鏈
2.3 target-XXX
在此編譯目標平台的目標文件,包括各個軟件包和內核文件.
3. bin
保存編譯完成后的二進制文件,包括:完整的bin文件,所有的ipk文件.
4. dl
在編譯過程中使用的很多軟件,剛開始下載源碼並沒有包含,而是在編譯過程中從其他服務器下載的,這里是統一的保存目錄
5. staging_dir
用於保存在build_dir
目錄中編譯完成的軟件.所以這里也和build_dir
有同樣的子目錄結構.
比如,在target-XXX
文件夾中保存了目標平台編譯好的頭文件,庫文件.在我們開發自己的ipk文件時,編譯過程中,預處理頭文件,鏈接動態庫,靜態庫都是到這個子文件夾中.
6.tmp
從名字來看,是臨時文件夾.在編譯過程中,有大量中間臨時文件需要保存,都是在這里.
7.logs
這個文件夾,有時可以看到,有時沒有.這是因為這個文件夾保存的是,編譯過程中出錯的信息,只有當編譯出錯了才會出現.我們可以從這里獲取信息,從而分析我們的軟件編譯為什么沒有完成.
至此我們把openwrt的目錄結構大體瀏覽了一遍.
尾記
- 本文中不少內容都是從網上看到的,時間長了,我已經找不到出處了.這也是我寫博客的一個原因,我從互聯網學到不少知識,現在再反饋給網絡.感謝所有有自由共享精神的朋友.
- 知識學習是不斷遞進的過程.這部分知識是我目前知道的一個大概,還不夠深刻.更深入的學習Makefile和openwrt之后,再來慢慢更新.