4. 编译镜像

源码拉取完成之后,我们不能直接进行镜像的编译。 还需要做一些工作,那就是OpenWrt所需编译工具的安装。

4.1. 编译工具的安装

打开Ubuntu,在桌面单击鼠标右键,选择打开终端,输入以下命令,等待软件包安装完成。

1
2
sudo apt install -y subversion g++ zlib1g-dev build-essential git python rsync man-db
sudo apt install -y libncurses5-dev gawk gettext unzip file libssl-dev wget zip time aria2

软件安装完成后,输入以下命令进入OpenWrt源码所在的目录。

1
cd ~/LubanCatWrt
compile01

4.2. 软件包下载

由于OpenWrt的软件包和其他资源都是以源码的形式拉取到本地然后进行编译, 也就是在编译之前会进行大量的下载工作,因此,要进行软件包源码的下载, 请确保当前网络环境能高速访问国外网站,否则会导致软件包源码下载超时导致失败。

本文也提供相对较少访问国外软件包源码的方法,但也请保证网络畅通。

以下两种方式选择一种即可。能畅通访问国外源码服务器的建议选择直接下载; 网络情况受限的可以直接下载我们提供的完整编译包,在提供的编译包中引进下载好了编译时所需的软件包源码。

4.2.1. 直接下载

在终端中输入以下命令,将出现初始化脚本功能的选择菜单,我们可以输入所需功能对应的数字来选择。 如果我们想更新软件包并应用默认配置文件,就输入 1 并按Enter键确认, 将会自动执行软件包列表的升级和安装和默认配置文件的生成,最后根据生成的配置文件下载必须的软件包源码。 我们耐心等待执行完成即可。如果网络不好的话,这一过程将会持续相当长的时间。

1
2
#一键下载
./mk-fire.sh
更新软件包列表 更新软件包列表

我们来看一下一键下载的脚本里都是哪些内容:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#!/bin/sh
#menu.sh

echo "---------------------------------------------------------"
echo "please enter your choise scripts number:"
echo "请输入要运行脚本的序号:"
echo "[0] Exit Menu"
echo "[1] Update feeds/config/download"
echo "[2] Save Defconfig"
echo "---------------------------------------------------------"
read input

case $input in
    0)
        exit;;
    1)
        SCRIPTS=Update
        ;;
    2)
        SCRIPTS=Defconfig
        ;;
    *)
        echo 'input type number error, exit !'
        exit;;
esac

if [ $SCRIPTS = Update ]
then
    echo '**************begining update and install feeds************'
    #更新升级软件包列表
    ./scripts/feeds update -a
    ./scripts/feeds install -a


    echo '**************application lubancat_defconfig ***************'
    #生成默认配置文件
    cat ./config/lubancat_defconfig > .config
    make defconfig


    echo '**************download all packages***********************'
    #下载软件包
    make download V=s

    ##如果自己在menuconfig中修改了配置,
    ##使用#把使用默认配置的命令注释掉再执行此脚本可一键更新软件包
fi



if [ $SCRIPTS = Defconfig ]
then
    echo '**************begining write lubancat_defconfig************'
    #写入默认配置文件
    ./scripts/diffconfig.sh > config/lubancat_defconfig

    cat config/lubancat_defconfig

    echo '**********************write successful *********************'
fi

警告

如果自己修改了配置文件,使用一键升级脚本会使修改失效。

4.2.2. 下载完整编译包

使用提供的完整编译包不需要从git仓库下载,直接在Ubuntu中解压, 执行下列编译命令即可,但是Ubuntu仍然要处于能连接网络的状态。

main分支下载地址为:资料下载链接->云盘资料下载->8_SDK源码压缩包

下载完成后,打开Ubuntu 文件 -> 主目录 ,将下载好的LubanCatWrt.zip压缩包拖入当前文件夹中, 然后对压缩包进行解压。

选中要解压的压缩包,点击鼠标右键选择 提取到此处

下载完整编译包

4.3. 编译镜像

野火所有板卡都使用了同一默认的配置文件,我们只需要在编译镜像时选择合适的板卡配置即可

警告

首次编译不建议修改其他设置,否则可能会出现编译失败的情况。

1
make menuconfig

警告

确保终端显示面积足够大,否则会出现 Your display is too small to run Menuconfig! 的错误

编译镜像1 编译镜像1

Target Profile 使用Enter键选中合适的板卡,然后按ESC按键。提示是否保存新配置,选择yes即可。

退出menuconfig之后,在终端输入以下命令,开始编译。

1
make V=s
编译镜像2

警告

