Search code examples
cmakefileheader-filesmodularity

How to make a modular Makefile for a modular c project?


I have a C program that has this code:

#if defined(MATRIX)
    #include "Matrix.h"
#elif defined(QTREE)
    #include "QTree.h"
#endif

and I want to create a Makefile that given a target passes de -D flag to GCC with the corresponding MACRO so that the correct header + source files are compiled.

Currently I have this Makefile:

# Makefile for compiling the battleship game

C=gcc
STANDARD=c99
HEADER_DIR=includes
ODIR=obj
CFLAGS=$(C) -c -std=$(STANDARD) -I$(HEADER_DIR)
SDIR=src

_OBJS = Battleship.o Game.o Cell.o Ship.o Bitmap.o IO.o Aux.o Matrix.o QTree.o Board.o
OBJS = $(patsubst %,$(ODIR)/%,$(_OBJS))

# Program name
PROG=battleship

$(ODIR)/%.o: $(SDIR)/%.c
    $(CFLAGS) -o $@ $<

$(PROG1): $(OBJS)
    $(C) -o $(PROG) -D MATRIX $(OBJS)

$(PROG2): $(OBJS)
    $(C) -o $(PROG) -D QTREE $(OBJS)

.PHONY: game_with_matrix

game_with_matrix: $(PROG1)

.PHONY: game_with_qtree

game_with_qtree: $(PROG2)

.PHONY: clean

clean:
    rm -f $(ODIR)/*.o $(PROG)

but it always outputs: make: Nothing to be done for [target].

I don't really know whats wrong :(

EDIT:

when I invoke make I am using either make game_with_matrix or make game_with_qtree.

Thanks in advance!


Solution

  • First, this:

    C=gcc
    CFLAGS=$(C) -c -std=$(STANDARD) -I$(HEADER_DIR)
    
    $(ODIR)/%.o: $(SDIR)/%.c
        $(CFLAGS) -o $@ $<
    

    "CFLAGS" is a bad name for that. I strongly advise this:

    C=gcc
    CFLAGS= -c -std=$(STANDARD) -I$(HEADER_DIR)
    
    $(ODIR)/%.o: $(SDIR)/%.c
        $(C) $(CFLAGS) -o $@ $<
    

    Now you could add a target-specific variable value:

    $(PROG1): CFLAGS += -DMATRIX
    
    $(PROG1): $(OBJS)
        $(C) -o $(PROG) $(OBJS)
    
    $(PROG2): CFLAGS += -DQTREE
    
    $(PROG2): $(OBJS)
        $(C) -o $(PROG) $(OBJS)
    

    But you haven't yet defined PRG1 nor PROG2, and I see no need for them. Get rid of them and do this:

    $(PROG): $(OBJS)
        $(C) -o $@ $^
    
    game_with_matrix: CFLAGS += -DMATRIX
    game_with_matrix: $(PROG)
    
    game_with_qtree: CFLAGS += -DQTREE
    game_with_qtree: $(PROG)