1
votes

I have two separate C projects, client and server, that share some source files. I have three dirs: server, client and common. I am trying to create a Makefile for one of them that will use sources from src/ dir in current project and sources from ../common/ dir, compile them all to .o files and put them in obj/ dir. Then link all .o files from obj/ together. For first attempt i only put one file: main.c in src/ and left ../common/ empty.

My current version gives me an error:

Makefile:18: target `src/main.c' doesn't match the target pattern
make: *** No rule to make target `../common/main.c', needed by `obj/main.o'.  Stop.

Here is my attempt:

TARGET    = server                                                                        
CC        = gcc -c
LINKER    = gcc
CFLAGS    = -Wall -Wextra -pedantic -O2 -g -std=gnu99

SRCDIR    = src
CMNDIR    = ../common
OBJDIR    = obj

SOURCES   := $(wildcard $(SRCDIR)/*.c) $(wildcard $(CMNDIR)/*.c)
INCLUDES  := $(wildcard $(SRCDIR)/*.h) $(wildcard $(CMNDIR)/*.h)
OBJECTS   := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o) $(SOURCES:$(CMNDIR)/%.c=$(OBJDIR)/%.o)

$(TARGET): $(OBJECTS)
  @$(LINKER) $(CFLAGS) $@ $(LFLAGS) $(OBJECTS)
  @echo "Linking complete"

$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c $(CMNDIR)/%.c
  @$(CC) $(CFLAGS) $< -o $@
  @echo "Compiled $<"

.PHONEY: clean

clean:
  @$(rm -f) $(OBJECTS)
1

1 Answers

1
votes

On line 18, you have an invalid dependency rule, in the form target : target : dependencies. Your definition of $(OBJECTS) generates a list that includes "c" source files as well, which is incorrect. And finally, the linker invocation is missing the "-o" switch. So I modified it in this way:

TARGET    = server
CC        = gcc -c
LINKER    = gcc
CFLAGS    = -Wall -Wextra -pedantic -O2 -g -std=gnu99

SRCDIR    = src
CMNDIR    = ../common
OBJDIR    = obj

SOURCES   := $(wildcard $(SRCDIR)/*.c) $(wildcard $(CMNDIR)/*.c)
INCLUDES  := $(wildcard $(SRCDIR)/*.h) $(wildcard $(CMNDIR)/*.h)
OBJECTS   := $(patsubst %.c,%.o,$(SOURCES))

$(TARGET): $(OBJECTS)
    @$(LINKER) $(CFLAGS) -o $@ $(LFLAGS) $(OBJECTS)
    @echo "Linking complete"

$(OBJDIR)/%.o : $(SRCDIR)/%.c
    @$(CC) $(CFLAGS) $< -o $@
    @echo "Compiled $<"

$(OBJDIR)/%.o : $(CMNDIR)/%.c
    @$(CC) $(CFLAGS) $< -o $@
    @echo "Compiled $<"

.PHONEY: clean

clean:
    @$(rm -f) $(OBJECTS)