gnu make、vpath、余分なoファイルディレクトリ、混乱

gnu make、vpath、余分なoファイルディレクトリ、混乱

私は、Fortran ソース コードから 2 つの異なるライブラリを構築しようとしています。1 つは OMP サポート付き、もう 1 つはサポートなしです。したがって、同じソースからの %.o ファイルは、コンパイラ フラグによって異なります。1 つのソース ファイルを変更/再コンパイルする場合、ar はライブラリを再構築するためにすべての o ファイルを必要とします。すべてのソース ファイルを再コンパイルしないようにするには、変更されていないソース ファイルの o ファイルを 2 つの異なるディレクトリに保存します。1 つは o ファイルに OMP サポートが含まれ、もう 1 つは含まれません。ライブラリが最終的に配置されるディレクトリにそのための makefile があるのはうれしいことです。

ただし、vpath 変数の動作のため、単一のコマンドでライブラリを再構築することはできません。以下は make ファイルです。

   SRC :=
   FORTRAN  = ifort
   OPTSSEQ = -mkl=sequential -DThreadUnSafe -warn nounused -warn declarations -O3 -DTIMEDETAIL
   DRVOPTS  = $(OPTS)
   NOOPT    =
   LOADER   = ifort
   LOADOPTS =
   kernel=$(shell uname -r)
   ARCH     = ar
   ARCHFLAGS= cr
   RANLIB   = ranlib
   LibName=Lib_LM_$(FORTRAN)_$(kernel)_1.0.a
  .SUFFIXES:
  .SUFFIXES: .f90 .o
   include Moduls.mk
   vpath %.f90 src/
   vpath %.o NoOMP/
   OBJS = $(patsubst %.f90,%.o,$(SRC))
   $(LibName): $(OBJS)
      $(ARCH) $(ARCHFLAGS) $@ $?
      $(RANLIB) $@
   %.o : %.f90
      $(FORTRAN) $(OPTSSEQ) -c $? -o $(addprefix NoOMP/,$@)
   clean:
     -rm *.mod
     -rm NoOMP/*.o
     -rm *.smod
     -rm $(LibName)

これにより、すべての %.f90 ファイルが src/ から読み込まれ、すべての %.o ファイルが NoOMP/ に書き込まれるため、"make clean" の後にすべての %.o ファイルのビルドが成功します。ただし、%.o ファイルの "NoOMP" プレフィックスが削除されるため、アーカイブのビルドは失敗します。したがって、ar は %.o ファイルが見つからないというエラーを出力します。"make" を再度実行した場合にのみ、%.o ファイルに NoOMP プレフィックスが付くため、アーカイブがビルドされます。アーカイブ ビルド ラインにプレフィックス コマンドを追加すると、最初からビルドする場合は正常に機能します。ただし、1 つのファイルのみが変更された場合、変更されていないファイルに "NoOMP/NoOMP/" プレフィックスが付くため、再び中止します。

これは非常に迷惑ですが、マニュアルを理解した限りでは、これが GNU make のデフォルトの動作です。私が間違っている場合、makefile を修復するにはどうすればよいでしょうか。正しい場合、この問題を回避するにはどうすればよいでしょうか。

答え1

解決済み

例は行を変更すると機能します

    $(ARCH) $(ARCHFLAGS) $@ $?

    $(ARCH) $(ARCHFLAGS) $@ $(addprefix NoOMP/,$?)

上記でこの解決策を除外しましたが、私の試みは$^ではなくに基づいています$?。最初の方法では古い %.o ファイルと新しい %.o ファイルからアーカイブ全体が再構築されますが、最後の方法では既存のアーカイブが新しい​​ %.o ファイルでのみ更新されます。古い %.o ファイルと新しい %.o ファイルからアーカイブ全体が再構築されると、古い %.o ファイルのプレフィックスは間違っており、新しい %.o のプレフィックスは正しいものになります。したがって、新しくコンパイルされた %.o ファイルでアーカイブを更新して古い %.o ファイルを除外すると、この問題を回避できます。

乾杯

関連情報