Makefile - 来回编译

时间:2012-10-15 10:30:58

标签: makefile fortran90

以下是我项目的目录结构:

                       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)

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

-

我编写了Makefile_main,它首先编译subdir-1中的代码(模块),然后编译subdir-2中的代码(模块),最后生成可执行文件。问题:subdir-1中的模块使用来自subdir-2的模块,并且以类似的方式,subdir-2中的模块使用subdir-1中的模块。我的make失败了,因为正在使用的模块在其他目录中。如何编写一个makefile来处理这个问题,即在编译subdir-1中的模块时,每当遇到来自subdir-2的对象文件的需要时,它应该切换到subdir-2编译必要的模块并返回回到subdir-1进行进一步的行动?

2 个答案:

答案 0 :(得分:2)

如果你说的不同子目录中的模块彼此需要,那么这不是一个很好的使用递归Make。

取消Makefile-1Makefile-2,让Makefile_main完成所有工作。 (我不能具体告诉你如何更改Makefile-main,因为我不做Fortran,我不理解Makefile-2,我没有看到subdir-2中模块的依赖性在子目录-1)中。

答案 1 :(得分:1)

如果你想坚持这个目录布局并且仍然保留三个独立的Makefile,那么你可以使用编译器标志来指示FORTRAN编译器将模块文件放入你选择的公共目录中。

例如使用:

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

您可以使用-I-J标志来指示编译器:

  1. 搜索模块文件(.mod)的位置
  2. 放置生成的模块文件的位置
  3. 那就是说我认为Beta加入Makefiles的建议很有意义。要了解您应该这样做的一些原因,请阅读this paper

    最后,由于您的项目在此阶段似乎不是很大,我还建议将CMake作为构建系统考虑,因为它可能提供了一种更方便的方法来指定目标之间的依赖关系(如以及许多其他事情。)