# Semana 2: ownership y templates. Se usa dentro del entorno del curso.
#
#   make            compila los programas de la clase en build/
#   make lab        compila el laboratorio en build/lab/
#   make copy-demo  corre la prueba del paso 2 del laboratorio, que copia una pila
#   make test       corre las pruebas de los ejemplos y de los apuntes
#   make test-lab   prueba su laboratorio; falla hasta que lo terminen
#   make clean      borra lo generado
#
# Los programas de errors/ tienen errores a propósito. No se compilan con make:
# los compilan las pruebas, y ustedes, con los comandos de los apuntes.

CC = gcc
CXX = g++
CFLAGS = -Wall -Wextra -std=c17 -g -fsanitize=address,undefined
CXXFLAGS = -Wall -Wextra -std=c++20 -g -fsanitize=address,undefined
BUILD = build
LAB_DIR ?= lab
OUT = $(BUILD)/$(LAB_DIR)

C_PROGRAMS = owner_in_c max_void
PROGRAMS = new_basics scope_trace array_constructs special_members implicit_moves vector_growth \
           library_moved_from max_of postfix no_default_vector buffer_test sorted_ints_test \
           vector_stack_test
BUFFER_PROGRAMS = copy_demo move_demo int_buffer_test
LAB_PROGRAMS = test_int_stack copy_demo test_stack check_brackets

.PHONY: all lab copy-demo test test-lab clean

all: $(C_PROGRAMS:%=$(BUILD)/%) $(PROGRAMS:%=$(BUILD)/%) $(BUFFER_PROGRAMS:%=$(BUILD)/%)

$(BUILD)/%: %.c | $(BUILD)
	$(CC) $(CFLAGS) $< -o $@

$(BUILD)/%: %.cpp $(wildcard *.h) | $(BUILD)
	$(CXX) $(CXXFLAGS) $< -o $@

$(BUFFER_PROGRAMS:%=$(BUILD)/%): $(BUILD)/%: %.cpp int_buffer.cpp int_buffer.h alloc_count.h | $(BUILD)
	$(CXX) $(CXXFLAGS) $< int_buffer.cpp -o $@

$(BUILD):
	mkdir -p $@

# Lo que escriben ustedes está en $(LAB_DIR). Las pruebas y lo que les damos, siempre en lab/.
INT_STACK = $(LAB_DIR)/int_stack.h $(LAB_DIR)/int_stack.cpp
TEMPLATE = $(LAB_DIR)/stack.h
LAB_FLAGS = $(CXXFLAGS) -I$(LAB_DIR) -Ilab

$(OUT)/test_int_stack: lab/tests/test_int_stack.cpp lab/tests/alloc_count.h $(INT_STACK) | $(OUT)
	$(CXX) $(LAB_FLAGS) lab/tests/test_int_stack.cpp $(LAB_DIR)/int_stack.cpp -o $@

$(OUT)/copy_demo: lab/tests/copy_demo.cpp $(INT_STACK) | $(OUT)
	$(CXX) $(LAB_FLAGS) lab/tests/copy_demo.cpp $(LAB_DIR)/int_stack.cpp -o $@

$(OUT)/test_stack: lab/tests/test_stack.cpp lab/tests/alloc_count.h $(TEMPLATE) | $(OUT)
	$(CXX) $(LAB_FLAGS) lab/tests/test_stack.cpp -o $@

$(OUT)/check_brackets: lab/check_brackets.cpp lab/code_text.cpp lab/code_text.h lab/brackets.h $(LAB_DIR)/brackets.cpp $(TEMPLATE) | $(OUT)
	$(CXX) $(LAB_FLAGS) lab/check_brackets.cpp lab/code_text.cpp $(LAB_DIR)/brackets.cpp -o $@

$(OUT):
	mkdir -p $@

lab: $(LAB_PROGRAMS:%=$(OUT)/%)

copy-demo: $(OUT)/copy_demo
	$(OUT)/copy_demo

# Si existe solution/, también se comprueba la solución del laboratorio.
test: all
	python3 -m unittest discover -p 'test_*.py'

test-lab: all lab
	LAB_DIR=$(LAB_DIR) python3 -m unittest -v test_lab

clean:
	rm -rf $(BUILD) __pycache__
