我想在Makefile中放置两个目标,exec1
和exec2
。 exec1
的依赖项应该看起来像
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,并且会有质量混乱。
答案 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
命令发现许多有趣的意外用途。你是一个。
如果您可以分别构建make
和bal1.o
,这是最愚蠢的做法,但是我想这对您没有用,否则您几乎不会问这个问题。
在您的情况下,我会尝试这样做:分别构建bal2.o
和bal1.o
,即使它们(本身)无法满足您的情况。 然后,在制表符缩进的生成命令,临时建立一个名为bal2.o
的符号链接,该链接指向bal.o
或bal1.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正确地表示制表符。分号有效。
当然,您将用特定情况下的命令替换;
。