Reputation: 551
i hava a makefile something like this:
outdir = release
allsrc = aaa/a.c bbb/b.c ccc/c.c
allobjs = $(addprefix $(outdir), $(notdir $(allsrc:.c=.o))
...
test: $(allobjs)
$(allobjs): $(allsrc)
gcc -c -o $@ $<
make test performs:
gcc -c -o release/a.o aaa/a.c
gcc -c -o release/b.o aaa/a.c
gcc -c -o release/c.o aaa/a.c
(automatic variable $< always takes first prerequisite) but i want "corresponding one":
gcc -c -o release/a.o aaa/a.c
gcc -c -o release/b.o bbb/b.c
gcc -c -o release/c.o ccc/c.c
what should i change to accomplish desirable result?
i know that this will work for sure:
$(outdir)/a.o: aaa/a.c
gcc -c -o $@ $<
$(outdir)/b.o: bbb/b.c
gcc -c -o $@ $<
$(outdir)/c.o: ccc/c.c
gcc -c -o $@ $<
and wondering how to accomplish the same in one receipe. (because in my real makefile i have ~20 different source files not just 3 like i made here for example)
Upvotes: 1
Views: 160
Reputation: 80921
You don't write your recipe like that. That's not how make works.
That recipe says that every item in $(allobjs)
has every item in $(allsrc)
as its prerequisite but that's not what you mean.
You mean that every .o
file has the matching .c
file as its prerequisite which is exactly what the built in %.o: %.c
rule already does. You don't even need a makefile to do that.
Edit: Actually, you don't mean that. I had missed that the source files were in different directories. That changes and complicates things.
Chris Dodd wrote up two good solutions for this.
Upvotes: 2
Reputation: 126140
The usual way to do what you are asking would be something like:
outdir = release
allsrc = aaa/a.c bbb/b.c ccc/c.c
allobjs = $(addprefix $(outdir), $(notdir $(allsrc:.c=.o)))
VPATH = $(sort $(dir $(allsrc)))
...
test: $(allobjs)
$(outdir)/%.o: %.c
gcc -c -o $@ $<
Of course, this will run into problems if you have a b.c
in both aaa
and bbb
, but since you're trying to put all the object files in the same directory, you have that regardless. It might make more sense to get rid of the $(notdir
and keep the same directory structure under $(outdir)
, in which case you don't need the VPATH
outdir = release
allsrc = aaa/a.c bbb/b.c ccc/c.c
allobjs = $(addprefix $(outdir), $(allsrc:.c=.o))
...
test: $(allobjs)
$(outdir)/%.o: %.c
mkdir -p `dirname $@`
gcc -c -o $@ $<
Upvotes: 1