从make

时间:2018-03-31 21:09:39

标签: shell makefile gnu-make

我在旧的Android手机上在一个chrooted环境中(可能是问题的一部分)从头开始构建Linux,在SD卡上安装的ext4分区上。我设法交叉编译安装我需要在本地构建的大部分东西。我安装了所有内容的最新版本。

现在是时候制作一些没有交叉编译的东西。

我决定制作并安装inetutils-1.9.4。

配置运行得很好,但是当我尝试制作时,它只是失败而没有说一句话:

# make                                                                         
make  all-recursive
make[1]: Entering directory '/tmp/inetutils_build'
Making all in lib
make[1]: *** [Makefile:1491: all-recursive] Error 1
make[1]: Leaving directory '/tmp/inetutils_build'
make: *** [Makefile:1428: all] Error 2

所以我看了一下生成的makefile,它包含这个规则:

$(am__recursive_targets):
    @fail=; \
    if $(am__make_keepgoing); then \
      failcom='fail=yes'; \
    else \
      failcom='exit 1'; \
    fi; \
    dot_seen=no; \
    target=`echo $@ | sed s/-recursive//`; \
    case "$@" in \
      distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
      *) list='$(SUBDIRS)' ;; \
    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; \
      ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
      || eval $$failcom; \
    done; \
    if test "$$dot_seen" = "no"; then \
      $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
    fi; test -z "$$fail"

插入一些回声后,我发现带有$(am__cd)的行失败了,并且运行的ored表达式会以失败的方式退出脚本。所以我试图找出哪个命令在那里失败,并在括号内插入一些回声,如下所示:

  (echo "1" && $(am__cd) $$subdir && echo "2" && $(MAKE) $(AM_MAKEFLAGS) $$local_target && echo "3") \
  || eval $$failcom; \

现在打印:

make  all-recursive
make[1]: Entering directory '/tmp/inetutils_build'
Making all in lib
1
make[1]: *** [Makefile:1491: all-recursive] Error 1
make[1]: Leaving directory '/tmp/inetutils_build'
make: *** [Makefile:1428: all] Error 2

但是我想确保回声没有失败,所以我又加了一个。

  (echo "1" && echo "1b" && $(am__cd) $$subdir && echo "2" && $(MAKE) $(AM_MAKEFLAGS) $$local_target && echo "3") \
  || eval $$failcom; \

我试过的时候。它再打印一次。

我还没有放弃。

我想确保echo在脚本中真的失败了。 所以我尝试在有问题的命令之前在脚本中添加新语句:

  (echo "A" && echo "B"); \
  (echo "X" || echo "Y"); \
  echo "N" && echo "M"; \
  (echo "C" && echo "D"); \

打印:

A
X
Y
N
M
C
D

然后打印

1
1b
2

开始建设!

我在这里完全不解。为什么前两个括号表达式失败,但不是最后一个? 实际上,即使写(true) || echo "ooops"也会失败,但是当我将它粘贴到ored X Y括号下面时就不会失败。显然,我们的括号和#34;修复了"它,无论它被困在哪个状态。

发生了什么事?

应该注意我无法在shell提示符下重现这一点,但只有插入到makefile中的语句才会这样做。

编辑:

通过从开头删除@,它回显命令但没有别的,没有错误:

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 'arm-unknown-linux-gnueabi'; then true; elif test -n '4.2' && test -n '/tmp/inetutils_build'; 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='lib libinetutils libtelnet libicmp libls src telnet telnetd ftp ftpd talk talkd whois ping ifconfig doc man tests' ;; \
  *) list='lib libinetutils libtelnet libicmp libls src telnet telnetd ftp ftpd talk talkd whois ping ifconfig doc man tests' ;; \
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"

编辑2:

感谢您的提示,我在规则的开头添加了set -x。这些是命令:

+ fail=
+ target_option=k
+ case ${target_option-} in
+ has_opt=no
+ sane_makeflags=w
+ test -z 1
+ test -n arm-unknown-linux-gnueabi
+ true
+ sane_makeflags=-w
+ skip_next=no
+ for flg in $sane_makeflags
+ test no = yes
+ case $flg in
+ case $flg in
+ test no = yes
+ failcom='exit 1'
+ dot_seen=no
++ echo all-recursive
++ sed s/-recursive//
+ target=all
+ case "all-recursive" in
+ list='lib libinetutils libtelnet libicmp libls src telnet telnetd ftp ftpd talk talkd whois ping ifconfig doc man tests'
+ for subdir in $list
+ echo 'Making all in lib'
Making all in lib
+ test lib = .
+ local_target=all
+ CDPATH=:
+ eval exit 1
++ exit 1

0 个答案:

没有答案