Aakash
Aakash

Reputation: 347

Makefile always recompiling some sections

The directory structure for Example is something like this.

Example - Contains Makefile, main.c, xyz.c, xyz.h and sub-directories Hal and Interrupt_Config Hal - Contains test2.c and test2.h Interrupt_Config - Contains try.h

EXE   := Micro
CC    := gcc
CPPFLAGS := -IHal -IInterruptConfig
VPATH := Hal:InterruptConfig    
OUT_DIR := Output/
OUT_SRC := Output/source/
OUT_EXE := Output/output
LIBS = Hal InterruptConfig

MAIN_OBS := $(patsubst %.c,%.o,$(wildcard *.c))
INT_OBS  := $(patsubst %.c,%.o,$(wildcard InterruptConfig/*.c))
HAL_OBS  := $(patsubst %.c,%.o,$(wildcard Hal/*.c))
ALL_DEPS := $(patsubst %.o,%.d,$(MAIN_OBS) $(HAL_OBS) $(INT_OBS))

ALL_OBS := $(MAIN_OBS) $(INT_OBS) $(HAL_OBS)    

all: $(OUT_DIR) $(EXE)

$(OUT_DIR):
    mkdir -p $(OUT_DIR)
    mkdir -p $(OUT_SRC)
    mkdir -p $(OUT_EXE)

%.o: %.c
    $(CC) -o $(OUT_SRC)$@ -MD -MP $(CPPFLAGS) $(CFLAGS) -c $<

$(EXE): $(MAIN_OBS) $(HAL_OBS) $(INT_OBS)
    $(CC) -o $(OUT_EXE)$@ $(LDFLAGS) $(OUT_SRC)*.o $(LDLIBS)

$(HAL_OBS): %.o: %.c 
    $(CC) -o $(OUT_SRC)$(notdir $@) -MD -MP $(CPPFLAGS) $(CFLAGS) -c $<

$(INT_OBS): %.o: %.c 
    $(CC) -o $(OUT_SRC)$(notdir $@) -MD -MP $(CPPFLAGS) $(CFLAGS) -c $< 

-include $(ALL_DEPS)

clean:
    rm -rf $(OUT_DIR) $(ALL_DEPS)

.PHONY: all clean

Whenever I do make, it successfully creates a directory called as Output with sub-directories source containing all the object files and output containing an executable named Micro . The first time if I do make it build everything successfully but if I do make again , I expected it should give make - has nothing to do but it builds everything except $(OUT_DIR) rule. I am not able to figure out what is the problem.

Repeated make - Expected - nothing

Actual -

gcc -o Output/source/main.o -MD -MP -IHal -IInterrupt_Config  -c main.c
gcc -o Output/source/xyz.o -MD -MP -IHal -IInterrupt_Config  -c xyz.c
gcc -o Output/source/test2.o -MD -MP -IHal -IInterrupt_Config  -c Hal/test2.c
gcc -o Output/output/nextgenrsm  Output/source/*.o

Also I am not sure whether I am doing dependencies thing correctly or not.

Upvotes: 0

Views: 85

Answers (2)

Aakash
Aakash

Reputation: 347

Many thanks to mjr and Etan Reisner. I am just posting here the final Makefile for learning purposes for other people.

UPDATED

EXE :=nextgenrsm
CC  := gcc
CPPFLAGS := -IHal -IInterrupt_Config
VPATH := Hal:Interrupt_Config
OUT_DIR := Output/
OUT_SRC := Output/source/
OUT_EXE := Output/output/$(EXE)
LIBS = Hal Interrupt_Config

MAIN_OBS := $(addprefix $(OUT_SRC), $(patsubst %.c,%.o, $(wildcard *.c)))
INT_OBS :=  $(addprefix $(OUT_SRC), $(notdir $(patsubst %.c,%.o,$(wildcard Interrupt_Config/*.c))))
HAL_OBS := $(addprefix $(OUT_SRC), $(notdir $(patsubst %.c,%.o,$(wildcard Hal/*.c))))
ALL_DEPS := $(patsubst %.o,%.d, $(MAIN_OBS) $(HAL_OBS) $(INT_OBS))

ALL_OBS =  $(notdir $(MAIN_OBS) $(INT_OBS) $(HAL_OBS)))

all: $(OUT_DIR) $(OUT_EXE)

$(OUT_DIR):
        mkdir -p $(OUT_DIR)
        mkdir -p $(OUT_DIR)source/
        mkdir -p $(OUT_DIR)output/

$(OUT_EXE): $(MAIN_OBS) $(HAL_OBS) $(INT_OBS)
        $(CC) -o $@ $(LDFLAGS)  $(OUT_SRC)*.o $(LDLIBS)

$(OUT_SRC)%.o: %.c
        $(CC) -o $@ -MD -MP $(CPPFLAGS) $(CFLAGS) -c $<

-include $(ALL_DEPS)

clean:
        rm -rf $(OUT_DIR)

.PHONY: all clean

Upvotes: 0

mjr
mjr

Reputation: 2113

Without knowing your build directory setup, its hard to give you an exact solution, but my build rules look something like this:

MAIN_OBS := $(add_prefix $(OUT_DIR), $(patsubst %.c,%.o,$(wildcard *.c)))

$(OUT_DIR):
    mkdir -p $(OUT_DIR)
    mkdir -p $(OUT_SRC)
    mkdir -p $(OUT_EXE)

$(OUT_SRC)/%.o: %.c
    $(CC) -o $@ -MD -MP $(CPPFLAGS) $(CFLAGS) -c $<

It gets complicated if you have a complicated directory structure because you will need to make more directories or get fancy with your object renaming.

Upvotes: 1

Related Questions