我目前面临以下问题:
如何创建一个全局Makefile来构建不同的应用程序(可能使用 来自我的源代码树的相同或不同的库? 目前我只有一个应用程序,我所做的就是:
include $(ROOT)/SETUP.MAK
SUBDIRS = \
lib1 \
lib2 \
app1
include $(ROOT)/RULES.MAK
应用程序是按原样构建的。但是现在我会有更多 应用程序和其他库。我不想创造 每个应用程序的单独Makefile,因为库/代码库是 同样适用于不同的应用。这就是我试过的:
include $(ROOT)/SETUP.MAK
ifeq ($(strip $(MAKECMDGOALS)),proj1)
SUBDIRS = \
lib1 \
lib2 \
app1
endif
ifeq ($(strip $(MAKECMDGOALS)),proj2)
SUBDIRS = \
lib1 \
lib2 \
lib3 \
app2
endif
.PHONY: proj1
proj1: $(SUBDIRS)
.PHONY: proj2
proj2: $(SUBDIRS)
include $(ROOT)/RULES.MAK
但问题是make进入第一个目录“lib1”并尝试构建 “lib1”,但“lib1”中没有“proj1”的规则。 这是如何正确完成的?我在命令行用“make proj1”调用make。
注意:SUBDIRS的制作规则位于文件RULES.MAK
中编辑1: 以下是SUBDIRS的规则:
# entering dir c; calculating deps; leaving dir c; entering dir c; making blah; leaving dir c
$(SUBDIRS) :
# call as make NOT_RECURSIVE=1 to avoid recursion
ifndef NOT_RECURSIVE
ifneq ($(MAKEFILE_DIR),./) # some makefile path given
$(VERBOSE) $(MKDIR) $@
ifneq ($(call isabspath, $(MAKEFILE_DIR)),) # absolute makefile path
@$(MAKE) -C $@ -f $(MAKEFILE_DIR)$@/$(MAKEFILE_NOTDIR) $(MAKECMDGOALS)
else # relative makefile path
@$(MAKE) -C $@ -f ../$(MAKEFILE_DIR)$@/$(MAKEFILE_NOTDIR) $(MAKECMDGOALS)
endif
else # no makefile path given
@$(MAKE) -C $@ $(MAKECMDGOALS)
endif
endif
答案 0 :(得分:1)
如果你打电话给make proj1,make会输入这个条件:
ifeq ($(strip $(MAKECMDGOALS)),proj1)
SUBDIRS = \
lib1 \
lib2 \
app1
endif
因此SUBDIRS被定义为“lib1 lib2 app1”。 不知道SETUP.MAK的内容,但是在没有给出makefile路径的情况下 输入最后一个if子句:
else # no makefile path given
@$(MAKE) -C $@ $(MAKECMDGOALS)
通过以下方式解释此命令:make -C lib1 proj1
你的Makefile没有任何proj1规则。
你应该在lib1 / Makefile中创建一个通用的all
规则,从lib1 / Makefile创建你的lib(.a / .so),不要指定项目的名称。
尝试
else # no makefile path given
@$(MAKE) -C $@
(或删除IF条款中的其他$(MAKECMDGOALS)
)
答案 1 :(得分:1)
你正在以一种非常不像Make的方式使用Make,并给自己造成很多不必要的麻烦。
看看lib1
。目前,您使用的规则
lib1:
$(MAKE) -C lib1 proj1
(我们现在假设“没有给出makefile文件路径”模式。)我假设lib1/
中的文件加起来一个库,并且该库不必使用特定的库构建考虑到项目。因此,无需将“proj1”传递给在lib1/
中运行的Make流程。并且Make不需要明确的目标;如果在没有目标的情况下调用,Make将尝试构建默认目标,这通常是makefile中的第一个目标,在这种情况下应该是库(lib1/lib1.a
或其他东西)。所以我们可以简化规则:
lib1:
@$(MAKE) -C lib1
或更好:
lib1:
@$(MAKE) -C $@
事实上,我们可以将它推广到我们使用相同方式的所有子目录:
lib1 lib2 lib3 app1 app2:
@$(MAKE) -C $@
如果我们使用“SUBDIRS”来表示我们这样处理的所有子目录,并拼出proj
先决条件,那么全局makefile会变得更加简单:
SUBDIRS = lib1 lib2 lib3 app1 app2
.PHONY: proj1
proj1: lib1 lib2 app1
.PHONY: proj2
proj2: lib1 lib2 lib3 app2
可以进一步改进,但这个答案越来越长。 (至于“给出的makefile路径”模式,你可以简化那个很好的处理,并且摆脱大部分或全部的分支,但它似乎与SETUP.MAK
中设置的参数纠缠在一起,也许还有细节你的操作系统。)所以也许最好留下他们一天。