0

環境関連:

  • NFS3を実行しているSolarisNFSファイルサーバー
  • LinuxまたはSolaris環境でエラーが発生する
  • GNUMake3.82の使用
  • 重要な場合は、SunStudioコンパイラを使用する

これは、私が見ているビルドの非常に単純化された例です。

all: ${list of shared objects to build}
  @do whatever

lib1.so: ${1s objects}
lib2.so: ${2s objects}
lib3.so: ${3s objects}
#...

%.so:
  $(call CHECK_DEPENDENCIES_EXIST)
  @${LD} ${LDFLAGS} ${^} -o ${@}

%.o : %.c
  @do stuff

%.o : %.cc
  @do stuff

define CHECK_DEPENDENCIES_EXIST =
$(if $(realpath ${^}),,$(warning No dependencies specified for ${@})false)
endef

短くて甘い:$(realpath x y z)(x / y / zが存在する場合は返されます。シンボリックリンクを含まない絶対パスを返します)は、状況によってはリストからファイルを削除します。これはNFSに関係していると思います。どのターゲットが失敗するかは予測できません。過去10回成功すると、ターゲットが失敗することがあります。マクロを@false削除すると、ビルドはエラーなしで続行されます。つまり、リンカーは、おそらく欠落しているファイルについて文句を言いません。

引き出された説明は割愛します。マクロはデバッグに役立ちます。

4

1 に答える 1

2

gmakeにバグがあることが判明しました。GNU Make 3.82ソースから、、、function.cまたは2026行目あたり:

while ((path = find_next_token (&p, &len)) != 0 ) {
/* ... */
    if (
#ifdef HAVE_REALPATH
         realpath (in, out)
#else
         abspath (in, out) && stat (out, &st) == 0
#endif
       )
    {
      /* ... */
    }
  }
}
/* ... */

場合によっては、へのさまざまな呼び出しrealpathが中断されることがあります(EINTR); このコードには何もチェックされてerrnoいないため、黙って失敗します。

したがって、ファイルが存在しなかったのではなく$(realpath ...)、シグナル(おそらくgmakeその完了をシグナルする子インスタンスなど)によって中断されていたため、この関数はその種のイベントから回復するように設計されていませんでした。

問題を解決するには:

while ((path = find_next_token (&p, &len)) != 0 ) {

...になります:

while ( errno == EINTR || (path = find_next_token (&p, &len)) != 0 ) {

||ショートカットして、次のトークンに進むのを防ぎます。

于 2013-02-26T21:26:49.113 に答える