I have the following 'working' snippet:
c_file_path := toto.c
asm_file_path := toto.S
c_files = $(notdir $(c_file_path))
asm_files = $(notdir $(asm_file_path))
vpath %.c $(dir $(c_file_path))
vpath %.S $(dir $(asm_file_path))
OBJDIR=objs/
c_objs:=$(addprefix $(OBJDIR),$(patsubst %.c,%.o,$(c_files)))
asm_objs:=$(addprefix $(OBJDIR),$(patsubst %.S,%.S.o,$(asm_files)))
$(info c_files $(c_files))
$(info s_files $(asm_files))
$(info c_objs $(c_objs))
$(info asm_objs $(asm_objs))
%.c:
@touch $@
%.S:
@touch $@
objs/%.o:%.c
@mkdir -p $(OBJDIR)
@gcc -c $^ -o $@
objs/%.S.o:%.S
@mkdir -p $(OBJDIR)
@gcc -c $^ -o $@
clean:
@rm -rf objs/*
all: $(c_objs) $(asm_objs)
@ls $(c_objs) $(asm_objs)
@echo "hello"
I tried to merge targets:
c_file_path := toto.c
asm_file_path := toto.S
c_files = $(notdir $(c_file_path))
asm_files = $(notdir $(asm_file_path))
vpath %.c $(dir $(c_file_path))
vpath %.S $(dir $(asm_file_path))
OBJDIR=objs/
c_objs:=$(addprefix $(OBJDIR),$(patsubst %.c,%.o,$(c_files)))
asm_objs:=$(addprefix $(OBJDIR),$(patsubst %.S,%.S.o,$(asm_files)))
$(info c_files $(c_files))
$(info s_files $(asm_files))
$(info c_objs $(c_objs))
$(info asm_objs $(asm_objs))
%.c %.S:
@touch $@
objs/%.o objs/%.S.o:%.c %.S
@mkdir -p $(OBJDIR)
@gcc -c $^ -o $@
clean:
@rm -rf objs/*
all: $(c_objs) $(asm_objs)
@ls $(c_objs) $(asm_objs)
@echo "hello"
which gives:
gcc: error: toto.c no such file or directory
why weren't target merged?
I'm not sure what you're trying to do but this rule:
objs/%.o objs/%.S.o:%.c %.S
tells make that for two files foo.c
and foo.S
(for any string foo
) they can be used to create the targets objs/foo.o
and objs/foo.S.o
by invoking the recipe (gcc
) one time.
I'm pretty sure that that's not what you want to say because it means you can't use this pattern unless both files foo.c
and foo.S
exist for a given string foo
.
If what you're asking is how to reduce these two pattern rules:
objs/%.o:%.c
@mkdir -p $(OBJDIR)
@gcc -c $^ -o $@
objs/%.S.o:%.S
@mkdir -p $(OBJDIR)
@gcc -c $^ -o $@
into a single pattern rule so you don't have to write it twice the answer is very simple:
You can't.
You could put the recipe into a variable, like this:
build = @mkdir -p $(OBJDIR) && gcc -c $^ -o $@
then you can simplify the pattern rules somewhat like this:
objs/%.o : %.c ; $(build)
objs/%.S.o : %.S ; $(build)
but that's the best you can do, without resorting to overly-complicated things like foreach
/eval
/call
loops etc.