23

What I have is a directory with 3 sub-directories. src/ for .c and .h files, bin/ where the compiled executable is supposed to go and obj/ where I want the .obj files to go.

Now I want the makefile to compile every .c file from src (without me having to list them all in the makefile) and put the .o files in obj and the executable built from foo.c saved as bin/foo.

Can someone help me out? Whenever I use wildcards, make complains about rules not being there and when I use implicit rules, it doesn't put the object files in a separate folder.

activedecay
  • 10,129
  • 5
  • 47
  • 71
Max
  • 431
  • 1
  • 5
  • 13

1 Answers1

57

To build foo.o from foo.c, locally:

foo.o: foo.c
    $(CC) -c $< -o $@

To do the same, but with any needed header files in src/:

SRC := src

foo.o: foo.c
    $(CC) -I$(SRC) -c $< -o $@

To do the same, but with the source file in src/:

SRC := src

foo.o: $(SRC)/foo.c
    $(CC) -I$(SRC) -c $< -o $@

To do that, but put the object file in obj/:

SRC := src
OBJ := obj

$(OBJ)/foo.o: $(SRC)/foo.c
    $(CC) -I$(SRC) -c $< -o $@

A pattern rule that will do that for any such object file (obj/foo.o, obj/bar.o, ...):

SRC := src
OBJ := obj

$(OBJ)/%.o: $(SRC)/%.c
    $(CC) -I$(SRC) -c $< -o $@

To create the list of desired objects:

SOURCES := $(wildcard $(SRC)/*.c)
OBJECTS := $(patsubst $(SRC)/%.c, $(OBJ)/%.o, $(SOURCES))

And a rule to cover them all:

all: $(OBJECTS)

Putting it all together:

SRC := src
OBJ := obj

SOURCES := $(wildcard $(SRC)/*.c)
OBJECTS := $(patsubst $(SRC)/%.c, $(OBJ)/%.o, $(SOURCES))

all: $(OBJECTS)
    $(CC) $^ -o $@

$(OBJ)/%.o: $(SRC)/%.c
    $(CC) -I$(SRC) -c $< -o $@

Note that this has one big shortcoming: is does not track dependencies on header files. This can be done automatically, but it's a subtle trick; it can wait until you've mastered this much.

Neuron
  • 5,141
  • 5
  • 38
  • 59
Beta
  • 96,650
  • 16
  • 149
  • 150
  • 2
    Thank you for the fantastic answer. The last snippet won't actually build the executable, but adding that was no problem and all the files are where I want them to be :) – Max Nov 16 '16 at 00:43
  • That last pattern rule would probably look better as a static pattern rule methinks. – bobbogo Nov 16 '16 at 16:22
  • @bobbogo: I agree, but I was trying for simplicity. – Beta Nov 17 '16 at 00:01
  • 1
    where can i get the "subtle trick" ... i'm ready for more, master – activedecay Jan 01 '19 at 21:57
  • 3
    @activedecay: look at [Mad Scientist's excellent paper](http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/). And please learn to use punctuation and upper-case letters. – Beta Jan 03 '19 at 01:23
  • @Beta where can i get the "subtle trick" ... i'm ready for more, master ?! – Mark Feb 15 '23 at 10:05