# A sample Makefile for building Google Test and using it in user
# tests.  Please tweak it to suit your environment and project.  You
# may want to move it to your project's root directory.
#
# SYNOPSIS:
#
#   make [all]  - makes everything.
#   make TARGET - makes the given target.
#   make clean  - removes all files generated by make.

# Please tweak the following variable definitions as needed by your
# project, except GTEST_HEADERS, which you can use in your own targets
# but shouldn't modify.

# Points to the root of Google Test, relative to where this file is.
# Remember to tweak this if you move this file.
GTEST_DIR = ../../lib/test/gtest

# Where to find user code.
USER_DIR = ../main
TEST_DIR = unit
USER_INCLUDE_DIR = $(USER_DIR)

OBJECT_DIR = ../../obj/test

COMMON_FLAGS = \
	-g \
	-Wall \
	-Wextra \
	-pthread \
	-ggdb3 \
	-O0 \
	-DUNIT_TEST \
	-isystem $(GTEST_DIR)/inc

# Flags passed to the C compiler.
C_FLAGS = $(COMMON_FLAGS) \
	-std=gnu99

# Flags passed to the C++ compiler.
CXX_FLAGS = $(COMMON_FLAGS) \
	-std=gnu++98

# All tests produced by this Makefile.  Remember to add new tests you
# created to the list.
TESTS = \
	battery_unittest \
	flight_imu_unittest \
	flight_mixer_unittest \
	altitude_hold_unittest \
	maths_unittest \
	gps_conversion_unittest \
	telemetry_hott_unittest \
	rc_controls_unittest \
	ledstrip_unittest \
	ws2811_unittest \
	encoding_unittest \
	io_serial_unittest \
	lowpass_unittest

