编译官方原版的openwrt并加入第三方软件包

打印 上一主题 下一主题

主题 542|帖子 542|积分 1626

近来又重新编译了最新的官方原版openwrt-2305(2024.3.22),此处记录一下以待日后参考。
目次
1.源码下载
1.1 通过官网直接下载
1.2 映射github加速下载
1.2.1 使用github账号fork源码
1.2.2 创建gitee账号映射github openwrt
2.编译准备
2.1 编译情况依赖准备
2.2 make加速的准备
2.2.1 修改openwrt镜像源
2.2.2 提前下载依赖库到dl
2.2.3 提前安装镜像生成工具
2.2.4 下载feeds依赖
3.make menuconfig设置
3.1 选中目标CPU范例
3.2 选中镜像文件格式
4.make编译
4.1 编译错误办理
4.1.1 you should not run configure as root...
4.1.2 But that file is already provided by package...
5.加入第三方软件包
5.1 了解openwrt编译框架
5.1.1 包的引入
5.1.2 编写软件包的基本信息
5.1.3 定义编译操作
1.基本信息定义
2.编译选项TARGET_CFLAGS
3.编译选项TARGET_LDFLAGS
4.操作设置
Package/$(PKG_NAME)/description
Build/Prepare #自行开发或非直接下载包
Build/Configure
Build/Compile
Package/$(PKG_NAME)/install
5.2 引入第三方开源mstpd
5.2.1 下载软件包整理
5.2.2 编写Makefile
5.2.3 make menuconfig 使能 mstpd
5.2.4 单独编译mstpd
5.3 加入自己编写的软件包
5.3.1 按照openwrt规范路径
5.3.2 编写内部Makefile
5.3.3 编写外部Makefile
5.3.4 make menuconfig 使能tsmsq
5.3.5 单独编译tsmsq
6.编译openwrt镜像源VDI加载到virtualBox



1.源码下载

1.1 通过官网直接下载

[OpenWrt Wiki] Welcome to the OpenWrt Project
https://openwrt.org/从上述官网地址进入,点击左侧 Downloads:点击【More】

点击进入,如下【Browse Source】


以上就是下载官方源码的git 地址,使用git clone即可下载
  1.         git clone https://git.openwrt.org/openwrt/openwrt.git
复制代码
1.2 映射github加速下载

由于官网下载太慢,参考了网上的方法,使用将github映射到gitee 的方式举行下载,速率能达10M/s,不过这只是下载编译框架的速率,编译过程中还会大量下载。
1.2.1 使用github账号fork源码

  1. https://github.com/openwrt
复制代码
首先注册账号,将openwrt项目fork到自己的repository,详细步骤此处不再赘述;
另外,为了在编译下载的时候重要package及其他组件下载能更快,发起同时将openwrt官方的 packages,luci,routing,telephony几个源码全部Fock过来。
1.2.2 创建gitee账号映射github openwrt

  1. https://gitee.com/
复制代码
使用上述地址注册账号,并从github导入仓库

导入后,即可通过git clone,通过【检察仓库】,选择HTTPS/【下载】,即可看到下载地址

假如在获取时出现错误,检察一下是不是仓库的权限是私有的。
2.编译准备

2.1 编译情况依赖准备

在Debian或Ubuntu系统,使用如下下令,准备编译情况依赖。
  1. sudo apt-get update
  2. sudo apt-get install subversion g++ zlib1g-dev build-essential git \
  3. python python3 python3-distutils libncurses5-dev gawk gettext unzip \
  4. file libssl-dev wget libelf-dev ecj fastjar java-propose-classpath
复制代码

2.2 make加速的准备

2.2.1 修改openwrt镜像源

颠末前面的步骤,把openwrt,packages,luci,routing,telephony的源码导入到自己的gitee仓库,现在把openwrt的镜像下载源给改成自己的gitee仓库地址。
修改feeds.conf.default文件,将里面的相关git地址改成gitee仓库地址。
  1. src-git packages https://git.openwrt.org/feed/packages.git
  2. src-git luci https://git.openwrt.org/project/luci.git
  3. src-git routing https://git.openwrt.org/feed/routing.git
  4. src-git telephony https://git.openwrt.org/feed/telephony.git
  5. #src-git video https://github.com/openwrt/video.git
  6. #src-git targets https://github.com/openwrt/targets.git
  7. #src-git oldpackages http://git.openwrt.org/packages.git
  8. #src-link custom /usr/src/openwrt/custom-feed
复制代码
替换上述4个对应地址即可。
2.2.2 提前下载依赖库到dl

在menuconfig时,会选择自己目标的构架和cpu等信息,此时openwrt就会根据选择生成所必要的相对应的依赖库的文件信息,这个文件信息就放在openwrt目次下的tools目次里。tools目次里的每个目次就是所必要的依赖库文件下载信息。
每个目次下都有一个Makefile文件,这个文件里多数就写明了必要的文件名,文件版本,下载地址等信息,PKG_NAME就是文件名称,PKG_VERSION是文件版本,在后面会组合成一个.tar.xz或是tar.bz2的压缩包完备文件名。
我们可以通过在tools目次下grep 来检察软件包名,如下图所示,软件包名为组合后的地址。

