使用Initramfs挂载根文件系统,编译过程multiple target patterns(多个目标匹配)问题的解决

时间:2022-08-04 16:29:31

############################################################################################

转载请注明出处

作者:Andoubi

原文链接:http://blog.csdn.net/andoubi/article/details/52052186

############################################################################################

编译内核前,配置内核用Initramfs挂载根文件系统,配置选项如下:

Genera setup-------------------------------->

  [ * ] Initial RAM filesystem and RAM disk (initramfs/initrd)support

( /home/myrootfs )Initramfs source file(s)

配置完毕,第一次编译OK。但是编译第二次时就出问题了,编译过程终止在了/user/Makefil里面,错误原因是多个目标匹配。详细信息如下:

<span style="font-size:18px;">root@localhost kernels]# make  CROSS_COMPILE=arm-arago-linux-gnueabi- ARCH=arm uImage
  CHK     include/linux/version.h
  CHK     include/generated/utsrelease.h
make[1]: “include/generated/mach-types.h”是最新的。
  CALL    scripts/checksyscalls.sh
  CHK     include/generated/compile.h
/home/ASM335/kernel/kernels/usr/Makefile:58: *** 多个目标匹配。 停止。
make: *** [usr] 错误 2</span>

我试着make clean和make disiclean,都不行,任然停在上面那个地方,同样的问题。我又试着把Initial RAM filesystem and RAM disk (initramfs/initrd)support取消,还是同样的错误。根据提示,问题出现在了/usr/Makefile的第58行,我打开/usr/目录下的Makefile,定位到58行,发现时一个变量:$(deps_initramfs)

其实后面网上看了很多博客,不少人也碰到了多目标匹配报错的问题,他们问题的原因大都由于作为目标的变量中(这些变量有时会是文件名或路径名)包含冒号( :)。大家都知道Makefile规则的格式是: 

目标:依赖

相关指令

若代表目标的变量中包含冒号,则会别识别成多个目标。于是,我打算把$(deps_initramfs)的值打印出来,看看里面是否含冒号。我在$(deps_initramfs)前面加上$(warning  $(deps_initramfs)),打印出了一大堆路径,占据了我的整个显示终端,仔细阅读这些路径,发现全是我根文件系统里的文件。猜测 $(deps_initramfs)的值是Initramfs source file(s)

里所有文件的绝对路径。

如何确定这些路径是否有冒号?从显示终端打印出的路径里用眼睛找?显然不可能!而且根文件系统文件比较多,路径也比较长,我的显示终端只能看到部分文件路径,好多跑前面去了,无法看到。我知道我的路径肯定不可能有冒号的,那么文件名呢?我试着在文件系统里新建一个文件,命名的时候加个冒号,结果报错,显然文件名也不能有冒号啊!何解?到这里我无从下手了。接着网上找资料!


直到后来。找到一篇博客,也是和我一样的问题,它介绍了一个解决方法。我照着它的方法来,发现还真管用。

它是用make -d命令打印出详细的编译信息,然后根据打印出的调试信息,找到与你问题相关部分(应该是最后几行吧,因为编译过程会停在有问题的地方)。我使用make -d命令,与/usr/Makefile相关的如下:

<span style="font-size:18px;">正在读入 makefile “/home/ASM335/kernel/kernels/usr/Makefile” (搜索路径) (no ~ expansion)...
正在读入 makefile “usr/.initramfs_data.cpio.d” (搜索路径) (no ~ expansion)...
/home/ASM335/kernel/kernels/usr/Makefile:58: *** 多个目标匹配。 停止。
正在中止失败的子进程 0x08acc7e8 PID 16580 
make: *** [usr] 错误 2
Removing child 0x08acc7e8 PID 16580 from chain.
</span>
学着那篇博客,我把/usr/.initramfs_data.cpio.d删除,然后重新编译,OK。问题解决。至于为什么会出现这个问题,一下子没弄明白。

参考博客:

http://blog.csdn.net/zjujoe/article/details/3185382


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

补充:

造成上述原因的确实是冒号的问题。我打开了/usr/.initramfs_data.cpio.d文件:

deps_initramfs := /home/asm335/kernel/kernels/scripts/gen_initramfs_list.sh \
/home/asm335/rootfs \
/home/asm335/rootfs/sys \
/home/asm335/rootfs/var \
/home/asm335/rootfs/var/spool \
/home/asm335/rootfs/var/spool/mail \
/home/asm335/rootfs/var/lib \
/home/asm335/rootfs/var/lib/misc \
/home/asm335/rootfs/var/lib/opkg \
/home/asm335/rootfs/var/lib/opkg/lists \
/home/asm335/rootfs/var/lib/opkg/info \
/home/asm335/rootfs/var/lib/opkg/info/libasound2.list \
.....................................
文件里面其实就是deps_initramfs变量的赋值!在打开的 .initramfs_data.cpio.d文件查找冒号,不找不知道,一找吓一跳啊,一大堆冒号:

使用Initramfs挂载根文件系统,编译过程multiple target patterns(多个目标匹配)问题的解决

再看看/usr/Makefile里deps_initramfs的位置


使用Initramfs挂载根文件系统,编译过程multiple target patterns(多个目标匹配)问题的解决


$(deps_initramfs)是一个目标啊,而deps_initramfs所代表的路径里又含有冒号,难怪会识别成多目标匹配!

另外,包含冒号的文件都在/etc/usb_modeswitch.d目录下(这些都是产品设备号?)

使用Initramfs挂载根文件系统,编译过程multiple target patterns(多个目标匹配)问题的解决

纠正一点:前面说文件名不能有冒号,这句话其实是错的。在Windows中文件名不能有冒号,但是在linux中是可以有冒号的!可以touch一个带名字冒号的文件试试看。


回过头来看:make是之所以会说多目标匹配,想必一定发现了多个目标。而网上好多文章都说Makefile里的目标包含冒号的话会导致这个问题。那么,解决问题的思路应该是:定位到出问题的Makefile里面的那个目标,然后想办法把相关变量的值导出来看看里面有没有冒号。在本次问题中,/usr/.initramfs_data.cpio.d文件中恰好就是deps_initramfs变量的值,直接搜索冒号即可。



一些疑惑:既然deps_initramfs所代表的路径包含冒号,那为什么第一次编译时OK的呢?而后面的编译就出问题? .initramfs_data.cpio.d 到底是什么文件,在使用initramfs挂载根文件系统时扮演什么角色。这些就得学习initramfs的知识了。这里推荐一篇博客:http://blog.chinaunix.net/uid-26009923-id-4072464.html