爲了達到本身編寫一個程序打包成ipk,並能在OpenWRT上運行的目的。我在網上找了些學習的資料。linux
本人蔘考的是:如何在OpenWRT上作開發shell
感謝該網友的耐心解答。雖然有現成的步驟,博主仍是喜歡親自實踐一下,寫下本身的實踐過程。
ssh
make menuconfig 選上 「Build the OpenWRT SDK」ide
在 trunk目錄下,執行:學習
$ make menuconfig
選擇對應的"Target System"與"Target Profile",並選上"Build the OpenWrt SDK"。
ui
而後 Save,退出。再make一次。url
$ make V=99
make 完成以後,在 bin/ar71xx/ 目錄下會生成SDK的壓縮文件:spa
OpenWrt-SDK-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-i686.tar.bz2code
將上面所生成的 OpenWrt-SDK-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-i686.tar.bz2 複製到其它路徑下(指能夠不在OpenWrt的源碼路徑下),再解壓出來。ip
好比我將其放到 ~/Workspace/OpenWRT/ 路徑下:
$ cp bin/ar71xx/OpenWrt-SDK-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-i686.tar.bz2 ~/Workspace/OpenWRT $ cd ~/Workspace/OpenWRT $ tar jxvf OpenWrt-SDK-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-i686.tar.bz2
在 ~/Workspace/OpenWRT/ 路徑下就生成了 OpenWrt-SDK-ar71xx-generic_gcc-4.8-linaro_uClibc-0.9.33.2.Linux-i686 目錄。
爲了方便,我將這個長長的目錄名簡化爲:OpenWrt-SDK。修改後,完整的路徑是:~/Workspace/OpenWRT/OpenWrt-SDK
聽說這個目錄結構跟 OpenWrt的源碼目錄結構差很少。
其實,這裏能夠是任意咱們想要加入的程序,庫等。這裏就以helloword爲例。
在任意路徑下,建立helloword項目。好比這裏仍是在 ~/Workspace/OpeWRT 目錄下。
$ cd ~/Workspace/OpenWRT $ mkdir helloword $ cd helloword $ touch helloword.c Makefile
在 ~/Workspace/OpenWRT/ 目錄下建立了 helloword 目錄,並生成 helloword.c與Makefile文件。
以下爲 helloworld.c的內容:
#include <stdio.h> int main() { printf("This is my hello word!\n"); return 0; }
Makefile的內容:
helloworld : helloworld.o $(CC) $(LDFLAGS) helloworld.o -o helloworld helloworld.o : helloworld.c $(CC) $(CFLAGS) -c helloworld.c clean : rm *.o helloworld
首先,確保在程序沒問題,在本地能正常編過。爲了檢驗一下,能夠就地 make 一下,看程序自己有沒有問題。
這個程序都如些之簡單了,本人本身了make了一下,OK,再run了一下,正常。
進入 OpenWrt/Packages/ 並在該目錄下建立 helloworld 目錄,並進入該目錄。
$ cd ~/Workspace/OpenWrt/OpenWrt-SDK/package $ mkdir helloworld $ cd helloworld
將咱們第三步寫的程序複製到這個目錄下來,改名爲src。再新建一個 Makefile 文件。
$ cp -r ../../../helloworld src $ touch Makefile
整個過程下來,package目錄結構以下:
package |-- helloworld | |-- Makefile | `-- src | |-- helloworld.c | `-- Makefile `-- Makefile
package/Makefile 不要去修改它。
咱們要編寫的是 package/helloworld/Makefile 這個文件。
在這個文件中,咱們要描述 helloworld 包的信息,好比:如何配置、如何編譯、如何打包、安裝等等信息。
這個文件與通常的 Makefile 格式還不同,詳見OpenWrt上的說明文檔:OpenWrt官網Packages說明
這裏我就依照例子編寫 helloworld/Makefile:
include $(TOPDIR)/rules.mk PKG_NAME:=helloworld PKG_RELEASE:=1 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) include $(INCLUDE_DIR)/package.mk define Package/helloworld SECTION:=utils CATEGORY:=Utilities TITLE:=Helloworld -- prints a snarky message endef define Package/helloworld/description It's my first package demo. endef define Package/helloworld/Prepare echo "Here is Package/Prepare" mkdir -p $(PKG_BUILD_DIR) $(CP) ./src/* $(PKG_BUILD_DIR)/ endef define Package/helloworld/install echo "Here is Package/install" $(INCLUDE_DIR) $(1)/bin $(INCLUDE_BIN) $(PKG_BUILD_DIR)/helloworld$(1)/bin/ endef $(eval $(call BuildPackage, helloworld))
而後回到 OpenWrt-SDK 目錄下,執行:make V=s,結果有如下錯誤提示:
$ make V=s ERROR: please fix package/helloworld/Makefile - see logs/package/helloworld/dump.txt for details
說是我寫的這個Makefile有錯,請查看 dump.txt 文件。無奈只好去看看到底錯在哪裏囉。
打開 OpenWrt-SDK/logs/package/helloworld/dump.txt 文件:
Package: helloworld Version: 1 Depends: +libc +SSP_SUPPORT:libssp +USE_GLIBC:librt +USE_GLIBC:libpthread Conflicts: Menu-Depends: Provides: Section: opt Category: Extra packages Title: Maintainer: Source: Type: ipkg Description: @@ Makefile:32: *** invalid syntax in conditional. Stop.
前面那麼多行信息沒什麼用,最重要的是最後一行,好像是說32行條件語法錯誤。趕忙打開 package/helloworld/Makefile,定位到32行看看。結果是:
$(eval $(call BuildPackage, helloworld))
這個,我何錯之有呢?
最後反覆排查,原來是 "BuildPackage," 逗號後面與 "helloworld" 之間多了個空格。不會吧!多個空格少個空格都會致使語法錯誤?!
好了,改正過來了。
$(eval $(call BuildPackage,helloworld)) #去掉空格
如今 make V=s 再也不是剛纔那個錯了。
make[3]: Entering directory `/home/hevake_lcj/Workspace/OpenWRT/my-packages/OpenWrt-SDK/package/helloworld' CFLAGS="-Os -pipe -mno-branch-likely -mips32r2 <此處省略好長串...>" CXXFLAGS="-Os -pipe -mno-branch-likely -mips32r2 <此處省略好長串...>" LDFLAGS="<此處省略好長串...>" make -j1 -C /home/hevake_lcj/Workspace/OpenWRT/my-packages/OpenWrt-SDK/build_dir/target-mips_34kc_uClibc-0.9.33.2/helloworld/. AR="mips-openwrt-linux-uclibc-gcc-ar" AS="mips-openwrt-linux-uclibc-gcc -c -Os -pipe -mno-branch-likely -mips32r2 -mtune=34kc -fno-caller-saves -fhonour-copts -Wno-error=unused-but-set-variable -msoft-float" LD=mips-openwrt-linux-uclibc-ld NM="mips-openwrt-linux-uclibc-gcc-nm" CC="mips-openwrt-linux-uclibc-gcc" GCC="mips-openwrt-linux-uclibc-gcc" CXX="mips-openwrt-linux-uclibc-g++" RANLIB="mips-openwrt-linux-uclibc-gcc-ranlib" STRIP=mips-openwrt-linux-uclibc-strip OBJCOPY=mips-openwrt-linux-uclibc-objcopy OBJDUMP=mips-openwrt-linux-uclibc-objdump SIZE=mips-openwrt-linux-uclibc-size CROSS="mips-openwrt-linux-uclibc-" ARCH="mips" ; make[4]: Entering directory `/home/hevake_lcj/Workspace/OpenWRT/my-packages/OpenWrt-SDK/build_dir/target-mips_34kc_uClibc-0.9.33.2/helloworld' make[4]: *** No targets specified and no makefile found. Stop. # 錯誤:沒有找 Makefile 文件!! make[4]: Leaving directory `/home/hevake_lcj/Workspace/OpenWRT/my-packages/OpenWrt-SDK/build_dir/target-mips_34kc_uClibc-0.9.33.2/helloworld' make[3]: *** [/home/hevake_lcj/Workspace/OpenWRT/my-packages/OpenWrt-SDK/build_dir/target-mips_34kc_uClibc-0.9.33.2/helloworld/.built] Error 2 make[3]: Leaving directory `/home/hevake_lcj/Workspace/OpenWRT/my-packages/OpenWrt-SDK/package/helloworld' make[2]: *** [package/helloworld/compile] Error 2 make[2]: Leaving directory `/home/hevake_lcj/Workspace/OpenWRT/my-packages/OpenWrt-SDK' make[1]: *** [/home/hevake_lcj/Workspace/OpenWRT/my-packages/OpenWrt-SDK/staging_dir/target-mips_34kc_uClibc-0.9.33.2/stamp/.package_compile] Error 2 make[1]: Leaving directory `/home/hevake_lcj/Workspace/OpenWRT/my-packages/OpenWrt-SDK' make: *** [world] Error 2
爲何 build_dir/target-mips_34kc_uClibc-0.9.33.2/helloworld 目錄下沒有 Makefile 文件?
咱們要好好排查一個 package/helloworld/Makefile 文件中的 Package/helloworld/Prepare 宏。
define Package/helloworld/Prepare echo "Here is Package/Prepare" mkdir -p $(PKG_BUILD_DIR) $(CP) ./src/* $(PKG_BUILD_DIR)/ endef
好像這個宏壓根沒有被執行到。
爲何呢?
<今天太晚了,明天再整>
<接着昨晚的問題>
最後與例子仔細比對,發現原來我將 "Build/Prepare" 寫成了 "Package/helloworld/Prepare"。
最終完整的 Makefile 文件以下:
include $(TOPDIR)/rules.mk PKG_NAME:=helloworld PKG_RELEASE:=1 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) include $(INCLUDE_DIR)/package.mk define Package/helloworld SECTION:=utils CATEGORY:=Utilities TITLE:=Helloworld -- prints a snarky message endef define Package/helloworld/description It's my first package demo. endef define Build/Prepare #已修正 echo "Here is Package/Prepare" mkdir -p $(PKG_BUILD_DIR) $(CP) ./src/* $(PKG_BUILD_DIR)/ endef define Package/helloworld/install echo "Here is Package/install" $(INSTALL_DIR) $(1)/bin $(INSTALL_BIN) $(PKG_BUILD_DIR)/helloworld $(1)/bin/ endef $(eval $(call BuildPackage,helloworld)) #已去除逗號後面的空格
此次 make -j1 V=s 成功了。生成了 helloworld_1_ar71xx.ipk 。find 一下,看在哪裏。
$ find -name helloworld*.ipk ./bin/ar71xx/packages/base/helloworld_1_ar71xx.ipk
將剛生成的 helloworld_1_ar71xx.ipk 文件用 scp 傳到目標路由上。本人的路由IP爲:192.168.1.2
$ scp bin/ar71xx/packages/base/helloworld_1_ar71xx.ipk root@192.168.1.2: root@192.168.1.2's password: helloworld_1_ar71xx.ipk 100% 1993 2.0KB/s 00:00
SSH登錄路由器,並安裝 helloworld_1_ar71xx.ipk包。
$ ssh root@192.168.1.2 root@192.168.1.2's password: BusyBox v1.23.2 (2015-05-03 12:46:04 CST) built-in shell (ash) _______ ________ __ | |.-----.-----.-----.| | | |.----.| |_ | - || _ | -__| || | | || _|| _| |_______|| __|_____|__|__||________||__| |____| |__| W I R E L E S S F R E E D O M ----------------------------------------------------- CHAOS CALMER (Bleeding Edge, r45594) ----------------------------------------------------- * 1 1/2 oz Gin Shake with a glassful * 1/4 oz Triple Sec of broken ice and pour * 3/4 oz Lime Juice unstrained into a goblet. * 1 1/2 oz Orange Juice * 1 tsp. Grenadine Syrup ----------------------------------------------------- root@OpenWrt:~# ls helloworld_1_ar71xx.ipk root@OpenWrt:~# opkg install helloworld_1_ar71xx.ipk Installing helloworld (1) to root... Configuring helloworld. root@OpenWrt:~#
安裝完成後,執行一下試試看。
root@OpenWrt:~# helloworld This is my hello word!
用which命令查看 helloworld 安裝的路徑:
root@OpenWrt:~# which helloworld /bin/helloworld
在 /bin/ 路徑下。
本人沒有將網上的例子直接貼在本身的博文上,而是本身親自嘗試整個過程,並記錄本身所遇到的問題,這樣會更真實一些。
整個過程,就屬「第四步:建helloworld包」遇到困難最多。這也是整個過程當中最核心的工做。不過,我仍是一一解決了。
咱們在按照例程走完一次流程,不能只是蜻蜓點水,而更應該是去領悟其中的原理。
能夠想像,真正的應用遠比這個複雜。後面,我會另起一個博文專門研究 OpenWrt 的 package Makefile。盡請關注~
想與我一塊兒研究技術,就請關注我吧!