着实除了tools依赖库,尚有其他开源软件下载后也在此目次。
大多数依赖库包及第三方开源软件包都可以在如下地址找到
  1. http://sources.cdn.openwrt.org/  --应该是国内镜像源,下载很快
  2. http://sources.openwrt.org/    -- 全,但慢
复制代码
针对openwrt 2305,我整理了依赖的tools库文件下载地址,部分地址无法访问,也从阿里云或其他第三方地址找到了替代。也可以自行从tools目次分析每个Makefile的下载地址及文件名。
可以直接到dl目次执行即可下载
  1. wget https://fedorapeople.org/~acme/dwarves/dwarves-1.26.tar.bz2
  2. wget http://sources.cdn.openwrt.org/patch-2.7.6.tar.gz
  3. wget http://sources.cdn.openwrt.org/xz-5.4.6.tar.bz2
  4. wget http://sources.cdn.openwrt.org/cmake-3.29.0.tar.gz
  5. wget https://libisl.sourceforge.io/isl-0.26.tar.gz
  6. wget http://sources.cdn.openwrt.org/lzop-1.04.tar.gz
  7. wget http://sources.cdn.openwrt.org/m4-1.4.19.tar.gz
  8. wget http://sources.cdn.openwrt.org/mtools-4.0.43.tar.bz2
  9. wget http://sources.cdn.openwrt.org/lz4-1.9.4.tar.gz
  10. wget http://sources.cdn.openwrt.org/mpc-1.3.1.tar.gz
  11. wget http://sources.cdn.openwrt.org/ELFkickers-3.2.tar.gz
  12. wget http://sources.cdn.openwrt.org/dosfstools-4.2.tar.gz
  13. wget http://sources.cdn.openwrt.org/libressl-3.7.3.tar.gz
  14. wget http://sources.cdn.openwrt.org/fakeroot_1.29.orig.tar.gz
  15. wget http://sources.cdn.openwrt.org/quilt-0.67.tar.gz
  16. wget http://sources.cdn.openwrt.org/zip30.tar.gz
  17. wget http://sources.cdn.openwrt.org/elfutils-0.191.tar.bz2
  18. wget https://mirrors.edge.kernel.org/pub/software/devel/sparse/dist/sparse-0.6.4.tar.gz
  19. wget http://sources.cdn.openwrt.org/cpio-2.15.tar.bz2
  20. wget https://mirrors.aliyun.com/gnu/coreutils/coreutils-9.5.tar.gz
  21. wget http://sources.cdn.openwrt.org/ccache-4.9.1.tar.gz
  22. wget http://sources.cdn.openwrt.org/flex-2.6.4.tar.gz
  23. wget http://sources.cdn.openwrt.org/genext2fs-1.5.0.tar.gz
  24. wget http://sources.cdn.openwrt.org/patchelf-0.18.0.tar.bz2
  25. wget http://sources.cdn.openwrt.org/squashfs3.0.tar.gz
  26. wget http://sources.cdn.openwrt.org/gmp-6.3.0.tar.gz
  27. wget http://sources.cdn.openwrt.org/gengetopt-2.23.tar.xz
  28. wget http://sources.cdn.openwrt.org/gnulib-c99c8d491850dc3a6e0b8604a2729d8bc5c0eff1.tar.gz
  29. wget http://sources.cdn.openwrt.org/sed-4.9.tar.gz
  30. wget http://sources.cdn.openwrt.org/automake-1.16.5.tar.gz
  31. wget http://sources.cdn.openwrt.org/lzma-old-4.32.tar.bz2
  32. wget http://sources.cdn.openwrt.org/mtd-utils-2.1.6.tar.bz2
  33. wget http://sources.cdn.openwrt.org/zstd-1.5.6.tar.gz
  34. wget http://sources.cdn.openwrt.org/libtool-2.4.7.tar.gz
  35. wget http://sources.cdn.openwrt.org/tar-1.34.tar.gz
  36. wget http://sources.cdn.openwrt.org/bc-1.07.1.tar.gz
  37. wget http://sources.cdn.openwrt.org/u-boot-2024.01.tar.bz2
  38. wget https://github.com/rui314/mold/archive/refs/tags/v2.30.0.tar.gz
  39. wget http://sources.cdn.openwrt.org/expat-2.6.2.tar.gz
  40. wget http://sources.cdn.openwrt.org/ninja-1.11.1.tar.gz
  41. wget http://sources.cdn.openwrt.org/meson-1.3.2.tar.gz
  42. wget http://sources.cdn.openwrt.org/bison-3.8.2.tar.gz
  43. wget http://sources.cdn.openwrt.org/bash-5.2.21.tar.gz
  44. wget http://sources.cdn.openwrt.org/mklibs_0.1.45.tar.xz
  45. wget http://sources.cdn.openwrt.org/squashfs4-4.6.1.tar.xz
  46. wget http://www.oberhumer.com/opensource/lzo/download/lzo-2.10.tar.gz
  47. wget http://sources.cdn.openwrt.org/lzma-4.65.tar.bz2
  48. wget http://sources.cdn.openwrt.org/elftosb-10.12.01.tar.gz
  49. wget http://sources.cdn.openwrt.org/util-linux-2.39.3.tar.gz
  50. wget http://sources.cdn.openwrt.org/zlib-1.3.1.tar.gz
  51. wget http://sources.cdn.openwrt.org/mpfr-4.2.1.tar.gz
  52. wget http://sources.cdn.openwrt.org/libdeflate-1.20.tar.gz
  53. wget http://sources.cdn.openwrt.org/autoconf-archive-2023.02.20.tar.xz
  54. wget http://sources.cdn.openwrt.org/bzip2-1.0.8.tar.gz
  55. wget http://sources.cdn.openwrt.org/autoconf-2.71.tar.gz
  56. wget http://sources.cdn.openwrt.org/findutils-4.9.0.tar.xz
  57. wget http://sources.cdn.openwrt.org/e2fsprogs-1.47.0.tar.gz
  58. wget http://sources.cdn.openwrt.org/pkgconf-2.1.1.tar.gz
  59. wget http://sources.cdn.openwrt.org/imx-uuc-2018-11-18-c6536ac5.tar.xz
  60. wget http://sources.cdn.openwrt.org/cbootimage-1.8.tar.xz
  61. wget https://github.com/llvm/llvm-project/releases/download/llvmorg-15.0.7/llvm-project-15.0.7.src.tar.xz
  62. wget http://sources.cdn.openwrt.org/kernel2minor-0.25.tar.xz
  63. wget http://sources.cdn.openwrt.org/make-ext4fs-2020-01-05-5c201be7.tar.xz
  64. wget http://sources.cdn.openwrt.org/7z2301-src.tar.xz
