tools、toolchain、include、scripts、target、package、目錄爲解壓OpenWrt後系統自帶的目錄。
bin、build_dir、staging_dir、dl、feeds 目錄爲執行相關命令後自動從網絡下載目錄和編譯目錄。
一、feeds
擴展軟件包目錄。html
# 執行該命令後自動建立feeds目錄,並下載相關文件至此目錄下。 $ ./scripts/feeds update -a
二、dl
編譯前將原始的軟件代碼包經過網絡下載到該目錄。ios
# 編譯時下載各軟件包保存至dl目錄下 $ make
三、package
待構建的軟件包源碼或patch文件。建立自定義軟件包時應保存至該目錄下。標準軟件包目錄結構:c++
目錄名稱 | 是否可選 | 說明 |
---|---|---|
Makefile | 必選 | OpenWrt 構建文件 |
src | 必選 | Makefile 或 CMakefile 工程目錄 |
files | 可選 | 配置文件和初始化文件 |
patches | 可選 | 補丁文件 |
四、build_dir
自定義軟件包會拷貝至該目錄的 target-mipsel_mips32_musl 目錄下,不一樣構建架構目錄名稱不一樣。git
# package 目錄下的src軟件包會拷貝至此路徑下,並執行編譯安裝操做。 $ build_dir/target-mipsel_mips32_musl/你軟件包的src目錄內容
五、staging_dir
軟件包編譯後的安裝目錄,包含開發板的根目錄路徑。github
# 開發板根目錄路徑 $ staging_dir/target-mipsel_mips32_musl/root-brcm47xx/
六、bin
編譯完成後生成的安裝鏡像文件及ipk安裝包。網絡
七、config
包含全局編譯設置、開發人員編譯設置、目標文件格式設置和內核編譯設置等4部分。多線程
八、include
包含準備環境腳本、下載補丁腳本、編譯 Makefile 以及編譯指令等。架構
九、scripts
包含準備環境腳本、下載補丁腳本、編譯 Makefile 以及編譯指令等。app
十、target
指的是嵌入式平臺,包括特定嵌入式平臺的內容。ide
十一、toolchain
編譯器和C庫等,例如包含編譯工具 gcc 和 glibc 庫。
十二、tools
通用命令,用來生成固定的輔助工具,如打補丁工具 patch、編譯工具 make 及 squashfs 等。
# 假設自定義工程名爲 Hello ######################################### # Hello # - Makefile // OpenWrt 構建文件 # + src // Hello 工程 # - Makefile // Hello 工程構建文件 # - hello.c # # openwrt 根目錄 ~/openwrt ######################################### # 工程源碼存放路徑(手動) ~/openwrt/package/Hello # 工程源碼構建路徑(自動) ~/openwrt/build_dir/target-mipsel_mips32_musl/Hello # 工程目標安裝路徑(自動,移植後開發板的根目錄) ~/openwrt/staging_dir/target-mipsel_mips32_musl/root-brcm47xx
說明
- openwrt 爲 OpenWrt SDK 根目錄
- 下文的 * 表示軟件包目錄名稱
軟件包變量
變量名 | 是否可選 | 含義 |
---|---|---|
PKG_NAME | 必填 | The name of the package, as seen via menuconfig and ipkg. |
PKG_RELEASE | 必填 | The version of this package Makefile |
PKG_VERSION | 可選 | The upstream version number that we're downloading. |
PKG_BUILD_DIR | 可選 | Where to compile the original sources |
PKG_SOURCE | 可選 | The filename of the original sources |
PKG_SOURCE_URL | 可選 | Where to download the sources from |
PKG_MD5SUM | 可選 | A Checksum to validate the downlaod |
PKG_CAT | 可選 | How to decompress the sources(zcat, bzcat, unzip) |
PKG_BUILD_DEPENDS | 可選 | Packages the need to build before this package, but are not required at runtime. |
Package/* 軟件包描述
名稱 | 是否可選 | 描述 |
---|---|---|
SECTION | 目前未使用 | 軟件包類型(可自定義填寫) |
CATEGORY | 必填 | 軟件包在 menuconfig 中的類別 |
DESCRIPTION | 已廢棄 | 軟件包的完整描述 |
URL | 可選 | 從哪裏下載原始軟件包 |
MAINTAINER | 可選 | 維護者信息,便於聯繫維護者。 |
DEPENDS | 可選 | 指定編譯該軟件包以前必須構建或安裝的軟件包 |
conffiles | 可選 | 該軟件包安裝的配置文件列表,每一個文件一行。 |
Build/* 軟件包構建指令
名稱 | 是否可選 | 描述 |
---|---|---|
Build/Prepare | 可選 | 針對源文件進行解壓縮或打補丁的一系列命令,能夠不定義。 |
Build/Configure | 可選 | 針對配置文件的一些列命令,能夠不定義。 |
Build/Compile | 可選 | 指定如何編譯源文件,絕大部分狀況下無需定義。 |
Package/package-name/config | 可選 | 可執行PACKAGE或CONFIG相關節點操做 |
Package/package-name/install | 必填 | 拷貝源碼編譯的文件至ipkg |
Package/package-name/preinst | 可選 | 執行Package/install前的腳本,切記包含 #!/bin/sh, return false 退出安裝。 |
Package/package-name/postinst | 可選 | 執行Package/install後的腳本,切記包含 #!/bin/sh。 |
Package/package-name/prerm | 可選 | 刪除文件前執行的操做,規則相似Package/preinst |
Package/package-name/postrm | 可選 | 刪除文件後執行的操做,規則相似Package/postrm |
OpenWrt 系統變量
變量名 | 變量定義 | 變量含義 | 變量值 |
---|---|---|---|
$(TOPDIR) | ${CURDIR} | OpenWrt 根目錄 | /openwrt |
$(DL_DIR) | $(TOPDIR)/dl | 經過網絡下載的標準軟件包 | /openwrt/dl |
${OUTPUT_DIR} | $(TOPDIR)/bin | 最終編譯出的ipk軟件包 | /openwrt/bin |
${INCLUDE_DIR} | $(TOPDIR)/include | 包含文件 | /openwrt/include |
$(SCRIPT_DIR) | $(TOPDIR)/scripts | 腳本文件 | /openwrt/scripts |
$(BUILD_DIR_BASE) | ??? | $(TOPDIR)/build_dir | /openwrt/build_dir |
$(PACKAGE_DIR) | $(BIN_DIR)/packages |
全部指令位於 rules.mk 文件
指令名稱 | 指令定義 | 說明 |
---|---|---|
INSTALL_DIR | install -d -m0755 | 建立安裝目錄 |
INSTALL_BIN | install -m0755 | 安裝可執行文件 |
INSTALL_SUID | install -m4755 | - |
INSTALL_DATA | install -m0644 | 安裝數據文件 |
INSTALL_CONF | install -m0600 | 安裝配置文件 |
全部軟件包編譯
$ make menuconfig $ ... 勾選相關軟件包保存後退出 $ make
單個軟件包編譯
# 編譯並安裝軟件包 $ make package/${packageName}/compile
編譯選項
# 編譯全部軟件包,不輸出詳細信息,單線程編譯 $ make # 單線程編譯(不帶j默認爲單線程) $ make -j=1 # 多線程編譯(指定數目) $ make -j=2 # 多線程編譯(根據硬件自動) $ make -j # 輸出詳細信息(默認不輸出詳細信息) $ make V=s # 組合使用示例 $ make V=s -j=2 # 說明: # 1. 多線程編譯速度快,但產生編譯錯誤時不便於定位故障緣由。 # 2. 想快速編譯可採用以下形式:make -j,不輸出信息且根據CPU內核數自動多線程編譯。 # 3. 想查看編譯錯誤可採用以下形式:make V=s 或 make V=s -j1。 # 4. 若是是初次添加自定義軟件包,必須先經過 make menuconfig 而後 make 的方式構建。
sprite/Makefile
include $(TOPDIR)/rules.mk PKG_NAME:=sprite PKG_RELEASE:=1 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) include $(INCLUDE_DIR)/package.mk define Package/$(PKG_NAME) SECTION:=utils CATEGORY:=Suning TITLE:=promote information for $(PKG_NAME). endef define Package/$(PKG_NAME)/description This is a Makefile project. endef define Package/$(PKG_NAME)/install $(INSTALL_DIR) $(1)/usr/bin $(INSTALL_BIN) $(PKG_BUILD_DIR)/$(PKG_NAME) $(1)/usr/bin/ endef $(eval $(call BuildPackage,$(PKG_NAME)))
符號 | 等價值 | 說明 |
---|---|---|
$(INSTALL_DIR) | install -d -m0755 | 建立特定權限的 /usr/bin 目錄 |
$(INSTALL_BIN) | install -m0755 | 修改文件權限並拷貝至/ usr/bin 目錄 |
sprite/src/sprite.c
#include <stdio.h> int main(void) { printf("Hello World!\n"); return 0; }
sprite/src/Makefile
CC = gcc FLAG = -Wall sprite: $(CC) $(FLAG) sprite.c -o sprite
編譯、安裝
# $(1) 表示目標系統的根目錄 # 或者經過 menuconfig 選中 sprite 選項,執行 make 命令 $ make package/sprite/compile V=s
刪除拷貝的構建目錄
# 刪除 ~/openwrt/build_dir/target-mipsel_mips32_musl/sprite $ make package/sprite/clean
clxye/Makefile
include $(TOPDIR)/rules.mk PKG_NAME:=clxye PKG_RELEASE:=1 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) include $(INCLUDE_DIR)/package.mk include $(INCLUDE_DIR)/cmake.mk define Package/${PKG_NAME} SECTION:=utils CATEGORY:=Suning DEPENDS:=+libstdcpp +libpthread TITLE:=promote information for ${PKG_NAME}. endef define Package/${PKG_NAME}/description This is a CMake project. endef define Package/${PKG_NAME}/install $(INSTALL_DIR) $(1)/usr/bin $(INSTALL_BIN) $(PKG_BUILD_DIR)/${PKG_NAME} $(1)/usr/bin/ endef $(eval $(call BuildPackage,${PKG_NAME}))
一、CMake 工程必須包含 include $(INCLUDE_DIR)/cmake.mk
二、C++ 工程必須包含 libstdcpp
clxye/src/clxye.cpp
#include <iostream> #include <thread> int main(void) { std::thread t( [](){ std::cout << "Hello World!" << std::endl; } ); t.join(); return 0; }
clxye/src/Makefile
# 所需 cmake 工具的最低版本 cmake_minimum_required(VERSION 2.6) # 工程名稱 project(clxye) # 生成可執行程序 add_executable(${PROJECT_NAME} clxye.cpp ) # 連接共享庫 target_link_libraries(${PROJECT_NAME} pthread ) # 安裝可執行文件(必須提供install) install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION "/usr/bin")
編譯、安裝
# 初次編譯需採用 make menuconfig、check and save、make V=s 編譯 $ make package/clxye/compile V=s
刪除拷貝的構建目錄
# 刪除 ~/openwrt/build_dir/target-mipsel_mips32_musl/clxye $ make package/sprite/clean
結果與 Makefile 基本一致(clxye與sprite文件名不一樣),這裏再也不重複展現。
Config 類型
config GST1_LIBAV_DECODER_mp3 bool "MP3 (MPEG Audio Layer 2)"
DEPENDS 依賴項
# 此方式只能爲 Package 類型,不支持 Config 類型 define Package/$(PKG_NAME) SECTION:=utils CATEGORY:=Suning DEPENDS:=+libc +libgcc +librt +libpcre +libpthread +pulseaudio-daemon +portaudio \ +gst1-libav +gstreamer1-libs +libgst1app TITLE:=promote information for $(PKG_NAME). endef
select 方法
# Package 與 Config 兩種類型均支持 define Package/$(PKG_NAME)/config select GST1_LIBAV_DECODER_mp3 select GST1_LIBAV_PARSER_mpegaudio select PACKAGE_gst1-mod-alsa select PACKAGE_gstreamer1-utils endef
efine Package/$(PKG_NAME) SECTION:=utils CATEGORY:=Suning DEPENDS:=+libc +libgcc +librt +libpcre +libpthread +pulseaudio-daemon +portaudio \ +gst1-libav +gstreamer1-libs +libgst1app TITLE:=promote information for $(PKG_NAME). endef define Package/$(PKG_NAME)/config # ** gst1-libav ** select GST1_LIBAV_DECODER_ac3 select GST1_LIBAV_DECODER_mp3 select GST1_LIBAV_DECODER_pcm_s16be select GST1_LIBAV_DECODER_pcm_s16le select GST1_LIBAV_DEMUXER_ac3 select GST1_LIBAV_DEMUXER_mp3 select GST1_LIBAV_PARSER_ac3 select GST1_LIBAV_PARSER_mpegaudio # ** gstreamer1-plugins-base ** select PACKAGE_gst1-mod-alsa select PACKAGE_gst1-mod-app select PACKAGE_gst1-mod-audioconvert select PACKAGE_gst1-mod-playback select PACKAGE_gst1-mod-typefindfunctions select PACKAGE_gst1-mod-volume # ** gstreamer1-plugins-good ** select PACKAGE_gst1-mod-audioparsers select PACKAGE_gst1-mod-autodetect select PACKAGE_gst1-mod-id3demux select PACKAGE_gst1-mod-wavparse # ** gstreamer1-utils ** select PACKAGE_gstreamer1-utils endef
一、Makefile:1: *** missing separator. Stop.
# 空格與Tab的問題,進入 Makefile 所在目錄執行以下腳本 $ perl -pi -e 's/^ */\t/' Makefile
二、make[2]: Nothing to be done for 'compile'.
# 暫時未找到從根本上解決問題的方法 # 可經過 make menuconfig 勾選後執行 make 操做的方式編譯
三、WARNING: your configuration is out of sync. Please run make menuconfig, oldconfig or defconfig!
# 執行 make package/${packagename}/compile 時的編譯警告 # 此時必須經過 make menuconfig... save... make 的方式編譯,不然 install 會致使目標系統沒有安裝文件的狀況。
四、Package xxx is missing dependencies for the following libraries: libstdc++.so.6
# 添加 c++ 依賴庫 DEPENDS:=+libstdcpp
五、Makefile:26: *** Package/clxye is missing the VERSION field. Stop
# Makefile 中該關鍵字不能省略(不是 PKG_VERSION) PKG_RELEASE:=1
六、Package/$(PKG_NAME)/install 腳本未執行
# 此時構建目錄中未生成 「.pkgdir」 和 「ipkg-mipsel_mips32」 目錄。 # 經過 make menuconfig 勾選該軟件包,而後再執行 make package/xxx/compile 編譯指令,此問題耗費了兩天。
1. OpenWrt Development Guide
2. Openwrt Examples
3. Creating packages
4. Openwrt package Makefile
5. Makefile 選項 CFLAGS,LDFLAGS,LIBS
6. OpenWRT的包依賴 package DEPEND
7. Alternative for missing __sync_fetch_and_add_8 on MIPS 32-bit
譯 《Documentation/kbuild/kconfig-language.txt》
kconfig語法整理)