最近,因为一些原因,我需要把自己之前开发的程序移植到OpenWrt上面。要做到这件事,至少需要一台装有OpenWrt的设备(可以用虚拟机)、一台Linux设备用于编译(WSL我猜或许也可以)、Linux编程的知识、GNU编译工具的用法、和一定的英语水平(看文档或者查错之类的)。
下载开发工具
从官方文档里能找到下载开发工具的部分:https://openwrt.org/docs/guide-developer/using_the_sdk#downloads。
我使用了最新快照对应的工具,平台是ramips/mt7621,所以对应的下载位置在 https://downloads.openwrt.org/snapshots/targets/ramips/mt7621/。找到名为openwrt-sdk-ramips-mt7621_gcc-8.4.0_musl.Linux-x86_64.tar.xz的文件,下载之。
在Linux下解压,我用了Ubuntu 20.04,其他的系统应该也可以:
tar -xf openwrt-sdk-ramips-mt7621_gcc-8.4.0_musl.Linux-x86_64.tar.xz mv openwrt-sdk-ramips-mt7621_gcc-8.4.0_musl.Linux-x86_64.tar openwrt
这样,开发工具就在openwrt目录下准备好了,下面提到的openwrt
目录都是指这个目录。
创建本地Feed
OpenWrt提供了包管理工具opkg,其开发工具编译生成的最小单元也是包,而不是单个的可执行文件,虽然也可以把生成的可执行文件解出来放到OpenWrt上运行。包中除了可执行文件外还定义了安装方式,在使用时就可以一键安装和更新。
虽然可以直接在openwrt/package
目录下面直接建包,但更推荐的方式是创建Feed来存放包,你可以把Feed整个放到代码版本库比如Git上面,当OpenWrt开发工具更新时,不需要把自己的包的代码移来移去。
Feed其实就是一个目录,里面包含了包的定义。我在openwrt
目录外的地方建了个目录来作为Feed,然后将它配置到OpenWrt中。
mkdir myfeed cd /path/to/openwrt cp feeds.conf.default feeds.conf
在feeds.conf
里加入以下内容:
src-link myfeed /path/to/myfeed
这样OpenWrt就知道多了一个名叫myfeed
的Feed,对应的路径是/path/to/myfeed
。
创建包
在myfeed
目录中创建目录:
mkdir mypackage
OpenWrt开发工具在找包的时候会遍历目录,所以把包放在Feed更深处也是可以的:
mkdir -p mycategory/mysubcategory/mypackage
在mypackage
中创建名为Makefile
的文件,写入:
# 作者 PKG_MAINTAINER:=Chaofan <herbix@163.com> PKG_LICENSE:=Private # 固定写法,INCLUDE_DIR指openwrt/include目录 include $(INCLUDE_DIR)/package.mk # 定义基本信息,DEPENDS这行如果没有依赖可以不写 define Package/mypackage SECTION:=utils CATEGORY:=Utilities TITLE:=My first package DEPENDS:=+another_package endef # 描述 define Package/mypackage/description My first package endef # 固定写法 $(eval $(call BuildPackage,mypackage))
虽然包里什么都没有,但是它已经是个合法的包了。
从Feed中导入包
回到openwrt
目录,用以下命令导入包:
./scripts/feeds update myfeed ./scripts/feeds install mypackage
这时,运行以下命令就应该能在Utilities
分类下看到mypackage
这个包了。
make menuconfig
还可以试着去编译它,虽然不会有输出,因为它是空的。
make package/mypackage/compile
加入可执行程序
在mypackage
目录下创建目录src
,用来放源代码。在src
下创建main.c
和Makefile
文件,分别写入:
main.c
#include <stdio.h> int main(int argc, char** argv) { puts("Hello, OpenWrt!"); return 0; }
Makefile
all: main.c $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -Wall -o mypackage $^ $(LDLIBS)
然后修改mypackage
目录中的Makefile
,在call BuildPackage
这一行前面加入以下内容:
define Build/Prepare mkdir -p $(PKG_BUILD_DIR) $(CP) ./src/* $(PKG_BUILD_DIR)/ endef # 安装命令,注意这些命令只是一些定义而不是在安装时实际执行的 # $(1)在这里相当于OpenWrt系统的根目录 # 所以这里是说安装时将mypackage这个可执行文件放到/usr/bin目录下 define Package/mypackage/install $(INSTALL_DIR) $(1)/usr/bin $(INSTALL_BIN) $(PKG_BUILD_DIR)/mypackage $(1)/usr/bin/ endef
然后回到openwrt
目录下运行:
make package/mypackage/compile
如果没出错,就能在openwrt/bin/packages/<平台>/myfeed/
目录下找到.ipk
后缀的文件,可以在OpenWrt界面上上传安装或者用opkg
命令安装这个包。安装后在/usr/bin
目录下能找到mypackage
文件,执行它会出现:
Hello, OpenWrt!
文章来源:https://blog.chaofan.io/archives/how-to-develop-on-openwrt