Chinaunix首页 | 论坛 | 博客
  • 博客访问: 62533
  • 博文数量: 4
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 120
  • 用 户 组: 普通用户
  • 注册时间: 2013-12-31 17:46
个人简介

On my Way

文章分类

全部博文(4)

文章存档

2015年(1)

2014年(2)

2013年(1)

我的朋友

分类: 嵌入式

2014-01-09 13:19:02

    前些日子又搞起了OpenWRT,之前一直只是使用shell或者Lua实现自己的想法,随着C渐渐使用的顺畅了,打算学习下OpenWRT上程序的编写以及交叉编译。
首先列下目录结构

  1. lee@ubuntu:~/OpenWrt-SDK-ar71xx-for-linux-i486-gcc-4.6-linaro_uClibc-0.9.33.2/package$ tree
  2. .
  3. |-- hiOpenWRT
  4. | |-- Makefile
  5. | `-- src
  6. | |-- hiOpenwrt.c
  7. | `-- Makefile
  8. |-- Makefile
  9. `-- rules.mk

    这是在OpenWRT-SDK/package下的文件结构,需要自己建的目录有hiOpenwrt/ 和hiOpenwrt/src/ ;需要自己建的文件有:
src下的hiOpenwrt.c
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. int main(void){
  4.     printf("Hi,OpenWRT!\n");
  5.     return 0;
  6. }

src下Makefile:src下Makefile:
  1. # build hiOpenwrt executable when user executes "make"
  2. hiOpenwrt: hiOpenwrt.o
  3. $(CC) $(LDFLAGS) hiOpenwrt.o -o hiOpenwrt
  4. hiOpenwrt.o: hiOpenwrt.c
  5. $(CC) $(CFLAGS) -c hiOpenwrt.c
  6. #remove object files and executable when user executes "make clean"
  7. clean:
  8. rm *.o hiOpenwrt

当然,在hiOpenwrt/Makefile也需要写,只不过这个要求比较多,格式如下:

点击(此处)折叠或打开

  1. #-----官方文档如下
  2. This is the OpenWrt SDK. It contains a stripped-down version of the buildroot. You can use it to test/develop packages without having to compile your own toolchain or any of the libraries included with OpenWrt.
  3. To use it, just put your buildroot-compatible package directory in the subdir 'package/' and run 'make' from this directory.
  4. #------ OPENWRT集成非官方包之Makefile规则
  5. include $(TOPDIR)/rules.mk
  6. PKG_NAME:=[软件包名字 和文件夹名称一样]
  7. PKG_VERSION:=[软件包版本 自己写个]
  8. PKG_RELEASE:=1
  9. PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
  10. include $(INCLUDE_DIR)/package.mk
  11. define Package/$(PKG_NAME)
  12. SECTION:=utils
  13. CATEGORY:=[软件包在menuconfig里的位置 比如Base system]
  14. DEPENDS:=[依赖包 两个之间通过空格分隔 前面加+为默认显示 选中该软件包自动选中依赖包 不加+为默认不显示 选中依赖包才显示]
  15. TITLE:=[标题]
  16. PKGARCH:=[平台 比如ar71xx 全部写all]
  17. MAINTAINER:=[作者]
  18. endef
  19. define Package/$(PKG_NAME)/description
  20. [软件包简介]
  21. endef
  22. #非本目录下的源码文件, 拷贝到此相应目录下.
  23. # 如../../xucommon/xucommon.c, 则将 xucommon.c 拷贝到此目录下的源码的 ../../
  24. define Build/Prepare
  25. mkdir -p $(PKG_BUILD_DIR)
  26. $(CP) ./src/* $(PKG_BUILD_DIR)/
  27. endef
  28. define Build/Configure
  29. endef
  30. define Build/Compile
  31. endef
  32. define Package/$(PKG_NAME)/conffiles
  33. [升级时保留文件/备份时备份文件 一个文件一行]
  34. endef
  35. define Package/$(PKG_NAME)/install
  36. $(CP) ./files/* $(1)/
  37. endef
  38. define Package/$(PKG_NAME)/preinst
  39. [安装前执行的脚本 记得加上#!/bin/sh 没有就空着]
  40. #!/bin/sh
  41. uci -q batch <<-EOF >/dev/null
  42. delete ucitrack.@aria2[-1]
  43. add ucitrack aria2
  44. set ucitrack.@aria2[-1].init=aria2
  45. commit ucitrack
  46. EOF
  47. exit 0
  48. endef
  49. define Package/$(PKG_NAME)/postinst
  50. [安装后执行的脚本 记得加上#!/bin/sh 没有就空着]
  51. #!/bin/sh
  52. rm -f /tmp/luci-indexcache
  53. exit 0
  54. endef
  55. Package/$(PKG_NAME)/prerm
  56. [删除前执行的脚本 记得加上#!/bin/sh 没有就空着]
  57. endef
  58. Package/$(PKG_NAME)/postrm
  59. [删除后执行的脚本 记得加上#!/bin/sh 没有就空着]
  60. endef
  61. $(eval $(call BuildPackage,$(PKG_NAME)))

自己的hiOpenwrt的Makefile自己的hiOpenwrt的Makefile

点击(此处)折叠或打开

  1. ##############################################
  2. # OpenWrtMakefile for hiOpenwrt program
  3. #
  4. #
  5. # Most ofthe variables used here are defined in
  6. # theinclude directives below. We just need to
  7. # specifya basic description of the package,
  8. # whereto build our program, where to find
  9. # thesource files, and where to install the
  10. # compiled program on the router.
  11. #
  12. # Be verycareful of spacing in this file.
  13. # Indentsshould be tabs, not spaces, and
  14. # thereshould be no trailing whitespace in
  15. # linesthat are not commented.
  16. #
  17. ##############################################
  18. include $(TOPDIR)/rules.mk
  19. # Nameand release number of this package
  20. PKG_NAME:=hiOpenWRT
  21. PKG_RELEASE:=1
  22. # Thisspecifies the directory where we're going to build the program.
  23. # Theroot build directory, $(BUILD_DIR), is by default the build_mipsel
  24. #directory in your OpenWrt SDK directory
  25. PKG_BUILD_DIR:= $(BUILD_DIR)/$(PKG_NAME)
  26. include $(INCLUDE_DIR)/package.mk
  27. # Specifypackage information for this program.
  28. # Thevariables defined here should be self explanatory.
  29. # If youare running Kamikaze, delete the DESCRIPTION
  30. #variable below and uncomment the Kamikaze define
  31. # directivefor the description below
  32. define Package/$(PKG_NAME)
  33. SECTION:=utils
  34. CATEGORY:=Utilities
  35. TITLE:=hiOpenwrt-- prints a snarky message
  36. endef
  37. # Specifywhat needs to be done to prepare for building the package.
  38. # In ourcase, we need to copy the source files to the build directory.
  39. # This isNOT the default. The default uses thePKG_SOURCE_URL and the
  40. #PKG_SOURCE which is not defined here to download the source from the web.
  41. # Inorder to just build a simple program that we have just written, it is
  42. # mucheasier to do it this way.
  43. define Build/Prepare
  44. mkdir -p $(PKG_BUILD_DIR)
  45. $(CP) ./src/* $(PKG_BUILD_DIR)/
  46. endef
  47. # We donot need to define Build/Configure or Build/Compile directives
  48. # Thedefaults are appropriate for compiling a simple program such as this one
  49. # Specifywhere and how to install the program. Since we only have one file,
  50. # thehelloworld executable, install it by copying it to the /bin directory on
  51. # therouter. The $(1) variable represents the root directory on the router running
  52. #OpenWrt. The $(INSTALL_DIR) variable contains a command to prepare the install
  53. #directory if it does not already exist. Likewise $(INSTALL_BIN) contains the
  54. # commandto copy the binary file from its current location (in our case the build
  55. #directory) to the install directory.
  56. define Package/$(PKG_NAME)/install
  57. $(INSTALL_DIR) $(1)/bin
  58. $(INSTALL_BIN) $(PKG_BUILD_DIR)/hiOpenwrt $(1)/bin/
  59. endef
  60. # Thisline executes the necessary commands to compile our program.
  61. # Theabove define directives specify all the information needed, but this
  62. # linecalls BuildPackage which in turn actually uses this information to
  63. # build apackage.
  64. $(eval $(call BuildPackage,$(PKG_NAME)))

生成ipk的命令:
  1. make package/hiOpenWRT/compile V=s
加上V=s的目的是为了详细打印。

生成出来的ipk文件将在bin/ar71xx/packages/下,同时,也可以在build_dir/ build_dir/下找到可执行文件以及源码。
  1. lee@ubuntu:~/OpenWrt-SDK-ar71xx-for-linux-i486-gcc-4.6-linaro_uClibc-0.9.33.2$ tree | head -n 20
  2. .
  3. |-- bin
  4. | |-- ar71xx
  5. | | `-- packages
  6. | | `-- hiOpenWRT_1_ar71xx.ipk
  7. | `-- packages
  8. |-- build_dir
  9. | `-- build_dir
  10. | `-- hiOpenWRT
  11. | |-- hiOpenwrt
  12. | |-- hiOpenwrt.c
  13. | |-- hiOpenwrt.o
  14. | |-- ipkg-ar71xx
  15. | | `-- hiOpenWRT
  16. | | |-- bin
  17. | | | `-- hiOpenwrt
  18. | | `-- CONTROL
  19. | | `-- control
  20. | `-- Makefile
  21. |-- Config.in

一点总结:

    目录结构很重要,如果目录结构不正确,那么Openwrt是不可能正确编译出ipk的。
    在学习编译过程中出现了很多处错误,最让我头疼的是Makefile的格式,这部分很容易错误而编译失败。
Makefile编写规则:
  1. target ... : prerequisites ...
  2. command
  3. ...
  4. ...

target也就是一个目标文件,可以是Object File,也可以是执行文件。还可以是一个标签
(Label),对于标签这种特性,在后续的“伪目标”章节中会有叙述。
prerequisites就是,要生成那个target所需要的文件或是目标。
command也就是make需要执行的命令。(任意的Shell命令)

这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisi
tes中的文件,其生成规则定义在command中。说白一点就是说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。这就是 Makefile的规则。也就是Makefile中最核心的内容。



参考资料
http://www.cnblogs.com/laojie4321/archive/2012/03/27/2420241.html
http://blog.chinaunix.net/uid-27194309-id-3432651.html

阅读(8665) | 评论(0) | 转发(7) |
给主人留下些什么吧!~~