Fortran 소스 코드에서 두 개의 서로 다른 라이브러리를 구축하려고 합니다. 하나는 OMP를 지원하고 다른 하나는 지원하지 않습니다. 따라서 동일한 소스의 %.o 파일은 컴파일러 플래그에 따라 다릅니다. 소스 파일을 변경/재컴파일할 때 ar에는 라이브러리를 다시 빌드하기 위해 여전히 모든 파일이 필요합니다. 모든 소스 파일을 다시 컴파일하는 것을 피하기 위해 변경되지 않은 소스 파일의 o 파일을 두 개의 다른 디렉토리에 저장하고 싶습니다. 하나는 omp를 지원하는 o 파일을 포함하고 다른 하나는 omp를 지원하지 않습니다. 라이브러리가 끝나는 디렉토리에 파일을 생성해야 해서 기쁘네요.
그러나 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 접두사가 있으므로 아카이브가 빌드됩니다. 처음부터 빌드하는 경우 아카이브 빌드 라인에 접두사 명령을 추가하면 잘 작동합니다. 그러나 단일 파일만 변경된 경우 변경되지 않은 파일에는 "NoOMP/NoOMP/" 접두사가 포함되어 또 다른 중단이 발생합니다.
이것은 매우 짜증나는 일이지만, 내가 매뉴얼을 이해하는 한 이는 GNU make의 기본 동작입니다. 내가 틀렸다면 makefile을 어떻게 고칠 수 있고, 내가 옳다면 이 문제를 어떻게 피할 수 있습니까?
답변1
해결됨
이 예제는 줄을 변경할 때 작동합니다.
$(ARCH) $(ARCHFLAGS) $@ $?
도착하다
$(ARCH) $(ARCHFLAGS) $@ $(addprefix NoOMP/,$?)
위에서는 이 솔루션을 배제했지만 $^
대신 내 실험은 이를 기반으로 했습니다 $?
. 첫 번째는 이전 및 새 %.o 파일에서 전체 아카이브를 재구축하는 반면, 마지막 것은 새 %.o 파일로 기존 아카이브만 업데이트합니다. 이전 %.o 파일과 새 %.o 파일에서 전체 아카이브를 재구축할 때 이전 %.o 파일은 잘못된 접두어를 가지며 새 파일은 올바른 접두어를 갖게 됩니다. 따라서 새로 컴파일된 %.o 파일로 아카이브를 업데이트하여 이전 %.o 파일을 제외하면 문제를 피할 수 있습니다.
건배