复制代码
通过提前下载依赖包,能减少在编译时一些默认地址下载的时间,默认地址下载有的不可用,有的为官方地址,下载很慢。
2.2.3 提前安装镜像生成工具

打包的时候,会用到qemu-img,如不提前安装,编译到最后会报如下错误,并制止。
  1. WARNING: Install qemu-img to create VDI/VMDK images
复制代码
下载安装
  1. apt search qemu-img   --- 查找文件名
  2. apt install qemu-utils   -- 得到文件名,install
复制代码
2.2.4 下载feeds依赖

  1. ./scripts/feeds update -a
  2. ./scripts/feeds install -a
复制代码
假如报错,办理报错,举比方下,此为编译构建情况错误
  1. Build dependency: Please install the Python3 distutils module
复制代码
使用如下安装,其余类似
  1. apt-get install python3-distutils
复制代码
  1. apt-get install rsync
复制代码
办理报错后,重复指向 update 和install,直至无报错。
3.make menuconfig设置

编译准备工作完成后,接下来就可以设置举行编译了。
只需简单的几步,就可以开始编译。
此处,我们使用x86虚拟机举行测试,因此,编译目标系统选择x86 64
3.1 选中目标CPU范例


3.2 选中镜像文件格式

目标镜像文件输出,我们选VDI,方便在virtualBox虚拟机创建。


此外,如无需http服务,那么Luci选项可以使用默认,无需勾选。如需勾选,可以在menuconfig界面输入"/"来举行uhttp依赖关系查找。
4.make编译

为了加速编译速率,我们使用-j参数指定线程数。如:
  1. make -j8
复制代码
  即便我们提前准备了软件包,依赖库,真正编译的时候,还是会下载很多东西,等待很长时间,完备编译竣事,整个openwrt大小凌驾12GB
  
4.1 编译错误办理

4.1.1 you should not run configure as root...

  1. “you should not run configure as root (set FORCE_UNSAFE_CONFIGURE=1 in environment)
复制代码
在编译buildroot的时候出现了此错误,表现不能使用root权限编译
根据提示,在网上查,说是export set FORCE_UNSAFE_CONFIGURE=1可以或许办理问题
但我在终端上输入还是报错,后来才知道是要添加到/etc/profile文件中设置全局才有效
执行:
  1. echo "export set FORCE_UNSAFE_CONFIGURE=1"  >> /etc/profile
  2. source /etc/profile
复制代码
最好重启终端
假如还是不行,看看是否存在~/profile文件,假如存在,在~/profile中也添加相应内容
4.1.2 But that file is already provided by package...

  1. Configuring urngd.
  2. Configuring ppp-mod-pppoe.
  3. Collected errors:
  4. * check_data_file_clashes: Package libustream-openssl20201210 wants to install file /home/openwrt/build_dir/target-i386_pentium4_musl/root-x86/lib/libustream-ssl.so
  5.         But that file is already provided by package  * libustream-wolfssl20201210
  6. * opkg_install_cmd: Cannot install package libustream-openssl20201210.
  7. * check_data_file_clashes: Package libustream-openssl20201210 wants to install file /home/openwrt/build_dir/target-i386_pentium4_musl/root-x86/lib/libustream-ssl.so
复制代码
以上报错,是表现libustream-openssl 与libustream-wolfss辩论
检察.config 发现两个都开启了,通过make menuconfig  将libustream-wolfssl 去除选中即可。
留意,去除libustream-wolfss 时必要将依赖的其他包去除,假如想知道被哪些包依赖,通过help 检察,被luci-ssl依赖。
5.加入第三方软件包

