我尝试使用 Docker 通过 Buildroot 构建 Linux 内核。我创建了一个简单的 Docker 镜像:
FROM debian:7
MAINTAINER OrangeTux
RUN apt-get update && \
apt-get install -y \
build-essential \
bash \
bc \
binutils \
build-essential \
bzip2 \
cpio \
g++ \
gcc \
git \
gzip \
make \
libncurses5-dev \
patch \
perl \
python \
rsync \
sed \
tar \
unzip \
wget
WORKDIR /root
RUN git clone git://git.buildroot.net/buildroot
WORKDIR /root/buildroot
CMD ["/bin/bash"]
我想在容器停止时保留dl/
and output/build/
,这样我就不必每次都下载和编译所有依赖项。我还想要在我的主机上构建产品。因此我像这样启动容器:
$ docker run -ti -v $(pwd)/dl:/root/buildroot/dl -v \ $(pwd)/output/build:/root/buildroot/output/build -v \ $(pwd)/output/images:/root/buildroot/output/images orangetux/buildroot
我可以运行make menuconfig
它来构建 Buildroot 的配置。我对默认值做了一些修改。这是输出make savedefconfig
:
BR2_arm=y
BR2_LINUX_KERNEL=y
BR2_LINUX_KERNEL_DEFCONFIG="at91_dt"
下一步是构建linux-menuconfig
.此操作失败了,我不知道出了什么问题:
$ make linux-menuconfig
/usr/bin/make -j1 HOSTCC="/usr/bin/gcc" HOSTCXX="/usr/bin/g++" silentoldconfig
make[1]: Entering directory `/root/buildroot'
BR2_DEFCONFIG='' KCONFIG_AUTOCONFIG=/root/buildroot/output/build/buildroot-config/auto.conf KCONFIG_AUTOHEADER=/root/buildroot/output/build/buildroot-config/autoconf.h KCONFIG_TRISTATE=/root/buildroot/output/build/buildroot-config/tristate.config BR2_CONFIG=/root/buildroot/.config BR2_EXTERNAL=support/dummy-external SKIP_LEGACY= /root/buildroot/output/build/buildroot-config/conf --silentoldconfig Config.in
*** Error during update of the configuration.
make[1]: *** [silentoldconfig] Error 1
make[1]: Leaving directory `/root/buildroot'
make: *** [/root/buildroot/output/build/buildroot-config/auto.conf] Error 2
该文件/root/buildroot/output/build/buildroot-config/auto.conf
不存在。
为什么该文件不存在以及如何构建linux-menuconfig
?
答案1
经过大量调试后,我发现在我的主机系统上安装文件夹/root/buildroot/output/
会导致问题。拆掉这个安装座也是make linux-menuconfig
可以的。
/root/buildroot/output/build
进一步的调试表明,在容器中安装主机文件夹是问题所在。我不知道为什么。
答案2
我使用在 Jenkins 代理上运行的 Docker 容器遇到了完全相同的问题。但是,当在本地计算机上执行容器并挂载到容器中时,也会出现问题。我只是想在这里记录一下我的经历。
Docker 容器中有准备好的构建数据,存储在/home/jenkins/data
.这些数据的符号链接是在/home/jenkins/workspace/<ourproject>/buildroot/output/build/
(安装到容器中的文件夹)中创建的。
如果我在 Jenkins 管道中使用“customWorkspace”,它会自动安装到 docker 容器中,如下所示:
$ docker run -t -d -u 1001:1001 -w /home/jenkins/workspace -v /home/jenkins/workspace:/home/jenkins/workspace:rw,z -v /home/jenkins/workspace@tmp:/home/jenkins/workspace@tmp:rw,z -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** ***.***.net/***/jenkins/build-images/***-builder:latest cat
我在这个安装的工作区文件夹中工作/home/jenkins/workspace/
(检查 buildroot 并尝试构建它),我得到与最初问题中提到的相同的错误:
jenkins@cec47254b4d1:~/workspace/clip/buildroot$ cat br.log
2022-08-11T17:43:47 >>> Buildroot 2021.02.9 Collecting legal info
2022-08-11T17:43:47 COPYING: OK (sha256: 9755181e27175cb3510b4da8629caa406fb355a19aa8e7d55f06bf8ab33323c4)
2022-08-11T17:43:47 /usr/bin/make -j1 O=/home/jenkins/workspace/clip/buildroot/output/beme HOSTCC="/usr/bin/gcc" HOSTCXX="/usr/bin/g++" syncconfig
2022-08-11T17:43:47 GEN /home/jenkins/workspace/clip/buildroot/output/beme/Makefile
2022-08-11T17:43:47
2022-08-11T17:43:47 *** Error during update of the configuration.
2022-08-11T17:43:47
2022-08-11T17:43:47 make[2]: *** [Makefile:1019: syncconfig] Error 1
2022-08-11T17:43:47 make[1]: *** [Makefile:592: /home/jenkins/workspace/clip/buildroot/output/beme/build/buildroot-config/auto.conf] Error 2
2022-08-11T17:43:47 make: *** [Makefile:84: _all] Error 2
但是,如果我没有使用“customWorkspace”,那么不在主机安装的文件夹中工作,而是在/home/jenkins/workspace
Docker 容器文件系统内的相同文件夹结构 ( ) 中工作,一切都工作得很好。如果未在从主机挂载到 Docker 容器的文件夹中创建链接,则创建指向准备好的数据的链接也可以。
正如我所提到的,M Y
我还尝试以特权模式启动 Docker 容器(将选项添加args "--privileged"
到 Jenkinsfile 中的 Docker Agent 选项)。这并没有解决我的问题。
已安装文件夹中的文件由用户 Jenkins 拥有,用户 ID 为 1001,与容器启动时使用的用户相同。
主要问题是调用make syncconfig
。
执行 amake clean
可以解决问题,因为准备好的构建数据被删除。
答案3
这听起来像是权限问题。用户权限(chmod 或 acl)、MAC(强制访问控制,通常是 selinux 或类似)或文件系统写入权限。我认为这可能是第三个,因为您的容器无法写入设备。
答案4
我通过以下方式解决了这个问题:
1-停止 lxc 。
lxc stop <container-name>
2-将安全特权调整为 true 。
lxc config set <container-name> security.privileged true
3-再次启动容器。
lxc start