tools、toolchain、include、scripts、target、package、目录为解压OpenWrt后系统自带的目录。
bin、build_dir、staging_dir、dl、feeds 目录为执行相关命令后自动从网络下载目录和编译目录。
一、feeds
扩展软件包目录。html
# 执行该命令后自动建立feeds目录,并下载相关文件至此目录下。 $ ./scripts/feeds update -a
二、dl
编译前将原始的软件代码包经过网络下载到该目录。ios
# 编译时下载各软件包保存至dl目录下 $ make
三、package
待构建的软件包源码或patch文件。建立自定义软件包时应保存至该目录下。标准软件包目录结构:c++
目录名称 | 是否可选 | 说明 |
---|---|---|
Makefile | 必选 | OpenWrt 构建文件 |
src | 必选 | Makefile 或 CMakefile 工程目录 |
files | 可选 | 配置文件和初始化文件 |
patches | 可选 | 补丁文件 |
四、build_dir
自定义软件包会拷贝至该目录的 target-mipsel_mips32_musl 目录下,不一样构建架构目录名称不一样。git
# package 目录下的src软件包会拷贝至此路径下,并执行编译安装操做。 $ build_dir/target-mipsel_mips32_musl/你软件包的src目录内容
五、staging_dir
软件包编译后的安装目录,包含开发板的根目录路径。github
# 开发板根目录路径 $ staging_dir/target-mipsel_mips32_musl/root-brcm47xx/
六、bin
编译完成后生成的安装镜像文件及ipk安装包。网络
七、config
包含全局编译设置、开发人员编译设置、目标文件格式设置和内核编译设置等4部分。多线程
八、include
包含准备环境脚本、下载补丁脚本、编译 Makefile 以及编译指令等。架构
九、scripts
包含准备环境脚本、下载补丁脚本、编译 Makefile 以及编译指令等。app
十、target
指的是嵌入式平台,包括特定嵌入式平台的内容。ide
十一、toolchain
编译器和C库等,例如包含编译工具 gcc 和 glibc 库。
十二、tools
通用命令,用来生成固定的辅助工具,如打补丁工具 patch、编译工具 make 及 squashfs 等。
# 假设自定义工程名为 Hello ######################################### # Hello # - Makefile // OpenWrt 构建文件 # + src // Hello 工程 # - Makefile // Hello 工程构建文件 # - hello.c # # openwrt 根目录 ~/openwrt ######################################### # 工程源码存放路径(手动) ~/openwrt/package/Hello # 工程源码构建路径(自动) ~/openwrt/build_dir/target-mipsel_mips32_musl/Hello # 工程目标安装路径(自动,移植后开发板的根目录) ~/openwrt/staging_dir/target-mipsel_mips32_musl/root-brcm47xx
说明
- openwrt 为 OpenWrt SDK 根目录
- 下文的 * 表示软件包目录名称
软件包变量
变量名 | 是否可选 | 含义 |
---|---|---|
PKG_NAME | 必填 | The name of the package, as seen via menuconfig and ipkg. |
PKG_RELEASE | 必填 | The version of this package Makefile |
PKG_VERSION | 可选 | The upstream version number that we're downloading. |
PKG_BUILD_DIR | 可选 | Where to compile the original sources |
PKG_SOURCE | 可选 | The filename of the original sources |
PKG_SOURCE_URL | 可选 | Where to download the sources from |
PKG_MD5SUM | 可选 | A Checksum to validate the downlaod |
PKG_CAT | 可选 | How to decompress the sources(zcat, bzcat, unzip) |
PKG_BUILD_DEPENDS | 可选 | Packages the need to build before this package, but are not required at runtime. |
Package/* 软件包描述
名称 | 是否可选 | 描述 |
---|---|---|
SECTION | 目前未使用 | 软件包类型(可自定义填写) |
CATEGORY | 必填 | 软件包在 menuconfig 中的类别 |
DESCRIPTION | 已废弃 | 软件包的完整描述 |
URL | 可选 | 从哪里下载原始软件包 |
MAINTAINER | 可选 | 维护者信息,便于联系维护者。 |
DEPENDS | 可选 | 指定编译该软件包以前必须构建或安装的软件包 |
conffiles | 可选 | 该软件包安装的配置文件列表,每一个文件一行。 |
Build/* 软件包构建指令
名称 | 是否可选 | 描述 |
---|---|---|
Build/Prepare | 可选 | 针对源文件进行解压缩或打补丁的一系列命令,能够不定义。 |
Build/Configure | 可选 | 针对配置文件的一些列命令,能够不定义。 |
Build/Compile | 可选 | 指定如何编译源文件,绝大部分状况下无需定义。 |
Package/package-name/config | 可选 | 可执行PACKAGE或CONFIG相关节点操做 |
Package/package-name/install | 必填 | 拷贝源码编译的文件至ipkg |
Package/package-name/preinst | 可选 | 执行Package/install前的脚本,切记包含 #!/bin/sh, return false 退出安装。 |
Package/package-name/postinst | 可选 | 执行Package/install后的脚本,切记包含 #!/bin/sh。 |
Package/package-name/prerm | 可选 | 删除文件前执行的操做,规则相似Package/preinst |
Package/package-name/postrm | 可选 | 删除文件后执行的操做,规则相似Package/postrm |
OpenWrt 系统变量
变量名 | 变量定义 | 变量含义 | 变量值 |
---|---|---|---|
$(TOPDIR) | ${CURDIR} | OpenWrt 根目录 | /openwrt |
$(DL_DIR) | $(TOPDIR)/dl | 经过网络下载的标准软件包 | /openwrt/dl |
${OUTPUT_DIR} | $(TOPDIR)/bin | 最终编译出的ipk软件包 | /openwrt/bin |
${INCLUDE_DIR} | $(TOPDIR)/include | 包含文件 | /openwrt/include |
$(SCRIPT_DIR) | $(TOPDIR)/scripts | 脚本文件 | /openwrt/scripts |
$(BUILD_DIR_BASE) | ??? | $(TOPDIR)/build_dir | /openwrt/build_dir |
$(PACKAGE_DIR) | $(BIN_DIR)/packages |
全部指令位于 rules.mk 文件
指令名称 | 指令定义 | 说明 |
---|---|---|
INSTALL_DIR | install -d -m0755 | 建立安装目录 |
INSTALL_BIN | install -m0755 | 安装可执行文件 |
INSTALL_SUID | install -m4755 | - |
INSTALL_DATA | install -m0644 | 安装数据文件 |
INSTALL_CONF | install -m0600 | 安装配置文件 |
全部软件包编译
$ make menuconfig $ ... 勾选相关软件包保存后退出 $ make
单个软件包编译
# 编译并安装软件包 $ make package/${packageName}/compile
编译选项
# 编译全部软件包,不输出详细信息,单线程编译 $ make # 单线程编译(不带j默认为单线程) $ make -j=1 # 多线程编译(指定数目) $ make -j=2 # 多线程编译(根据硬件自动) $ make -j # 输出详细信息(默认不输出详细信息) $ make V=s # 组合使用示例 $ make V=s -j=2 # 说明: # 1. 多线程编译速度快,但产生编译错误时不便于定位故障缘由。 # 2. 想快速编译可采用以下形式:make -j,不输出信息且根据CPU内核数自动多线程编译。 # 3. 想查看编译错误可采用以下形式:make V=s 或 make V=s -j1。 # 4. 若是是初次添加自定义软件包,必须先经过 make menuconfig 而后 make 的方式构建。
sprite/Makefile
include $(TOPDIR)/rules.mk PKG_NAME:=sprite PKG_RELEASE:=1 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) include $(INCLUDE_DIR)/package.mk define Package/$(PKG_NAME) SECTION:=utils CATEGORY:=Suning TITLE:=promote information for $(PKG_NAME). endef define Package/$(PKG_NAME)/description This is a Makefile project. endef define Package/$(PKG_NAME)/install $(INSTALL_DIR) $(1)/usr/bin $(INSTALL_BIN) $(PKG_BUILD_DIR)/$(PKG_NAME) $(1)/usr/bin/ endef $(eval $(call BuildPackage,$(PKG_NAME)))
符号 | 等价值 | 说明 |
---|---|---|
$(INSTALL_DIR) | install -d -m0755 | 建立特定权限的 /usr/bin 目录 |
$(INSTALL_BIN) | install -m0755 | 修改文件权限并拷贝至/ usr/bin 目录 |
sprite/src/sprite.c
#include <stdio.h> int main(void) { printf("Hello World!\n"); return 0; }
sprite/src/Makefile
CC = gcc FLAG = -Wall sprite: $(CC) $(FLAG) sprite.c -o sprite
编译、安装
# $(1) 表示目标系统的根目录 # 或者经过 menuconfig 选中 sprite 选项,执行 make 命令 $ make package/sprite/compile V=s
删除拷贝的构建目录
# 删除 ~/openwrt/build_dir/target-mipsel_mips32_musl/sprite $ make package/sprite/clean
clxye/Makefile
include $(TOPDIR)/rules.mk PKG_NAME:=clxye PKG_RELEASE:=1 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) include $(INCLUDE_DIR)/package.mk include $(INCLUDE_DIR)/cmake.mk define Package/${PKG_NAME} SECTION:=utils CATEGORY:=Suning DEPENDS:=+libstdcpp +libpthread TITLE:=promote information for ${PKG_NAME}. endef define Package/${PKG_NAME}/description This is a CMake project. endef define Package/${PKG_NAME}/install $(INSTALL_DIR) $(1)/usr/bin $(INSTALL_BIN) $(PKG_BUILD_DIR)/${PKG_NAME} $(1)/usr/bin/ endef $(eval $(call BuildPackage,${PKG_NAME}))
一、CMake 工程必须包含 include $(INCLUDE_DIR)/cmake.mk
二、C++ 工程必须包含 libstdcpp
clxye/src/clxye.cpp
#include <iostream> #include <thread> int main(void) { std::thread t( [](){ std::cout << "Hello World!" << std::endl; } ); t.join(); return 0; }
clxye/src/Makefile
# 所需 cmake 工具的最低版本 cmake_minimum_required(VERSION 2.6) # 工程名称 project(clxye) # 生成可执行程序 add_executable(${PROJECT_NAME} clxye.cpp ) # 连接共享库 target_link_libraries(${PROJECT_NAME} pthread ) # 安装可执行文件(必须提供install) install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION "/usr/bin")
编译、安装
# 初次编译需采用 make menuconfig、check and save、make V=s 编译 $ make package/clxye/compile V=s
删除拷贝的构建目录
# 删除 ~/openwrt/build_dir/target-mipsel_mips32_musl/clxye $ make package/sprite/clean
结果与 Makefile 基本一致(clxye与sprite文件名不一样),这里再也不重复展现。
Config 类型
config GST1_LIBAV_DECODER_mp3 bool "MP3 (MPEG Audio Layer 2)"
DEPENDS 依赖项
# 此方式只能为 Package 类型,不支持 Config 类型 define Package/$(PKG_NAME) SECTION:=utils CATEGORY:=Suning DEPENDS:=+libc +libgcc +librt +libpcre +libpthread +pulseaudio-daemon +portaudio \ +gst1-libav +gstreamer1-libs +libgst1app TITLE:=promote information for $(PKG_NAME). endef
select 方法
# Package 与 Config 两种类型均支持 define Package/$(PKG_NAME)/config select GST1_LIBAV_DECODER_mp3 select GST1_LIBAV_PARSER_mpegaudio select PACKAGE_gst1-mod-alsa select PACKAGE_gstreamer1-utils endef
efine Package/$(PKG_NAME) SECTION:=utils CATEGORY:=Suning DEPENDS:=+libc +libgcc +librt +libpcre +libpthread +pulseaudio-daemon +portaudio \ +gst1-libav +gstreamer1-libs +libgst1app TITLE:=promote information for $(PKG_NAME). endef define Package/$(PKG_NAME)/config # ** gst1-libav ** select GST1_LIBAV_DECODER_ac3 select GST1_LIBAV_DECODER_mp3 select GST1_LIBAV_DECODER_pcm_s16be select GST1_LIBAV_DECODER_pcm_s16le select GST1_LIBAV_DEMUXER_ac3 select GST1_LIBAV_DEMUXER_mp3 select GST1_LIBAV_PARSER_ac3 select GST1_LIBAV_PARSER_mpegaudio # ** gstreamer1-plugins-base ** select PACKAGE_gst1-mod-alsa select PACKAGE_gst1-mod-app select PACKAGE_gst1-mod-audioconvert select PACKAGE_gst1-mod-playback select PACKAGE_gst1-mod-typefindfunctions select PACKAGE_gst1-mod-volume # ** gstreamer1-plugins-good ** select PACKAGE_gst1-mod-audioparsers select PACKAGE_gst1-mod-autodetect select PACKAGE_gst1-mod-id3demux select PACKAGE_gst1-mod-wavparse # ** gstreamer1-utils ** select PACKAGE_gstreamer1-utils endef
一、Makefile:1: *** missing separator. Stop.
# 空格与Tab的问题,进入 Makefile 所在目录执行以下脚本 $ perl -pi -e 's/^ */\t/' Makefile
二、make[2]: Nothing to be done for 'compile'.
# 暂时未找到从根本上解决问题的方法 # 可经过 make menuconfig 勾选后执行 make 操做的方式编译
三、WARNING: your configuration is out of sync. Please run make menuconfig, oldconfig or defconfig!
# 执行 make package/${packagename}/compile 时的编译警告 # 此时必须经过 make menuconfig... save... make 的方式编译,不然 install 会致使目标系统没有安装文件的状况。
四、Package xxx is missing dependencies for the following libraries: libstdc++.so.6
# 添加 c++ 依赖库 DEPENDS:=+libstdcpp
五、Makefile:26: *** Package/clxye is missing the VERSION field. Stop
# Makefile 中该关键字不能省略(不是 PKG_VERSION) PKG_RELEASE:=1
六、Package/$(PKG_NAME)/install 脚本未执行
# 此时构建目录中未生成 “.pkgdir” 和 “ipkg-mipsel_mips32” 目录。 # 经过 make menuconfig 勾选该软件包,而后再执行 make package/xxx/compile 编译指令,此问题耗费了两天。
1. OpenWrt Development Guide
2. Openwrt Examples
3. Creating packages
4. Openwrt package Makefile
5. Makefile 选项 CFLAGS,LDFLAGS,LIBS
6. OpenWRT的包依赖 package DEPEND
7. Alternative for missing __sync_fetch_and_add_8 on MIPS 32-bit
译 《Documentation/kbuild/kconfig-language.txt》
kconfig语法整理)