gnu make、vpath、额外的 o 文件目录、混乱

gnu make、vpath、额外的 o 文件目录、混乱

我正在尝试从 Fortran 源代码构建两个不同的库,一个支持 OMP,另一个不支持。因此,来自同一源的 %.o 文件根据编译器标志的不同而有所不同。当更改/重新编译一个源文件时,ar 仍然需要所有 o 文件来重建库。为了避免重新编译所有源文件,我想将未更改的源文件中的 o 文件存储在两个不同的目录中,一个目录包含 omp 支持的 o 文件,另一个目录不包含 omp 支持。我很高兴必须在库最终所在的目录中生成文件。

但是,由于 vpath 变量行为,我无法在单个命令中重建库。这是制作文件:

   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)

这会导致在“make clean”后成功构建所有 %.o 文件,因为所有 %.f90 文件均从 src/ 读取,并且所有 %.o 文件均写入 NoOMP/。但是,构建存档失败,因为 %.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 文件可以避免该问题。

干杯

相关内容