Makefile-来回编译

Makefile-来回编译,makefile,fortran90,Makefile,Fortran90,以下是我的项目的目录结构: expt-main --------- Makefile_main / \ subdir-1 subdir-2 -------- --------

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

                       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)

---------------------------------------------------------------------------------
导出
SHELL=/bin/sh
F90=mpxlf95
SRCDIRS=$(细分利率-1)$(细分利率-2)
全部:
@对于${SRCDIRS}中的DIR;
做\
back=`pwd`\
cd$$DIR\
美元(制造);状态=$\
如果[$$status!=0];然后\
echo“make的退出状态为$$status”;退出$$状态\
fi\
cd$$back\
完成
-------------------------------------------------------------------------------
Makefile-1:
%.o:%.f90
$(F90)$(F90标志)-I$(细分市场-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
全部:$(进度)
$(项目):$(次级开发区-2_-objs)$(次级开发区-1_-objs)-o$@$(次级开发区-2_-objs)$(次级开发区-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以进行进一步的操作?

如果不同子目录中的模块如您所说的那样需要彼此,那么这不是递归Make的一个好用法


取消
Makefile-1
Makefile-2
,让
Makefile\u main
完成所有工作。(我无法具体告诉您如何更改
Makefile main
,因为我不使用Fortran,我不理解
Makefile-2
,也看不到subdir-2中的模块与subdir-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
标志指示编译器:

  • 在何处搜索模块文件(.mod)
  • 将生成的模块文件放在何处
  • 也就是说,我认为作者提出的加入makefile的建议非常有意义。了解一些你应该这样做的原因,你可以阅读


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

    谢谢!这两个子目录是两个独立的模型,我正试图根据逻辑开关集成它们。因此,将两个子目录合并为一个子目录并不是一种干净的方法。2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:5:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2:2(execc)subdir-1)mod-coda.o-codb.o.o mod.o.o.o.o.o.o.o.o.o.o.o.o所有:所有:所有:所有:所有:所有:所有:::$(PROG(PROG)所有:::$(PROG(PROG)(5)(5)(5)(3)(PROG)(PROG)(PROG)(PROG)(PROG)(PROG)(PROG)(PROG)(PROG)(PROG)(PROG)(PROG)(PROG)(PROG)(PROG)(PROG):(PROG):(PROG):(PROG)(2)元_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu@jkp,您不必合并目录。只需合并makefile。谢谢Beta!已经阅读了马西米利亚诺建议的论文,并且理解了你想要表达的意思say@Beta&@Massimiliamo:我上面描述的目录结构只是我项目的一个示例。实际上,该项目非常大:subdir-1(200多个文件)和subdir-2(400多个文件)。任务是将两个在不同中心构建的模型结合起来,因此它们具有不同的构建规则(编译器、编译器和链接选项)。我会仔细阅读这篇论文,我也在研究Beta给出的建议。但是,我更希望有单独的makefile。现在,我正在研究在1 dir中创建所有代码的软链接,然后使用单个makefile的可能性。@Massimiliamo:您能详细说明您的解决方案的第一部分吗(…使用编译器标志…)@jkp您可以使用类似
    gfortran-I-J…
    的规则。部分
    -I
    告诉
    gfortran
    中查找.mod,而
    -J
    告诉
    gfortran
    中放置.mod文件。谢谢!我读过这篇文章,内容丰富。现在将制作一个makefile.Oops!我删除了我以前的Q:(我希望我最近的Q给出了整个画面:(