具有范围变量的全局Makefile

Suedocode

我试图我的整个项目转换为一个单一的Makefile的授意下,如果这个文件,我看到乱扔垃圾了我所有的搜索结果,每当我有一个递归的Makefile问题。但是,我遇到了一个非常基本的问题,我不确定该如何解决。我想为每个Makefile模块定义几个常见但不完全相同的变量。为此,我Makefile.var首先创建了一个文件:

# ============================================================================
# Common aliases for local dirs
# ============================================================================
# Every make module must define WORKING_DIR :=
BIN = $(WORKING_DIR)/bin
OBJ = $(WORKING_DIR)/obj
SRC = $(WORKING_DIR)/src
DEP = $(WORKING_DIR)/obj
INC = $(WORKING_DIR)/include
INCLUDES = -I$(INC)

ALL_SRCS   = $(wildcard $(SRC)/*.C)
ALL_INCS   = $(wildcard $(INC)/*.h)
ALL_OBJS   = $(subst $(SRC),$(OBJ),$(ALL_SRCS:%.C=%.o))
ALL_DEPS   = $(subst $(SRC),$(DEP),$(ALL_SRCS:%.C=%.d))

Makefile.var文件位于主文件中首先包含的文件中。此后,包括后续的makefile模块。这是我的主人Makefile

include MakeModules/Makefile.var
include MakeModules/Makefile.tools

clean: $(CLEAN_LIST)

all: $(MAKE_LIST)

最后,这是模块的外观。为简便起见,我将复制和粘贴相同的模块两次,然后为第二个实例调整名称。这是Makefile.tools

# ============================================================================
# queuing (QUE)
# ============================================================================
WORKING_DIR := $(TOP)/tools/queuing
QUE_TARGET  := libqueue.so

-include $(DEP)/*.d

$(QUE_TARGET): $(ALL_OBJS)
    $(CPP) $(CFLAGS) -shared -o $@ $(ALL_OBJS)

que-clean:
    -rm -f $(OBJ)/*.o $(DEP)/*.d

CLEAN_LIST += que-clean
MAKE_LIST += $(QUE_TARGET)

# ============================================================================
# queuing2 (QUE2)
# ============================================================================
WORKING_DIR := $(TOP)/tools/queuing2
QUE2_TARGET := libqueue2.so

-include $(DEP)/*.d

$(QUE2_TARGET): $(ALL_OBJS)
    $(CPP) $(CFLAGS) -shared -o $@ $(ALL_OBJS)

que2-clean:
    -rm -f $(OBJ)/*.o $(DEP)/*.d

CLEAN_LIST += que2-clean
MAKE_LIST += $(QUE2_TARGET)

如您所见,基于的值Makefile.tools使用从派生的变量好吧,这实际上是行不通的,因为可以进行两阶段读取变量将仅接受最后一次已知的分配,并且对于所有规则,无论它们位于何处,其值都将相同。这意味着只有最后定义的模块实际上具有正确的规则。Makefile.varWORKING_DIRmakeWORKING_DIRALL_OBJS

有没有办法让BIN, OBJ, SRC, ...每个模块都可以访问公共变量,而不必仅仅用新的前缀一遍又一遍地c / ping?也就是说,我可以将变量定义的作用域限定在Makefile节中,然后在保留旧规则的情况下进行更改吗?我有点发痒的感觉,这是不可能的,但是如果我错过了一些很好的技巧可以很好地解决这个问题,那将是非常好的。否则,这种全局Makefile事情实际上是不可行的(使用了TONS的通用变量来从派生值,该变量WORKING_DIR以前由递归make限定范围)。

伊坦·雷斯纳(Etan Reisner)

当评估一个变量时,将使用当时的大多数make变量会递归扩展,因此将其评估推迟到“最终”位置使用。

最终位置在哪里(以及在处理中何时发生)取决于变量的目的。

CFLAGS在规则主体运行之前,不会评估规则主体中使用的变量(例如),因此将看到在解析阶段分配的最后一个值。

在make上下文中使用的变量本身更易于处理。您需要做的就是创建简单扩展(并因此立即进行评估)的变量,这些变量引用公共变量并在您的特定makefile中使用它们。(此外,您可能刚刚意识到,这也是规则主体变量问题的一种解决方案……至少对于您自己编写的规则而非通用模式规则而言。)

也可以针对通用模式规则解决此问题,并且需要特定于目标的简单扩展变量来遮盖全局变量。

我只有一分钟的时间,所以我无法详细解释,但是这里有一个示例makefile,它显示了一些问题以及我提到的修复方法之一(模式规则/特定于目标的变量一个)。看看这是否有意义。提出任何无用的问题,如果有时间,我会尽力解释/回答。

all: $(addsuffix -tgt,main second third)

W_D := main
ALLOBJS = $(addprefix main-,one two three)
OBJ = main-obj
DEP = main-dep
M_TGT := main-tgt
$(M_TGT): OBJ := $(OBJ)
$(M_TGT): DEP := $(DEP)
$(M_TGT): $(ALLOBJS)

W_D := second
ALLOBJS = $(addprefix second-,one two three)
OBJ = second-obj
DEP = second-dep
S_TGT := second-tgt
$(S_TGT): $(ALLOBJS)

W_D := third
ALLOBJS = $(addprefix third-,one two three)
OBJ = third-obj
DEP = third-dep
T_TGT := third-tgt
$(R_TGT): $(ALLOBJS)

%:
        @echo Making '$@' $(if $^,from '$^')
        @echo 'OBJ=$(OBJ)'
        @echo 'DEP=$(DEP)'

重复包括:

$ more inc.mk Makefile | cat
::::::::::::::
inc.mk
::::::::::::::
FOO:=$(PREFIX)_bar
$(PREFIX)_OBJS=wildcard $(PREFIX)/*
::::::::::::::
Makefile
::::::::::::::
PREFIX=one
include inc.mk
$(info FOO:$(FOO))
$(info $$(PREFIX)_OBJS:$($(PREFIX)_OBJS))
rule_one: PREFIX:=$(PREFIX)

PREFIX=two
include inc.mk
$(info FOO:$(FOO))
$(info $$(PREFIX)_OBJS:$($(PREFIX)_OBJS))
rule_two: PREFIX:=$(PREFIX)

PREFIX=three
include inc.mk
$(info FOO:$(FOO))
$(info $$(PREFIX)_OBJS:$($(PREFIX)_OBJS))
rule_three: PREFIX:=$(PREFIX)

all: rule_one rule_two rule_three

%:
        @echo '# Making $@'
        @echo FOO:$(FOO)
        @echo PREFIX_OBJS:$($(PREFIX)_OBJS)

$ make
FOO:one_bar
$(PREFIX)_OBJS:wildcard one/*
FOO:two_bar
$(PREFIX)_OBJS:wildcard two/*
FOO:three_bar
$(PREFIX)_OBJS:wildcard three/*
# Making rule_one
FOO:three_bar
PREFIX_OBJS:wildcard one/*
# Making rule_two
FOO:three_bar
PREFIX_OBJS:wildcard two/*
# Making rule_three
FOO:three_bar
PREFIX_OBJS:wildcard three/*
# Making all
FOO:three_bar
PREFIX_OBJS:wildcard three/*

您甚至可以变得更加聪明,并在包含的文件中定义罐头配方,该配方采用目标名称并创建每个目标变量的分配,从而避免了需要时手动执行该操作。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章