openwrt 是一个编译工具,帮助自定义编译内核和应用(是否可以这么明确明确)。所以假如有定制自己必要的内核,并基于这个定制化内核编译一些应用的话,可以使用openwrt,openwrt 还是很成熟,很方便的。
openwrt是一个比较完满的嵌入式Linux开发平台,在无线路由器应用上已有100多个软件包。人们可以在其基础上增加软件包,以扩大其应用范围。OpenWrt在增加软件方面使用极其方便,按照OpenWrt的约定就可以很简单完成。
加入的软件包可以是网上可下载的开源软件或自行开发的软件。为加入软件包必要在package目次下创建一个目次,以包罗软件包的各种信息和与OpenWrt建立接洽的文件。然后创建一个Makefile与OpenWrt建立接洽,Makefile必要遵照OpenWrt的约定。另外可以创建一个patchs目次保存patch文件,对下载的源代码举行适量修改。
5.1 了解openwrt编译框架

在加入第三方开源软件包之前,我们先了解openwrt的编译框架。这里不做编译框架介绍,现实也不必要了解过深,除非必要调整框架内容。因此我们只需了解如何使得openwrt可以或许辨认我们加入的软件包并调提供的Makefile编译出我们所需的软件即可。
   必要编译第三方的软件(驱动、库等),只必要按照openwrt 的规则,安排好源码的路径结构,轻微改下 makefile 等文件,使openwrt 可以或许辨认你的软件,就可以了,着实还是很简单的。
          一样平常是这样:
                  在package/libs(对于库)、package/kernel/(对于驱动)、package/utils(应用软件) 路径下,创建一个文件夹,里面放你的代码,结构如下:
                  Makefile 和 src/ 
                  Makefile 我在后面会根据软件范例不同贴出来。
                  src里面就放你的源码。
                  src 有些会自带Makefile ,不要紧,不必要对它举行修改。比如src/Makefile 里面指定了编译器:CC=gcc,没事啊,表面的Makefile 也会指定openwrt 的编译器,并覆盖内层Makefile 中的设置。
          这些填好后,去make menuconfig 里面勾选上这个软件,就可以开始编译了
  
5.1.1 包的引入

OpenWrt软件包规则中使用三个makefile的子文件,分别为:
  1. include $(TOPDIR)/rules.mk      #一般在Makefile的开头
  2. include $(INCLUDE_DIR)/kernel.mk    # 对于软件包为内核时不可缺少
  3. include $(INCLUDE_DIR)/package.mk  # 一般软件包
复制代码
软件包加入OpenWrt的方式就由这些makefile所决定,一样平常软件包使用package.mk
5.1.2 编写软件包的基本信息

以下为软件包定义的一些关键字,软件包可以自己下载整理目次结构后加入openwrt,也可以在Makefile中定义软件包的下载方式和,但下载时一样平常必要查对MD5,必要提前盘算MD5填入。发起自己下载整理路径后加入。
  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。获取方式可以为:git、svn、cvs、hg、bzr等。下载规则定义在:$(INCLUDE_DIR)/download.mk和$(SCRIPT_DIR)/download.pl中
  6. PKG_MD5SUM     表示源代码文件的效验码。用于核对软件包是否正确下载。
  7. PKG_CAT     表示源代码文件的解压方法。包括zcat, bzcat, unzip等。
  8. PKG_BUILD_DIR     表示软件包编译目录。它的父目录为$(BUILD_DIR)。如果不指定,默认为$(BUILD_DIR)/$( PKG_NAME)$( PKG_VERSION)。
  9. PKG_INSTALL     Setting it to ‘1’ will call the package’s original  ‘make install’  with prefix set to ‘PKG_INSTALL_DIR’
  10. PKG_INSTALL_DIR    Where ‘make install’ copies the compiled files
  11. PKG_FIXUP    关于autotools的选项。软件源码中的makefile使用makefile工具自动生成
复制代码
5.1.3 定义编译操作

用户程序和内核模块的定义不一样。用户态软件包使用Package,内核模块使用KernelPackage。
这里只阐明用户模块程序定义。
用户程序的编译包以Package/开头,然后接着软件名,在Package定义中的软件名可以与软件包名不一样,而且可以多个定义。
以下介绍重要的定义:
1.基本信息定义

  1. Package/$(PKG_NAME)
  2. SECTION    表示包的类型,预留。
  3. CATEGORY    表示分类,在menuconfig的菜单下将可以找到。
  4. TITLE    用于软件包的简短描述
  5. DESCRIPTION    用于软件包的详细描述,已放弃使用。如果使用DESCRIPTION将会提示“error DESCRIPTION:= is obsolete, use Package/PKG_NAME/description”。
  6. URL    表示软件包的下载网址。
  7. MAINTAINER    表示维护者,选项。
  8. DEPENDS    表示与其他库文件的依赖。即如编译或安装需要其他软件时需要说明。如果存在多个依赖,则每个依赖需用空格分开。依赖前使用+号表示默认显示,即对象没有选中时也会显示,使用@则默认为不显示,即当依赖对象选中后才显示。
复制代码
2.编译选项TARGET_CFLAGS

GCC编译选项CFLAGS参数,CFLAGS与LDFLAGS的阐明,他们都是是隐含规则的变量,且是一种下令参数变量。

