# example/example.mk: living example part (plan 10-workflow-example.md). # Included by the root Makefile through per-part subdir .mk includes, or run # standalone from the repo root: # make -f example/example.mk example # build lib + server # make -f example/example.mk example-test # build + run example suite # make -f example/example.mk example-clean # remove build/example # Portable make: variables plus sh loops only, no GNU-only functions. CXX ?= g++ EXAMPLE_CXXFLAGS ?= -std=c++23 -Wall -Wextra -O1 EXAMPLE_DIR ?= example EXAMPLE_BUILD ?= build/example EXAMPLE_TESTDIR ?= tests/example EXAMPLE_SRCS = \ $(EXAMPLE_DIR)/fw/Http.cpp \ $(EXAMPLE_DIR)/fw/Router.cpp \ $(EXAMPLE_DIR)/fw/App.cpp \ $(EXAMPLE_DIR)/fw/View.cpp \ $(EXAMPLE_DIR)/fw/Validate.cpp \ $(EXAMPLE_DIR)/fw/Templates.cpp \ $(EXAMPLE_DIR)/fw/Negotiate.cpp \ $(EXAMPLE_DIR)/fw/Cookies.cpp \ $(EXAMPLE_DIR)/fw/StaticFiles.cpp \ $(EXAMPLE_DIR)/fw/Tls.cpp \ $(EXAMPLE_DIR)/fw/Kv.cpp \ $(EXAMPLE_DIR)/fw/Observ.cpp \ $(EXAMPLE_DIR)/fw/Data.cpp \ $(EXAMPLE_DIR)/fw/Jobs.cpp \ $(EXAMPLE_DIR)/fw/Net.cpp \ $(EXAMPLE_DIR)/fw/Workflow.cpp \ $(EXAMPLE_DIR)/fw/TestClient.cpp \ $(EXAMPLE_DIR)/fw/Server.cpp \ $(EXAMPLE_DIR)/app/App.cpp \ $(EXAMPLE_DIR)/app/Seed.cpp \ $(EXAMPLE_DIR)/app/Templates.cpp \ $(EXAMPLE_DIR)/app/Embedded.cpp \ $(EXAMPLE_DIR)/app/Index.cpp \ $(EXAMPLE_DIR)/app/RoutingDemo.cpp \ $(EXAMPLE_DIR)/app/DataDemo.cpp \ $(EXAMPLE_DIR)/app/SecurityDemo.cpp \ $(EXAMPLE_DIR)/app/FormatsDemo.cpp \ $(EXAMPLE_DIR)/app/RealtimeDemo.cpp \ $(EXAMPLE_DIR)/app/OpsDemo.cpp EXAMPLE_TESTS = \ $(EXAMPLE_TESTDIR)/index_test.cpp \ $(EXAMPLE_TESTDIR)/health_test.cpp \ $(EXAMPLE_TESTDIR)/routing/hello_test.cpp \ $(EXAMPLE_TESTDIR)/routing/views_test.cpp \ $(EXAMPLE_TESTDIR)/routing/routers_test.cpp \ $(EXAMPLE_TESTDIR)/chain/deep_test.cpp \ $(EXAMPLE_TESTDIR)/orm/users_test.cpp \ $(EXAMPLE_TESTDIR)/kv/items_test.cpp \ $(EXAMPLE_TESTDIR)/cache/lookup_test.cpp \ $(EXAMPLE_TESTDIR)/pubsub/publish_test.cpp \ $(EXAMPLE_TESTDIR)/auth/login_test.cpp \ $(EXAMPLE_TESTDIR)/auth/me_test.cpp \ $(EXAMPLE_TESTDIR)/sessions/counter_test.cpp \ $(EXAMPLE_TESTDIR)/uploads/file_test.cpp \ $(EXAMPLE_TESTDIR)/forms/contact_test.cpp \ $(EXAMPLE_TESTDIR)/validate/user_test.cpp \ $(EXAMPLE_TESTDIR)/templates/page_test.cpp \ $(EXAMPLE_TESTDIR)/formats/data_test.cpp \ $(EXAMPLE_TESTDIR)/static/files_test.cpp \ $(EXAMPLE_TESTDIR)/embedded/assets_test.cpp \ $(EXAMPLE_TESTDIR)/streaming/feed_test.cpp \ $(EXAMPLE_TESTDIR)/streaming/passthrough_test.cpp \ $(EXAMPLE_TESTDIR)/ws/chat_test.cpp \ $(EXAMPLE_TESTDIR)/socketio/rooms_test.cpp \ $(EXAMPLE_TESTDIR)/sse/events_test.cpp \ $(EXAMPLE_TESTDIR)/webdav/files_test.cpp \ $(EXAMPLE_TESTDIR)/events/fire_test.cpp \ $(EXAMPLE_TESTDIR)/metrics/counters_test.cpp \ $(EXAMPLE_TESTDIR)/telemetry/trace_test.cpp \ $(EXAMPLE_TESTDIR)/supervisor/tasks_test.cpp \ $(EXAMPLE_TESTDIR)/supervisor/workers_test.cpp \ $(EXAMPLE_TESTDIR)/replication/state_test.cpp \ $(EXAMPLE_TESTDIR)/restclient/self_test.cpp \ $(EXAMPLE_TESTDIR)/openapi/docs_test.cpp \ $(EXAMPLE_TESTDIR)/cli/ai_test.cpp \ $(EXAMPLE_TESTDIR)/workflow/release_test.cpp \ $(EXAMPLE_TESTDIR)/redirect/here_test.cpp .PHONY: example example-test example-clean example: mkdir -p $(EXAMPLE_BUILD)/obj for s in $(EXAMPLE_SRCS); do \ o=$(EXAMPLE_BUILD)/obj/`echo $$s | tr '/' '_'`.o; \ $(CXX) $(EXAMPLE_CXXFLAGS) -I$(EXAMPLE_DIR) -c $$s -o $$o || exit 1; \ done ar rcs $(EXAMPLE_BUILD)/libexample.a $(EXAMPLE_BUILD)/obj/*.o $(CXX) $(EXAMPLE_CXXFLAGS) -I$(EXAMPLE_DIR) $(EXAMPLE_DIR)/main.cpp \ $(EXAMPLE_BUILD)/libexample.a -o $(EXAMPLE_BUILD)/living-server example-test: example mkdir -p $(EXAMPLE_BUILD)/tests pass=0; fail=0; \ for t in $(EXAMPLE_TESTS); do \ n=`echo $$t | sed 's|$(EXAMPLE_TESTDIR)/||; s|/|_|g; s|\.cpp$$||'`; \ $(CXX) $(EXAMPLE_CXXFLAGS) -I$(EXAMPLE_DIR) -I$(EXAMPLE_TESTDIR) \ $$t $(EXAMPLE_BUILD)/libexample.a \ -o $(EXAMPLE_BUILD)/tests/$$n || exit 1; \ if $(EXAMPLE_BUILD)/tests/$$n; then pass=$$((pass+1)); \ else fail=$$((fail+1)); echo "FAIL: $$t"; fi; \ done; \ echo "example suite: $$pass passed, $$fail failed"; \ test $$fail -eq 0 example-clean: rm -rf $(EXAMPLE_BUILD) # Root Makefile aggregation points (double-colon: safe with other parts). all:: example test:: example-test clean:: example-clean