初次编译时间较长,请耐心等待。依电脑性能和网络情况,编译时间在2-6小时或更长时间。

编译完成

编译过程中可能会有确认提示,直接按Enter键即可。

生成的镜像在 LubanCatWrt/bin/targets/rockchip/armv8 路径下

生成的镜像

文件说明:

  • packegs:存放编译好的软件包

  • openwrt-rockchip-armv8-embedfire_doornet1.manifest:镜像内已经安装的软件包列表

  • openwrt-rockchip-armv8-embedfire_doornet1-squashfs-sysupgrade.img.gz:生成的squashfs格式镜像

  • openwrt-rockchip-armv8-embedfire_doornet1-ext4-sysupgrade.img.gz:生成的ext4格式镜像

  • sha256sums:各文件SHA256校验和

4.4. 编译流程分析

4.4.1. 更新并安装软件包列表

在我们拿到OpenWrt的源码之后,要做的第一件事就是安装软件包列表。只有安装软件包列表, 我们才能在menuconfig中选择选择正确的设备类型,才能选择添加软件包。

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

这两条命令实际执行的是源码根目录scripts路径下名为feeds的脚本文件。 传入的参数update表示升级软件包列表,实际是从git拉取软件包列表的仓库,此时拉取的数据还在临时目录中。 install则用于安装软件包列表,实质上是将临时目录中的列表替换到实际使用的软件包列表位置。 -a参数则表示选择所有软件包。他还有很多不常用的参数,具体可以使用下面命令查看。

1
./scripts/feeds help

实际情况是,只要输入了错误的参数,都会出现命令的使用说明。

4.4.2. 使用默认配置文件

如果使用OpenWrt官方仓库拉取的源代码是没有这一步的,那是因为OpenWrt自带一个通用的配置文件。 我们只需要简单的进行配置就能编译出固件,但是其内容只包含了OpenWrt运行所需的最基本的配置。 为了可重复的复现我们对DoorNet的定制配置,这里就需要多一步生成配置文件的工作。

1
2
cat ./config/lubancat_defconfig > .config
make defconfig

首先,将位于源码根目录config路径下的lubancat_defconfig配置文件写入根目录的.config中, .config是实际在编译过程中使用的配置文件。然后,使用make defconfig命令, 根据我们之前拉取的软件包列表,将.config补充完整,以便于之后的过程中使用menuconfig这样的工具来修改配置文件。

4.4.3. make menuconfig

在完成默认配置文件的添加之后,我们可以根据自己的需求来添加或删除软件包及修改功能设置。

4.4.4. make download

下载配置文件中选择的软件包、依赖库、内核等文件的源码压缩包。下载以后的文件保存在dl目录下。

4.4.5. make V=s -jn

使用make命令进行源码的编译。参数V表示输出log的等级,V=s为输出所有的信息,等同于V=99,V=0为不输出,不使用V参数时默认为0。 -j表示同时进行指定数量的任务进行编译,也就是指定编译的线程数,n为线程数大小,不指定-jn参数时自动判断编译所需的线程数。

由于OpenWrt部分软件包不支持多线程编译,当我们指定n大于1时,会有极大的可能导致编译失败, 所以推荐大家使用 make V=s命令来减少不必要的麻烦。

由于我们在实际的开发过程中使用服务器进行编译,服务器具有核心多但单核频率低的特点, 如果仅使用单线程编译,效率甚至不如普通PC。所以,我们往往会先进行多线程编译, 直到工程编译失败,再使用单线程编译,具体过程如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#首先进行多线程编译
make V=s -j56

#遇到编译错误,尝试单线程编译
make V=s -j1

#如果单线程编译不通过,检查详细报错信息并解决错误

#单线程编译报错软件包通过之后,Ctrl+C打断编译,继续使用多线程编译
make V=s -j56

#重复上述过程,直到编译完成

注解

以上开发编译流程仅针对DoorNet镜像构建环境具有较高效率

直接使用make命令可以编译整个工程,当然我们也可以构建单个软件包。具体操作详见 编译软件包 章节

4.4.6. ./scripts/diffconfig.sh > defconfig

在我们对OpenWrt的配置做了修改以后,为了能重复多次的编译出相同的镜像,我们要对配置文件进行保存。

defconfig为文件名,我们可以任意设置,保存路径也可以任意指定。

4.4.7. 清除编译文件

1
2
3
4
5
6
7
8
make clean
#清除bin目录和build_dir/target-xxx目录

make dirclean
#清除[make clean] + 清除交叉编译工具及工具链目录

make distclean
#清除所有编译和下载的文件,使当前内容恢复到拉取时的状态