1-OpenWrt编译过程-2

2023-11-18

前言:接触 op 已达四年,今年开始梳理整体所学,具体还参考了佐大的视频,对 op 缺乏系统知识的可以尝试,总体而言官方文档和源码是最好的教程

编译OpenWrt

本文是 OpenWrt 编译的后半部分,本章会结合具体的编译操作来分析编译过程

实验环境: 物理机ubuntu20.04 docker ubuntu16.04 目标机 ipq6010

概述

主体代码->源代码(/feeds(.config))->准备编译(/package)->编译(/staging_dir)->封装(/build_dir)->成品(/bin)

参考

1 更新安装所有可选的软件包

./scripts/feeds update -a # 下载 feeds 源中的软件包源码
./scripts/feeds install -a # 安装 feeds 中的软件包

执行完 feeds update后,多了tmp、staging_dir、feeds

  • tmp:存放临时文件 //
  • staging_dir:存放准备编译的源码
  • feeds:feeds指令会把feeds.conf里面指定的文件从网上下下来,存放到这里

feeds install会把./feeds文件夹的文件拷贝到./package/feeds文件夹下。此时,这时候./feeds里面的packages是./package/feeds/packages的补充,提高项目的灵活性。
更详细的 feeds 介绍参考

2 编译设置

make menuconfig,系统将进入配置工具选项菜单来配置编译固件的内容,会检查所需的编译工具是否齐备,并生成默认的编译配置文件 .config

**[TIPS]**make defconfig defconfig是根据选择的 target 生成默认配置,在不配置的时候生成一个默认的配置选项,会修改当前的 .config(已经过实验测试)

make menuconfig菜单选项分析

每一个模块通常都有 |Y|N|M|,Y包含在固件中,M是作为一个模块来编译
可以按 H 来获取具体的信息

  • Target System:目标平台,这里选择 Qualcomm Atheros IPQ
  • Subtarget:选择QCA IPQ60xx(32bit) based boards
  • Target Profile:Qualcomm-Atheros SDK Premium Profile
  • Target Images:编译生成物控制,例如根文件系统格式,内核空间大小和是否生成映像文件
  • Global build settings:全局编译设置
  • Base system:OpenWrt基本系统
  • Kernel modules(内核模块配置)

3 编译

make V=s j=12 # 输出详细日志,用于编译失败时找出错误

出现错误时,应该使用单进程查看具体出错原因

编译过程首先检查编译环境,然后编译host工具,再编译编译工具链,最后编译目标平台的各个软件包。编译make进入各个模块进行编译时,首先下载代码压缩包,然后解压缩,并打补丁,再根据设置选项来生成Makefile,最后根据生成的Makefile进行编译和安装。在编译时需要连接互联网,因为OpenWrt采用补丁包方式来管理代码,第三方的代码不放在它自己的代码库中,仅在编译前从第三方服务器下载。

make download

