
Estoy intentando crear dos bibliotecas diferentes a partir del código fuente de Fortran, una con soporte OMP y la otra sin él. Por lo tanto, los archivos %.o de la misma fuente difieren dependiendo de los indicadores del compilador. Al cambiar/recompilar un archivo fuente, todavía necesita todos los archivos O para reconstruir la biblioteca. Para evitar volver a compilar todos los archivos fuente, quiero almacenar los archivos o de los archivos fuente sin cambios en dos directorios diferentes, uno con archivos o que incluyen soporte omp y el otro sin. Estoy feliz de tener archivos make para eso en ese directorio donde finalmente se encuentran las bibliotecas.
Sin embargo, no puedo reconstruir la biblioteca con un solo comando debido al comportamiento de la variable vpath. Aquí está el archivo de creación:
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)
Esto da como resultado la compilación exitosa de todos los archivos %.o después de "hacer limpieza", ya que todos los archivos %.f90 se leen desde src/ y todos los archivos %.o se escriben en NoOMP/. Sin embargo, la creación del archivo falla porque se elimina el prefijo "NoOMP" en los archivos %.o. Por lo tanto, ar se queja de que no puede encontrar los archivos %.o. Sólo si ejecuto "make" nuevamente, el archivo se compila porque entonces los archivos %.o tienen el prefijo NoOMP. Agregar un comando de prefijo a la línea de compilación del archivo funciona bien si se compila desde cero. Sin embargo, si solo ha cambiado un archivo, los archivos que no han cambiado tendrán el prefijo "NoOMP/NoOMP/", lo que provocará una nueva cancelación.
Si bien esto es terriblemente molesto, hasta donde entendí el manual, ese es el comportamiento predeterminado de GNU make. Si me equivoco, ¿cómo puedo reparar el archivo MAKE? Si me equivoco, ¿cómo puedo evitar este problema?
Respuesta1
Resuelto
los ejemplos funcionan al cambiar la línea
$(ARCH) $(ARCHFLAGS) $@ $?
a
$(ARCH) $(ARCHFLAGS) $@ $(addprefix NoOMP/,$?)
Anteriormente había descartado esta solución, pero mi prueba se basó en en $^
lugar de $?
. Mientras que el primero reconstruirá todo el archivo a partir de archivos %.o nuevos y antiguos, el último solo actualizará el archivo existente con archivos %.o nuevos. Al reconstruir todo el archivo a partir de archivos %.o antiguos y nuevos, los archivos %.o antiguos tendrán el prefijo incorrecto y los nuevos el correcto. Por lo tanto, excluir archivos %.o antiguos actualizando el archivo con archivos %.o recién compilados evita ese problema.
Salud