os1
os1

Reputation: 490

How to save modules in a separate directory using a makefile

I am compiling some of my own FORTRAN code using a simple makefile but dislike having my code directory cluttered up with *.mod and *.o files. Is there a simple way I can edit my makefile so that these compiled files are placed in a separate directory (something like ./obj/ )? I've searched through here and google to find a few examples but I can't get any of them working. Probably as I have very little experience of makefiles and fortran (have only coded C until now).

Below is my current makefile:

LIBBASE=/my/lib/dir/

HDF5LIB=$(LIBBASE)/hdf5/lib
HDF5INCLUDE=$(LIBBASE)/hdf5/include

MYLIB_LIB=$(LIBBASE)/mylib
MYLIB_INCLUDE=$(LIBBASE)/mylib

LIBS=-L$(HDF5LIB) -lhdf5 -lhdf5_fortran -lhdf5hl_fortran \
     -L$(MYLIB_LIB) -lmylib

INC=-I./ -I$(HDF5INCLUDE) -I$(MYLIB_INCLUDE) -DINCLUDE_MYLIB

# Compiler
F90     =   ifort
CC      =   ifort

FLAGS   =   -g -O2 -openmp

# ------ No machine-specific paths/variables after this  -----

FSOURCE = my_structures my_constants my_utils my_prog MainMOD
OBJECTS = my_structures.o my_constants.o my_utils.o my_prog.o

all:    $(FSOURCE)

MainMOD: MainMOD.F90 
    $(F90) $(FLAGS) -o  $@ $(INC) MainMOD.F90 $(LIBS) $(OBJECTS)
my_structures: my_structures.F90 
    $(F90) $(FLAGS) -c $(INC) imager_structures.F90 $(LIBS) 
my_prog: my_prog.F90
    $(F90) $(FLAGS) -c $(INC) my_prog.F90 $(LIBS) 
my_constants: my_constants.F90 
    $(F90) $(FLAGS) -c $(INC) preproc_constants.F90 $(LIBS) 
utils: my_utils.F90 
    $(F90) $(FLAGS) -c $(INC) my_utils.F90 $(LIBS) 

clean:
    rm -f $(FSOURCE) $(OBJECTS)

# Compilation rules


$(OBJ_DIR)\\%.o: %.F90
    $(F90) $(FLAGS) -c $@ $<

# Rule to prevent make from identifying Fortran .mod files as Modula2 source
# files
%.o : %.mod

Upvotes: 1

Views: 1656

Answers (1)

Alexander Solovets
Alexander Solovets

Reputation: 2507

First, the way Makefile works is based on that targets and sources are in the same directory. For sure, you can do the opposite, but Makefile wasn't designed with that option in mind so you'll have to make your recipes a bit ugly.

Now, if I really wanted to have object files in a separate directory and wasn't bounded by using make only, I'd use cmake which in contrast to make assumes that sources are separated from the build files.

If you still want to go with make, then I think you need to fix one thing. From

$(OBJ_DIR)\\%.o: %.F90

to

$(OBJ_DIR)/%.o: %.F90

Also,

%.o : %.mod

is not required if you put

.SUFFIXES:

on the very first line of the file. This will turn off all implicit rules since you don't use them anyway.

Upvotes: 1

Related Questions