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 的相关文章

  • 无法从 jenkins 作为后台进程运行 nohup 命令

    更新 根据下面的讨论 我编辑了我的答案以获得更准确的描述 我正在尝试从詹金斯运行 nohup 命令 完整的命令是 nohup java jar home jar server process 0 35 jar prod gt gt var
  • sendfile64 只复制约2GB

    我需要使用 sendfile64 复制大约 16GB 的文件 到目前为止我所取得的成就是 include
  • 使用 sed 更新 xml 属性(Windows + cygwin 和 Linux)?

    我需要使用 sed 命令对 xml 文件进行更新 但我在这方面遇到了麻烦 它需要在 Windows 使用 cygwin 和 Linux 上运行 XML 具有以下元素
  • fopen 不返回

    我在 C 程序中使用 fopen 以只读模式 r 打开文件 但就我而言 我观察到 fopen 调用没有返回 它不返回 NULL 或有效指针 执行在 fopen 调用时被阻止 文件补丁绝对正确 我已经验证过 并且不存在与权限相关的问题 任何人
  • 如何有效截断文件头?

    大家都知道truncate file size 函数 通过截断文件尾部将文件大小更改为给定大小 但是如何做同样的事情 只截断文件的尾部和头部呢 通常 您必须重写整个文件 最简单的方法是跳过前几个字节 将其他所有内容复制到临时文件中 并在完成
  • 如何使用GDB修改内存内容?

    我知道我们可以使用几个命令来访问和读取内存 例如 print p x 但是如何更改任何特定位置的内存内容 在 GDB 中调试时 最简单的是设置程序变量 参见GDB 分配 http sourceware org gdb current onl
  • linux perf:如何解释和查找热点

    我尝试了linux perf https perf wiki kernel org index php Main Page今天很实用 但在解释其结果时遇到了困难 我习惯了 valgrind 的 callgrind 这当然是与基于采样的 pe
  • PHP 从命令行启动 gui 程序,但 apache 不启动

    首先 我阅读了有类似问题的人的一些帖子 但所有答案都没有超出导出 DISPLAY 0 0 和 xauth cookies 这是我的问题 提前感谢您的宝贵时间 我开发了一个小库 它使用 OpenGL 和 GLSL 渲染货架 过去几天我将它包装
  • CentOS:无法安装 Chromium 浏览器

    我正在尝试在 centOS 6 i 中安装 chromium 以 root 用户身份运行以下命令 cd etc yum repos d wget http repos fedorapeople org repos spot chromium
  • 将 PDF 转换为 600dpi 的 TIFF 和 jpg 96 dpi

    我想使用 ImageMagick 从 Python 脚本将 pdf 转换为 600 dpi 的 tiff 和 96 dpi 的 jpg 我使用 imagemagick 命令行完成了这项任务 但我想使用python中的Imagemagick将
  • os.Mkdir 和 os.MkdirAll 权限

    我正在尝试在程序开始时创建一个日志文件 我需要检查是否 log如果不创建目录 则目录存在 然后继续创建日志文件 好吧 我尝试使用os Mkdir 也os MkdirAll 但无论我在第二个参数中输入什么值 我都会得到一个没有权限的锁定文件夹
  • 使用 sh 运行 bash 脚本

    我有 bash 脚本 它需要 bash 另一个人尝试运行它 sh script name sh 它失败了 因为 sh 是他的发行版中 dash 的符号链接 ls la bin sh lrwxrwxrwx 1 root root 4 Aug
  • jpegtran 优化而不更改文件名

    我需要优化一些图像 但不更改它们的名称 jpegtran copy none optimize image jpg gt image jpg 但是 这似乎创建了 0 的文件大小 当我对不同的文件名执行此操作时 大小仍然完全相同 怎么样 jp
  • 在脚本内使用不带密码的 sudo

    由于某种原因 我需要作为用户在没有 sudo 的情况下运行脚本 script sh 该脚本需要 root 权限才能工作 我认为将 sudo 放入 script sh 中是唯一的解决方案 让我们举个例子 script sh bin sh su
  • 如何确保应用程序在 Linux 上持续运行

    我试图确保脚本在开发服务器上保持运行 它会整理统计数据并提供网络服务 因此它应该会持续存在 但一天中有几次 它会因未知原因而消失 当我们注意到时 我们只需再次启动它 但这很麻烦 并且某些用户没有权限 或专有技术 来启动它 作为一名程序员 我
  • 我不明白 execlp() 在 Linux 中如何工作

    过去两天我一直在试图理解execlp 系统调用 但我还在这里 让我直奔主题 The man pageexeclp 将系统调用声明为int execlp const char file const char arg 与描述 execl exe
  • 按进程名称过滤并记录 CPU 使用情况

    Linux 下有选项吗顶部命令 https www man7 org linux man pages man1 top 1 html我可以在哪里按名称过滤进程并将每秒该进程的 CPU 使用情况写入日志文件 top pgrep 过滤输出top
  • 如何减去两个 gettimeofday 实例?

    我想减去两个 gettimeofday 实例 并以毫秒为单位给出答案 这个想法是 static struct timeval tv gettimeofday tv NULL static struct timeval tv2 gettime
  • 监视目录的更改

    很像一个类似的问题 https stackoverflow com questions 112276 directory modification monitoring 我正在尝试监视 Linux 机器上的目录以添加新文件 并希望在这些新文
  • 确定我可以向文件句柄写入多少内容;将数据从一个 FH 复制到另一个 FH

    如何确定是否可以将给定数量的字节写入文件句柄 实际上是套接字 或者 如何 取消读取 我从其他文件句柄读取的数据 我想要类似的东西 n how much can I write w handle n read r handle buf n a

随机推荐