注意: 如果有报错,
1:可以查看日志:OpenWrt-SDK/logs/package/helloworld/dump.txt 2:注意Makefile中的空格与tab键的使用。
1:实现ipk Demo的编译,理解架构:
1. 了解架构:
hlp@ubuntu:~/openwrt/openwrt-sdk-ramips-mt7621_gcc-7.4.0_musl.Linux-x86_64$ tree package/utils/ package/utils/ └── hello_world ├── Makefile ===》这是模块的规则Makefile └── src ├── hello_world.c └── Makefile ===》这是我们代码的规则Makefile 2 directories, 3 files
2. 代码块:
hlp@ubuntu:~/openwrt/openwrt-sdk-ramips-mt7621_gcc-7.4.0_musl.Linux-x86_64$ cat package/utils/hello_world/src/hello_world.c #include <stdio.h> int main(char argc, char *argv[]) { int i = 1; while(1) { //1~10 循环 printf("Hello world!!!%d\n",i); //打印内容 if (i < 10) { i++; } else { i = 1; } sleep(1);// 一秒钟打印一次 } return 0; }
3. 代码块中对应的Makefile
hlp@ubuntu:~/openwrt/openwrt-sdk-ramips-mt7621_gcc-7.4.0_musl.Linux-x86_64$ cat package/utils/hello_world/src/Makefile all: hello_world hello_world: hello_world.o $(CC) $(LDFLAGS) hello_world.o -o hello_world helloworld.o: hello_world.c $(CC) $(CFLAGS) -c hello_world.c clean: rm *.o hello_world hlp@ubuntu:~/openwrt/openwrt-sdk-ramips-mt7621_gcc-7.4.0_musl.Linux-x86_64$
4. 模块对应的外层的Makefile,即hello_world模块,hello_world下层Makefile
hlp@ubuntu:~/openwrt/openwrt-sdk-ramips-mt7621_gcc-7.4.0_musl.Linux-x86_64$ cat package/utils/hello_world/Makefile # 引入头文件 rules.mk include $(TOPDIR)/rules.mk # 设置PKG_*变量 PKG_NAME:=hello_world PKG_VERSION:=1.0 PKG_BUILD_DIR:= $(BUILD_DIR)/$(PKG_NAME) # 引入头文件 package.mk include $(INCLUDE_DIR)/package.mk # 定义hello_world信息 define Package/hello_world SECTION:=base CATEGORY:=Utilities TITLE:=Hello world -prints a hello world message endef # 定义hello_world说明 define Package/hello_world/description If you can't figure out what this program does, you're probably brain-dead and need immediate medical attention. endef # 编译前的准备 define Build/Prepare mkdir -p $(PKG_BUILD_DIR) $(CP) ./src/* $(PKG_BUILD_DIR)/ endef # 定义hello_world安装什么 define Package/hello_world/install $(INSTALL_DIR) $(1)/bin $(INSTALL_BIN) $(PKG_BUILD_DIR)/hello_world $(1)/bin/ endef # hello_world脚本处理完毕,调用 $(eval $(call BuildPackage,hello_world)) hlp@ubuntu:~/openwrt/openwrt-sdk-ramips-mt7621_gcc-7.4.0_musl.Linux-x86_64$
5. 编译: make 可以带相关参数 -j1 V=s 查看运行过程中的报错。
hlp@ubuntu:~/openwrt/openwrt-sdk-ramips-mt7621_gcc-7.4.0_musl.Linux-x86_64$ make package/utils/hello_world/compile WARNING: Makefile 'package/linux/Makefile' has a dependency on 'r8169-firmware', which does not exist WARNING: Makefile 'package/linux/Makefile' has a dependency on 'e100-firmware', which does not exist WARNING: Makefile 'package/linux/Makefile' has a dependency on 'bnx2-firmware', which does not exist WARNING: Makefile 'package/linux/Makefile' has a dependency on 'bnx2x-firmware', which does not exist WARNING: Makefile 'package/linux/Makefile' has a dependency on 'ar3k-firmware', which does not exist WARNING: Makefile 'package/linux/Makefile' has a dependency on 'mwifiex-sdio-firmware', which does not exist WARNING: Makefile 'package/linux/Makefile' has a dependency on 'kmod-phy-bcm-ns-usb2', which does not exist WARNING: Makefile 'package/linux/Makefile' has a dependency on 'edgeport-firmware', which does not exist WARNING: Makefile 'package/linux/Makefile' has a dependency on 'kmod-phy-bcm-ns-usb3', which does not exist WARNING: Makefile 'package/linux/Makefile' has a dependency on 'amdgpu-firmware', which does not exist WARNING: Makefile 'package/linux/Makefile' has a dependency on 'radeon-firmware', which does not exist WARNING: Makefile 'package/linux/Makefile' has a dependency on 'prism54-firmware', which does not exist WARNING: Makefile 'package/linux/Makefile' has a dependency on 'rtl8192su-firmware', which does not exist tmp/.config-package.in:7:warning: ignoring type redefinition of 'PACKAGE_libatomic' from 'boolean' to 'tristate' tmp/.config-package.in:36:warning: ignoring type redefinition of 'PACKAGE_libc' from 'boolean' to 'tristate' tmp/.config-package.in:64:warning: ignoring type redefinition of 'PACKAGE_libgcc' from 'boolean' to 'tristate' tmp/.config-package.in:149:warning: ignoring type redefinition of 'PACKAGE_libpthread' from 'boolean' to 'tristate' tmp/.config-package.in:177:warning: ignoring type redefinition of 'PACKAGE_librt' from 'boolean' to 'tristate' tmp/.config-package.in:234:warning: ignoring type redefinition of 'PACKAGE_libstdcpp' from 'boolean' to 'tristate' # # configuration written to .config # make[1] package/utils/hello_world/compile make[2] -C package/toolchain compile make[2] -C package/utils/hello_world clean-build make[2] -C package/utils/hello_world compile
6. 编译成功后,查看文件
hlp@ubuntu:~/openwrt/openwrt-sdk-ramips-mt7621_gcc-7.4.0_musl.Linux-x86_64$ find -name *.ipk|grep hello ./bin/packages/mipsel_24kc/base/helloworld_1.0-1_mipsel_24kc.ipk ./bin/packages/mipsel_24kc/base/hello_world_1.0_mipsel_24kc.ipk hlp@ubuntu:~/openwrt/openwrt-sdk-ramips-mt7621_gcc-7.4.0_musl.Linux-x86_64$
opkg install helloworld_1_ar71xx.ipk
2:模块对应的Makefile分析
我们的代码对应的Makefile可以自测运行进行检测,然后上层makefile编译测试。
出现报错,可以查看日志,分析报错,makefile哪行错误或者没有执行,对比例子分析错误原因。
- PKG_* 作用:
检测软件包是否被选中。
软件包如果有需要下载的源码,按PKG_SUORCE_URL 进行下载。
检测本地dl/目录是否包含了源码文件 PKG_SOURCE。
如果需要检验源码,就执行PKG_MD5SUM。
解压缩源码。
常用变量:
PKG_NAME: 软件包名称,在菜单项中将看见,必须与目录名称一致。
PKG_VERSION:软件包版本,如果软件包的源码是在线下载的,版本号要与服务器上的一致。
PKG_RELEASE: 软件包的Makefile版本,自己设定。
PKG_BUILE_DIR:软件包的编译过程目录名字,这个要与源码解压完以后生成的目录名字一样,否则就找不到源码了。
PKG_SOURCE:软件包源码文件的名字。
PKG_SUORCE_URL: 软件包源码的下载地址,若为空则从dl/目录下寻找。
PKG_MD5SUM:对下载的软件包进行校验。
PKG_CAT:指定使用哪个解压工具(zcat,bzcat,unzip)。
PKG_BUILD_DEPENDS:软件包编译的时候依赖哪个其他软件包。
PKG_SOURCE_PROTO:通过代码仓库获得代码git,svn。
PKG_REV:如果是通过svn获得代码,这表示svn版本号。
- 定义Build/* 作用:
定义的预处理方法。
配置时的处理方法。
编译时的处理方法。
编译安装时的处理方法。
安装库文件的处理方法。
Build选项:
***Build/Prepare:**用于解包及打补丁的命令
*Build/Configure:如果源代码不需要configure来生成Makefie或者是通用的configure脚本,就不需要这部分。否则就需要你自己的命令脚本或使用( c a l l B u i l d / C o n f i g u r e / D e f a u l t , F O O = b a r ) 增 加 额 外 的 参 数 传 递 给 c o n f i g u r e 脚 本 ∗ B u i l d / C o m p i l e : 编 译 源 代 码 , 在 大 多 数 情 况 下 应 该 不 用 定 义 而 使 用 默 认 值 。 如 果 你 想 传 递 给 m a k e 特 定 的 参 数 , 可 以 使 用 (call Build/Configure/Default, FOO=bar) 增加额外的参数传递给configure 脚本 *Build/Compile:编译源代码,在大多数情况下应该不用定义而使用默认值。如果你想传递给make特定的参数,可以使用(callBuild/Configure/Default,FOO=bar)增加额外的参数传递给configure脚本∗Build/Compile:编译源代码,在大多数情况下应该不用定义而使用默认值。如果你想传递给make特定的参数,可以使用(call Build/Compile/Default, FOO=bar)
*Build/Install:安装编译后的文件,默认是调用make install, 如果需要传递指定的参数,使用$(call Build/Install/Default, install install-foo)。注意你需要传递的参数,要增加在 install 参数后面,不要忘了 install 参数
*Build/InstallDev: 例如静态库和头文件等
- 定义Package/* 作用:
描述软件包的一些情况,用于菜单选项使用。
定义软件包安装在设备上的时候安装哪些软件。
安装之前的处理脚本。
安装之后的处理脚本。
卸载之前的处理脚本。
卸载之后的处理脚本。
常用变量:
**SECTION:**软件包的类型,如:network、Sound、Utilities、Multimedia等
GATEGORY: 软件包所属的菜单项选项中的菜单,值既可以是已经有的分类,也可以是自己的一个新分类。已经有的分类可以参考同类别软件包的GATEGORY写法。
TITLE:软件包显示的名称。
URL:软件包来源公司网站。
MAINTAINER:软件包的维护者信息。
DEPENDS:软件包依赖哪些软件包,被依赖的软件包会自动选中。
USERID:软件包安装的时候生成账号和组。格式为:账号/值。
Package包选项:
Package/<>: 定义软件包的描述信息,例如网站地址和menuconfig中的菜单的分类等
Package/<>/description: 软件包的详细描述
Package/<>/install: 复制文件到ipkg目录中,使用( 1 ) 代 表 i p k g 目 录 , 在 源 码 中 使 用 相 对 目 录 。 编 译 生 成 的 安 装 文 件 同 (1) 代表ipkg目录,在源码中使用相对目录 。编译生成的安装文件同(1)代表ipkg目录,在源码中使用相对目录。编译生成的安装文件同(PKG_INSTAALL_DIR)目录
Package/<>/Default: 软件包的默认选项
Package/<>/config: 根据软件包的选择对编译选项进行定义
Package/<>/conffiles: 定义本软件包的运行配置文件列表,一行一个文件
Package/<>/preinst: 安装前执行的脚本(记得添加 #!/bin/sh)
Package/<>/postinst: 安装后执行的脚本(记得添加 #!/bin/sh)
Package/<>/prerm: 删除前执行的脚本(记得添加 #!/bin/sh)
Package/<>/postrm: 删除后执行的脚本(记得添加 #!/bin/sh)
注: * 表示 可选,其他表示 必选。
3:编译运行
可以通过 源目录中执行 make menuconfig ,选择要编译的模块。 openwrt机制(有兴趣可以阅读源码的一些相关Makefile,了解编译机制)会自动去搜寻package/utils/ 所有文件,然后根据hello_wolrd顶层Makefile中的信息自动将hello_world添加进入菜单中。 - 注意:<M> 将软件编译成ipk包,单独存放在openwrt/ bin/ramips/packages/base/* 目录下;<*> 将软件包编译进入内核固件中。
编译运行:
全部编译: make V=s (速度慢,时间长); 单独编译: make package/utils/hello_world/compile V=s(时间短,方便调试)
拷贝到板子,安装:
opkg install /拷贝目录/hello_world_1.0_ramips_24kec.ipk
在板子上执行:
hello_world ===》注:如果未执行成功,查看hello_world是否有可执行权限,没有则用`chmod +x hello_world`添加权限。