Reputation: 4615
I have two sources files, library.f90
and toolbox.f90
in a separate directory. These are compiled into object files, which are linked when compiling the main file, aptly called main
. Initially, I had this Makefile:
TARGET = main
SRC = ${TARGET}.f95
FC = /usr/bin/gfortran
CFLAGS = -O2 -std=gnu -Wfatal-errors -I${INCLUDE}
INCLUDE = /home/ma/include
OBJ = library.o toolbox.o
OBJ_SRC = $(subst .o,.f90,${OBJ})
all: ${TARGET}
${TARGET}: ${SRC} ${OBJ}
@${FC} ${CFLAGS} -pedantic -Wall ${OBJ} ${SRC} -o ${TARGET}
${OBJ}:
@echo "Compiling $(subst .o,,$@)"
@${FC} ${CFLAGS} -c ${INCLUDE}/$(subst .o,.f90,$@) -o $@
clean:
@rm -vf ${TARGET} ${OBJ}
but this doesn't recompile library.o
(or toolbox.o
, respectively) when the source file library.f90
or toolbox.f90
is edited. I figured this was because the dependency was missing, so I tweaked the Makefile to look like this:
TARGET = main
SRC = ${TARGET}.f95
FC = /usr/bin/gfortran
CFLAGS = -O2 -std=gnu -Wfatal-errors -I${INCLUDE}
INCLUDE = /home/ma/include
OBJ = library.o toolbox.o
all: ${TARGET}
${TARGET}: ${SRC} ${OBJ}
@${FC} ${CFLAGS} -pedantic -Wall ${OBJ} ${SRC} -o ${TARGET}
${OBJ}: ${OBJ_SRC}
@echo "Compiling $(subst .o,,$@)"
@${FC} ${CFLAGS} -c ${INCLUDE}/$(subst .o,.f90,$@) -o $@
clean:
@rm -vf ${TARGET} ${OBJ}
This, however, throws the error
make: *** No rule to make target 'library.f90', needed by 'library.o'. Stop.
I don't understand this, because there isn't a rule to build ${SRC}
either, but make recognizes the dependency there and compiles the source file as expected.
Upvotes: 0
Views: 827
Reputation: 8140
In your first version, the object files' rule did not specify any prerequisite. That's why make did not check whether library.f90
had changed, and therefore did not recreate it.
Your second version is slightly better, but it now means that both library.o
and toolbox.o
depend on both library.f90
and toolbox.f90
, meaning that if either one is changed, both are rebuild, and if either one is missing, both builds will fail.
As for why your rule failed: It was looking for library.f90
in your current directory, but from the rule I deduce that the sources are in the subdirectory /home/ma/include
.
A better solution would be this:
${OBJ} : %.o : ${INCLUDE}/%.f90
${FC} ${CFLAGS} -c $^ -o $@
(I also removed the leading @
, as I find it very useful to see the actual command it's trying to run.)
Upvotes: 2