openwrt編譯 -- 添加用戶自定義app


OpenWrt 是一個比較完善的嵌入式 Linux 開發平台,在 OpenWrt 中增加軟件包極其方便,按照 OpenWrt 的約定就可以很簡單的完成。軟件包需要在 package 目錄下創建一個目錄,以包含該軟件包的各種信息和與 OpenWrt 建立聯系的文件。然后創建一個MakefileOpenWrt 建立聯系, Makefile 需要遵循 OpenWrt 的約定。下面就簡單的說明一下具體的創建和測試過程。

一、源碼編譯使用模塊,用戶自定義安裝,卸載

1、在package下新建文件夾,其名稱一般為你要添加的軟件包的名稱,此處為測試特意使用別的名稱,按 OpenWrt 的習慣,一般把自己設計的程序全部放在 src 目錄下。所以,文件結構如下

myapp/
├── Makefile
└── src
    ├── Makefile
    └── myabcd.c

2、編寫src文件下的文件內容

1)、myabcd.c 內容如下

 1 #include <stdio.h>
 2 #include <unistd.h>
 3  
 4 int main(int argc, const char argv)
 5 {
 6      int i = 0;
 7      FILE *fs;
 8      fs = fopen("/dev/console", "w+");
 9      for (i = 0; ; i++)
10     {
11         fprintf(fs, "[ %02d ] This is /dev/console Test\n", i);
12         sleep(1);
13     }
14     return 0;
15 } 

2)、Makefile內容如下

1 all: mycode
2 mycode:
3 $(CC) $(CFLAGS) -o $@ myabcd.c -Wall
4 
5 clean:
6 rm -f myabcd

3、上級 Makefile的寫法

 1 ##############################################
 2 # 
 3 # OpenWrt Makefile for mycode program
 4 #
 5 ##############################################
 6 include $(TOPDIR)/rules.mk
 7 include $(INCLUDE_DIR)/kernel.mk
 8 
 9 PKG_NAME := mycode
