usustarr
usustarr

Reputation: 418

how to specify obj and bin directories in GNUmake

I have a following directory structure,

I also have this make file that works fine, but it needs all files in the same directory and also it creates *.o and bin files in the same directory. Can someone please show me how to improve this code so that i can move *.h files into /h, *.c files into /src. Also *.o files would be created in /obj and the binary file will be created in /bin?

I was thinking of something like this. This part only creates *.o files, no binary files. However, this is giving me an error right now.

Upvotes: 1

Views: 877

Answers (1)

Beta
Beta

Reputation: 99104

Step 1: h/

Add a variable, make a small change to the %.o rule, and add a vpath directive, so that the %.o rule will know where to look:

INC_DIR = h
%.o: %.c
    $(cc) -I$(INC_DIR) -c $<

vpath %.h $(INC_DIR)

Step 2: src/

Add another variable, change the assignment of objs, add another vpath:

SRC_DIR := src
objs:=$(patsubst $(SRC_DIR)/%.c,%.o,$(wildcard $(SRC_DIR)/*.c))

vpath %.c $(SRC_DIR)

Step 3: obj/

Add a variable, change objs and the %.o rule again, and the clean rule:

OBJ_DIR = obj
objs:=$(patsubst $(SRC_DIR)/%.c,$(OBJ_DIR)/%.o,$(wildcard $(SRC_DIR)/*.c))

$(OBJ_DIR)/%.o: %.c
    $(cc) -Ih -c $< -o $@

clean:
    rm -f *.d $(OBJ_DIR)/*.o $(prog)

Step 4: bin/

Add another variable, and change the assignment of prog:

BIN_DIR := bin
prog:=$(BIN_DIR)/$(notdir $(PWD))

EDIT:

What you are now asking for is a bad design. But here it is:

obj/makefile:

SRC_DIR := ../src
objs:=$(patsubst $(SRC_DIR)/%.c,%.o,$(wildcard $(SRC_DIR)/*.c))

cc:=gcc

.PHONY: ALL_OBJS
ALL_OBJS: $(objs)

INC_DIR := ../h
%.o: %.c
    $(cc) -I$(INC_DIR) -c $<

vpath %.c $(SRC_DIR)

.PHONY: clean test

clean:
    rm -f *.[od]

-include *.d

bin/makefile:

P:= $(PWD)
P:= $(dir $(P))
prog:= $(notdir $(P:/=))

OBJ_DIR := ../obj
objs:=$(notdir $(wildcard $(OBJ_DIR)/*.o))

cc:=gcc
ccflags:=-lcurses -lgdbm -lgdbm_compat

$(prog): $(objs)
    $(cc) $(ccflags) -o $@ $^

vpath %.o $(OBJ_DIR)

.PHONY: clean test

clean:
    rm -f *.d $(prog)

test: $(prog)
    $(test)

-include *.d

Upvotes: 2

Related Questions