Currently my project has all files within a single directory. I am trying to reorganize it such that I have a src
directory for *.c files, an include
directory for *.h files, and an obj
directory for *.o files as a subdirectory of src. My makefile with every file in one directory works fine and looks like this:
CC=gcc
CFLAGS=-I. -Wall -Wextra -Wpedantic -Werror
DEPS = Triangle.h
OBJ = Trianglecalc.o Triangle.o
TESTOBJ = area_of_triangle_test.o verify_triangle_test.o validate_input_test.o get_side_length_test.o Triangle.o
LIBS=-lm
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
Trianglecalc: $(OBJ)
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
tests: $(TESTOBJ)
$(CC) -o area_of_triangle_test area_of_triangle_test.o Triangle.o $(CFLAGS) $(LIBS)
$(CC) -o verify_triangle_test verify_triangle_test.o Triangle.o $(CFLAGS) $(LIBS)
$(CC) -o validate_input_test validate_input_test.o Triangle.o $(CFLAGS) $(LIBS)
$(CC) -o get_side_length_test get_side_length_test.o Triangle.o $(CFLAGS) $(LIBS)
test-all:
./area_of_triangle_test > test_log.txt
./verify_triangle_test >> test_log.txt
./validate_input_test >> test_log.txt
./get_side_length_test >> test_log.txt
.PHONY: clean
clean:
rm *.o $(objects) Trianglecalc area_of_triangle_test verify_triangle_test validate_input_test get_side_length_test
I have been following this guide to create my makefile: A Simple Makefile Tutorial
Here is what my makefile looks like after reorganizing my project as described above. This makefile is within the src
directory:
CC=gcc
IDIR=../include
CFLAGS=-I$(IDIR) -Wall -Wextra -Wpedantic -Werror
ODIR=obj
_DEPS = Triangle.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
_OBJ = Trianglecalc.o Triangle.o
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
_TESTOBJ = area_of_triangle_test.o verify_triangle_test.o validate_input_test.o get_side_length_test.o Triangle.o
TESTOBJ = $(patsubst %,$(ODIR)/%,$(_TESTOBJ))
LIBS=-lm
$(OBJ): $(ODIR)/%o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
Trianglecalc: $(OBJ)
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
tests: $(TESTOBJ)
$(CC) -o area_of_triangle_test area_of_triangle_test.o Triangle.o $(CFLAGS) $(LIBS)
$(CC) -o verify_triangle_test verify_triangle_test.o Triangle.o $(CFLAGS) $(LIBS)
$(CC) -o validate_input_test validate_input_test.o Triangle.o $(CFLAGS) $(LIBS)
$(CC) -o get_side_length_test get_side_length_test.o Triangle.o $(CFLAGS) $(LIBS)
test-all:
./area_of_triangle_test > test_log.txt
./verify_triangle_test >> test_log.txt
./validate_input_test >> test_log.txt
./get_side_length_test >> test_log.txt
.PHONY: clean
clean:
rm *.o $(objects) Trianglecalc area_of_triangle_test verify_triangle_test validate_input_test get_side_length_test
Following the guide linked above I originally had $(OBJ): $(ODIR)/%o: %.c $(DEPS)
as $(ODIR)/%o: %.c $(DEPS)
, but then I got the error:
$ make
make: *** No rule to make target 'obj/Trianglecalc.o', needed by 'Trianglecalc'. Stop.
I change the line to $(OBJ): $(ODIR)/%o: %.c $(DEPS)
as suggested in this answer: Makefile C subdirectory rule to make obj
but now I get:
$ make
make: *** No rule to make target 'Trianglecalc..c', needed by 'obj/Trianglecalc.o'. Stop.
The previous post I linked suggests that this might be due to a spelling error, but I can't find it. I'm confused at how make ended up at Trianglecalc..c
instead of Trianglecalc.c
, the only place in the makefile with a ..
is as part of the IDIR
variable. Any suggestions?
P.S. I haven't gotten around to updating the tests:
and clean:
rules but I'm sure that at least the clean:
rule will need to be fixed. As best I can tell the current problem is with the Trianglecalc:
rule.