MAKEFLAGS += --warn-undefined-variables
SRCPATH = src
BUILD_DIR = build
RD ?= docker run -v $(CURDIR):$(CURDIR) --user=$(shell id -u):$(shell id -g) -w $(CURDIR)
DOCKER_GCC ?= $(RD) mgos/gcc
DOCKER_CLANG ?= $(RD) mgos/clang
include $(SRCPATH)/mjs_sources.mk
TOP_HEADERS = $(addprefix $(SRCPATH)/, $(HEADERS))
TOP_MJS_PUBLIC_HEADERS = $(addprefix $(SRCPATH)/, $(MJS_PUBLIC_HEADERS))
TOP_MJS_SOURCES = $(addprefix $(SRCPATH)/, $(MJS_SOURCES))
TOP_COMMON_SOURCES = $(addprefix $(SRCPATH)/, $(COMMON_SOURCES))
CFLAGS_EXTRA ?=
MFLAGS += -I. -Isrc -Isrc/frozen
MFLAGS += -DMJS_MAIN -DMJS_EXPOSE_PRIVATE -DCS_ENABLE_STDIO -DMJS_ENABLE_DEBUG -I../frozen
MFLAGS += $(CFLAGS_EXTRA)
CFLAGS += -lm -std=c99 -Wall -Wextra -pedantic -g $(MFLAGS)
COMMON_CFLAGS = -DCS_MMAP -DMJS_MODULE_LINES
ASAN_CFLAGS = -fsanitize=address
.PHONY: all test test_full difftest ci-test
VERBOSE ?=
ifeq ($(VERBOSE),1)
Q :=
else
Q := @
endif
ifeq ($(OS),Windows_NT)
UNAME_S := Windows
else
UNAME_S := $(shell uname -s)
endif
ifeq ($(UNAME_S),Linux)
COMMON_CFLAGS += -Wl,--no-as-needed -ldl
ASAN_CFLAGS += -fsanitize=leak
endif
ifeq ($(UNAME_S),Darwin)
MFLAGS += -D_DARWIN_C_SOURCE
endif
PROG = $(BUILD_DIR)/mjs
all: mjs.c mjs_no_common.c $(PROG)
TESTUTIL_FILES = $(SRCPATH)/common/cs_dirent.c \
$(SRCPATH)/common/cs_time.c \
$(SRCPATH)/common/test_main.c \
$(SRCPATH)/common/test_util.c
mjs.h: $(TOP_MJS_PUBLIC_HEADERS) Makefile tools/amalgam.py
@printf "AMALGAMATING $@\n"
$(Q) (tools/amalgam.py \
--autoinc -I src --prefix MJS --strict --license src/mjs_license.h \
--first common/platform.h $(TOP_MJS_PUBLIC_HEADERS)) > $@
mjs.c: $(TOP_COMMON_SOURCES) $(TOP_MJS_SOURCES) mjs.h Makefile
@printf "AMALGAMATING $@\n"
$(Q) (tools/amalgam.py \
--autoinc -I src -I src/frozen --prefix MJS --license src/mjs_license.h \
--license src/mjs_license.h --public-header mjs.h --autoinc-ignore mjs_*_public.h \
--first mjs_common_guard_begin.h,common/platform.h,common/platforms/platform_windows.h,common/platforms/platform_unix.h,common/platforms/platform_esp_lwip.h \
$(TOP_COMMON_SOURCES) $(TOP_MJS_SOURCES)) > $@
mjs_no_common.c: $(TOP_MJS_SOURCES) mjs.h Makefile
@printf "AMALGAMATING $@\n"
$(Q) (tools/amalgam.py \
--autoinc -I src -I src/frozen --prefix MJS --license src/mjs_license.h \
--public-header mjs.h --ignore mjs.h,*common/*,*frozen.[ch] \
--first mjs_common_guard_begin.h,common/platform.h,common/platforms/platform_windows.h,common/platforms/platform_unix.h,common/platforms/platform_esp_lwip.h \
$(TOP_MJS_SOURCES)) > $@
CFLAGS += $(COMMON_CFLAGS)
$(PROG): $(TOP_MJS_SOURCES) $(TOP_COMMON_SOURCES) $(TOP_HEADERS) $(BUILD_DIR)
$(DOCKER_CLANG) clang $(CFLAGS) $(TOP_MJS_SOURCES) $(TOP_COMMON_SOURCES) -o $(PROG)
$(BUILD_DIR):
mkdir -p $@
$(BUILD_DIR)/%.o: %.c $(TOP_HEADERS) mjs.h
$(CLANG) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
COMMON_TEST_FLAGS = -W -Wall -I. -Isrc -g3 -O0 $(COMMON_CFLAGS) $< $(TESTUTIL_FILES) -DMJS_MEMORY_STATS
TEST_VARIANTS =
define compile_test
$(BUILD_DIR)/unit_test_$1: tests/unit_test.c mjs.c $(TESTUTIL_FILES) $(BUILD_DIR)
@echo BUILDING $$@ with $2[$3], flags: "'$4'"
$(RD) --entrypoint $3 $2 $$(COMMON_TEST_FLAGS) $4 -ldl -lm -o $$@
$(RD) --entrypoint ./$$@ $2
TEST_VARIANTS += $(BUILD_DIR)/unit_test_$1
endef
define compile_test_with_compiler
$(eval $(call compile_test,$3,$1,$2,$4))
endef
define compile_test_with_opt
$(eval $(call compile_test_with_compiler,mgos/clang,/usr/bin/clang-3.6,clang_$2,$(ASAN_CFLAGS) $1 $3))
$(eval $(call compile_test_with_compiler,mgos/clang,/usr/bin/clang-3.6,clang_32bit_$2,-m32 $1 $3))
$(eval $(call compile_test_with_compiler,mgos/gcc,/usr/bin/gcc,gcc_$2,$1 $3))
endef
define compile_test_with_offset
$(eval $(call compile_test_with_opt,-O0,O0_$2,$1 $3))
$(eval $(call compile_test_with_opt,-O1,O1_$2,$1 $3))
$(eval $(call compile_test_with_opt,-O3,O3_$2,$1 $3))
endef
define compile_test_with_aggressive_gc
$(eval $(call compile_test_with_offset,,offset_def_$2,$1 $3))
$(eval $(call compile_test_with_offset,-DMJS_INIT_OFFSET_SIZE=0,offset_0_$2,$1 $3))
$(eval $(call compile_test_with_offset,-DMJS_INIT_OFFSET_SIZE=4,offset_4_$2,$1 $3))
endef
define compile_test_all
$(eval $(call compile_test_with_aggressive_gc,-DMJS_AGGRESSIVE_GC,aggressive_gc_$2,$1 $3))
$(eval $(call compile_test_with_aggressive_gc,,nonaggressive_gc_$2,$1 $3))
endef
$(eval $(call compile_test_all))
test_full: $(TEST_VARIANTS) $(PROG)
test: $(firstword $(TEST_VARIANTS))
clean:
rm -rf $(BUILD_DIR) *.obj mjs.c mjs.h _CL_*
difftest:
@TMP=`mktemp -t checkout-diff.XXXXXX`; \
git diff >$$TMP ; \
if [ -s "$$TMP" ]; then echo found diffs in checkout:; git status -s; head -n 50 "$$TMP"; exit 1; fi; \
rm $$TMP
ci-test: $(BUILD_DIR) vc98 vc2017 test_full
$(PROG).exe: $(BUILD_DIR) $(TOP_HEADERS) mjs.c
$(RD) mgos/vc98 wine cl mjs.c $(CLFLAGS) $(MFLAGS) /Fe$@
TEST_SOURCES = tests/unit_test.c $(TESTUTIL_FILES)
CLFLAGS = /DWIN32_LEAN_AND_MEAN /MD /O1 /TC /W2 /WX /I.. /I. /DNDEBUG /DMJS_MEMORY_STATS
vc98 vc2017: mjs.c mjs.h
$(RD) mgos/$@ wine cl $(TEST_SOURCES) $(CLFLAGS) /Fe$@.exe
$(RD) mgos/$@ wine ./$@.exe