需要在Makefile中灵活定义目标依赖项

时间:2019-02-01 15:56:51

标签: makefile

我想在Makefile中放置两个目标,exec1exec2exec1的依赖项应该看起来像

exec1: aux1.o bal.o exec1.f90
bal.o: aux1.o bal.f90

exec2之类的

exec2: aux2.o bal.o exec1.f90
bal.o: aux2.o bal.f90

长话短说:我需要make来了解bal.o具有不同的依赖关系,具体取决于正在构建exec1还是exec2。如何在我的Makefile中“解释”此内容?

问题在于,如果我尝试构建exec2,则必须构建aux1.o 。原因是aux1.f90具有与aux2.f90中的模块同名的模块,如果首先将aux1.f90编译为aux1.o,则bal.f90的编译将从aux1.f90中获取其模块。真正需要的是aux2.f90,并且会有质量混乱。

3 个答案:

答案 0 :(得分:2)

您应该使用单独的Makefile并使用依赖于目标的Makefile(“递归”)。

主要Makefile

exec1 exec2:
    $(MAKE) -f Makefile.$@

您有Makefile.exec1

exec1: aux1.o bal.o exec1.f90
    @echo "$^ => $@"

bal.o: aux1.o bal.f90
    @echo "$^ => $@"

还有Makefile.exec2

exec2: aux2.o bal.o exec1.f90
    @echo "$^ => $@"

bal.o: aux2.o bal.f90
    @echo "$^ => $@"

测试(在touch aux2.o bal.f90之后):

$ gmake -s exec1
aux1.o bal.f90 => bal.o
aux1.o bal.o exec1.f90 => exec1
$ gmake -s exec2
aux2.o bal.f90 => bal.o
aux2.o bal.o exec1.f90 => exec2

(我正在使用FreeBSD,在其上,GNU make是gmake-假设您使用GNU make,而-s则禁止其“调试”消息)。

我希望这个主意很清楚。

答案 1 :(得分:2)

纯GNU make解决方案:

exec1: aux1.o bal.o exec1.f90

bal.o: $(if $(filter exec1,${MAKECMDGOALS}),aux1.o,aux2.o) bal.f90
# It will fail if someone will try building BOTH `exec1` and `exec2`
# If you care about this case, let's put some safeguards in:
ifeq ($words $(filter exec1 exec2,${MAKECMDGOALS}),2)
  $(error You cannot build exec1 and exec2 simultaneously)
endif

答案 2 :(得分:1)

static命令发现许多有趣的意外用途。你是一个。

如果您可以分别构建makebal1.o,这是最愚蠢的做法,但是我想这对您没有用,否则您几乎不会问这个问题。

在您的情况下,我会尝试这样做:分别构建bal2.obal1.o,即使它们(本身)无法满足您的情况。 然后,在制表符缩进的生成命令,临时建立一个名为bal2.o的符号链接,该链接指向bal.obal1.o。链接完成其职责后,将其删除。

例如:

bal2.o

exec1: aux1.o bal1.o exec1.f90; rm -f aux2.o && ln -s bal1.o bal.o && command-to-build-exec1 && rm bal.o bal1.o: aux1.o bal.f90 .PHONY: bal.o 行是最不重要的。您可以忽略它,但是如果您的.PHONY是GNU Make,则它通知GNU Make将不会构建任何实际的文件make。 )

如果需要,分号bal.o可以用换行符后接水平制表符代替,但是我不知道如何使Stack Overflow正确地表示制表符。分号有效。

当然,您将用特定情况下的命令替换;