buildRoot编译rootfs实战
为什么用buildroot
很多嵌入式linux都是使用交叉编译编译的系统和rootfs。没有包管理,没有网络管理,很多软件都没有,对于一些依赖简单的软件,可以直接使用交叉编译器编译后移动到系统就可以直接运行了。但对于一些依赖关系复杂的软件,要想安装到已经生成的文件系统中简直是困难重重。如果想要自己一个一个编译几乎不可能,要不就手动修改代码,将其中没有必要的依赖手动删除。还有一个方法就是用buildroot来处理这此依赖软件的编译,但buildroot由于国内环境原因,使用上也是困难重重,因此记录一下buildroot实际编译cups和cups-filters的实际过程。
准备
使用docker+ubuntu18.04的环境。可以实现docker打包,以后就直接导入docker镜像直接编译了。
bash
# 安装docker
sudo apt install docker-io docker-cli docker-buildx
# 为普通用户加入权限
sudo usermod -aG docker YouName
# 下载ubuntu:18.04, 并运行
docker pull ubuntu:18.04
docker run --name YouContainerName -i -t -v /home/xxx/sharePath:/home/pathNameInContainer ubuntu:18.04
# 容器中安装编译必要的软件
apt install build-essential gzip git cmake python3 lib32ncurses5-dev binutils-dev
# 确保容器中有以下命令软件
which sed makea gcc g++ bash patch gzip bzip2 perl tar cpio unzip rsync file bc wget
# 获取buildroot,我下载的是buildroot-2022.02,下载地址https://buildroot.org/downloads/
# 下载后放入主机与容器的共享目录
tar zxvf buildroot-2022.02.tar.gz
cd buildroot-2022.02
cd config
# 在orangepi one的基础上修改
cp orangepi_one_defconfig my_arm_defconfig
cd ..
make my_arm_defconfig
make menuconfig
# Target options没有什么修改的如下
arget Architecture (ARM (little endian)) ---> │ │
│ │ Target Binary Format (ELF) ---> │ │
│ │ Target Architecture Variant (cortex-A7) ---> │ │
│ │ Target ABI (EABIhf) ---> │ │
│ │ Floating point strategy (VFPv4) ---> │ │
│ │ ARM instruction set (ARM) --->
# Build options中就修改一下镜像地址设置(Mirrors and Download locations)
# 实际测试发现这里设置了kernel镜像地址,但buildroot还是找不到linux内核,因为目录结构有差异,只能自己手动下载对应内核到dl,再make。很多后面下载的软件包都需要这个操作。
() Primary download site │ │
│ │ (http://sources.buildroot.net) Backup download site │ │
│ │ (https://mirrors.aliyun.com/linux-kernel) Kernel.org mirror │ │
│ │ (https://mirrors.aliyun.com/gnu) GNU Software mirror │ │
│ │ (https://luarocks.cn) LuaRocks mirror │ │
│ │ (https://mirrors.aliyun.com/CPAN) CPAN mirror (Perl packages)
# Toolchain
# Toolchain type建议都用buildroot的,因为你自己安装的编译器是不能直接用在这里的,需要buildroot导出的它才认
Toolchain type (Buildroot toolchain) --->
# clib 因为我需要编译cups和cups-filters好像只能用glibc
C library (glibc) --->
# 也是因为cups和cups-filters需要
[*] Enable C++ support
[*] Enable MMU support
# Filesystem images 下面有个打包rootfs设置,不打开output/image目录下不会打包rootfs.tar,它下面还有个压缩格式这里就不压缩了
[*] tar the root filesystem
# Target packages 里面就有需要安装的包cups, cups-filters, Qt等都在这个里面
# 不知道在那个位置,或里面找不到相关软件包开关,可以按 / 键搜索,它会给出这个设置所在位置和所需要的依赖,非常好用
# Graphic libraries and applications (graphic/text) ---> 下面就有Qt5的开关,如果没有就按 / 键,搜索BR2_PACKAGE_QT5就可以看到它需要那些依赖,是不是有依赖没有打开
# 打开Qt5和一些插件
# Libraries->Crypto->libxcrypt,对于一些较新的buildroot需要打开才能看到cups的开关,这里也可以一起打开
# libraries->Networking applications->cups打开后,下面会出现cups-filters开关,打开就可以了
# 退出前保存一下写入.config
# 如果不确定请按 / 键搜索相关软件包的依赖
# 保存后一路esc退出menuconfig
# 保存当前设置到defconfig
make savedefconfig
# 不知道defconfig保存到了那里可以在buildroot根目录
grep DEFCONFIG .config
这里展示一个保存后的defconfig
bash
BR2_arm=y
BR2_cortex_a7=y
BR2_ARM_FPU_VFPV4=y
BR2_KERNEL_MIRROR="https://mirrors.aliyun.com/linux-kernel"
BR2_GNU_MIRROR="https://mirrors.aliyun.com/gnu"
BR2_LUAROCKS_MIRROR="https://luarocks.cn"
BR2_CPAN_MIRROR="https://mirrors.aliyun.com/CPAN"
BR2_TOOLCHAIN_BUILDROOT_GLIBC=y
BR2_KERNEL_HEADERS_4_4=y
BR2_GCC_VERSION_9_X=y
BR2_TOOLCHAIN_BUILDROOT_CXX=y
BR2_TARGET_GENERIC_HOSTNAME="Your host name"
BR2_TARGET_GENERIC_ISSUE="Welcome to Buildroot for the Arm linux"
BR2_TARGET_GENERIC_ROOT_PASSWD="root"
BR2_TARGET_GENERIC_GETTY_PORT="ttymxc0"
BR2_PACKAGE_QT5=y
BR2_PACKAGE_QT5BASE_MYSQL=y
BR2_PACKAGE_QT5BASE_SQLITE_QT=y
BR2_PACKAGE_QT5BASE_GIF=y
BR2_PACKAGE_QT5BASE_JPEG=y
BR2_PACKAGE_QT5BASE_PNG=y
BR2_PACKAGE_QT5BASE_TSLIB=y
BR2_PACKAGE_QT5CHARTS=y
BR2_PACKAGE_QT5MQTT=y
BR2_PACKAGE_QT5SERIALPORT=y
BR2_PACKAGE_QT5SVG=y
BR2_PACKAGE_QJSON=y
BR2_PACKAGE_LIBXCRYPT=y
BR2_PACKAGE_CUPS=y
BR2_PACKAGE_CUPS_FILTERS=y
BR2_PACKAGE_DROPBEAR=y
BR2_PACKAGE_KMOD=y
BR2_PACKAGE_UTIL_LINUX_LIBBLKID=y
编译
就用make -j8命令就可以了,编译过程中需要从网络下载内核,软件源码。因此很大可能卡在下载其中的一个软件。这时就需要手动按Ctrl+c停止编译,用浏览器搜索下载相应软件或kernel下载的文件名字要与需要下载的软件包名完全一致,buildroot会使用checksum判断下载的软件是否是需要下载的那个,如果checkSum不一致还是会从网络下载。下载下来的软件包需要放入 dl/包名/软件压缩包 目录下,如果checkSum正确再次make -j8就会直接使用下载好的离线包。
如果一切问题都处理完成会在 output/images/ 目录下生成一个rootfs.tar文件,此文件就是编译完成的rootfs文件,需要的软件包文件也可以从这个文件中提取出来,当然也可以从 output/target/目录下提取单独打包。 output/target/目录下的是没有打包的rootfs。