2

Following is the directory structure of my project:

                       expt-main
                       ---------
                       Makefile_main
                    /             \
         subdir-1                    subdir-2
         --------                    --------
         Makefile_1                  Makefile_2
         mod_codeA.f90               mod_code1.f90
         mod_codeB.f90               mod_code2.f90
         mod_codeC.f90               mod_code3.f90

Makefile_main:

export

SHELL = /bin/sh

F90     = mpxlf95

SRCDIRS = $(subdir-1) $(subdir-2)

all:
        @for DIR in ${SRCDIRS} ;

          do \
            back=`pwd`; \
            cd $$DIR ;\
            $(MAKE) ; status=$$? ; \
            if [ $$status != 0 ] ; then \
              echo "Exit status fro make was $$status" ; exit $$status ; \
            fi ; \
            cd $$back ; \
         done

-------------------------------------------------------------------------------

Makefile-1:

%.o: %.f90
        $(F90) $(F90FLAGS) -I$(subdir-2) -c $<

mod_codeA.o: mod_codeC.o $(subdir-2)/mod_code2.o

-------------------------------------------------------------------------------

Makefile-2:

PROG = $(exec)

subdir-1_objs = $(subdir-1)/mod_codeA.o mod_codeB.o mod_codeC.o

all: $(PROG)

$(PROG): $(subdir-2_objs) $(subdir-1_objs) -o $@ $(subdir-2_objs) $(subdir-1_objs)

---------------------------------------------------------------------------------

-

I've written the Makefile_main such that it compiles the codes (modules) in subdir-1 first and then the ones in subdir-2 and finally makes the executable. The issue: modules in subdir-1 uses modules from subdir-2 and in similar fashion, modules in subdir-2 uses those in subdir-1. My make is getting failed because the modules being used is in other directory. How to write a makefile which will take care of this issue that is, while compiling modules in subdir-1, whenever it encounters the need for an object file from subdir-2, it should switch to subdir-2 compile the necessary modules and return back to subdir-1 for further action?

jkp
  • 155
  • 2
  • 7

2 Answers2

2

If modules in different subdirectories need each other as you say, then this is not a good use of recursive Make.

Do away with Makefile-1 and Makefile-2, and let Makefile_main do all the work. (I can't tell you specifically how to change Makefile-main, since I don't do Fortran, I don't understand Makefile-2, and I don't see any dependency of modules in subdir-2 upon those in subdir-1).

Beta
  • 96,650
  • 16
  • 149
  • 150
  • Thanks Beta! The two sub-directories are two separate models that I am trying to integrate depending on a logic switch. Therefore, it won't be a clean way of combining the two sub-directories into one. The Makefile-2: PROG = $(exec) subdir-1_objs = $(subdir-1)/mod_codeA.o mod_codeB.o mod_codeC.o all: $(PROG) $(PROG): $(subdir-2_objs) $(subdir-1_objs) -o $@ $(subdir-2_objs) $(subdir-1_objs) mod_code1: mod_code3.o $(subdir-1)/mod_codeA.o ___________________________________________________________________ – jkp Oct 16 '12 at 05:21
  • @jkp, you don't have to combine the directories. Just combine the makefiles. – Beta Oct 16 '12 at 05:55
  • Thanks Beta! Have read the paper suggested by Massimiliano and understood what you are trying to say – jkp Oct 16 '12 at 11:46
1

If you want to stick to this directory layout and still keep three separated Makefiles, then you can use compiler flags to instruct the FORTRAN compiler to put module files into a common directory of your choice.

For instance using:

$ gfortran --version
GNU Fortran (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
Copyright (C) 2011 Free Software Foundation, Inc.

you can use -I and -J flags to instruct the compiler on:

  1. where to search for module files (.mod)
  2. where to put generated module files

That said I think that the suggestion given by Beta to join the Makefiles makes a lot of sense. To know some of the reasons why you should do that you can read this paper.

Finally, as your project seems not to be very large at this stage, I also suggest to take into consideration CMake as a build system, as it possibly provides a more convenient way of specifying dependencies between targets (as well as many other things).

Community
  • 1
  • 1
Massimiliano
  • 7,842
  • 2
  • 47
  • 62
  • @Beta &@Massimiliamo: The directory structure I described above is only a sample of my project. Indeed the project is very large: subdir-1 (200+ files) and subdir-2 (400+ files). The task is to combine two models which were built at separate centres and hence they have different rules (compilers, compiler & linking options) for building. I'll go through the paper and I am also working on suggestion given by Beta. But preferably, I am keen on having separate makefiles. Right now, I am looking into the possibility of making a soft link of all the codes in 1 dir and then using a single makefile. – jkp Oct 16 '12 at 11:08
  • @Massimiliamo:Can you please elaborate on the first part of your soultion (... use compiler flags ...) – jkp Oct 16 '12 at 11:17
  • @jkp You could use a rule like `gfortran -I -J ...`. The part `-I` tells `gfortran` to look for .mod in ``, while `-J` tells `gfortran` to put .mod files in ``. – Massimiliano Oct 16 '12 at 11:38
  • Thanks! I've read the paper and is informative. Will now work on making a single makefile. – jkp Oct 16 '12 at 11:45