10 PKG_VERSION := 0.1
11 PKG_RELEASE := 1
12 
13 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
14 
15 include $(INCLUDE_DIR)/package.mk
16 
17 define Package/$(PKG_NAME)
18   SECTION:=utils
19   CATEGORY:=Songshuai Package
20   SUBMENU:=Software Testing modules
21   TITLE:=This is SongShuai's test project.
22   MAINTAINER:=Songshuai
23 endef
24 
25 define Package/$(PKG_NAME)/description
26     If you can't figure out what this program does, you're probably
27     brain-dead and need immediate medical attention.
28 endef
29 
30 define Build/Prepare
31     mkdir -p $(PKG_BUILD_DIR)
32     $(CP) ./src/* $(PKG_BUILD_DIR)/
33 endef
34 
35 define Build/Configure
36 endef
37 
38 define Build/Compile
39     $(MAKE) -C $(PKG_BUILD_DIR) \
40         ARCH="$(LINUX_KARCH)" \
41         CC="$(TARGET_CC)" \
42         CFLAGS="$(TARGET_CFLAGS) -Wall" \
43         LDFLAGS="$(TARGET_LDFLAGS)"
44 endef
45 
46 define Package/$(PKG_NAME)/install
47     $(INSTALL_DIR) $(1)/app
48     $(INSTALL_BIN) $(PKG_BUILD_DIR)/$(PKG_NAME) $(1)/app/
49 endef
50 
51 $(eval $(call BuildPackage,$(PKG_NAME)))

OpenWrt 使用三個 Makefile 的子文件,分別為:

1 $(TOPDIR)/rules.mk # 一般在 Makefile 的開頭,
2 $(INCLUDE_DIR)/kernel.mk # 文件對於軟件包為內核時是不可缺少,
3 $(INCLUDE_DIR)/package.mk # 一般在軟件包的基本信息完成后再引入。

由 這 些 Makefile 子 文 件 確 立 軟 件 包 加 入 OpenWrt 的 方 式 和 方 法 。

說明一、軟件包的信息均以 PKG_開頭,其意思和作用如下:

1 PKG_NAME:示軟件包名稱,將在 menuconfig 和 ipkg 可以看到。
2 PKG_VERSION:表示軟件包版本號。
3 PKG_RELEASE:表示 Makefile 的版本號。
4 PKG_SOURCE:表示源代碼的文件名。
5 PKG_SOURCE_URL:表示源代碼的下載網站位置。 @SF 表示在 sourceforge 網站,@GNU 表示在 GNU 網站,還有@GNOME、 @KERNEL。
6 PKG_MD5SUM:表示源代碼文件的效驗碼。用於核對軟件包是否正確下載。
7 PKG_CAT:表示源代碼文件的解壓方法。包括 zcat, bzcat, unzip 等。
8 PKG_BUILD_DIR:表示軟件包編譯目錄。它的父目錄為$(BUILD_DIR)。如果不指定,默認為$(BUILD_DIR)/$( PKG_NAME)/$( PKG_VERSION)

說明二、應用程序的編譯包以 Package/ 開頭,然后接着軟件名稱,在 Package 定義中的軟件名稱可以與軟件包名稱不一樣,而且可以多個定義

1 SECTION:表示包的類型,預留。
2 CATEGORY:表示分類,在 make menuconfig 的菜單下將可以找到。 
3 TITLE:用於軟件包的簡短描述。 
4 URL:表示軟件包的下載位置。
5 MAINTAINER:表示維護者,選項。
6 DEPENDS:表示與其他軟件的依賴。即如編譯或安裝需要其他軟件時需要說明。如果有多個依賴,則每個依賴需要用空格分開。依賴前使用+號表示默認為顯示,即對象沒有選中時也會顯示,使用@則默認為不顯示,即當依賴對象選中后才顯示。

說明三、在Makefile中,package定義的說明

1 Package/$(PKG_NAME)/conffiles 本包安裝的配置文件,一行一個。如果文件結尾使用 / ,則表示為目錄。用於備份配置文件說明,在 sysupgrade 命令執行時將會用到。
2 Package/$(PKG_NAME)/description 軟件包的詳細描述,取代 DESCRIPTION 詳細描述。
3 Build/Prepare 編譯准備方法,對於網上下載的軟件包不需要再描述。對於非網上下載或自行開發的軟件包必須說明編譯准備方法。
4 Build/Configure 在 Automake 中需要進行./configure,所以本配置方法主要針對需要配置的軟件包而設計,一般自行開發的軟件包可以不在這里說明。
5 Build/Compile 編譯方法,沒有特別說明的可以不予以定義。如果不定義將使用默認的編譯方法 Build/Compile/Default。
6 Package/$(PKG_NAME)/install 軟件包的安裝方法,包括一系列拷貝編譯好的文件到指定位置。調用時會帶一個參數,就是嵌入系統的鏡像文件系統目錄,因此 $(1) 表示嵌入系統的鏡像目錄。可以用戶自定義目錄,本例中使用的是app目錄。

INSTALL_DIR、 INSTALL_BIN 在 $(TOPDIR)/rules.mk 文件定義,基本不要額外關注。其中:

1 INSTALL_DIR :=install -d -m0755 意思是創建所屬用戶可讀寫和執行,其他用戶可讀可執行的目錄。
2 INSTALL_BIN:=install -m0755 意思編譯好的文件存放到鏡像文件目錄。

說明:

    如果用戶空間的應用軟件在 boot 時要自動運行, 則需要在安裝方法說明中增加自動運行的腳本文件安裝和配置文件安裝方法。后續在更新程序自啟動中詳細說明。

完成前面定義后,必須使用 eval 函數實現各種定義。其格式為:
對於一般應用軟件包

$(eval $(call BuildPackage,$(PKG_NAME)))

如果一個軟件包有多個程序,例如:一個應用程序有自己的內核驅動模塊,上面使用的PKG_NAME 需要靈活變通。 eval 函數可以設計多個。也可以當成多個軟件包處理。

4、進行編譯,首先進行 make menuconfig 進行選擇
Songshuai Package --> Software Testing modules

 這里選擇為 M,表示安裝成 ipk 模塊, 也可以選擇 y 將其編譯進固件。

現在可以單獨編譯該軟件包, 執行如下命令

$ make package/myapp/compile V=99

編譯完成后注意下生成的ipk文件的位置

 或者也可以使用

find . -name "mycode*" 

來查找一下。

5、將編譯完成后生成的ipk傳到開發板上(如何傳請自行解決 ^^_^^ ),進行下一步的安裝和測試操作。

# opkg install mycode_0.1-1_mipsel_24kc.ipk 
Installing mycode (0.1-1) to root...
Configuring mycode.

安裝完成后可以將 mycode_0.1-1_mipsel_24kc.ipk 刪除了,然后進入到安裝目錄 app目錄下

 測試完成,可以通過指令卸載

# opkg remove mycode 
Removing package mycode from root...

卸載完成后,在/app/目錄下,也會刪除mycode可執行程序文件。

好奇心促使下面的內容誕生:
在網上看到大佬們一直在說preinst、postinst、prerm、postrm的,因為不知道具體的實際使用的場合,此處也是滿足一下自己的好奇心,特意試了一下,在上面的 Makefile $(eval $(call BuildPackage,$(PKG_NAME))) 之前添加如下內容

 1 define Package/$(PKG_NAME)/preinst
 2     #!/bin/bash
 3     echo 'installing $(PKG_NAME)'
 4 endef
 5 
 6 define Package/$(PKG_NAME)/postinst
 7     #!/bin/bash
 8     echo '$(PKG_NAME) installed successed !'
 9 endef
10 
11 define Package/$(PKG_NAME)/prerm
12     #!/bin/bash
13     echo 'removeing $(PKG_NAME)'
14 endef
15 
16 define Package/$(PKG_NAME)/postrm
17     #!/bin/bash
18     echo '$(PKG_NAME) remove successed !'
19 endef

說明:

因為筆記的開發板上支持bash,所以此處使用的bash,但是Openwrt默認是使用ash,可以將bash替換成ash進行測試。

然后 編譯、上傳到開發板,之后進行安裝

 1 # opkg install mycode_0.1-1_mipsel_24kc.ipk 
 2 Installing mycode (0.1-1) to root...
 3 installing mycode
 4 Configuring mycode.
 5 mycode installed successed !
 6 # ls /app/
 7 mycode
 8 # opkg remove mycode
 9 Removing package mycode from root...
10 removeing mycode
11 mycode remove successed !

含義說明:

1 Package/$(PKG_NAME)/preinst 軟件包安裝前處理方法,使用腳本語言,調用時帶入的參數為嵌入式系統的鏡像目錄。
2 Package/$(PKG_NAME)/postinst 軟件包安裝后處理方法,使用腳本語言。
3 Package/$(PKG_NAME)/prerm 軟件包刪除前處理方法,使用腳本語言。
4 Package/$(PKG_NAME)/postrm 軟件包刪除后處理方法,使用腳本語言。

二、編譯源碼,直接編譯到內核中

進行 make menuconfig 進行選擇 y 將其編譯進固件。

 此時需要進行整個openwrt的全編譯,使用

$ make V=99

進行編譯,編譯完成后,重新燒寫內核文件即可,內核啟動完成,可以直接在/app/目錄下看到 mycode 可執行程序的文件。

三、不使用源碼編譯
當然 ,如果不想這么麻煩的編輯Makefile,那么關於用戶自定義添加的軟件包的方法,還有另外一種比較省事情的方法,就是將通過交叉編譯(我的交叉編譯工具鏈為mipsel-openwrt-linux-gcc)完成的可執行程序文件 (比如本歷程中的 mycode )直接放置在目錄下package/base-files/files/app/,然后編譯內核文件,再進行燒寫即可,之后,可執行程序文件mycode也存在/app/下。
具體步驟以及指令可以使用:

1 $ mipsel-openwrt-linux-gcc myabcd.c -o mycode
2 $ cp mycode ~/openwrt/package/base-files/files/app/
3 $ make V=99

此效果與上面的 二 的效果一樣。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM