0

.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

ですから、再帰的な呼び出しは避けたいと思います。手伝って頂けますか?ありがとうございました。

4

2 に答える 2

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のコメントには句読点を使用してください。理解するのは非常に困難です。)

問題には複数の解決策があります。これが1つです:

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

CFILES := $(notdir $(CFILES))
于 2012-10-12T14:15:43.033 に答える
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 $^

ありがとう、ベータ。あなたは試しただけです。:)たぶん誰もがスタイルや効率の提案を持っています。

于 2012-10-16T05:50:42.603 に答える