
私は、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 ファイルを除外すると、この問題を回避できます。
乾杯