| OpenWRT目录结构,然后创建feeds,并创建package。 编译package,并安装到target进行测试。 1 OpenWRT目录结构
 
 ├── bin--编译完成后ipk和image文件存放在此。
 │   ├── packages--存放base/luci/packages/routing/telephony等编译出来的ipk包。
 │   └── targets--目标镜像文件。
 ├── BSDmakefile
 ├── build_dir--下载的软件包解压到此,然后进行编译。
 │   ├── hostpkg--编译在host环境中使用的工具。
 │   ├── target-aarch64_cortex-a53_musl--编译在target环境中使用的工具。
 │   └── toolchain-aarch64_cortex-a53_gcc-11.2.0_musl--交叉工具链的编译。
 ├── config--menuconfig配置文件。
 │   ├── check-uname.sh
 │   ├── Config-build.in
 │   ├── Config-devel.in
 │   ├── Config-images.in
 │   └── Config-kernel.in
 ├── Config.in--配置文件的总入口。
 ├── COPYING
 ├── dl--下载的软件包存放在此目录。
 │   ├── attr-2.5.1.tar.gz
 ...
 │   └── zstd-1.5.5.tar.gz
 ├── feeds--根据feeds.conf.default生成的OpenWRT的package来源地。
 │   ├── luci
 │   ├── luci.index -> luci.tmp/.packageinfo
 │   ├── luci.targetindex -> luci.tmp/.targetinfo
 │   ├── luci.tmp
 │   ├── packages
 │   ├── packages.index -> packages.tmp/.packageinfo
 │   ├── packages.targetindex -> packages.tmp/.targetinfo
 │   ├── packages.tmp
 │   ├── routing
 │   ├── routing.index -> routing.tmp/.packageinfo
 │   ├── routing.targetindex -> routing.tmp/.targetinfo
 │   ├── routing.tmp
 │   ├── telephony
 │   ├── telephony.index -> telephony.tmp/.packageinfo
 │   ├── telephony.targetindex -> telephony.tmp/.targetinfo
 │   └── telephony.tmp
 ├── feeds.conf.default
 ├── include--存放mk文件。
 │   ├── autotools.mk
 ...
 │   └── version.mk
 ├── key-build
 ├── key-build.pub
 ├── key-build.ucert
 ├── key-build.ucert.revoke
 ├── LICENSES
 │   ├── BSD-2-Clause
 │   ├── BSD-3-Clause
 │   ├── GPL-1.0
 │   ├── GPL-2.0
 │   ├── ISC
 │   ├── Linux-syscall-note
 │   └── MIT
 ├── Makefile--make默认的配置文件。
 ├── package--不同类别package的makefile文件和menuconfig配置文件。
 │   ├── base-files
 │   ├── boot
 │   ├── devel
 │   ├── feeds
 │   ├── firmware
 │   ├── kernel
 │   ├── libs
 │   ├── Makefile
 │   ├── network
 │   ├── system
 │   └── utils
 ├── README.md
 ├── rules.mk
 ├── scripts--编译过程中使用的脚本文件。
 │   ├── arm-magic.sh
 ...
 │   └── xxdi.pl
 ├── staging_dir--生成最终文件系统之前的临时安装目录。
 │   ├── host
 │   ├── hostpkg
 │   ├── packages
 │   ├── target-aarch64_cortex-a53_musl
 │   └── toolchain-aarch64_cortex-a53_gcc-11.2.0_musl
 ├── target--imagebuilder、linux、sdk、toolchain的makefile和配置文件。
 │   ├── Config.in
 │   ├── imagebuilder
 │   ├── linux
 │   ├── llvm-bpf
 │   ├── Makefile
 │   ├── sdk
 │   └── toolchain
 ├── tmp
 │   ├── a.out
 │   ├── info
 │   ├── opkg_install_list
 │   └── test.fs
 ├── toolchain--编译gcc/binutils/gdb/glibc/mold/must/nasm等工具的makefile文件和配置文件。
 │   ├── binutils
 │   ├── build_version
 │   ├── Config.in
 │   ├── fortify-headers
 │   ├── gcc
 │   ├── gdb
 │   ├── glibc
 │   ├── info.mk
 │   ├── kernel-headers
 │   ├── Makefile
 │   ├── musl
 │   ├── nasm
 │   └── wrapper
 └── tools--编译过程中所使用到的工具。
 ├── autoconf
 ...
 └── zstd
 
 
 2 OpenWRT feeds管理
 2.1 feeds管理
 ./scripts/feeds用于管理OpenWRT的feeds:[url=]
  [/url] Usage: ./scripts/feeds <command> [options]Commands:    list [options]: List feeds, their content and revisions (if installed)    Options:        -n :            List of feed names.        -s :            List of feed names and their URL.        -r <feedname>:  List packages of specified feed.        -d <delimiter>: Use specified delimiter to distinguish rows (default: spaces)        -f :            List feeds in feeds.conf compatible format (when using -s).    install [options] <package>: Install a package    Options:        -a :           Install all packages from all feeds or from the specified feed using the -p option.        -p <feedname>: Prefer this feed when installing packages.        -d <y|m|n>:    Set default for newly installed packages.        -f :           Install will be forced even if the package exists in core OpenWrt (override)    search [options] <substring>: Search for a package    Options:        -r <feedname>: Only search in this feed    uninstall -a|<package>: Uninstall a package    Options:        -a :           Uninstalls all packages.    update -a|<feedname(s)>: Update packages and lists of feeds in feeds.conf .    Options:        -a :           Update all feeds listed within feeds.conf. Otherwise the specified feeds will be updated.        -i :           Recreate the index only. No feed update from repository is performed.        -f :           Force updating feeds even if there are changed, uncommitted files.    clean:             Remove downloaded/generated files.[url=]
  [/url] 
 
 2.2 新增feedsupdate:根据feeds.conf获取package,并拷贝到feeds目录下。list:显示feeds,或其package列表详细信息。install:将update命令从feeds获取packages链接到package/feeds/中。uninstall:移除某个package。search:查找特定package信息。
  修改feeds.conf.default文件,新增feeds配置: 
 | Method | Function |  | src-bzr | Data is downloaded from the source path/URL using bzr |  | src-cpy | Data is copied from the source path. The path can be specified as either relative to OpenWrt repository root or absolute. |  | src-darcs | Data is downloaded from the source path/URL using darcs |  | src-git | Data is downloaded from the source path/URL using git as a shallow (depth of 1) clone |  | src-git-full | Data is downloaded from the source path/URL using git as a full clone |  | src-gitsvn | Bidirectional operation between a Subversion repository and git |  | src-hg | Data is downloaded from the source path/URL using hg |  | src-link | A symlink to the source path is created. The path must be absolute. |  | src-svn | Data is downloaded from the source path/URL using svn | 
 
 以git为例: 复制代码src-git local_feed_name https://example.com/repo_name/something.git;branch_namesrc-git local_feed_name https://example.com/repo_name/something.git^commit_hash
 3 OpenWRT编译流程3.1 整体编译
  在对OpenWRT的feeds进行配置后,可以进行配置和编译。 配置toolchain、kernel、packages:make menuconfig 
 make即可开始编译: 下载选中的package源码。编译交叉编译工具链和host应用。交叉编译kernel和选中的packages。
 make V=x指定输出的不同编译log等级:[url=]  [/url] V=99 and V=1 are now deprecated in favor of a new verbosity class system,    though the old flags are still supported.    You can set the V variable on the command line (or OPENWRT_VERBOSE in the    environment) to one or more of the following characters:        - s: stdout+stderr (equal to the old V=99)    - c: commands (for build systems that suppress commands by default, e.g. kbuild, cmake)    - w: warnings/errors only (equal to the old V=1)[url=]
  [/url] 
 
 其他常见编译操作: 运行make menuconfig选定目标映像;运行make defconfig为构建环境和设备设定默认配置;运行make kernel_menuconfig(可选);运行make menuconfig配置软件包;运行make download(在最终构建前下载所有依赖, 并激活多线程编译);运行scripts/diffconfig.sh >mydiffconfig(将所有修改保存到mydiffconfig文件);
 3.2 package编译
 单独编译某一个模块:make package/example/download - download the soures of examplemake package/example/prepare - extract the sources, apply patches and download if necessarymake package/example/compile - compile example, prepare and download if necessarymake package/example/clean - clean the sourcecodemake package/index - build a repository index to make the output directory usable as local opkg source 
 对一个package执行多个编译选项,注意clean和compile之间不能有空格:make package/example/{clean,compile} V=99 
 编译中间过程位于build_dir中,按照不同的package分列,里面包含源代码、编译脚本、编译中间文件以及输出可执行或者库文件等:[url=]  [/url] build_dir/target-aarch64_cortex-a53_musl/├── busybox-default...├── root-armvirt--即将要打包的rootfs文件集合。├── root.orig-armvirt...└── zlib-1.2.11[url=]
  [/url] 
 
 staging_dir是一个临时集合,后面可能还会有strip等操作:[url=]  [/url] staging_dir/target-aarch64_cortex-a53_musl/├── host├── packages├── pkginfo├── root-armvirt├── stamp└── usr[url=]
  [/url] 
 
 bin中存放最终镜像和安装包:[url=]  [/url] bin/targets/└── armvirt    └── 64        ├── config.buildinfo        ├── feeds.buildinfo        ├── openwrt-armvirt-64-default.manifest        ├── openwrt-armvirt-64-default-rootfs.tar.gz        ├── openwrt-armvirt-64-Image        ├── openwrt-armvirt-64-Image-initramfs        ├── openwrt-armvirt-64-rootfs.cpio.gz        ├── openwrt-armvirt-64-rootfs-ext4.img.gz        ├── openwrt-armvirt-64-rootfs-squashfs.img.gz        ├── packages        │   ├── base-files_1505-r20341-591b7e93d3_aarch64_cortex-a53.ipk        │   ├── dropbear_2022.82-4_aarch64_cortex-a53.ipk        │   ├── fstools_2022-06-02-93369be0-2_aarch64_cortex-a53.ipk        │   ├── fwtool_2019-11-12-8f7fe925-1_aarch64_cortex-a53.ipk        │   ├── index.json        │   ├── kernel_5.10.221-1-95f66e1daaaff0091d354d5d867e8a64_aarch64_cortex-a53.ipk...        │   ├── mtd_26_aarch64_cortex-a53.ipk        │   ├── Packages        │   ├── Packages.gz        │   ├── Packages.manifest        │   └── Packages.sig        ├── sha256sums        └── version.buildinfo[url=]
  [/url] 
 4 OpenWRT新增package和feeds4.1 创建package内容
 编写测试程序hello world.c:[url=]  [/url] #include <stdio.h>int main(void){    printf("\nHello, world!\n\n");    return 0;}[url=]
  [/url] 
 
 编写Makefile文件:[url=]  [/url] include $(TOPDIR)/rules.mk# Name, version and release number# The name and version of your package are used to define the variable to point to the build directory of your package: $(PKG_BUILD_DIR)PKG_NAME:=helloworldPKG_VERSION:=1.0PKG_RELEASE:=1# Source settings (i.e. where to find the source codes)# This is a custom variable, used belowSOURCE_DIR:=/home/al/openwrt/openwrt/mypackages/examples/helloworldinclude $(INCLUDE_DIR)/package.mk# Package definition; instructs on how and where our package will appear in the overall configuration menu ('make menuconfig')define Package/helloworld  SECTION:=examples  CATEGORY:=Examples  TITLE:=Hello, World!endef# Package description; a more verbose description on what our package doesdefine Package/helloworld/description  A simple "Hello, world!" -application.endef# Package preparation instructions; create the build directory and copy the source code. # The last command is necessary to ensure our preparation instructions remain compatible with the patching system.define Build/Prepare        mkdir -p $(PKG_BUILD_DIR)        cp $(SOURCE_DIR)/* $(PKG_BUILD_DIR)        $(Build/Patch)endef# Package build instructions; invoke the target-specific compiler to first compile the source file, and then to link the file into the final executabledefine Build/Compile        $(TARGET_CC) $(TARGET_CFLAGS) -o $(PKG_BUILD_DIR)/helloworld.o -c $(PKG_BUILD_DIR)/helloworld.c        $(TARGET_CC) $(TARGET_LDFLAGS) -o $(PKG_BUILD_DIR)/$1 $(PKG_BUILD_DIR)/helloworld.oendef# Package install instructions; create a directory inside the package to hold our executable, and then copy the executable we built previously into the folderdefine Package/helloworld/install        $(INSTALL_DIR) $(1)/usr/bin        $(INSTALL_BIN) $(PKG_BUILD_DIR)/helloworld $(1)/usr/binendef# This command is always the last, it uses the definitions and variables we give above in order to get the job done$(eval $(call BuildPackage,helloworld))[url=]
  [/url] 
 4.2 创建feeds并安装
 为helloworld package创建feeds目录,并将hello world.c和Makefile放入其中:mypackages/└── examples    └── helloworld        ├── helloworld.c        └── Makefile 
  修改feeds.conf.default文件:src-git-full packages https://git.openwrt.org/feed/packages.git;openwrt-22.03src-git-full luci https://git.openwrt.org/project/ ... t-22.03src-git-full routing https://git.openwrt.org/feed/rou ... t-22.03src-git-full telephony https://git.openwrt.org/feed/telephony.git;openwrt-22.03src-link mypackages /home/al/openwrt/openwrt/mypackages 
 单独更新mypackages feed:./scripts/feeds update mypackage 
  在feeds下创建mypackages feed相关信息: feeds├── mypackages -> /home/al/openwrt/openwrt/mypackages
 ├── mypackages.index -> mypackages.tmp/.packageinfo
 ├── mypackages.targetindex -> mypackages.tmp/.targetinfo
 ├── mypackages.tmp│
 ├── info│
 └── location
 
 
 将mypackages feed的package安装到OpenWRT系统中: 复制代码./scripts/feeds install -a -p mypackages
  安装结果如下:package/feeds/mypackages/ └── helloworld -> ../../../feeds/mypackages/examples/helloworld
 
 4.3 配置并编译package
 make menuconfig选择helloworld,并保存配置: 编译helloworld:make package/feeds/mypackages/helloworld/compile 
 在./build_dir/target-aarch64_cortex-a53_musl/helloworld-1.0目录存放编译过程文件:[url=]  [/url] ./build_dir/target-aarch64_cortex-a53_musl/helloworld-1.0├── helloworld├── helloworld.c├── helloworld.o├── ipkg-aarch64_cortex-a53│   └── helloworld│       ├── CONTROL│       │   ├── control│       │   ├── postinst│       │   └── prerm│       └── usr│           └── bin│               └── helloworld└── Makefile[url=]
  [/url] 
 
 生成ipkg安装包位于./bin/packages/aarch64_cortex-a53/mypackages/:./bin/packages/aarch64_cortex-a53/mypackages/ └── helloworld_1.0-1_aarch64_cortex-a53.ipk
 
 根据Makefile配置helloworld也被安装到staging_dir下: ./staging_dir/target-aarch64_cortex-a53_musl/root-armvirt/usr/bin/helloworld。 此时如果执行make,则helloworld可执行文件已经位于镜像中,烧录启动即可使用。 4.4 安装卸载package
  通过scp将ipk传到target:scp bin/packages/aarch64_cortex-a53/mypackages/helloworld_1.0-1_aarch64_cortex-a53.ipk root@192.168.2.2:/ 
 安装ipk:opkg install helloworld_1.0-1_aarch64_cortex-a53.ipk 
 执行helloworld:Hello, world! 
 卸载helloworld:opkg remove helloworld 
 opkg显示已安装列表:opkg list 
 
 
 |