0

私は、他の誰かが書いたものを解読しようとしている make ビルド システムを持っています。Redhat システムで実行するとエラーが発生しますが、solaris システムで実行するとエラーが発生しません。gmake のバージョンは同じメジャー リビジョンです (マイナー リビジョンで 1 つオフ)。

これは C プロジェクトをビルドするためのもので、make システムには、各ディレクトリのローカル Makefile によって継承されるグローバルな Makefile.global があります。

Makefile.global には、次で始まるすべてのターゲットが含まれています。

 all: $(LIB) $(BIN)

グローバルファイルには次の行もあります

 ifndef INCLUDE_GEN_DEPS
 sinclude $(GEN_DEPS)
 endif

LIB はライブラリをビルドし、BIN はバイナリをビルドします。

私が持っているターゲットを飛び降りる

 $(LIB) : $(GEN_LIB) 

 $(GEN_LIB) : $(GEN_DEPS) $(GEN_OBJS)
      $(AR) $(ARFLAGS) $(GEN_LIB) $(GEN_OBJS)
 $(GEN_DEPS) :
      @set -e; rm -f $@; \
      $(CC) $(CDEP_FLAG) $(CFLAGS) $(INCDIRS) `basename $@ | sed 's/\.d/\.c/' | sed 's,^,$(HOME_SRC)/,'` | sed 's,\(.*\)\.o: ,$(GEN_OBJDIR)/\1.o $@ :,g' > $@.tmp ; \
      cat $@.tmp > $@ ; \
      cat $@.tmp | cut -d: -f2 | grep '\.h' | sed 's,\.h,.h :,g' >> $@ ; \
      rm $@.tmp
  $(GEN_OBJS) :
       $(CC) $(CFLAGS) $(INCDIRS) -c $(*F).c -lmpi -o $@

これらは、私の質問に答えるために含める必要があるすべての関連するターゲットだと思います。

これらの変数の定義:

 CC = icc
 CDEP_FLAG = -M
 CFLAGS = various compiler flags ifdef type flags
 INCDIRS = include directory where all .h files are
 GEN_OBJDIR = /lib/objs
 HOME_SRC = .
 GEN_LIB = lib/$(LIB)
 GEN_DEPDIR=/lib/deps
 GEN_DEPS = $(addprefix $(GEN_DEPDIR)/,$(addsuffix .d,$(basename $(OBJS))))

これで必要なものはすべて網羅されていると思います。基本的に名前から自明です。

これで、オブジェクトとソースの依存関係を含む .d ファイルが /lib/deps に生成されます。つまり、utilities.a ライブラリの場合、utils.o と utils.c の依存関係スタックをすべて utils.d ファイルで取得します。

次のエラーが発生するため、そのファイルで生成されている構文エラーがあると思います。

 ../lib/deps/util.d:25: *** target pattern contains no '%'. Stop.
 gmake[2]: *** [all] Error 2
 gmake[1]: *** [all] Error 2
 gmake: *** [all] Error 2

エラーが依存関係の生成にあるのか、それともオブジェクト生成ターゲットなどのさらに下の部分にあるのかわかりません。

さらに情報が必要な場合はお知らせください。投稿に追加します

4

1 に答える 1

1

動作している (Solaris) マシンの lib/deps/util.d に書き込まれた内容と、動作していない (redhat) マシンの 25 行目に特に注意して比較します。

それらが同一である場合、問題は 1 回限りのマイナー バージョンの作成です。

それらが異なる場合、問題はおそらく実行されているツール間の違い、または (より可能性が高い) インストールされている icc の異なるバージョンです。

編集

復号化ルール:

$(GEN_DEPS) :
        @set -e; rm -f $@; \
        $(CC) $(CDEP_FLAG) $(CFLAGS) $(INCDIRS) `basename $@ | sed 's/\.d/\.c/' | sed 's,^,$(HOME_SRC)/,'` | sed 's,\(.*\)\.o: ,$(GEN_OBJDIR)/\1.o $@ :,g' > $@.tmp ; \
        cat $@.tmp > $@ ; \
        cat $@.tmp | cut -d: -f2 | grep '\.h' | sed 's,\.h,.h :,g' >> $@ ; \
        rm $@.tmp

このルールは、依存関係ファイルを に作成します。これは、に変更され$(GEN_DEPS)たすべてのソース ファイルに対応します。.c.d

@set -e; rm -f $@;

エラーが発生すると、続行するのではなく、失敗してこのルールをすぐに終了し、再生成しようとしているターゲットを削除します。

$(CC) $(CDEP_FLAG) $(CFLAGS) $(INCDIRS) `basename $@ | sed 's/\.d/\.c/' | sed 's,^,$(HOME_SRC)/,'` | sed 's,\(.*\)\.o: ,$(GEN_OBJDIR)/\1.o $@ :,g' > $@.tmp ;

生成しようとしている .d ファイルに対応する .c ファイルに対して icc を実行し、フラグを使用して、コンパイルする代わりに依存関係を自動的に生成します。このbasename $@ | sed 's/\.d/\.c/' | sed 's,^,$(HOME_SRC)/,' 句は、.d 名を .c 名に変換しています。

出力 (依存関係ルール) を sed script にパイプします。これにより、iccが依存する(オブジェクト) ファイルをsed 's,\(.*\)\.o: ,$(GEN_OBJDIR)/\1.o $@ :,g'見つけたすべてのものに依存するものとして、依存ファイル自体が追加されます。.oこれらすべてを一時ファイルに書き込みます。

cat $@.tmp > $@ ;

一時ファイルを出力依存ファイルにコピーします。

cat $@.tmp | cut -d: -f2 | grep '\.h' | sed 's,\.h,.h :,g' >> $@ ;

依存関係の 2 番目のコピーを依存関係ファイルに追加します。これは、ターゲットを取り除き、最初のヘッダーをターゲットにする小さなスクリプトによって変更されます。したがって、これは、ソース ファイルに表示される最初のヘッダー ファイルの追加の依存関係のセットを追加しています。

rm $@.tmp

一時ファイルを削除します。

于 2010-05-26T18:55:44.647 に答える