Camarada
Camarada

Reputation: 107

Make Target Name From Another

Have problem in dynamically "create" target name with .SECONDEXPANSION:

Small Makefile to reproduce problem:

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

It says: "No rule to make target 'test1_OBJECTS'. How can I solve this problem?

EDIT: CHANGE OF THE ANSWER

Thank you much for the answer. It was the simple variant for my task.

So I try to answer in another way.

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

So, I would like to avoid recursive make calls. Can you help me? Thank you.

Upvotes: 0

Views: 212

Answers (2)

Camarada
Camarada

Reputation: 107

I've gotcha it.

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 $^

Thank you, Beta. You only have tried. :) Maybe anyone have style or efficiency suggestions.

Upvotes: 0

Beta
Beta

Reputation: 99084

You have a rule for $(OBJECTS), but that target expands to $(CFG_NAME)_OBJECTS, which is not expanded again (ever), so it can't match anything. Try this instead:

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

Or better:

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

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

(And I'm sure you realize your example doesn't really need SECONDEXPANSION at all.)

EDIT:

That should be a separate question, but I'll try to answer it here. (And please use punctuation in the comments in your makefile; they are very difficult to understand.)

There is more than one solution to your problem. Here is one:

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

CFILES := $(notdir $(CFILES))

Upvotes: 1

Related Questions