gnu make, vpath, 추가 o 파일 디렉토리, 혼란

gnu make, vpath, 추가 o 파일 디렉토리, 혼란

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 파일을 제외하면 문제를 피할 수 있습니다.

건배

관련 정보