I am trying to write a Makefile for a small C program. It’s structure is
project_root
- src (source files)
- tests (test files)
- build (program binary)
My make file is below.
CFLAGS = -g -Wall -Isrc $(OPTFLAGS)
LDLIBS = $(OPTLIBS)
PREFIX ?= /usr/local/
OPTVALGRIND="valgrind --track-origins=yes --log-file=tests/valgrind.log"
TARGET_SRC = src/hello_make.c
TARGET = build/hello_make
SOURCES := $(wildcard src/*.c)
SOURCES := $(filter-out $(TARGET_SRC),$(SOURCES))
OBJECTS = $(patsubst %.c,%.o,$(SOURCES))
TEST_SRC = $(wildcard tests/*_tests.c)
TESTS = $(patsubst %.c,%,$(TEST_SRC))
TEST_FILE ?= hello_make_tests
all: $(TARGET) tests
$(TARGET): build $(OBJECTS)
$(CC) $(CFLAGS) $(TARGET_SRC) $(OBJECTS) $(LDLIBS) -o $@
.PHONY: compile_tests tests test testv valgrind build clean
compile_tests: LDLIBS += -lrt -lm
compile_tests: CFLAGS += $(OBJECTS)
compile_tests: build $(OBJECTS) $(TESTS)
@echo "TARGET=$(TARGET), TESTS=$(TESTS)"
@echo "compile_tests done"
tests: compile_tests
sh ./tests/run_tests.sh
test: compile_tests
sh ./tests/run_test.sh tests/$(TEST_FILE)
testv: compile_tests
sh ./tests/run_test.sh tests/$(TEST_FILE)
valgrind:
VALGRIND=$(OPTVALGRIND) $(MAKE) -s
clean:
rm -rf $(OBJECTS)
rm -rf $(TARGET)
rm -rf $(TESTS)
rm -rf build
rm -rf tests/*.log
build:
@mkdir -p build
I have a target test and testv(corresponding for running with valgrind).
So when I do,
make test TEST_FILE=hello_make_tests
it should build anything needed for this test. Then run tests/hello_make_tests.
I have most of the Makefile working. It builds and compiles the source files to .o
links those to the test program.
$\
My problem is that this only works if I use make all first then followed by make test.
When I do make clean followed by make test. I get the following error.
cc -g -Wall -Isrc src/get_one.o src/get_three.o src/get_two.o -c -o src/get_one.o src/get_one.c
cc: error: src/get_one.o: No such file or directory
cc: error: src/get_three.o: No such file or directory
cc: error: src/get_two.o: No such file or directory
make: *** [src/get_one.o] Error 1
The cc call seems to be wrong with object files acting as sources? I am pretty new to make and am
unable to figure this out. Please help.
This line
adds all objects to the CFLAGS variable which will be used by the implicit rules (that are built into make) when compiling.
Try to keep source, compiler flags and resulting object files separate in your makefile to avoid this kind of confusion.
Have a quick look at the documentation for the makefile flags if you’re uncertain of their usage.