1

我目前面临以下问题:

如何创建一个全局 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
4

2 回答 2

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 通过以下方式解释此命令: make -C lib1 proj1 您的 Makefile 没有任何 proj1 规则。您应该在 lib1/Makefile 中创建一个通用all规则,从 lib1/Makefile 创建您的 lib (.a / .so),无需指定项目名称。

尝试

else # no makefile path given
@$(MAKE) -C $@ 

(或删除$(MAKECMDGOALS)您的 IFs 条款中的其他人)

于 2013-06-10T12:22:31.677 回答
1

你以一种非常不像 Make 的方式使用 Make,给自己带来了很多不必要的麻烦。

lib1。目前,您使用的规则可以解决

lib1:
    $(MAKE) -C lib1 proj1

(我们现在假设“没有给出 makefile 路径”模式。)我假设文件lib1/添加到一个库中,并且该库不必在构建时考虑到特定的项目。因此无需将“proj1”传递给运行在lib1/. Make 不需要明确的目标;如果在没有目标的情况下调用,Make 将尝试构建默认目标,这(通常)是 makefile 中的第一个目标,在这种情况下应该是库(lib1/lib1.a或其他东西)。所以我们可以简化规则:

lib1:
    @$(MAKE) -C lib1

或更好:

lib1:
    @$(MAKE) -C $@

实际上,我们可以将其推广到我们使用相同方式的所有子目录:

lib1 lib2 lib3 app1 app2:
    @$(MAKE) -C $@

如果我们使用“SUBDIRS”来表示我们以这种方式处理的所有子目录,并拼出projprereqs,那么全局 makefile 会变得简单得多:

SUBDIRS = lib1 lib2 lib3 app1 app2

.PHONY: proj1
proj1: lib1 lib2 app1

.PHONY: proj2
proj2: lib1 lib2 lib3 app2

进一步的改进是可能的,但这个答案越来越长。(至于“给定的makefile路径”模式,你也可以简化很多,并摆脱大部分或全部分支,但它似乎与设置的参数纠缠在一起SETUP.MAK,也许是你的操作系统的细节。)所以也许最好让他们再待一天。

于 2013-06-10T16:24:01.617 回答