# All Google Test headers.  Usually you shouldn't change this
# definition.
GTEST_HEADERS = $(GTEST_DIR)/inc/gtest/*.h

# House-keeping build targets.

all : $(TESTS)

clean :
	rm -rf $(TESTS) $(OBJECT_DIR)

# Builds gtest.a and gtest_main.a.

# Usually you shouldn't tweak such internal variables, indicated by a
# trailing _.
GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/inc/gtest/*.h $(GTEST_HEADERS)

# For simplicity and to avoid depending on Google Test's
# implementation details, the dependencies specified below are
# conservative and not optimized.  This is fine as Google Test
# compiles fast and for ordinary users its source rarely changes.
$(OBJECT_DIR)/gtest-all.o : $(GTEST_SRCS_)
	@mkdir -p $(dir $@)
	$(CXX) $(CXX_FLAGS) -I$(GTEST_DIR) -c \
            $(GTEST_DIR)/src/gtest-all.cc -o $@

$(OBJECT_DIR)/gtest_main.o : $(GTEST_SRCS_)
	@mkdir -p $(dir $@)
	$(CXX) $(CXX_FLAGS) -I$(GTEST_DIR) -c \
            $(GTEST_DIR)/src/gtest_main.cc -o $@

$(OBJECT_DIR)/gtest.a : $(OBJECT_DIR)/gtest-all.o
	$(AR) $(ARFLAGS) $@ $^

$(OBJECT_DIR)/gtest_main.a : $(OBJECT_DIR)/gtest-all.o $(OBJECT_DIR)/gtest_main.o
	$(AR) $(ARFLAGS) $@ $^

# Builds a sample test.  A test should link with either gtest.a or
# gtest_main.a, depending on whether it defines its own main()
# function.

# includes in test dir must override includes in user dir
TEST_INCLUDE_DIRS := $(TEST_DIR) \
	$(USER_INCLUDE_DIR)

TEST_CFLAGS	 = $(addprefix -I,$(TEST_INCLUDE_DIRS))

$(OBJECT_DIR)/common/maths.o : \
	$(USER_DIR)/common/maths.c \
	$(USER_DIR)/common/maths.h \
	$(GTEST_HEADERS)

	@mkdir -p $(dir $@)
	$(CC) $(C_FLAGS) $(TEST_CFLAGS) -c $(USER_DIR)/common/maths.c -o $@


$(OBJECT_DIR)/sensors/battery.o : $(USER_DIR)/sensors/battery.c $(USER_DIR)/sensors/battery.h $(GTEST_HEADERS)
	@mkdir -p $(dir $@)
	$(CC) $(C_FLAGS) $(TEST_CFLAGS) -c $(USER_DIR)/sensors/battery.c -o $@

$(OBJECT_DIR)/battery_unittest.o : \
	$(TEST_DIR)/battery_unittest.cc \
	$(USER_DIR)/sensors/battery.h \
	$(GTEST_HEADERS)

	@mkdir -p $(dir $@)
	$(CXX) $(CXX_FLAGS) $(TEST_CFLAGS) -c $(TEST_DIR)/battery_unittest.cc -o $@

battery_unittest : \
	$(OBJECT_DIR)/sensors/battery.o \
	$(OBJECT_DIR)/common/maths.o \
	$(OBJECT_DIR)/battery_unittest.o \
	$(OBJECT_DIR)/gtest_main.a

	$(CXX) $(CXX_FLAGS) -lpthread $^ -o $(OBJECT_DIR)/$@
	
$(OBJECT_DIR)/common/encoding.o : $(USER_DIR)/common/encoding.c $(USER_DIR)/common/encoding.h $(GTEST_HEADERS)
	@mkdir -p $(dir $@)
	$(CC) $(C_FLAGS) $(TEST_CFLAGS) -c $(USER_DIR)/common/encoding.c -o $@

$(OBJECT_DIR)/encoding_unittest.o : \
	$(TEST_DIR)/encoding_unittest.cc \
	$(USER_DIR)/common/encoding.h \
	$(GTEST_HEADERS)

	@mkdir -p $(dir $@)
	$(CXX) $(CXX_FLAGS) $(TEST_CFLAGS) -c $(TEST_DIR)/encoding_unittest.cc -o $@

encoding_unittest : \
	$(OBJECT_DIR)/common/encoding.o \
	$(OBJECT_DIR)/encoding_unittest.o \
	$(OBJECT_DIR)/gtest_main.a

	$(CXX) $(CXX_FLAGS) -lpthread $^ -o $(OBJECT_DIR)/$@

$(OBJECT_DIR)/flight/imu.o : \
	$(USER_DIR)/flight/imu.c \
	$(USER_DIR)/flight/imu.h \
	$(GTEST_HEADERS)

	@mkdir -p $(dir $@)
	$(CC) $(C_FLAGS) $(TEST_CFLAGS) -c $(USER_DIR)/flight/imu.c -o $@

$(OBJECT_DIR)/flight_imu_unittest.o : \
	$(TEST_DIR)/flight_imu_unittest.cc \
	$(USER_DIR)/flight/imu.h \
	$(GTEST_HEADERS)

	@mkdir -p $(dir $@)
	$(CXX) $(CXX_FLAGS) $(TEST_CFLAGS) -c $(TEST_DIR)/flight_imu_unittest.cc -o $@

flight_imu_unittest : \
	$(OBJECT_DIR)/flight/imu.o \
	$(OBJECT_DIR)/flight/altitudehold.o \
	$(OBJECT_DIR)/flight_imu_unittest.o \
	$(OBJECT_DIR)/common/maths.o \
	$(OBJECT_DIR)/gtest_main.a

	$(CXX) $(CXX_FLAGS) -lpthread $^ -o $(OBJECT_DIR)/$@

$(OBJECT_DIR)/maths_unittest.o : \
	$(TEST_DIR)/maths_unittest.cc \
	$(GTEST_HEADERS)

	@mkdir -p $(dir $@)
	$(CXX) $(CXX_FLAGS) $(TEST_CFLAGS) -c $(TEST_DIR)/maths_unittest.cc -o $@

maths_unittest : \
	$(OBJECT_DIR)/maths_unittest.o \
	$(OBJECT_DIR)/common/maths.o \
	$(OBJECT_DIR)/gtest_main.a

	$(CXX) $(CXX_FLAGS) -lpthread $^ -o $(OBJECT_DIR)/$@



$(OBJECT_DIR)/flight/altitudehold.o : \
	$(USER_DIR)/flight/altitudehold.c \
	$(USER_DIR)/flight/altitudehold.h \
	$(GTEST_HEADERS)

	@mkdir -p $(dir $@)
	$(CC) $(C_FLAGS) $(TEST_CFLAGS) -c $(USER_DIR)/flight/altitudehold.c -o $@

$(OBJECT_DIR)/altitude_hold_unittest.o : \
	$(TEST_DIR)/altitude_hold_unittest.cc \
	$(USER_DIR)/flight/altitudehold.h \
	$(GTEST_HEADERS)

	@mkdir -p $(dir $@)
	$(CXX) $(CXX_FLAGS) $(TEST_CFLAGS) -c $(TEST_DIR)/altitude_hold_unittest.cc -o $@

altitude_hold_unittest : \
	$(OBJECT_DIR)/flight/altitudehold.o \
	$(OBJECT_DIR)/altitude_hold_unittest.o \
	$(OBJECT_DIR)/gtest_main.a

	$(CXX) $(CXX_FLAGS) -lpthread $^ -o $(OBJECT_DIR)/$@


$(OBJECT_DIR)/flight/gps_conversion.o : \
	$(USER_DIR)/flight/gps_conversion.c \
	$(USER_DIR)/flight/gps_conversion.h \
	$(GTEST_HEADERS)

	@mkdir -p $(dir $@)
	$(CC) $(C_FLAGS) $(TEST_CFLAGS) -c $(USER_DIR)/flight/gps_conversion.c -o $@

$(OBJECT_DIR)/gps_conversion_unittest.o : \
	$(TEST_DIR)/gps_conversion_unittest.cc \
	$(USER_DIR)/flight/gps_conversion.h \
	$(GTEST_HEADERS)

	@mkdir -p $(dir $@)
	$(CXX) $(CXX_FLAGS) $(TEST_CFLAGS) -c $(TEST_DIR)/gps_conversion_unittest.cc -o $@

gps_conversion_unittest : \
	$(OBJECT_DIR)/flight/gps_conversion.o \
	$(OBJECT_DIR)/gps_conversion_unittest.o \
	$(OBJECT_DIR)/gtest_main.a

	$(CXX) $(CXX_FLAGS) -lpthread $^ -o $(OBJECT_DIR)/$@



$(OBJECT_DIR)/telemetry/hott.o : \
	$(USER_DIR)/telemetry/hott.c \
	$(USER_DIR)/telemetry/hott.h \
	$(GTEST_HEADERS)

	@mkdir -p $(dir $@)
	$(CC) $(C_FLAGS) $(TEST_CFLAGS) -c $(USER_DIR)/telemetry/hott.c -o $@

$(OBJECT_DIR)/telemetry_hott_unittest.o : \
	$(TEST_DIR)/telemetry_hott_unittest.cc \
	$(USER_DIR)/telemetry/hott.h \
	$(GTEST_HEADERS)
	
	@mkdir -p $(dir $@)
	$(CXX) $(CXX_FLAGS) $(TEST_CFLAGS) -c $(TEST_DIR)/telemetry_hott_unittest.cc -o $@

telemetry_hott_unittest : \
	$(OBJECT_DIR)/telemetry/hott.o \
	$(OBJECT_DIR)/telemetry_hott_unittest.o \
	$(OBJECT_DIR)/flight/gps_conversion.o \
	$(OBJECT_DIR)/gtest_main.a

	$(CXX) $(CXX_FLAGS) -lpthread $^ -o $(OBJECT_DIR)/$@



$(OBJECT_DIR)/io/rc_controls.o : \
	$(USER_DIR)/io/rc_controls.c \
	$(USER_DIR)/io/rc_controls.h \
	$(GTEST_HEADERS)

	@mkdir -p $(dir $@)
	$(CC) $(C_FLAGS) $(TEST_CFLAGS) -c $(USER_DIR)/io/rc_controls.c -o $@

$(OBJECT_DIR)/rc_controls_unittest.o : \
	$(TEST_DIR)/rc_controls_unittest.cc \
	$(USER_DIR)/io/rc_controls.h \
	$(GTEST_HEADERS)

	@mkdir -p $(dir $@)
	$(CXX) $(CXX_FLAGS) $(TEST_CFLAGS) -c $(TEST_DIR)/rc_controls_unittest.cc -o $@

rc_controls_unittest : \
	$(OBJECT_DIR)/common/maths.o \
	$(OBJECT_DIR)/io/rc_controls.o \
	$(OBJECT_DIR)/rc_controls_unittest.o \
	$(OBJECT_DIR)/gtest_main.a

	$(CXX) $(CXX_FLAGS) -lpthread $^ -o $(OBJECT_DIR)/$@


$(OBJECT_DIR)/io/ledstrip.o : \
	$(USER_DIR)/io/ledstrip.c \
	$(USER_DIR)/io/ledstrip.h \
	$(GTEST_HEADERS)
	
	@mkdir -p $(dir $@)
	$(CC) $(C_FLAGS) $(TEST_CFLAGS) -c $(USER_DIR)/io/ledstrip.c -o $@

$(OBJECT_DIR)/ledstrip_unittest.o : \
	$(TEST_DIR)/ledstrip_unittest.cc \
	$(USER_DIR)/io/ledstrip.h \
	$(GTEST_HEADERS)

	@mkdir -p $(dir $@)
	$(CXX) $(CXX_FLAGS) $(TEST_CFLAGS) -c $(TEST_DIR)/ledstrip_unittest.cc -o $@

ledstrip_unittest : \
	$(OBJECT_DIR)/io/ledstrip.o \
	$(OBJECT_DIR)/ledstrip_unittest.o \
	$(OBJECT_DIR)/gtest_main.a

	$(CXX) $(CXX_FLAGS) -lpthread $^ -o $(OBJECT_DIR)/$@



$(OBJECT_DIR)/drivers/light_ws2811strip.o : \
	$(USER_DIR)/drivers/light_ws2811strip.c \
	$(USER_DIR)/drivers/light_ws2811strip.h \
	$(GTEST_HEADERS)

	@mkdir -p $(dir $@)
	$(CC) $(C_FLAGS) $(TEST_CFLAGS) -c $(USER_DIR)/drivers/light_ws2811strip.c -o $@

$(OBJECT_DIR)/ws2811_unittest.o : \
	$(TEST_DIR)/ws2811_unittest.cc \
	$(USER_DIR)/drivers/light_ws2811strip.h \
	$(GTEST_HEADERS)

	@mkdir -p $(dir $@)
	$(CXX) $(CXX_FLAGS) $(TEST_CFLAGS) -c $(TEST_DIR)/ws2811_unittest.cc -o $@

ws2811_unittest : \
	$(OBJECT_DIR)/drivers/light_ws2811strip.o \
	$(OBJECT_DIR)/ws2811_unittest.o \
	$(OBJECT_DIR)/gtest_main.a

	$(CXX) $(CXX_FLAGS) -lpthread $^ -o $(OBJECT_DIR)/$@


$(OBJECT_DIR)/flight/lowpass.o : \
	$(USER_DIR)/flight/lowpass.c \
	$(USER_DIR)/flight/lowpass.h \
	$(GTEST_HEADERS)

	@mkdir -p $(dir $@)
	$(CC) $(C_FLAGS) $(TEST_CFLAGS) -c $(USER_DIR)/flight/lowpass.c -o $@

$(OBJECT_DIR)/lowpass_unittest.o : \
	$(TEST_DIR)/lowpass_unittest.cc \
	$(USER_DIR)/flight/lowpass.h \
	$(GTEST_HEADERS)

	@mkdir -p $(dir $@)
	$(CXX) $(CXX_FLAGS) $(TEST_CFLAGS) -c $(TEST_DIR)/lowpass_unittest.cc -o $@

lowpass_unittest : \
	$(OBJECT_DIR)/flight/lowpass.o \
	$(OBJECT_DIR)/lowpass_unittest.o \
	$(OBJECT_DIR)/gtest_main.a

	$(CXX) $(CXX_FLAGS) -lpthread $^ -o $(OBJECT_DIR)/$@

$(OBJECT_DIR)/flight/mixer.o : \
	$(USER_DIR)/flight/mixer.c \
	$(USER_DIR)/flight/mixer.h \
	$(GTEST_HEADERS)

	@mkdir -p $(dir $@)
	$(CC) $(C_FLAGS) $(TEST_CFLAGS) -c $(USER_DIR)/flight/mixer.c -o $@

$(OBJECT_DIR)/flight_mixer_unittest.o : \
	$(TEST_DIR)/flight_mixer_unittest.cc \
	$(USER_DIR)/flight/mixer.h \
	$(GTEST_HEADERS)

	@mkdir -p $(dir $@)
	$(CXX) $(CXX_FLAGS) $(TEST_CFLAGS) -c $(TEST_DIR)/flight_mixer_unittest.cc -o $@

flight_mixer_unittest : \
	$(OBJECT_DIR)/flight/mixer.o \
	$(OBJECT_DIR)/flight_mixer_unittest.o \
	$(OBJECT_DIR)/common/maths.o \
	$(OBJECT_DIR)/gtest_main.a

	$(CXX) $(CXX_FLAGS) -lpthread $^ -o $(OBJECT_DIR)/$@

$(OBJECT_DIR)/io/serial.o : \
	$(USER_DIR)/io/serial.c \
	$(USER_DIR)/io/serial.h \
	$(GTEST_HEADERS)

	@mkdir -p $(dir $@)
	$(CC) $(C_FLAGS) $(TEST_CFLAGS) -c $(USER_DIR)/io/serial.c -o $@

$(OBJECT_DIR)/io_serial_unittest.o : \
	$(TEST_DIR)/io_serial_unittest.cc \
	$(USER_DIR)/io/serial.h \
	$(GTEST_HEADERS)

	@mkdir -p $(dir $@)
	$(CXX) $(CXX_FLAGS) $(TEST_CFLAGS) -c $(TEST_DIR)/io_serial_unittest.cc -o $@

io_serial_unittest : \
	$(OBJECT_DIR)/io/serial.o \
	$(OBJECT_DIR)/io_serial_unittest.o \
	$(OBJECT_DIR)/gtest_main.a

	$(CXX) $(CXX_FLAGS) -lpthread $^ -o $(OBJECT_DIR)/$@

test: $(TESTS)
	set -e && for test in $(TESTS) ; do \
		$(OBJECT_DIR)/$$test; \
	done

