![使无法递归类似 autoconf 的项目](https://linux22.com/image/116948/%E4%BD%BF%E6%97%A0%E6%B3%95%E9%80%92%E5%BD%92%E7%B1%BB%E4%BC%BC%20autoconf%20%E7%9A%84%E9%A1%B9%E7%9B%AE.png)
我已经构建了一个在 ARMv7 芯片上运行的 Linux 系统,并且运行得非常好,但是我在本机构建方面遇到了问题。
首先,我通过在 x86-64 系统上进行交叉编译来引导,现在我想我应该在本机重建所有内容并运行测试等。
我遇到的问题会影响执行 autoconf 项目倾向于执行的某些操作的项目。我在多个组件中遇到了这个问题,例如 gmake 和 m4,但我在这里将重点关注 gmake(其他受影响项目的行为完全相同)。 Python、nginx、uwsgi、perl 等,构建没有任何问题。
这是我正在做的事情的基本顺序:
$ tar xjf ~/download/make-4.2.1.tar.bz2
$ cd make-4.2.1
$ ./configure
到目前为止,一切都运行良好 - 它找到了我用交叉编译器构建的本机编译器,并且还找到了所有交叉构建的工具(sed、gawk 等)。问题是,当我运行“make”时,它立即抛出错误:
$ make
make all-recursive
make[1]: Entering directory '/home/jan/tmp/make-4.2.1'
Making all in glob
make[1]: *** [Makefile:798: all-recursive] Error 1
make[1]: Leaving directory '/home/jan/tmp/make-4.2.1'
make: *** [Makefile:534: all] Error 2
正如您所看到的,它本质上根本没有做任何事情;它声称要进入 glob 子目录,但它永远不会到达那里。
跑步
$ make --trace
.. 产量:
Makefile:573: update target 'config.h' due to: stamp-h1
test -f config.h || rm -f stamp-h1
test -f config.h || make stamp-h1
Makefile:534: update target 'all' due to: config.h
make all-recursive
make[1]: Entering directory '/home/jan/tmp/make-4.2.1'
Makefile:798: target 'all-recursive' does not exist
fail=; \
if (target_option=k; case ${target_option-} in ?) ;; *) echo "am__make_running_with_option: internal error: invalid" "target option '${target_option-}' specified" >&2; exit 1;; esac; has_opt=no; sane_makeflags=$MAKEFLAGS; if { if test -z '1'; then false; elif test -n 'armv7l-unknown-linux-gnueabihf'; then true; elif test -n '4.2.1' && test -n '/home/jan/tmp/make-4.2.1'; then true; else false; fi; }; then sane_makeflags=$MFLAGS; else case $MAKEFLAGS in *\\[\ \ ]*) bs=\\; sane_makeflags=`printf '%s\n' "$MAKEFLAGS" | sed "s/$bs$bs[$bs $bs ]*//g"`;; esac; fi; skip_next=no; strip_trailopt () { flg=`printf '%s\n' "$flg" | sed "s/$1.*$//"`; }; for flg in $sane_makeflags; do test $skip_next = yes && { skip_next=no; continue; }; case $flg in *=*|--*) continue;; -*I) strip_trailopt 'I'; skip_next=yes;; -*I?*) strip_trailopt 'I';; -*O) strip_trailopt 'O'; skip_next=yes;; -*O?*) strip_trailopt 'O';; -*l) strip_trailopt 'l'; skip_next=yes;; -*l?*) strip_trailopt 'l';; -[dEDm]) skip_next=yes;; -[JT]) skip_next=yes;; esac; case $flg in *$target_option*) has_opt=yes; break;; esac; done; test $has_opt = yes); then \
failcom='fail=yes'; \
else \
failcom='exit 1'; \
fi; \
dot_seen=no; \
target=`echo all-recursive | sed s/-recursive//`; \
case "all-recursive" in \
distclean-* | maintainer-clean-*) list='glob config po doc w32' ;; \
*) list='glob config po doc ' ;; \
esac; \
for subdir in $list; do \
echo "Making $target in $subdir"; \
if test "$subdir" = "."; then \
dot_seen=yes; \
local_target="$target-am"; \
else \
local_target="$target"; \
fi; \
(CDPATH="${ZSH_VERSION+.}:" && cd $subdir && make $local_target) \
|| eval $failcom; \
done; \
if test "$dot_seen" = "no"; then \
make "$target-am" || exit 1; \
fi; test -z "$fail"
Making all in glob
make[1]: *** [Makefile:798: all-recursive] Error 1
make[1]: Leaving directory '/home/jan/tmp/make-4.2.1'
make: *** [Makefile:534: all] Error 2
我有点知道哪里失败了,但我不明白为什么。靠近底部有一个部分:
(CDPATH="${ZSH_VERSION+.}:" && cd $subdir && make $local_target)
如果我将其更改为:
(printf "hello\n" && CDPATH="${ZSH_VERSION+.}:" && printf "world\n" && cd $subdir && make $local_target)
..并重新运行整行,然后输出:
Making all in glob
hello
exit
换句话说,它似乎没有超越 CDPATH=... 部分,这让我感到困惑。我详细检查了至少一个其他项目,同样的逻辑也失败了。
所有组件都是新的(如果不是最新的稳定版本,也只是落后一两个版本(GCC 7.2.0、gmake 4.2.1、bash 4.4 等))。我正在使用 glibc,虽然它是一个 busybox 系统,但其中几个工具已被 coreutils 工具取代。而且,正如我之前提到的,我正在使用 bash(SHELL 设置为 /bin/bash)。
我用谷歌搜索了很多来寻找解决方案;我发现的唯一提示是针对与我的问题仅模糊相似的问题,解决方案是运行 autoreconf。我显然尝试过,但没有什么区别。
什么可能导致构建失败?
答案1
事实证明,这是由于 bash 交叉构建造成的。幸运的是,这个问题并没有影响在 ARM 平台上本地构建 bash 本身,因此一旦我构建了本地构建,运行所有测试,安装新的 bash 二进制文件并重新启动,问题就消失了。