从另一个目标名称

时间:2012-10-12 10:15:29

标签: makefile

使用动态“创建”目标名称时遇到问题.SECONDEXPANSION:

Makefile 重现问题:

CONFIGS = test1 test2 test3

.SECONDEXPANSION:

all: $(CONFIGS)

OBJECTS=$$(CFG_NAME)_OBJECTS


$(CONFIGS) : CFG_NAME=$@
$(CONFIGS) : $(OBJECTS) 
    @echo $(CFG_NAME) $@ from $^

$(OBJECTS):
    @echo OBJECTS $@ from $^
    @echo DO IT

它说:“没有规则来制作目标'test1_OBJECTS'。 我该如何解决这个问题?

编辑:更改答案

非常感谢您的回答。这是我任务的简单变体。

所以我试着以另一种方式回答。

CONFIGS = test1 test2 test3
PLATFORMS = x86 ppc arm
#will be test1x86 test2x86 ... test1ppc ... test3arm,
#so it is long way to enumarate all variants
VARIANTS = $(foreach c, $(CONFIGS), $(foreach p, $(PLATFORMS), $(c)$(p)))
#C FILE LIST
CFILES:=$(shell /bin/find -name "*.c")


.SECONDEXPANSION:

all: $(VARIANTS)

#More Comlex Rule
#Want to corresponding objects be in bins/test1x86/
OBJECTS:=$(CFILES:%.c=bins/$$(CFGNAME)%.o)


$(CONFIGS) : CFG_NAME=$@
$(CONFIGS) : $(OBJECTS) 
    @echo $(CFG_NAME) $@ from $^

#More complex prerequisites
#I understand that $$(CFGNAME) will be resolve incorrect.
#For each *.c file in subdir I would have object in corresponding path.
#For example, '1/2/3/test.c' will use for generate 
#object file 'bins/test1x86/1/2/3/test.o',
#when I call 'make testx86' or 'make all' (it will build all VARIANTS),
#in 'bins/test1x86/1/2/3/'.
#So what have I do?
$(OBJECTS): bins/$$(CFGNAME)_OBJECTS/%o : %.c
    @echo OBJECTS $@ from $^
    @echo DO IT

所以,我想避免递归调用。你能帮助我吗? 谢谢。

2 个答案:

答案 0 :(得分:1)

您有$(OBJECTS)的规则,但该目标会扩展为$(CFG_NAME)_OBJECTS,而不会再次展开(永远),因此无法匹配任何内容。试试这个:

test1_OBJECTS test2_OBJECTS test3_OBJECTS:
    @echo OBJECTS $@ from $^
    @echo DO IT

或更好:

OBJECT_SETS = $(addsuffix _OBJECTS, $(CONFIGS))

$(OBJECT_SETS):
    @echo OBJECTS $@ from $^
    @echo DO IT

(我相信你会发现你的例子根本不需要SECONDEXPANSION。)

修改

这应该是一个单独的问题,但我会在这里尝试回答。 (请在makefile的注释中使用标点符号;它们很难理解。)

您的问题有多种解决方案。这是一个:

vpath %.c $(dir $(CFILES))

CFILES := $(notdir $(CFILES))

答案 1 :(得分:0)

我知道了。

CONFIGS = test1 test2 test3
PLATFORMS = p1 p2
#Will be testp1 test1p2 .. test3p2
VARIANTS = $(foreach c, $(CONFIGS), $(foreach p, $(PLATFORMS), $(c)$(p)))

.SECONDEXPANSION:
#.c files list in all subfolders
cfiles = $(shell /bin/find -name "*.c")
#objects for these .c files for custom VARIANT
objects = $(patsubst %.c,%.o,$(addprefix bins/$1/,$(cfiles)))
#Get .c source for object (e.g. bins/test1p1/tests/main_test.o => tests/main_test.c)
get_src=$(shell echo $1 | sed 's/[^\/]*\/[^\/]*\/\(.*\)/\1.c/')

#Build All Variants
all: $(VARIANTS)

#Build objects. Target list contains all objects for all variants.
#Prerequisites get .c sources from the pattern rule for targets
$(foreach v, $(VARIANTS), $(call objects,$(v))) : %.o : $$(call get_src,$$*)
    @echo OBJECTS $@ FROM $^

#Variants rule, depends on objects 
$(VARIANTS): $(call objects,$$@)
    @echo $@ from $^

谢谢你,Beta。你只是尝试过。 :) 也许任何人都有风格或效率的建议。