CC ?= cc CFLAGS ?= -O2 -g VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null \ || echo 0.1.0-dev) WARN = -Wall -Wextra -Wshadow -Wstrict-prototypes -Wmissing-prototypes \ -Wpointer-arith -Wvla -Wformat=2 WARN += $(if $(WERROR),-Werror) DEPFLAGS = -MMD -MP CPPFLAGS = -Isrc -Iclients -Ivendor -Ivendor/argon2 DEFS = -D_GNU_SOURCE -DARGON2_NO_THREADS -DBOKF_VERSION=\"$(VERSION)\" BUILD ?= build VENDOR_SRC = vendor/sqlite3.c vendor/yyjson.c vendor/sha256.c \ vendor/argon2/argon2.c vendor/argon2/core.c \ vendor/argon2/encoding.c vendor/argon2/ref.c \ vendor/argon2/thread.c vendor/argon2/blake2/blake2b.c CORE_SRC = src/util.c src/log.c src/config.c src/db.c src/auth.c \ src/sessions.c src/audit.c src/protocol.c src/commands.c \ src/cmd_util.c src/cmd_auth.c src/cmd_org.c src/cmd_users.c \ src/cmd_audit.c src/cmd_accounts.c src/cmd_fiscal.c \ src/cmd_vouchers.c src/cmd_templates.c src/cmd_settings.c \ src/cmd_customers.c src/cmd_invoices.c src/cmd_rules.c \ src/cmd_attachments.c src/cmd_reports.c src/cmd_sru.c \ src/cmd_sie.c src/cmd_bokslut.c src/cmd_bank.c \ src/cmd_employees.c src/cmd_payroll.c \ src/seed.c src/ledger.c src/reports.c src/sru.c src/sie.c \ src/formula.c src/pdf.c src/invoice.c src/payslip.c src/mail.c \ src/secret.c src/smtp.c src/tax_table.c VENDOR_OBJ = $(patsubst %.c,$(BUILD)/%.o,$(VENDOR_SRC)) CORE_OBJ = $(patsubst %.c,$(BUILD)/%.o,$(CORE_SRC)) all: $(BUILD)/bokfd $(BUILD)/bokfctl $(BUILD)/bokftui backend: $(BUILD)/bokfd $(BUILD)/bokfctl SSL_LIBS = -lssl -lcrypto $(BUILD)/bokfd: $(BUILD)/src/bokfd.o $(CORE_OBJ) $(VENDOR_OBJ) $(CC) $(CFLAGS) -o $@ $^ -lm $(SSL_LIBS) $(BUILD)/bokfctl: $(BUILD)/clients/bokfctl.o $(BUILD)/clients/client.o \ $(BUILD)/src/util.o $(BUILD)/src/log.o $(BUILD)/vendor/yyjson.o \ $(BUILD)/vendor/sha256.o $(CC) $(CFLAGS) -o $@ $^ -lm $(SSL_LIBS) TUI_SCREENS = clients/screens_dashboard.c clients/screens_vouchers.c \ clients/screens_accounts.c clients/screens_reports.c \ clients/screens_rules.c clients/screens_attachments.c \ clients/screens_bank.c clients/screens_audit.c \ clients/screens_templates.c clients/screens_ib.c \ clients/screens_settings.c clients/screens_invoices.c \ clients/screens_bokslut.c TUI_SCREEN_OBJ = $(patsubst %.c,$(BUILD)/%.o,$(TUI_SCREENS)) TUI_SCREEN_DEP = $(TUI_SCREEN_OBJ:.o=.d) $(BUILD)/bokftui: $(BUILD)/clients/bokftui.o $(BUILD)/clients/ui.o \ $(TUI_SCREEN_OBJ) $(BUILD)/clients/tui.o \ $(BUILD)/clients/client.o \ $(BUILD)/src/util.o $(BUILD)/src/log.o $(BUILD)/src/formula.o \ $(BUILD)/vendor/yyjson.o $(BUILD)/vendor/sha256.o $(CC) $(CFLAGS) -o $@ $^ -lm -lncursesw $(SSL_LIBS) $(BUILD)/test_core: $(BUILD)/tests/test_core.o $(BUILD)/clients/client.o \ $(CORE_OBJ) $(VENDOR_OBJ) $(CC) $(CFLAGS) -o $@ $^ -lm $(SSL_LIBS) $(BUILD)/test_tui: $(BUILD)/tests/test_tui.o $(BUILD)/clients/tui.o \ $(BUILD)/src/util.o $(BUILD)/src/log.o $(BUILD)/vendor/yyjson.o \ $(BUILD)/vendor/sha256.o $(CC) $(CFLAGS) -o $@ $^ -lm -lncursesw $(BUILD)/test_pdf: $(BUILD)/tests/pdf_check.o $(BUILD)/src/pdf.o \ $(BUILD)/src/util.o $(BUILD)/vendor/sha256.o $(CC) $(CFLAGS) -o $@ $^ -lm $(BUILD)/test_invoice: $(BUILD)/tests/invoice_check.o $(BUILD)/src/invoice.o \ $(BUILD)/src/pdf.o $(BUILD)/src/util.o \ $(BUILD)/vendor/sha256.o $(CC) $(CFLAGS) -o $@ $^ -lm -lssl -lcrypto $(BUILD)/test_smtp: $(BUILD)/tests/smtp_check.o $(BUILD)/src/smtp.o \ $(BUILD)/src/util.o $(BUILD)/src/log.o \ $(BUILD)/vendor/sha256.o $(CC) $(CFLAGS) -o $@ $^ -lm -lssl -lcrypto $(BUILD)/gen_protocol: $(BUILD)/scripts/gen_protocol.o $(CORE_OBJ) $(VENDOR_OBJ) $(CC) $(CFLAGS) -o $@ $^ -lm $(SSL_LIBS) gen-protocol: $(BUILD)/gen_protocol $(BUILD)/gen_protocol --write docs/PROTOCOL.md test: check $(BUILD)/test_core $(BUILD)/test_tui $(BUILD)/test_pdf \ $(BUILD)/test_invoice $(BUILD)/test_smtp $(BUILD)/test_core $(BUILD)/test_tui $(BUILD)/test_pdf $(BUILD)/test_invoice $(BUILD)/test_smtp test-core: $(BUILD)/test_core $(BUILD)/test_core check: $(BUILD)/gen_protocol $(BUILD)/gen_protocol --check docs/PROTOCOL.md sh scripts/check-consistency.sh test-pty: all python3 scripts/tui-golden.py SAN_CFLAGS = -O1 -g -fno-omit-frame-pointer ASAN_BUILD ?= build-asan UBSAN_BUILD ?= build-ubsan test-asan: $(MAKE) BUILD=$(ASAN_BUILD) CFLAGS="$(SAN_CFLAGS) -fsanitize=address" test-core test-ubsan: $(MAKE) BUILD=$(UBSAN_BUILD) CFLAGS="$(SAN_CFLAGS) -fsanitize=undefined" test-core GATE_BUILD ?= build-gate # A pre-stop check in its own build directory: never touches build/, so the # human's clients are still there when it is done. gate: $(MAKE) BUILD=$(GATE_BUILD) ASAN_BUILD=$(GATE_BUILD)-asan \ UBSAN_BUILD=$(GATE_BUILD)-ubsan clean $(MAKE) BUILD=$(GATE_BUILD) WERROR=1 all $(MAKE) BUILD=$(GATE_BUILD) WERROR=1 test $(MAKE) BUILD=$(GATE_BUILD) ASAN_BUILD=$(GATE_BUILD)-asan test-asan $(BUILD)/vendor/%.o: vendor/%.c @mkdir -p $(dir $@) $(CC) $(CFLAGS) $(DEPFLAGS) $(CPPFLAGS) $(DEFS) -w -c $< -o $@ $(BUILD)/src/%.o: src/%.c @mkdir -p $(dir $@) $(CC) $(CFLAGS) $(DEPFLAGS) $(WARN) $(CPPFLAGS) $(DEFS) -c $< -o $@ $(BUILD)/clients/%.o: clients/%.c @mkdir -p $(dir $@) $(CC) $(CFLAGS) $(DEPFLAGS) $(WARN) $(CPPFLAGS) $(DEFS) -c $< -o $@ $(BUILD)/scripts/%.o: scripts/%.c @mkdir -p $(dir $@) $(CC) $(CFLAGS) $(DEPFLAGS) $(WARN) $(CPPFLAGS) $(DEFS) -c $< -o $@ $(BUILD)/tests/%.o: tests/%.c @mkdir -p $(dir $@) $(CC) $(CFLAGS) $(DEPFLAGS) $(WARN) $(CPPFLAGS) $(DEFS) -c $< -o $@ -include $(VENDOR_OBJ:.o=.d) $(CORE_OBJ:.o=.d) $(BUILD)/src/bokfd.d \ $(BUILD)/clients/bokfctl.d $(BUILD)/clients/bokftui.d \ $(BUILD)/clients/ui.d $(TUI_SCREEN_DEP) \ $(BUILD)/clients/tui.d $(BUILD)/clients/client.d \ $(BUILD)/tests/test_core.d $(BUILD)/tests/test_tui.d \ $(BUILD)/tests/pdf_check.d $(BUILD)/tests/invoice_check.d \ $(BUILD)/tests/smtp_check.d \ $(BUILD)/scripts/gen_protocol.d install: all install -d $(DESTDIR)/usr/local/bin $(DESTDIR)/usr/local/share/bokf install -m 0755 $(BUILD)/bokfd $(BUILD)/bokfctl $(BUILD)/bokftui \ $(DESTDIR)/usr/local/bin/ install -m 0644 data/bas_k2.csv data/bas_k3.csv $(DESTDIR)/usr/local/share/bokf/ clean: rm -rf $(BUILD) $(ASAN_BUILD) $(UBSAN_BUILD) .PHONY: all backend test test-core test-pty check gen-protocol test-asan test-ubsan gate \ install clean