381 lines
17 KiB
Makefile
381 lines
17 KiB
Makefile
# Build and test the calog broker core and engine adapters.
|
|
#
|
|
# Layout:
|
|
# src/ project source; one subdir per script language
|
|
# (src/lua, src/mybasic, src/squirrel); core + actor live in src/
|
|
# tests/ test programs
|
|
# vendor/ third-party engine sources, built from source (lua, mybasic,
|
|
# squirrel-src) -- no system engine packages, so the build is
|
|
# reproducible
|
|
# obj/ all object files (ours and the vendored engines)
|
|
# bin/ all binaries
|
|
#
|
|
# Core is strict (-Wconversion/-Wsign-conversion) + ASan/UBSan; adapters drop the
|
|
# two conversion warnings (engine headers use wide macros). Vendored engines build
|
|
# relaxed and un-sanitized but link into the sanitized binaries so cross-boundary
|
|
# heap misuse is still caught. -MMD/-MP generate header dependencies automatically.
|
|
|
|
CC = gcc
|
|
CXX = g++
|
|
STRICT = -Wall -Wextra -Werror -Wconversion -Wsign-conversion
|
|
WARN = -Wall -Wextra -Werror
|
|
SAN = -fsanitize=address,undefined
|
|
DEP = -MMD -MP
|
|
COREFLAGS = -std=c11 $(STRICT) $(DEP) -g -O1 $(SAN)
|
|
ADPFLAGS = -std=c11 $(WARN) $(DEP) -g -O1 $(SAN)
|
|
LDFLAGS = $(SAN)
|
|
|
|
# Our headers: src/ plus the per-language subdirs. VPATH lets the object rules find
|
|
# a source by name without spelling out its directory.
|
|
INC = -Isrc -Isrc/lua -Isrc/mybasic -Isrc/squirrel -Isrc/js -Isrc/berry -Isrc/s7 -Isrc/wren
|
|
VPATH = src:src/lua:src/mybasic:src/squirrel:src/js:src/berry:src/s7:src/wren:tests
|
|
|
|
CORE = obj/value.o obj/broker.o
|
|
|
|
# --- vendored my-basic (C) ---
|
|
MBDIR = vendor/mybasic
|
|
MBINC = -I$(MBDIR)
|
|
MBFLAGS = -std=gnu11 -w -g -O1 -DMB_DOUBLE_FLOAT
|
|
|
|
# --- vendored Lua 5.4.6 (C) ---
|
|
# The platform define is chosen from uname, the way upstream Lua's own Makefile
|
|
# does, so the build is correct on Linux / macOS / other POSIX without hand-editing.
|
|
# LUA_USE_LINUX and _MACOSX enable dlopen-based package loading (loadlib.c); on
|
|
# Linux that needs -ldl. The standalone interpreter (lua.c, the only file that uses
|
|
# readline) is not built, so there is no readline dependency. The library is every
|
|
# src/*.c except the two standalone mains (lua.c, luac.c).
|
|
LUADIR = vendor/lua
|
|
LUAINC = -I$(LUADIR)/src
|
|
# Check $(OS) first -- Windows sets OS=Windows_NT in the environment (make inherits
|
|
# it) and has no `uname`, so probing uname there yields an empty string that would
|
|
# wrongly select POSIX. Only fall back to `uname` on Unix. (The rest of the project
|
|
# is Unix-only anyway -- pthreads, sanitizers, setarch -- so the Windows branch just
|
|
# keeps the Lua define correct, it does not by itself make a Windows build work.)
|
|
ifeq ($(OS),Windows_NT)
|
|
LUAPLAT =
|
|
LUAPLATLIBS =
|
|
else
|
|
UNAMES := $(shell uname -s)
|
|
ifeq ($(UNAMES),Linux)
|
|
LUAPLAT = -DLUA_USE_LINUX
|
|
LUAPLATLIBS = -ldl
|
|
else ifeq ($(UNAMES),Darwin)
|
|
LUAPLAT = -DLUA_USE_MACOSX
|
|
LUAPLATLIBS =
|
|
else
|
|
LUAPLAT = -DLUA_USE_POSIX
|
|
LUAPLATLIBS =
|
|
endif
|
|
endif
|
|
LUAFLAGS = -std=c99 -w -g -O2 $(LUAPLAT)
|
|
LUASRC = $(filter-out $(LUADIR)/src/lua.c $(LUADIR)/src/luac.c, $(wildcard $(LUADIR)/src/*.c))
|
|
LUAOBJ = $(patsubst $(LUADIR)/src/%.c,obj/%.o,$(LUASRC))
|
|
LUALIBS = $(LUAPLATLIBS) -lm
|
|
|
|
# --- vendored Squirrel 3.2 (C++) ---
|
|
# -D_SQ64 -DSQUSEDOUBLE so SQInteger/SQFloat are 64-bit int / double; the adapter
|
|
# MUST share those defines so the ABI (object layout) matches the VM.
|
|
SQDIR = vendor/squirrel-src
|
|
SQDEF = -D_SQ64 -DSQUSEDOUBLE
|
|
SQINC = -I$(SQDIR)/include
|
|
SQXXFLAGS = -std=c++11 -w -g -O1 $(SQDEF) $(SQINC) -I$(SQDIR)/squirrel
|
|
SQSRC = $(wildcard $(SQDIR)/squirrel/*.cpp)
|
|
SQOBJ = $(patsubst $(SQDIR)/squirrel/%.cpp,obj/%.o,$(SQSRC))
|
|
|
|
# --- vendored QuickJS-ng (C, JavaScript, ES2023+). The core library is these four
|
|
# .c files (cutils is header-only now). Needs -D_GNU_SOURCE: cutils.h uses
|
|
# clock_gettime(CLOCK_MONOTONIC). ---
|
|
QJSDIR = vendor/quickjs
|
|
QJSINC = -I$(QJSDIR)
|
|
QJSFLAGS = -std=c11 -w -g -O1 -D_GNU_SOURCE
|
|
QJSOBJ = obj/quickjs.o obj/libregexp.o obj/libunicode.o obj/dtoa.o
|
|
|
|
# --- vendored Berry (C). The library is every src/*.c; its build needs the coc-
|
|
# generated headers under generate/ (regenerate with tools/coc from upstream) and
|
|
# berry_conf.h. BE_INTGER_TYPE=2 in berry_conf.h gives 64-bit ints. ---
|
|
# The library is every src/*.c plus the OS port (default/be_port.c) and the built-in
|
|
# module/class tables (default/be_modtab.c); the standalone REPL (default/berry.c) is
|
|
# omitted. src/ and default/ file names do not collide, so objects use $(notdir ...).
|
|
BERRYDIR = vendor/berry
|
|
BERRYINC = -I$(BERRYDIR)/src -I$(BERRYDIR)
|
|
BERRYFLAGS = -std=c99 -w -g -O1
|
|
BERRYSRC = $(wildcard $(BERRYDIR)/src/*.c) $(BERRYDIR)/default/be_port.c $(BERRYDIR)/default/be_modtab.c
|
|
BERRYOBJ = $(foreach f,$(BERRYSRC),obj/$(notdir $(f:.c=)).o)
|
|
|
|
# --- vendored s7 Scheme (C, single file). Needs -D_GNU_SOURCE (struct timezone) and,
|
|
# at link, -ldl (its optional C loader uses dlopen) + -lm. mus-config.h is our minimal
|
|
# feature config; s7 int is 64-bit and strings are binary-safe. ---
|
|
S7DIR = vendor/s7
|
|
S7INC = -I$(S7DIR)
|
|
S7FLAGS = -std=c99 -w -g -O1 -D_GNU_SOURCE
|
|
S7OBJ = obj/s7.o
|
|
S7LIBS = -ldl -lm
|
|
|
|
# --- vendored Wren (C, amalgamated single file wren.c + wren.h; regenerate via
|
|
# util/generate_amalgamation.py from upstream). Links -lm. ---
|
|
WRENDIR = vendor/wren
|
|
WRENINC = -I$(WRENDIR)
|
|
WRENFLAGS = -std=c99 -w -g -O1
|
|
WRENOBJ = obj/wren.o
|
|
WRENLIBS = -lm
|
|
|
|
BINS = bin/testBroker bin/testLua bin/testMyBasic bin/testPolyglot bin/testActor \
|
|
bin/testEngineLua bin/testEngineMyBasic bin/testSquirrel bin/testEngineSquirrel bin/testJs bin/testEngineJs \
|
|
bin/testEngineBerry bin/testEngineS7 bin/testEngineWren bin/testLoad bin/embed
|
|
|
|
all: $(BINS)
|
|
|
|
# ---- object rules, grouped by flag set (sources resolved via VPATH) ----
|
|
|
|
# strict C, no threads
|
|
STRICTOBJ = obj/broker.o obj/value.o obj/luaEngine.o obj/squirrelEngine.o obj/jsEngine.o obj/berryEngine.o obj/s7Engine.o obj/wrenEngine.o obj/testBroker.o
|
|
$(STRICTOBJ): obj/%.o: %.c | obj
|
|
$(CC) $(COREFLAGS) $(INC) -c -o $@ $<
|
|
|
|
# strict C, threaded
|
|
THREADOBJ = obj/context.o obj/mybasicEngine.o obj/testActor.o obj/testEngineLua.o obj/testEngineSquirrel.o obj/testEngineJs.o obj/testEngineMyBasic.o obj/testEngineBerry.o obj/testEngineS7.o obj/testEngineWren.o
|
|
$(THREADOBJ): obj/%.o: %.c | obj
|
|
$(CC) $(COREFLAGS) $(INC) -pthread -c -o $@ $<
|
|
|
|
# relaxed C + Lua headers
|
|
LUAADP = obj/luaAdapter.o obj/testLua.o
|
|
$(LUAADP): obj/%.o: %.c | obj
|
|
$(CC) $(ADPFLAGS) $(INC) $(LUAINC) -c -o $@ $<
|
|
|
|
# relaxed C + my-basic headers
|
|
MBADP = obj/mybasicAdapter.o obj/testMyBasic.o
|
|
$(MBADP): obj/%.o: %.c | obj
|
|
$(CC) $(ADPFLAGS) $(INC) $(MBINC) -DMB_DOUBLE_FLOAT -c -o $@ $<
|
|
|
|
# relaxed C + Squirrel headers
|
|
SQADP = obj/squirrelAdapter.o obj/testSquirrel.o
|
|
$(SQADP): obj/%.o: %.c | obj
|
|
$(CC) $(ADPFLAGS) $(INC) $(SQDEF) $(SQINC) -c -o $@ $<
|
|
|
|
# relaxed C + QuickJS headers
|
|
JSADP = obj/jsAdapter.o obj/testJs.o
|
|
$(JSADP): obj/%.o: %.c | obj
|
|
$(CC) $(ADPFLAGS) $(INC) $(QJSINC) -c -o $@ $<
|
|
|
|
# relaxed C + Berry headers
|
|
BERRYADP = obj/berryAdapter.o
|
|
$(BERRYADP): obj/%.o: %.c | obj
|
|
$(CC) $(ADPFLAGS) $(INC) $(BERRYINC) -c -o $@ $<
|
|
|
|
# relaxed C + s7 headers
|
|
S7ADP = obj/s7Adapter.o
|
|
$(S7ADP): obj/%.o: %.c | obj
|
|
$(CC) $(ADPFLAGS) $(INC) $(S7INC) -c -o $@ $<
|
|
|
|
# relaxed C + Wren headers
|
|
WRENADP = obj/wrenAdapter.o
|
|
$(WRENADP): obj/%.o: %.c | obj
|
|
$(CC) $(ADPFLAGS) $(INC) $(WRENINC) -c -o $@ $<
|
|
|
|
# polyglot test pulls in both Lua and my-basic
|
|
obj/testPolyglot.o: testPolyglot.c | obj
|
|
$(CC) $(ADPFLAGS) $(INC) $(LUAINC) $(MBINC) -DMB_DOUBLE_FLOAT -c -o $@ $<
|
|
|
|
# ---- vendored engine objects (also land in obj/) ----
|
|
obj/myBasic.o: $(MBDIR)/myBasic.c | obj
|
|
$(CC) $(MBFLAGS) -c -o $@ $<
|
|
|
|
obj/%.o: $(LUADIR)/src/%.c | obj
|
|
$(CC) $(LUAFLAGS) -c -o $@ $<
|
|
|
|
obj/%.o: $(SQDIR)/squirrel/%.cpp | obj
|
|
$(CXX) $(SQXXFLAGS) -c -o $@ $<
|
|
|
|
obj/%.o: $(QJSDIR)/%.c | obj
|
|
$(CC) $(QJSFLAGS) $(QJSINC) -c -o $@ $<
|
|
|
|
obj/%.o: $(BERRYDIR)/src/%.c | obj
|
|
$(CC) $(BERRYFLAGS) $(BERRYINC) -c -o $@ $<
|
|
|
|
obj/%.o: $(BERRYDIR)/default/%.c | obj
|
|
$(CC) $(BERRYFLAGS) $(BERRYINC) -c -o $@ $<
|
|
|
|
obj/s7.o: $(S7DIR)/s7.c | obj
|
|
$(CC) $(S7FLAGS) $(S7INC) -c -o $@ $<
|
|
|
|
obj/wren.o: $(WRENDIR)/wren.c | obj
|
|
$(CC) $(WRENFLAGS) $(WRENINC) -c -o $@ $<
|
|
|
|
# ---- library archives ----
|
|
# libcalog.a is calog itself (core + actor + every engine adapter/binding). The
|
|
# vendored engines are separate archives; a host links libcalog.a plus whichever
|
|
# engine archives it uses -- unused adapters, and their engine deps, stay unlinked
|
|
# (static members are pulled only when referenced). See examples/embed.c.
|
|
CALOGLIB = obj/value.o obj/broker.o obj/context.o \
|
|
obj/luaAdapter.o obj/luaEngine.o obj/jsAdapter.o obj/jsEngine.o \
|
|
obj/squirrelAdapter.o obj/squirrelEngine.o obj/mybasicAdapter.o obj/mybasicEngine.o \
|
|
obj/berryAdapter.o obj/berryEngine.o obj/s7Adapter.o obj/s7Engine.o obj/wrenAdapter.o obj/wrenEngine.o
|
|
|
|
lib/libcalog.a: $(CALOGLIB) | lib
|
|
ar rcs $@ $^
|
|
lib/liblua.a: $(LUAOBJ) | lib
|
|
ar rcs $@ $^
|
|
lib/libquickjs.a: $(QJSOBJ) | lib
|
|
ar rcs $@ $^
|
|
lib/libsquirrel.a: $(SQOBJ) | lib
|
|
ar rcs $@ $^
|
|
lib/libmybasic.a: obj/myBasic.o | lib
|
|
ar rcs $@ $^
|
|
lib/libberry.a: $(BERRYOBJ) | lib
|
|
ar rcs $@ $^
|
|
lib/libs7.a: $(S7OBJ) | lib
|
|
ar rcs $@ $^
|
|
lib/libwren.a: $(WRENOBJ) | lib
|
|
ar rcs $@ $^
|
|
|
|
# ---- binaries (link libcalog.a + the vendored engine archives they use) ----
|
|
bin/testBroker: obj/testBroker.o lib/libcalog.a | bin
|
|
$(CC) $(LDFLAGS) -o $@ $^
|
|
|
|
bin/testActor: obj/testActor.o lib/libcalog.a | bin
|
|
$(CC) $(LDFLAGS) -pthread -o $@ $^
|
|
|
|
bin/testLua: obj/testLua.o lib/libcalog.a lib/liblua.a | bin
|
|
$(CC) $(LDFLAGS) -o $@ $^ $(LUALIBS)
|
|
|
|
bin/testEngineLua: obj/testEngineLua.o lib/libcalog.a lib/liblua.a | bin
|
|
$(CC) $(LDFLAGS) -pthread -o $@ $^ $(LUALIBS)
|
|
|
|
bin/testMyBasic: obj/testMyBasic.o lib/libcalog.a lib/libmybasic.a | bin
|
|
$(CC) $(LDFLAGS) -o $@ $^ -lm
|
|
|
|
bin/testEngineMyBasic: obj/testEngineMyBasic.o lib/libcalog.a lib/libmybasic.a | bin
|
|
$(CC) $(LDFLAGS) -pthread -o $@ $^ -lm
|
|
|
|
bin/testPolyglot: obj/testPolyglot.o lib/libcalog.a lib/liblua.a lib/libmybasic.a | bin
|
|
$(CC) $(LDFLAGS) -o $@ $^ $(LUALIBS)
|
|
|
|
bin/testSquirrel: obj/testSquirrel.o lib/libcalog.a lib/libsquirrel.a | bin
|
|
$(CC) $(LDFLAGS) -o $@ $^ -lstdc++ -lm
|
|
|
|
bin/testEngineSquirrel: obj/testEngineSquirrel.o lib/libcalog.a lib/libsquirrel.a | bin
|
|
$(CC) $(LDFLAGS) -pthread -o $@ $^ -lstdc++ -lm
|
|
|
|
bin/testJs: obj/testJs.o lib/libcalog.a lib/libquickjs.a | bin
|
|
$(CC) $(LDFLAGS) -o $@ $^ -lm
|
|
|
|
bin/testEngineJs: obj/testEngineJs.o lib/libcalog.a lib/libquickjs.a | bin
|
|
$(CC) $(LDFLAGS) -pthread -o $@ $^ -lm
|
|
|
|
bin/testEngineBerry: obj/testEngineBerry.o lib/libcalog.a lib/libberry.a | bin
|
|
$(CC) $(LDFLAGS) -pthread -o $@ $^ -lm
|
|
|
|
bin/testEngineS7: obj/testEngineS7.o lib/libcalog.a lib/libs7.a | bin
|
|
$(CC) $(LDFLAGS) -pthread -o $@ $^ $(S7LIBS)
|
|
|
|
bin/testEngineWren: obj/testEngineWren.o lib/libcalog.a lib/libwren.a | bin
|
|
$(CC) $(LDFLAGS) -pthread -o $@ $^ $(WRENLIBS)
|
|
|
|
# example host: embeds calog + JS via calog.h only, linking the two archives.
|
|
obj/embed.o: examples/embed.c src/calog.h | obj
|
|
$(CC) $(COREFLAGS) -Isrc -pthread -c -o $@ $<
|
|
|
|
bin/embed: obj/embed.o lib/libcalog.a lib/libquickjs.a | bin
|
|
$(CC) $(LDFLAGS) -pthread -o $@ $^ -lm
|
|
|
|
# load test: links every engine (compiled with all CALOG_WITH_* engine flags) so it
|
|
# exercises calogContextLoad + calogRegisterBuiltinEngines across all four languages --
|
|
# including my-basic under the actor model. Uses only calog.h (the extern engine vtables).
|
|
obj/testLoad.o: tests/testLoad.c src/calog.h | obj
|
|
$(CC) $(COREFLAGS) -Isrc -pthread -DCALOG_WITH_LUA -DCALOG_WITH_JS -DCALOG_WITH_SQUIRREL -DCALOG_WITH_MYBASIC -DCALOG_WITH_BERRY -DCALOG_WITH_S7 -DCALOG_WITH_WREN -c -o $@ $<
|
|
|
|
bin/testLoad: obj/testLoad.o lib/libcalog.a lib/liblua.a lib/libquickjs.a lib/libsquirrel.a lib/libmybasic.a lib/libberry.a lib/libs7.a lib/libwren.a | bin
|
|
$(CC) $(LDFLAGS) -pthread -o $@ $^ $(LUALIBS) -lstdc++ -lm
|
|
|
|
obj bin lib:
|
|
mkdir -p $@
|
|
|
|
test: all
|
|
./bin/testBroker && ./bin/testLua && ./bin/testMyBasic && ./bin/testPolyglot && \
|
|
./bin/testActor && ./bin/testEngineLua && ./bin/testEngineMyBasic && ./bin/testSquirrel && ./bin/testEngineSquirrel && \
|
|
./bin/testJs && ./bin/testEngineJs && ./bin/testEngineBerry && ./bin/testEngineS7 && ./bin/testEngineWren && ./bin/testLoad
|
|
|
|
# ThreadSanitizer build of the actor core and the Lua engine path (cannot combine
|
|
# with ASan). Recompiled from source under TSan; the vendored Lua objects are
|
|
# linked un-sanitized (each VM is single-threaded, so that is sound). Run under
|
|
# `setarch -R` (ASLR off): some kernels hand out more mmap randomization than TSan's
|
|
# shadow allocator tolerates, which aborts it before any test runs.
|
|
tsan: $(LUAOBJ) | bin
|
|
$(CC) -std=c11 $(WARN) -g -O1 -fsanitize=thread -pthread $(INC) -o bin/testActorTsan \
|
|
tests/testActor.c src/context.c src/value.c src/broker.c
|
|
setarch -R ./bin/testActorTsan
|
|
$(CC) -std=c11 $(WARN) -g -O1 -fsanitize=thread -pthread $(INC) $(LUAINC) -o bin/testEngineLuaTsan \
|
|
tests/testEngineLua.c src/lua/luaEngine.c src/lua/luaAdapter.c src/context.c src/value.c src/broker.c \
|
|
$(LUAOBJ) $(LUALIBS)
|
|
setarch -R ./bin/testEngineLuaTsan
|
|
|
|
# ThreadSanitizer build of the Squirrel engine path: the vendored VM is recompiled
|
|
# under TSan here (throwaway obj/*.tsan.o) so races are caught across the whole
|
|
# stack. Slower than `tsan`, so kept separate.
|
|
tsansq: $(SQSRC) | bin obj
|
|
for f in $(SQSRC); do $(CXX) $(SQXXFLAGS) -fsanitize=thread -c $$f -o obj/$$(basename $${f%.cpp}).tsan.o; done
|
|
$(CC) -std=c11 $(WARN) -g -O1 -fsanitize=thread -pthread $(INC) $(SQDEF) $(SQINC) -o bin/testEngineSquirrelTsan \
|
|
tests/testEngineSquirrel.c src/squirrel/squirrelEngine.c src/squirrel/squirrelAdapter.c \
|
|
src/context.c src/value.c src/broker.c \
|
|
$(patsubst $(SQDIR)/squirrel/%.cpp,obj/%.tsan.o,$(SQSRC)) -lstdc++ -lm
|
|
setarch -R ./bin/testEngineSquirrelTsan
|
|
rm -f $(patsubst $(SQDIR)/squirrel/%.cpp,obj/%.tsan.o,$(SQSRC))
|
|
|
|
# ThreadSanitizer build of the JS engine path: the vendored QuickJS core is
|
|
# recompiled under TSan (throwaway objs) so races are caught across the whole stack.
|
|
tsanjs: | bin obj
|
|
for f in quickjs libregexp libunicode dtoa; do $(CC) $(QJSFLAGS) $(QJSINC) -fsanitize=thread -c $(QJSDIR)/$$f.c -o obj/$$f.tsan.o; done
|
|
$(CC) -std=c11 $(WARN) -g -O1 -fsanitize=thread -pthread $(INC) $(QJSINC) -o bin/testEngineJsTsan \
|
|
tests/testEngineJs.c src/js/jsEngine.c src/js/jsAdapter.c src/context.c src/value.c src/broker.c \
|
|
obj/quickjs.tsan.o obj/libregexp.tsan.o obj/libunicode.tsan.o obj/dtoa.tsan.o -lm
|
|
setarch -R ./bin/testEngineJsTsan
|
|
rm -f obj/quickjs.tsan.o obj/libregexp.tsan.o obj/libunicode.tsan.o obj/dtoa.tsan.o
|
|
|
|
# ThreadSanitizer build of the my-basic engine path: the vendored interpreter is
|
|
# recompiled under TSan (throwaway obj) so the engine's serialization of my-basic's
|
|
# process-global state (mb_init singletons, the _mb_allocated counter) is verified
|
|
# across the whole stack -- it races without the engine lock.
|
|
tsanmb: | bin obj
|
|
$(CC) $(MBFLAGS) -fsanitize=thread -c $(MBDIR)/myBasic.c -o obj/myBasic.tsan.o
|
|
$(CC) -std=c11 $(WARN) -g -O1 -fsanitize=thread -pthread $(INC) $(MBINC) -DMB_DOUBLE_FLOAT -o bin/testEngineMyBasicTsan \
|
|
tests/testEngineMyBasic.c src/mybasic/mybasicEngine.c src/mybasic/mybasicAdapter.c src/context.c src/value.c src/broker.c \
|
|
obj/myBasic.tsan.o -lm
|
|
setarch -R ./bin/testEngineMyBasicTsan
|
|
rm -f obj/myBasic.tsan.o
|
|
|
|
# ThreadSanitizer build of the Berry engine path: the vendored VM is recompiled under
|
|
# TSan (throwaway objs) so races are caught across the whole stack.
|
|
tsanberry: | bin obj
|
|
for f in $(BERRYSRC); do $(CC) $(BERRYFLAGS) $(BERRYINC) -fsanitize=thread -c $$f -o obj/$$(basename $${f%.c}).tsan.o; done
|
|
$(CC) -std=c11 $(WARN) -g -O1 -fsanitize=thread -pthread $(INC) $(BERRYINC) -o bin/testEngineBerryTsan \
|
|
tests/testEngineBerry.c src/berry/berryEngine.c src/berry/berryAdapter.c src/context.c src/value.c src/broker.c \
|
|
$(foreach f,$(BERRYSRC),obj/$(notdir $(f:.c=)).tsan.o) -lm
|
|
setarch -R ./bin/testEngineBerryTsan
|
|
rm -f $(foreach f,$(BERRYSRC),obj/$(notdir $(f:.c=)).tsan.o)
|
|
|
|
# ThreadSanitizer build of the s7 engine path: the vendored interpreter is recompiled
|
|
# under TSan (throwaway obj) so races are caught across the whole stack.
|
|
tsans7: | bin obj
|
|
$(CC) $(S7FLAGS) $(S7INC) -fsanitize=thread -c $(S7DIR)/s7.c -o obj/s7.tsan.o
|
|
$(CC) -std=c11 $(WARN) -g -O1 -fsanitize=thread -pthread $(INC) $(S7INC) -o bin/testEngineS7Tsan \
|
|
tests/testEngineS7.c src/s7/s7Engine.c src/s7/s7Adapter.c src/context.c src/value.c src/broker.c \
|
|
obj/s7.tsan.o $(S7LIBS)
|
|
setarch -R ./bin/testEngineS7Tsan
|
|
rm -f obj/s7.tsan.o
|
|
|
|
# ThreadSanitizer build of the Wren engine path: the vendored VM is recompiled under
|
|
# TSan (throwaway obj) so races are caught across the whole stack.
|
|
tsanwren: | bin obj
|
|
$(CC) $(WRENFLAGS) $(WRENINC) -fsanitize=thread -c $(WRENDIR)/wren.c -o obj/wren.tsan.o
|
|
$(CC) -std=c11 $(WARN) -g -O1 -fsanitize=thread -pthread $(INC) $(WRENINC) -o bin/testEngineWrenTsan \
|
|
tests/testEngineWren.c src/wren/wrenEngine.c src/wren/wrenAdapter.c src/context.c src/value.c src/broker.c \
|
|
obj/wren.tsan.o $(WRENLIBS)
|
|
setarch -R ./bin/testEngineWrenTsan
|
|
rm -f obj/wren.tsan.o
|
|
|
|
clean:
|
|
rm -rf obj bin lib
|
|
|
|
-include $(wildcard obj/*.d)
|
|
|
|
.PHONY: all test tsan tsansq tsanjs tsanmb tsanberry tsans7 tsanwren clean
|