web-dev-qa-db-ja.com

autoconfのようなプロジェクトでは再帰できないようにする

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 = ...の部分を通過していないようで、混乱します。私は少なくとも1つの他のプロジェクトを詳細にチェックしましたが、それも同じロジックで失敗します。

すべてのコンポーネントは新しいものです(最新の安定バージョンではないにしても、1つまたは2つのバージョンが遅れています(GCC 7.2.0、gmake 4.2.1、bash 4.4など))。私はglibcを使用しており、busyboxシステムですが、いくつかのツールがcoreutilsツールに置き換えられています。そして、前に述べたように、私はbashを使用しています(シェルを/ bin/bashに設定)。

私は解決策を探すためにかなりググってみました。私が見つけた唯一のヒントは、私のものと漠然と似ているだけの問題であり、解決策はautoreconfを実行することでした。私は明らかにそれを試しましたが、違いはありませんでした。

ビルドが失敗する原因は何ですか?

2
cypheratheist

これは、bashがクロスビルドされたことが原因であることが判明しました。幸い、この問題はARMプラットフォームでのbash自体のネイティブビルドには影響しなかったため、ネイティブビルドをビルドしたら、すべてのテストを実行し、新しいbashバイナリをインストールして再起動すると、問題は解消されます。

2
cypheratheist