'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 |
|---|