首先会执行 make download类似操作,会把.config指定的组件源码下载下来,放到dl目录(为了编译快速,将dl依赖自行进行添加

然后汇总dl和另外三个地方的源码进行编译

./dl
./staging_dir
./feeds
./package/feeds

编译过程是在 ./staging_dir 里面进行的,编译完成会把二进制文件放在 ./build_dir 文件夹里面等待被打包

make

打包完成后会把结果放到 ./bin 目录

单独编译

  1. make menuconfig将这个包 M,然后可以通过 find ./ -name "xxxx"来寻找该包位置(或者可以在make menuconfig中查看它的Defined at)
  2. make package/system/xxxx/compile V=s
    • 编译完成后,可以在 ./bin/packages中发现,log会显示编译后的位置,也可以通过find寻找
      • find ./* -name “coreutils*”
  3. 然后将 ipk 上传到目标主机(scp),使用 opkg install安装
  • 相关编译命令:
    • make package/xxxx/clean 清除编译生成的文件,包含安装包及编译过程生成的临时文件
    • make package/xxxx/prepare 进行编译准备,包含下载软件代码包、并解压缩和打补丁
    • make package/xxxx/configure 根据设置选项进行配置并生成Makefile
    • make package/xxxx/compile 根据生成的Makefile进行编译
    • make package/xxxx/install 生成安装包

编译扩展机制feeds

参考文章
非官方的包

  • 传统 Linux系统在安装或者编译某一个软件时,会检查其依赖库是否安装,如果没有安装,则会报错,安装或编译退出
  • 该机制使得在安装软件之前,不得不查找该软件所需的依赖库,并手动去安装这些软件
    • 遇到嵌套式的安装依赖文件,会使得开发者头昏脑涨
  • 而 OpenWrt 通过引入 feeds机制,较好的解决了这个问题

下文是 OpenWrt 的官方对于 feeds 的表述:

“In OpenWrt, a “feed” is a collection of packages which share a common location. Feeds may reside on a remote server, in a version control system, on the local filesystem, orin any other location addressable by a single name (path/URL) over a protocol with a supported feed method.Feeds are additional predefined package build recipes for OpenWrt Buildroot”.
在OpenWrt系统中,“feed”是一系列的软件包,这些软件包需要通过一个统一的接口地址进行访问。“feed”软件包中的软件包可能分布在远程服务器上、在svn上、在本地文件系统中或者其他的地方,用户可以通 过一种支持feed机制的协议,通过同一个地址进行访问。

OpenWrt 源码,feeds 提供了在编译固件时所需的的许多额外扩展软件。

  • 理解就是 feeds 是 OpenWrt 环境所需要的软件包套件,它将一个或一组软件封装成一个 feeds
    • 这样做的好处就是 OpenWrt 成为了一个模块化的软件
    • 如果我们想让它成为路由器就加载路由器相关的 feeds,想让他成为读卡器就加载读卡器相关的 feeds
    • 比较重要的 feeds 有:pacakges, LuCI, routing, telephony, management, 这些都是默认的可以通过修改feeds.conf.default文件进行配置。

利用 feeds 提供的接口将 OpenWrt 所需的全部扩展软件包进行下载并安装

./scripts/feeds update -a
./scripts/feeds install -a

feeds 首先读取并解析 feeds.conf 配置文件,然后执行相应的命令
查看 feeds.conf.default

cat ./feeds.conf.default
src-git packages https://gitee.com/harvey520/packages.git;for-15.05
src-git luci https://gitee.com/harvey520/luci.git;for-15.05
src-git routing https://gitee.com/harvey520-routing/packages.git;for-15.05
src-git telephony https://gitee.com/harvey520/telephony.git;for-15.05
src-git management https://gitee.com/harvey520-management/packages.git;for-15.05
#src-git targets https://gitee.com/harvey520/targets.git
#src-git oldpackages http://git.openwrt.org/packages.git
#src-svn xwrt http://x-wrt.googlecode.com/svn/trunk/package
#src-svn phone svn://svn.openwrt.org/openwrt/feeds/phone
#src-svn efl svn://svn.openwrt.org/openwrt/feeds/efl
#src-svn xorg svn://svn.openwrt.org/openwrt/feeds/xorg
#src-svn desktop svn://svn.openwrt.org/openwrt/feeds/desktop
#src-svn xfce svn://svn.openwrt.org/openwrt/feeds/xfce
#src-svn lxde svn://svn.openwrt.org/openwrt/feeds/lxde
#src-link custom /usr/src/openwrt/custom-feed

feeds 详细操作命令

❯ ./scripts/feeds
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)

	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.

	clean:             Remove downloaded/generated files.
  • update:下载在feeds.conf或feeds.conf.default文件中的软件包列表并创建索引。-a表示更新所有的软件包。只有更新后才能进行后面的操作
  • 安装软件包以及它所依赖的软件包,从feeds目录安装到package目录,即在“package/feeds”目录创建软件包的软链接。只有安装之后,在后面执行“make menuconfig”时,才可以对相关软件包是否编译进行选择

编译的注意事项

提升编译速度

  1. 磁盘(大),因为编译的时候大部分都是小文件
  2. CPU,推荐 3-5GHz
ubuntu@ubuntu:~$ cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c
     12  Intel(R) Core(TM) i7-10750H CPU @ 2.60GHz

make -jN 没必要,因为可能多线程编译依赖的时候,会遇到所需的依赖还未编译完毕,不加参数,自动分配(// TODO 好像并不会自动分配>)

clean

make clean

清理bin目录下生成的烧录镜像文件

make clean V=s -j1
make[1]: Entering directory '/.../ipq6010'

make target/linux/clean

make[2]: Entering directory '/.../ipq6010'
make[3]: Entering directory '/.../ipq6010/target/linux'
make[4]: Entering directory '/.../ipq6010/target/linux/ipq'
find /.../ipq6010/build_dir/target-arm_cortex-a7_musl-1.1.16_eabi/linux-ipq_ipq60xx/linux-4.4.60/ -name '*.dtb' -type f -print | xargs rm -f; make -C /.../ipq6010/build_dir/target-arm_cortex-a7_musl-1.1.16_eabi/linux-ipq_ipq60xx/linux-4.4.60 clean
make[5]: Entering directory '/.../ipq6010/qca/src/linux-4.4'
Makefile:1217: target '_clean_samples' given more than once in the same rule
  CLEAN   .
crypto/ocf/ep80579/Makefile:75: ICP_ROOT is undefined. Please set the path to EP80579 release package directory "-> setenv ICP_ROOT <path>"
  CLEAN   samples/hidraw
  CLEAN   .tmp_versions
make[5]: Leaving directory '/.../ipq6010/qca/src/linux-4.4'
make[4]: Leaving directory '/.../ipq6010/target/linux/ipq'
make[3]: Leaving directory '/.../ipq6010/target/linux'
make[2]: Leaving directory '/.../ipq6010'
rm -rf /.../ipq6010/build_dir/target-arm_cortex-a7_musl-1.1.16_eabi /.../ipq6010/staging_dir/target-arm_cortex-a7_musl-1.1.16_eabi /.../ipq6010/bin/ipq /.../ipq6010/logs

make toolchain/kernel-headers/clean

make[2]: Entering directory '/.../ipq6010'
make[3]: Entering directory '/.../ipq6010/toolchain/kernel-headers'
rm -rf /.../ipq6010/build_dir/toolchain-arm_cortex-a7_gcc-5.2.0_musl-1.1.16_eabi/linux-4.4.60 /.../ipq6010/build_dir/toolchain-arm_cortex-a7_gcc-5.2.0_musl-1.1.16_eabi/linux /.../ipq6010/build_dir/toolchain-arm_cortex-a7_gcc-5.2.0_musl-1.1.16_eabi/linux-dev
rm -rf /.../ipq6010/build_dir/toolchain-arm_cortex-a7_gcc-5.2.0_musl-1.1.16_eabi/linux-4.4.60 /.../ipq6010/staging_dir/toolchain-arm_cortex-a7_gcc-5.2.0_musl-1.1.16_eabi/stamp/.linux_installed /.../ipq6010/build_dir/toolchain-arm_cortex-a7_gcc-5.2.0_musl-1.1.16_eabi/linux-4.4.60/.built
make[3]: Leaving directory '/.../ipq6010/toolchain/kernel-headers'
make[2]: Leaving directory '/.../ipq6010'
make[1]: Leaving directory '/.../ipq6010


❯ du -lh --max-depth=1
5.7G	./build_dir
1.8M	./scripts
8.0M	./feeds
1.8G	./dl
2.8M	./tools
29M	./tmp
223M	./wireshark-github
4.0K	./bin
1.8M	./meta-tools
25M	./package
132K	./docs
514M	./.git
883M	./staging_dir
176K	./wireshark-2.4.2-11ax-patches
324K	./include
37M	./target
324M	./toolchain
52K	./config
93M	./prebuilt
1.3G	./qca
11G

make dirclean

make clean+ 清理toolchain目录和目录中的(交叉)编译工具

make dirclean V=s
make[1]: Entering directory '/.../ipq6010'
make target/linux/clean
make[2]: Entering directory '/.../ipq6010'
make[3]: Entering directory '/.../ipq6010/target/linux'
make[4]: Entering directory '/.../ipq6010/target/linux/ipq'
make[4]: 'clean' is up to date.
make[4]: Leaving directory '/.../ipq6010/target/linux/ipq'
make[3]: Leaving directory '/.../ipq6010/target/linux'
make[2]: Leaving directory '/.../ipq6010'
rm -rf /.../ipq6010/build_dir/target-arm_cortex-a7_musl-1.1.16_eabi /.../ipq6010/staging_dir/target-arm_cortex-a7_musl-1.1.16_eabi /.../ipq6010/bin/ipq /.../ipq6010/logs
make toolchain/kernel-headers/clean
make[2]: Entering directory '/.../ipq6010'
make[3]: Entering directory '/.../ipq6010/toolchain/kernel-headers'
rm -rf /.../ipq6010/build_dir/toolchain-arm_cortex-a7_gcc-5.2.0_musl-1.1.16_eabi/linux-4.4.60 /.../ipq6010/build_dir/toolchain-arm_cortex-a7_gcc-5.2.0_musl-1.1.16_eabi/linux /.../ipq6010/build_dir/toolchain-arm_cortex-a7_gcc-5.2.0_musl-1.1.16_eabi/linux-dev
rm -rf /.../ipq6010/build_dir/toolchain-arm_cortex-a7_gcc-5.2.0_musl-1.1.16_eabi/linux-4.4.60 /.../ipq6010/staging_dir/toolchain-arm_cortex-a7_gcc-5.2.0_musl-1.1.16_eabi/stamp/.linux_installed /.../ipq6010/build_dir/toolchain-arm_cortex-a7_gcc-5.2.0_musl-1.1.16_eabi/linux-4.4.60/.built
make[3]: Leaving directory '/.../ipq6010/toolchain/kernel-headers'
make[2]: Leaving directory '/.../ipq6010'
rm -rf /.../ipq6010/staging_dir/host /.../ipq6010/staging_dir/toolchain-arm_cortex-a7_gcc-5.2.0_musl-1.1.16_eabi /.../ipq6010/build_dir/host /.../ipq6010/build_dir/toolchain-arm_cortex-a7_gcc-5.2.0_musl-1.1.16_eabi
rm -rf /.../ipq6010/tmp
make[1]: Leaving directory '/.../ipq6010'du -lh --max-depth=1
4.0K	./build_dir
1.8M	./scripts
8.0M	./feeds
1.8G	./dl
2.8M	./tools
223M	./wireshark-github
4.0K	./bin
1.8M	./meta-tools
25M	./package
132K	./docs
514M	./.git
4.0K	./staging_dir
176K	./wireshark-2.4.2-11ax-patches
324K	./include
37M	./target
324M	./toolchain
52K	./config
93M	./prebuilt
1.3G	./qca
4.3G

make distclean

make dirclean+ 清除所有原目录后来产生的文件,包括下载的软件包,配置文件,feed内容等。

make distclean V=s -j1
Checking 'working-make'... ok.
Checking 'case-sensitive-fs'... ok.
Checking 'gcc'... ok.
Checking 'working-gcc'... ok.
Checking 'g++'... ok.
Checking 'working-g++'... ok.
Checking 'ocamlc'... ok.
Checking 'ncurses'... ok.
Checking 'zlib'... ok.
Checking 'libssl'... ok.
Checking 'tar'... ok.
Checking 'find'... ok.
Checking 'bash'... ok.
Checking 'patch'... ok.
Checking 'diff'... ok.
Checking 'cp'... ok.
Checking 'seq'... ok.
Checking 'awk'... ok.
Checking 'grep'... ok.
Checking 'getopt'... ok.
Checking 'stat'... ok.
Checking 'md5sum'... ok.
Checking 'unzip'... ok.
Checking 'bzip2'... ok.
Checking 'wget'... ok.
Checking 'perl'... ok.
Checking 'python'... ok.
Checking 'svn'... ok.
Checking 'git'... ok.
Checking 'file'... ok.
Checking 'openssl'... ok.
Checking 'ldconfig-stub'... ok.
Collecting package info: done
Collecting target info: done
cp: target '/.../ipq6010/build_dir/target-arm_cortex-a7_musl-1.1.16_eabi/linux-ipq_ipq60xx/qca-wifi-g96305b9ff-dirty-/qca-wifi-g96305b9ff-dirty/' is not a directory
Checking 'uuencode'... ok.
Checking 'xgettext'... ok.
make[1]: Entering directory '/.../ipq6010'
make target/linux/clean
make[2]: Entering directory '/.../ipq6010'
make[3]: Entering directory '/.../ipq6010/target/linux'
make[4]: Entering directory '/.../ipq6010/target/linux/ipq'
make[4]: 'clean' is up to date.
make[4]: Leaving directory '/.../ipq6010/target/linux/ipq'
make[3]: Leaving directory '/.../ipq6010/target/linux'
make[2]: Leaving directory '/.../ipq6010'
make[1]: Leaving directory '/.../ipq6010'
make[1]: Entering directory '/.../ipq6010/scripts/config'
rm -f *.o lxdialog/*.o zconf.tab.c lex.zconf.c zconf.hash.c conf mconf
make[1]: Leaving directory '/.../ipq6010/scripts/config'du -lh --max-depth=1
1.1M	./scripts
2.8M	./tools
223M	./wireshark-github
1.8M	./meta-tools
25M	./package
132K	./docs
514M	./.git
176K	./wireshark-2.4.2-11ax-patches
324K	./include
37M	./target
324M	./toolchain
52K	./config
93M	./prebuilt
1.3G	./qca
2.5G	.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

1-OpenWrt编译过程-2 的相关文章

随机推荐