从makefile目标向上传递变量

从makefile目标向上传递变量,makefile,gnu-make,Makefile,Gnu Make,我在Makefile中有几个目标。每个目标向makefile变量添加一些值。例如,CFLAGS CFLAGS := 1 a: CFLAGS += 2 b: CFLAGS += 3 我需要写下目标“c”,它将“看到”在“a”和“b”中分配的值。这可能会增加更多的值 我试着这样做: c: CFLAGS += 4 c: a b echo ${CFLAGS} 在这里,我计划看到CFLAGS等于“1234”或“143” 但事实上,CGLAG等于: a: 1 4 2 b: 1 4 3 c: 1 4 示

我在Makefile中有几个目标。每个目标向makefile变量添加一些值。例如,CFLAGS

CFLAGS := 1
a: CFLAGS += 2
b: CFLAGS += 3
我需要写下目标“c”,它将“看到”在“a”和“b”中分配的值。这可能会增加更多的值

我试着这样做:

c: CFLAGS += 4
c: a b
echo ${CFLAGS}
在这里,我计划看到CFLAGS等于“1234”或“143” 但事实上,CGLAG等于:

a: 1 4 2
b: 1 4 3
c: 1 4
示例生成文件:

CFLAGS := 1
.PHONY: all a b c
all: c

a: CFLAGS += 2
a:
    echo TargetA ${CFLAGS}

b: CFLAGS += 3
b:
    echo TargetB ${CFLAGS}

c: CFLAGS += 4
c: a b
    echo TargetC ${CFLAGS}
有办法吗

附言:为那些想要的人提供一些理由。 我有一些程序需要libA。目标“a”,其包含libA的inclide/libs,并用于这些程序。 我有一些程序需要libB。 我有一些程序需要全部:libA、libB和libC。 我想“重用”目标“a”和“b”,以避免任务重复。

问题 来自GNU Make手册的以下部分:

定义特定于目标的变量时,该变量值也适用于该目标的所有先决条件及其所有先决条件等

在生成文件中,
a
b
c
的先决条件,因此将
CFLAGS
设置为
c
的目标特定变量在
a
b
中也会起作用。相反,也就是说,将
CFLAGS
设置为
a
b
的目标特定变量在
c
中根本没有影响,因为这不是任何一个变量的先决条件


可能的替代方案 如果您实现这一目标的动机是,目标可能需要任意组合libA、libB或libC。然后,我建议您定义代表相应库组合的变量
libA
libB
libC
libAB
libAC
libBC
libABC
,然后将其中一个变量作为先决条件包含到相应的目标中

以下makefile可以作为一个起点,并阐明了我想要表达的内容:

.PHONY: all

libsCommon := 1
libsA := $(libsCommon) 2
libsB := $(libsCommon) 3
libsC := $(libsCommon) 4

# $(call include-to,varSrc,varDst)
# for avoiding repetition of libraries
define include-to
    $(eval $2 += $(filter-out $($2),$($1)))
endef

# libsAB
$(call include-to,libsA,libsAB)
$(call include-to,libsB,libsAB)

# libsAC
$(call include-to,libsA,libsAC)
$(call include-to,libsC,libsAC)

# libsBC
$(call include-to,libsB,libsBC)
$(call include-to,libsC,libsBC)

# libsABC (all)
$(call include-to,libsA,libsABC)
$(call include-to,libsB,libsABC)
$(call include-to,libsC,libsAll)

all:
    @echo "libsA:   $(libsA)"
    @echo "libsB:   $(libsB)"
    @echo "libsC:   $(libsC)"
    @echo
    @echo "libsAB:  $(libsAB)"
    @echo "libsAC:  $(libsAC)"
    @echo "libsBC:  $(libsBC)"
    @echo
    @echo "libsABC: $(libsABC)"
使用此makefile运行
make
,将生成:

libsA:   1 2
libsB:   1 3
libsC:   1 4

libsAB:  1 2 3
libsAC:  1 2 4
libsBC:  1 3 4

libsABC: 1 2 3 4
然而,当您有许多库或它们的不同可能组合时,这种方法无法很好地扩展


无论如何,我强烈建议,如果目标
a
确实需要
libA
,那么
libA
应该成为
a
的先决条件

正如在另一条评论中提到的,您拥有向后的先决条件关系以获得所需的行为

与其编写大量的
call
eval
函数,我更愿意在这里使用计算变量名。您可以这样做:

CFLAGS = 1
CFLAGS_a = 2
CFLAGS_b = 3
CFLAGS_c = 4

all: c
c: a b
a b c:
        @echo '$(CFLAGS) $(CFLAGS_$@) $(foreach P,$<,$(CFLAGS_$P))'
CFLAGS=1
CFLAGS_a=2
CFLAGS_b=3
CFLAGS_c=4
全体:c
c:a-b
a、b、c:
@echo'$(CFLAGS)$(CFLAGS_$@)$(foreach P$