'Makefile: maybe the problem in vpath and rule

My makefile

CC := cc
CFLAGS := -g
SRCDIR := src
BUILDDIR := build
INCDIR := inc
TARGET := bin/runner

SRCEXT := c
INCEXT := h
SOURCES := $(shell find $(SRCDIR) -type f -name *.$(SRCEXT))
OBJECTS := $(patsubst $(SRCDIR)/%, $(BUILDDIR)/%, $(SOURCES:.$(SRCEXT)=.o))
SOURCES_DIR := $(shell find $(SRCDIR) -type f -name *.$(SRCEXT) -exec dirname {} \;)
OBJECTS_DIR := $(patsubst $(SRCDIR)%, $(BUILDDIR)%, $(SOURCES_DIR))
INCLUDES_DIR := $(shell find $(INCDIR) -type f -name *.$(INCEXT) -exec dirname {} \;)
INC := $(patsubst %, -I %, $(INCLUDES_DIR))

vpath %.h $(INCLUDES_DIR)
vpath %.c $(SOURCES_DIR)
vpath %.o $(OBJECTS_DIR)

$(TARGET): delete_directories create_directories $(OBJECTS)
    @echo "Linking ..."
    $(CC) $^ -o $@

%.o: %.c %.h
    $(CC) $(CFLAGS) $(INC) -c -o $@ $^

.PHONY: create_directories 
create_directories:
    @echo "Create directories ..."
    mkdir -p $(OBJECTS_DIR)
    mkdir -p bin

.PHONY: delete_directories
delete_directories:
    @echo "Delete directories ..."
    rm -r build
    rm -r bin
Variables:  
SOURCES_DIR = 
    src/sort
    src/search
    src  
OBJECTS_DIR =
    build/sort
    build/search
    build  
INCLUDES_DIR = 
    inc/sort 
    inc/search  
SOURCES = 
    src/sort/selection_sort.c 
    src/search/linear_search.c 
    src/main.c  
OBJECTS = 
    build/sort/selection_sort.o 
    build/search/linear_search.o 
    build/main.o  

My project structure looks like:

├── inc
│   ├── search
│   │   └── linear_search.h
│   └── sort
│       └── selection_sort.h
├── makefile
└── src
    ├── main.c
    ├── search
    │   └── linear_search.c
    └── sort
        └── selection_sort.c

When the makefile build completely, I want my project structure looks like:

├── bin
│   └── runner
├── build
│   ├── main.o
│   ├── search
│   │   └── linear_search.o
│   └── sort
│       └── selection_sort.o
├── inc
│   ├── search
│   │   └── linear_search.h
│   └── sort
│       └── selection_sort.h
├── makefile
└── src
    ├── main.c
    ├── search
    │   └── linear_search.c
    └── sort
        └── selection_sort.c

When I run makefile, I get an error:

make: *** No rule to make target 'build/sort/selection_sort.o', needed by 'bin/runner'.  Stop.

I think my mistake is in $(TARGET) rule and %.o rule:
When run makefile, make go to the target $(TARGET) and find for $(OBJECTS). Because of file in $(OBJECTS) has the form build/sort/selection_sort.o and %.o rule has the form selection_sort.o, so make cannot find the rule for the prerequisite $(OBJECTS), right?
And how to solve it? Thanks.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source