1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125VENV = .venv
ifeq ($(OS),Windows_NT)
VENV_BIN_DIR = $(VENV)/Scripts
else
VENV_BIN_DIR = $(VENV)/bin
endif
ACTIVATE = $(VENV_BIN_DIR)/activate
PYTHON = $(VENV_BIN_DIR)/python
PIP = $(VENV_BIN_DIR)/pip
BLACK = $(VENV_BIN_DIR)/black
MYPY = $(VENV_BIN_DIR)/mypy
PYTEST = $(VENV_BIN_DIR)/pytest
PY_SRCS = main.py $(wildcard frontend/*.py)
# Use GCC by default
CC = gcc
CFLAGS = -Wall -pedantic -Wextra -Werror -O3 -fPIC -ffast-math
LIB_SRC = backend/library.c
LIB_HDR = backend/library.h
LIB_OBJ = backend/library.o
LIB_TARGET = backend/libbackend.so
LIB_OBJ_TEST = backend/library_test.o
LIB_TARGET_TEST = backend/libbackend_test.so
.PHONY: all
all: build
# Run application
.PHONY: run
run: build $(PY_SRCS) $(LIB_HDR)
$(PYTHON) main.py
# Build application
.PHONY: build
build: build-backend install-deps
.PHONY: build-backend
build-backend: $(LIB_TARGET)
$(LIB_TARGET): $(LIB_OBJ)
$(CC) $(LIB_OBJ) -shared -o $(LIB_TARGET)
$(LIB_OBJ): $(LIB_SRC)
$(CC) -c $(LIB_SRC) $(CFLAGS) -o $(LIB_OBJ)
.PHONY: install-deps
install-deps: $(ACTIVATE)
$(ACTIVATE): requirements.txt
python -m venv $(VENV)
$(PIP) install -r requirements.txt
# Check application
.PHONY: check
check: check-frontend-formatting check-frontend-linting test
.PHONY: check-frontend-formatting
check-frontend-formatting: $(BLACK)
$(BLACK) --check .
.PHONY: check-frontend-linting
check-frontend-linting: $(MYPY)
$(MYPY) .
.PHONY: test
test: build-backend-test $(PYTEST)
$(PYTHON) -m pytest tests
.PHONY: build-backend-test
build-backend-test: $(LIB_TARGET_TEST)
$(LIB_TARGET_TEST): $(LIB_OBJ_TEST)
$(CC) $(LIB_OBJ_TEST) -shared -o $(LIB_TARGET_TEST)
$(LIB_OBJ_TEST): $(LIB_SRC)
$(CC) -c $(LIB_SRC) $(CFLAGS) -DTEST -o $(LIB_OBJ_TEST)
# Format application
.PHONY: format
format: $(BLACK)
$(BLACK) .
# Install dependencies for check and format
$(BLACK): $(ACTIVATE)
$(PIP) install black
$(MYPY): $(ACTIVATE)
$(PIP) install mypy
$(PYTEST): $(ACTIVATE)
$(PIP) install pytest
# Clean
.PHONY: clean
clean:
rm -f backend/*.o
rm -f backend/*.so
rm -rf ./**/__pycache__
rm -rf .mypy_cache
rm -rf .pytest_cache
.PHONY: clean-full
clean-full: clean
rm -rf $(VENV)