假如在编译时,必要包罗特定路径头文件,如:程序包内当前目次include ,可以使用-I./include , 将该目次加入 include路径。
3.编译选项TARGET_LDFLAGS


该选项一样平常较多使用-I来链接动态库或静态库。
如层序中必要链接libpthread和libc.so,则可使用  LDFLAGS += -pthread -lc
   该选项共同基本信息定义中的 DEPENDS 来使用,比方
  TARGET_LDFLAGS += -pthread -lc
  ...
  DEPENDS:=+libpthread +libc
  
4.操作设置



  • Package/$(PKG_NAME)/description
软件包的详细形貌,代替前面提到的DESCRIPTION详细形貌。



  • Build/Prepare #自行开发或非直接下载包
编译准备方法,对于网上下载的软件包不必要再形貌。对于非网上下载或自行开发的软件包必须阐明编译准备方法。一样平常的准备方法为:留意:PKG_BUILD_DIR为openwrt/build_dir/<软件包路径名>/ ,默认情况下,此处的<软件包路径名>为$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
也可以在Makefile中重新定义,如PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
(按OpenWrt的习惯,一样平常把自己计划的程序全部放在src目次下)

  1. define Build/Prepare
  2.     mkdir -p $(PKG_BUILD_DIR)
  3.     $(CP) ./src/* $(PKG_BUILD_DIR)/
  4. endef
复制代码


  • Build/Configure
在Automake中必要举行./configure,所以本设置方法重要针对必要设置的软件包而计划,一样平常自行开发的软件包可以不在这里阐明。必要使用本定义的情况,可参考dropbear。



  • Build/Compile
编译方法,没有特别阐明的可以不予以定义。假如不定义将使用默认的编译方法Build/Compile/Default

自行开发的软件包可以考虑使用下面的定义,也可以不定义。
  1. define Build/Compile
  2.     $(MAKE) -C $(PKG_BUILD_DIR) \
  3.     $(TARGET_CONFIGURE_OPTS) CFLAGS="$(TARGET_CFLAGS) -I$(LINUX_DIR)/include"
  4. endef
复制代码


  • Package/$(PKG_NAME)/install
软件包的安装方法,包括一系列拷贝编译好的文件到指定位置。调用时会带一个参数,就是嵌入系统的镜像文件系统目次,因此$(1)表现嵌入系统的镜像目次。一样平常可以采用下面的方法:
  1. define Package/$(PKG_NAME)/install
  2.     $(INSTALL_DIR) $(1)/usr/bin
  3.     $(INSTALL_BIN) $(PKG_BUILD_DIR)/ $(PKG_NAME) $(1)/usr/bin/
  4. Endef
复制代码
      INSTALL_DIR、INSTALL_BIN在 $(TOPDIR)/rules.mk 文件定义,所以本Makefile必须导入 $(TOPDIR)/rules.mk 文件。
    INSTALL_DIR :=install -d -m0755 意思创建所属用户可读写即执行,其他用户可读可执行的目次。
    INSTALL_BIN:=install -m0755意思编译好的文件到镜像文件目次。
    类似的PKG_BUILD_DIR、PKG_INSTALL_DIR 等都在 $(TOPDIR)/rules.mk 、 $(INCLUDE_DIR)/package.mk中可以找到定义.
  
自启动安装定义
假如用户态软件在boot时要自动运行,则必要在安装方法阐明中增加自动运行的脚本文件安装和设置文件安装方法。自启动路径在/etc/init.d。详细编写规则,可参考netifd特性。
举比方下。
  1. define Package/mstpd/install
  2.         $(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/init.d $(1)/sbin/
  3.         $(INSTALL_BIN) ./files/mstpd.init $(1)/etc/init.d/mstpd
  4.         $(INSTALL_BIN) $(PKG_BUILD_DIR)/mstpd $(1)/usr/sbin/
  5.         $(INSTALL_BIN) $(PKG_BUILD_DIR)/mstpctl $(1)/usr/sbin/
  6.         $(INSTALL_BIN) $(PKG_BUILD_DIR)/bridge-stp $(1)/sbin/
  7. endef
复制代码
非程序自己的安装文件发起放在files子目次下,不要与源代码文件目次src混在一起,以提高可读性,使用清晰的文件扩展名,更方便安装辨认文件。
5.2 引入第三方开源mstpd


这里以mstpd为例
Mstp为开源的生成树实现,openwrt默认并没有自带,因此,必要从第三方下载软件包并编译。
5.2.1 下载软件包整理

  1. http://sources.cdn.openwrt.org/
复制代码
从上述地址下载 mstpd-0.1.0.tar.gz 解压,此处我解压并重定名为mstpd.将解压的文件举行重新整理:目标是为了后续在openwrt 的menuconfig中辨认。
如下图,创建src目次,将解压的所有文件全部移动到src内(Makefile后续编写,files为自启动文件,如无需可以不管。)

将整理好的mstpd目次放入openwrt\package\utils\下

5.2.2 编写Makefile

在编写Makefile之前,先检察mstpd原有的Makefile。这里发现,没有Makefile,但有Makefile.am,这个像是Makefile但为什么带后缀am呢?automake。
   automake 读取 Makefile.am 来产生 Makefile.in,
configure 读取 Makefile.in 来产生 Makefile
configure 脚本通常由 autoconf 读取 configure.in 产生
尚有aclocal....
目标就是让程序员只写一个规则:.am文件/或.in文件,
就能生成得当各种设置/平台的Makfiles。
  在【编写软件包的基本信息】中,我们了解了automake定义选项 PKG_FIXUP
因此,此处假如不想自己编写依赖关系Makefile包,就必要使用该选项,重新举行Makefile的生成。以下贴出mstpd的Makefile。
  1. include $(TOPDIR)/rules.mkPKG_NAME:=mstpdPKG_VERSION:=0.1.0PKG_RELEASE:=1#PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz #PKG_SOURCE_URL:=http://sources.cdn.openwrt.org/#PKG_MD5SUM:=PKG_INSTALL:=1PKG_BUILD_PARALLEL:=1PKG_FIXUP:=autoreconf#PKG_LICENSE:include $(INCLUDE_DIR)/package.mkdefine Package/mstpd#SECTION 软件包范例  SECTION:=utils#CATEGORY menuconfig中软件包所属的一级目次,如Network  CATEGORY:=Utilities#SUBMENU - menuconfig中软件包所属的二级目次,如dial-in/up#SUBMENU:=  TITLE:=mstpd  DEPENDS:=+libpthread endefdefine Package/mstpd/description  mstpd is added by meendefTARGET_CFLAGS +=#定义make prepare 动作define Build/Prepare        mkdir -p $(PKG_BUILD_DIR)        $(CP) ./src/* $(PKG_BUILD_DIR)#$(CP) ./files/* $(PKG_BUILD_DIR)endef#define Build/InstallDev#        $(INSTALL_DIR) $(1)/usr#        $(CP) $(PKG_INSTALL_DIR)/usr/local/* $(1)/usr/#endefdefine Package/mstpd/install
  2.         $(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/init.d $(1)/sbin/
  3.         $(INSTALL_BIN) ./files/mstpd.init $(1)/etc/init.d/mstpd
  4.         $(INSTALL_BIN) $(PKG_BUILD_DIR)/mstpd $(1)/usr/sbin/
  5.         $(INSTALL_BIN) $(PKG_BUILD_DIR)/mstpctl $(1)/usr/sbin/
  6.         $(INSTALL_BIN) $(PKG_BUILD_DIR)/bridge-stp $(1)/sbin/
  7. endef$(eval $(call BuildPackage,mstpd))
复制代码
5.2.3 make menuconfig 使能 mstpd

假如目次结构及Makefile定义精确,我们应该能在make menuconfig 中找到mstpd,根据路径使能即可。

我们只必要进入Utilities选中打开即可。
5.2.4 单独编译mstpd

   make package/utils/mstpd/compile V=s
  等待编译通过。如提示
   *** No targets specified and no makefile found.  Stop.
  大概是你的目次结构不对,或者Makefile未指定autoreconf参数。
5.3 加入自己编写的软件包

5.3.1 按照openwrt规范路径

此demo(tsmsq)的功能是server端与client端各启一个线程,子线程分别使用消息队列在server与client端举行通信,server端发,client端收。大抵结构如下。
软件代码包请到我的资源下载tsmsq
   find package/utils/tsmsq/ -type d
  package/utils/tsmsq/
  package/utils/tsmsq/src
  package/utils/tsmsq/src/include -- 公共头文件
  package/utils/tsmsq/src/server -- server端源码
  package/utils/tsmsq/src/utils -- 公用接口如消息队列,文件操作,字符串操作,时间函数等
  package/utils/tsmsq/src/utils/lib -- 用于生成共享库(动态库)
  package/utils/tsmsq/src/client -- server 端源码
  5.3.2 编写内部Makefile

外部Makefile着实是一套框架,该框架调用了build_dir/tsmsq下的Makefile生成目标文件,并对目标文件举行打包。因此我们重要工作在内部Makefile实现。Makefile对于我来说,仅停留在能简单阅读修改的程度,对于多目次,多文件,动态库的Makefile,编写起来还是有些费劲(着实是我太菜)。好在之前学习过一套简单的CMake,Cmake可以根据不同平台生成对应的Makefile,而且语法相对较简单,因此,我们可以借助Cmake帮我们生成Makefile。我们只需编写CMakeList.txt就可以生成高质量的Makefile。
按照上述目次结构,我们的外层CmakeList.txt如下:
为了能看明确一点,此中有很多注释,关注未注释部分即可。关于cmake的一些语法及关键字,请自行bing。
  1. cmake_minimum_required(VERSION 2.6)
  2. PROJECT(tsmsq)
  3. SET(CLIEN_NAME tsmsqcl)
  4. SET(SERVER_NAME tsmsqsv)
  5. SET(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
  6. #ADD_DEFINITIONS(-l/usr/local/lib/)
  7. #引用头文件,对于集中的头文件,CMake提供了一个很方便的函数include_directories ( dir ) 作用是 自动去dir目录下寻找头文件,相当于 gcc中的 gcc -I dir
  8. INCLUDE_DIRECTORIES(/usr/local/include /usr/local/lib ./include)
  9. # 添加一个子目录
  10. #add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL] [SYSTEM])
  11. #添加同级及其子目录,可省略binary_dir参数
  12. #添加父级及其子目录,必须指定用于存储输出文件的binary_dir参数。否则报如下错误
  13. #add_subdirectory not given a binary directory but the given source directory "xxx" is not a subdirectory of "xxx".  
  14. #When specifying an out-of-tree source a binary directory must be explicitly specified.
  15. # add_subdirectory (source_dir [binary_dir] [EXCLUDE_FROM_ALL]) 添加子目录并构建该子目录
  16. #        source_dir
  17. #必选参数。该参数指定一个子目录,子目录下应该包含CMakeLists.txt文件和代码文件。子目录可以是相对路径也可以是绝对路径,如果是相对路径,则是相对当前目录的一个相对路径。
  18. #        binary_dir
  19. #可选参数。该参数指定一个目录,用于存放输出文件。可以是相对路径也可以是绝对路径,如果是相对路径,则是相对当前输出目录的一个相对路径。如果该参数没有指定,则默认的输出目录使用source_dir。
  20. #        EXCLUDE_FROM_ALL
  21. #可选参数。当指定了该参数,则子目录下的目标不会被父目录下的目标文件包含进去,父目录的CMakeLists.txt不会构建子目录的目标文件,必须在子目录下显式去构建。例外情况:当父目录的目标依赖于子目录的目标,则子目录的目标仍然会被构建出来以满足依赖关系(例如使用了target_link_libraries)。
  22. add_subdirectory(./utils ./utils/lib)
  23. #支持gdb
  24. set(CMAKE_BUILD_TYPE "Debug")
  25. set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")
  26. set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
  27. #aux_source_directory(dir var) 作用是把dir目录中的所有源文件都储存在var变量中,然后需要用到源文件的地方用 变量var来取代
  28. AUX_SOURCE_DIRECTORY(./ SRC_MAIN)
  29. AUX_SOURCE_DIRECTORY(./client SRC_CL)
  30. AUX_SOURCE_DIRECTORY(./server SRC_SR)
  31. AUX_SOURCE_DIRECTORY(./utils SRC_UTILS)
  32. # add_library(test_utils STATIC/SHARED ${SRC_UTILS})添加lib哭,动态库或者静态库, 不指定第二个参数默认为静态库
  33. #SET(LIBRARY_OUTPUT_PATH ${EXECUTABLE_OUTPUT_PATH})  #LIBRARY_OUTPUT_PATH 是cmake系统变量,项目生成的库文件都放在这个目录下
  34. #add_library(test_utils SHARED ${SRC_UTILS})  # 也可以通过  add_subdirectory(.//utils .//utils/lib)  构建子目录来生成lib
  35. # 第一个参数,存储查找到的库文件,第二个参数:要查找的库文件,第三个参数:查找路径
  36. #find_library(UTIL_LIB test_utils ./utils/lib)  #这里是动态库
  37. #指定了项目名后,后面可能会有多个地方用到这个项目名,如果更改了这个名字,就要改多个地方,比较麻烦,可以使用 PROJECT_NAME 来表示项目名。
  38. ADD_EXECUTABLE(${SERVER_NAME} ${SRC_MAIN} ${SRC_SR})
  39. TARGET_LINK_LIBRARIES(${SERVER_NAME} pthread test_utils)
  40. ADD_EXECUTABLE(${CLIEN_NAME} ${SRC_MAIN} ${SRC_CL})
  41. TARGET_LINK_LIBRARIES(${CLIEN_NAME} pthread test_utils)
  42. #add_library(lib_name STATIC/SHARED src)
  43. # 函数作用:生成库。
  44. # 参数lib_name:是要生成的库名称,
  45. # 参数STATIC/SHARED:指定生成静态库或动态库,
  46. # 参数src:指明库的生成所需要的源文件
  47. #install(TARGETS mylibrary DESTINATION lib)   TARGETS 参数指定了要安装的目标(通常是一个已经通过 add_library() 或 add_executable() 定义的目标),DESTINATION 参数指定了目标的安装位置
  48. #安装一个目标库到指定的目录 install(TARGETS mylibrary DESTINATION lib)
  49. #安装目录及其子目录 install(DIRECTORY ${CMAKE_SOURCE_DIR}/mydir DESTINATION share/mydir)
  50. #文件匹配与过滤 install(DIRECTORY ${CMAKE_SOURCE_DIR}/mydir DESTINATION share/mydir FILES_MATCHING PATTERN "*.h" PATTERN "*.hpp")
  51. install(TARGETS ${SERVER_NAME} DESTINATION bin)
  52. install(TARGETS ${CLIEN_NAME} DESTINATION bin)
  53. install(TARGETS test_utils DESTINATION lib)
复制代码
由于本例子还生成了动态库,因此,这里也是一个cmake学习的精良例子,通过上述外层的CmakeList.txt,指定了内部lib的路径,内部lib依赖的源文件在utils目次下,因此,可以在该路径定义一个内部的CmakeList.txt,指定lib依赖的文件,生成的方式与路径。完备内容如下:
  1. set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../)
  2. # 查找当前目录下的所有源文件
  3. # 并将名称保存到 DIR_LIB_SRCS 变量
  4. aux_source_directory(. DIR_LIB_SRCS)
  5. # 生成链接库  静态库
  6. #add_library (count ${DIR_LIB_SRCS})
  7. add_library (test_utils SHARED ${DIR_LIB_SRCS})
复制代码
5.3.3 编写外部Makefile

外部的Makefile按照基本框架填充即可。
由于该例子使用了pthread,因此依赖pthread库,尚有libc库。以下Makefile中通过LDFLAGS指定了链接库文件。
另外,由于我们使用的是cmake,因此,为了是openwrt能精确帮助我们生成Makefile,我们在定义基本信息的时候,包罗进cmake.mk。
   include $(INCLUDE_DIR)/cmake.mk
  完备例子如下。
  1. include $(TOPDIR)/rules.mk
  2. PKG_NAME:=tsmsq
  3. PKG_VERSION:=1.0
  4. PKG_RELEASE:=1
  5. #PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
  6. #PKG_SOURCE_URL:=http://sources.cdn.openwrt.org/
  7. #PKG_MD5SUM:=
  8. PKG_INSTALL:=1
  9. PKG_BUILD_PARALLEL:=1
  10. #PKG_FIXUP:=autoreconf
  11. #PKG_LICENSE:
  12. #TARGET_CFLAGS +=
  13. TARGET_LDFLAGS += -pthread -lc
  14. include $(INCLUDE_DIR)/package.mk
  15. include $(INCLUDE_DIR)/cmake.mk
  16. define Package/tsmsq
  17. #SECTION 软件包类型
  18.   SECTION:=utils
  19. #CATEGORY menuconfig中软件包所属的一级目录,如Network
  20.   CATEGORY:=Utilities
  21. #SUBMENU - menuconfig中软件包所属的二级目录,如dial-in/up
  22. #SUBMENU:=
  23.   TITLE:=tsmsq
  24.   DEPENDS:=+libpthread +libc
  25. endef
  26. define Package/tsmsq/description
  27.   tsmsq is added by me
  28. endef
  29. #定义make prepare 动作
  30. define Build/Prepare
  31.         mkdir -p $(PKG_BUILD_DIR)
  32.         $(CP) ./src/* $(PKG_BUILD_DIR)/
  33. #cmake $(PKG_BUILD_DIR)/ -B $(PKG_BUILD_DIR)/
  34. #$(CP) ./files/* $(PKG_BUILD_DIR)
  35. endef
  36. #define Build/InstallDev
  37. #        $(INSTALL_DIR) $(1)/usr
  38. #        $(CP) $(PKG_INSTALL_DIR)/usr/local/* $(1)/usr/
  39. #endef
  40. define Package/tsmsq/install
  41.         $(INSTALL_DIR) $(1)/usr/sbin $(1)/usr/lib
  42.         $(INSTALL_BIN) $(PKG_BUILD_DIR)/tsmsqcl $(1)/usr/sbin/
  43.         $(INSTALL_BIN) $(PKG_BUILD_DIR)/tsmsqsv $(1)/usr/sbin/
  44.         $(INSTALL_BIN) $(PKG_BUILD_DIR)/libtest_utils.so $(1)/usr/lib/
  45. endef
  46. $(eval $(call BuildPackage,tsmsq))
复制代码
5.3.4 make menuconfig 使能tsmsq

在make menuconfig 界面,按下“/” 可输入内容查找tsmsq,如能找到,阐明我们的目次及Makefile定义没有问题。选中打开即可。
5.3.5 单独编译tsmsq

   make package/utils/tsmsq/compile V=s
  假如编译通过,应该会生成目标文件:

至此,我们基本完成了openwrt的整体编译过程。
6.编译openwrt镜像源VDI加载到virtualBox

此处编译的是x86,VDI镜像文件,用于virtualBox加载,目标文件路\openwrt\bin\targets\x86\generic

假如没有virtualBox,先安装virtualBox Oracle VM VirtualBox
以下简单介绍如何在virtualBox虚拟机加载openwrt。
如下,点击【新建】输入名称,选中范例linux。

虚拟硬盘选中使用已有,选择openwrt vdi镜像源。

加载完成后,我们对openwrt_2305举行一些设置。
设置串口,主机管道,可以通过串口访问openwrt系统(默认的窗口终端欠好使用)。

串口路径地址格式
   \\.\pipe\openwrt_2305
  至此,我们完成了openwrt编译,并加入第三方软件包的全部过程,在Makefile中定义的安装目次下,可以找到我们添加的mstpd与tsmsq相关的 可执行文件及lib动态库。

在编译openwrt的过程中,很多东西着实是不求甚解的,明确肯定存在不敷与未验证之处。但好在openwrt的框架非常完满,让我们在定制化开发过程中可以或许通过简单的几步就能构建自己的linux定制系统。
同时也参考了很多优秀的博文,列出如下:
openwrt 编译外部源码 过程与问题办理_openwrt 编译第三方库-CSDN博客
OpenWrt开发 之扩展软件包_openwrt pkg_fixup-CSDN博客



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

兜兜零元

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表