I have the following Makefile:
CC=gcc
CFLAGS=-Wall -g -Wextra -DNDEBUG $(OPTFLAGS)
VPATH=%.c src
VPATH=%.h src
VPATH=%.o obj
SOURCES=$(wildcard **/*.c *.c)
OBJECTS=$(patsubst %.c,obj/%.o,$(SOURCES))
TEST_SRC=$(wildcard tests/*_tests.c)
TESTS=$(patsubst,%.c,%o,$(TEST_SRC))
TARGET=bin/ex
$(OBJECTS):$(SOURCES)
$(CC) -c $(CFLAGS) $< -o $@
# The target build
all:$(TARGET)
$(TARGET):CFLAGS+=-fPIC
$(TARGET):build $(OBJECTS)
$(CC) -c $(CFLAGS) $< -o $@ $(OBJECTS)
What I am trying to achive is to have all *.o files in obj directory and the final executable in the bin directory.
Folder structure as follows:
project/
src/
obj/
bin/
When I run make all I get the following error which I am not able to fix: can't create obj/src/ex.o: No such file or directory
Obviously its targeting the wrong path. any help would be appreciated.
EDIT
Based on first comment I got to my question I have cleaned up the Makefile and came with the following solution that does the job, except that it created the "src" sub-folder into "obj". One of my mistakes was that I was using -c flag when trying to build the exec.
CC=gcc
CFLAGS=-Wall -g -Wextra -DNDEBUG $(OPTFLAGS)
LIBS=-ldl $(OPTLIBS)
#PREFIX?=/usr/local
SOURCESDIR=src
OBJECTSDIR=obj
SOURCES=$(wildcard **/*.c *.c)
OBJECTS=$(patsubst %.c,obj/%.o,$(SOURCES))
TEST_SRC=$(wildcard tests/*_tests.c)
TESTS=$(patsubst,%.c,%o,$(TEST_SRC))
TARGET=bin/ex
$(OBJECTS):$(SOURCES)
@$(call make-repo)
$(CC) -c $(CFLAGS) $< -o $@
# The target build
all:$(TARGET) tests
dev:CFLAGS=-Wall -g -Isrc -Wextra $(OPTFLAGS)
dev:all
$(TARGET):CFLAGS+=-fPIC
$(TARGET):build $(OBJECTS)
$(CC) $(OBJECTS) $(LDFLAGS) -o $@
build:
@mkdir -p bin
define make-repo
for dir in $(SOURCESDIR); \
do \
mkdir -p $(OBJECTSDIR)/$$dir; \
done
endef