24

I am trying to compile set of targets. However it only seems to do the first one. Below is a cut down of the my makefile that shows the error.

  OBJECTS = abc def ghi
  SOURCES = abc.c def.c ghi.c

  $(OBJECTS):     $(SOURCES)
          @echo target is $@, source is $<

In shell,

  $ touch abc.c def.c ghi.c
  $ make

When I run make I get the following output:

  target is abc, source is abc.c

So it only seems to be running the first target.

If I replace $< with $^, the output is:

  target is abc, source is abc.c def.c ghi.c

My question, is it possible to perform expansions on variables like with the (%: %) pattern?

wmercer
  • 1,102
  • 2
  • 11
  • 24

1 Answers1

30

Try this:

  OBJECTS = abc def ghi

  all: $(OBJECTS)

  $(OBJECTS):%:%.c
          @echo target is $@, source is $<

The trouble was

  1. The default target (which is what Make chooses if you just type `make`) is the first target in the makefile, which was `abc`.
  2. You made all sources prerequisites of every object. That is, all three sources were prerequisites of `abc`. They were also prerequisites of `def` and of `ghi`.
Beta
  • 96,650
  • 16
  • 149
  • 150
  • Running `make` with no arguments still only executes the first target (`abc`). – Gingi Jun 06 '13 at 16:39
  • @Gingi: Is that the result you get? What version of Make are you using? – Beta Jun 07 '13 at 00:38
  • @Beta GNU Make 3.81, Mac OS X 10.8.4 – Gingi Jun 07 '13 at 19:43
  • @Gingi: That's strange... what if you add a command to the `all` rule: `@echo all preqs are $^`, what does it say? – Beta Jun 08 '13 at 01:22
  • Thanks, this works for my particular problem. Here's a shot (after four years) but what does $(OBJECTS):%:%.c mean? I read: for any given object, take the equivalent .c file as a prerequisite. But what does the additional %: mean? Hope you can help! – Nebula Jul 21 '15 at 09:26
  • 2
    @Nebula: Static pattern rules are described [here](http://www.gnu.org/software/make/manual/make.html#Static-Pattern). The rule does not assume that Make knows what the equivalent .c file is, it is more general. It says: for any target in this list (`$(OBJECTS)`), take the entire target name (`%`), and add ".c" (`%.c`) to get the prerequisite. – Beta Jul 21 '15 at 11:46
  • Hi @Beta, thanks a bunch! That explains it very well. My life is more complete now =p – Nebula Jul 22 '15 at 08:57
  • 1
    Here's a question: how do you go the other way? For instance if you had a bunch of zip files you wanted to create so "OBJECTS=f1.zip f2.zip f3.zip" and you wanted your dependency to be "f1 f2 f3" etc. I tried something like "$(ZIPS):%:$(ZIPS:.zip=)" but that doesn't seem to work. – Kelly Beard May 03 '16 at 20:54
  • 2
    @KellyBeard: No problem, `$(ZIPS):%.zip:%` – Beta May 04 '16 at 01:11