forked from cesanta/mjs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Makefile
229 lines (188 loc) · 7.89 KB
/
Makefile
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
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)
# NOTE: we compile straight from sources, not from the single amalgamated file,
# in order to make sure that all sources include the right headers
$(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
#include $(REPO_ROOT)/common.mk
# ==== Test Variants ====
#
# We want to build tests with various combinations of different compilers and
# different options. In order to do that, there is some simple makefile magic:
#
# There is a function compile_test_with_compiler which takes compiler name, any
# compile flags, name for the binary, and declares a rule for building that
# binary.
#
# Now, there is a higher level function: compile_test_with_opt, which takes the
# optimization flag to use, binary name component, and it declares a rule for
# both clang and for gcc with given optimization flags (by means of the
# aforementioned compile_test_with_compiler). And there are more higher level
# function which add more flags, etc etc.
#
# ========================================
# Suppose you want to add more build variants, say with flags -DFOO=1 and
# -DFOO=2. Here's what you need to do:
#
# - Rename compile_test_all to compile_test_with_foo
# - Inside of your new fancy compile_test_with_foo function, adjust a bit each
# invocation of the lower-level function, whatever it is:
# to the arg 2, add "_$2", and replace empty arg 3 with this: "$1 $3".
# - Write new compile_test_all, which should call your new
# compile_test_with_foo, like this:
#
# define compile_test_all
# $(eval $(call compile_test_with_foo,-DFOO=1,foo_1,))
# $(eval $(call compile_test_with_foo,-DFOO=2,foo_2,))
# endef
#
# - Done!
#
# ========================================
# test variants, will be populated by compile_test, called by
# compile_test_with_compiler, called by compile_test_with_opt, .... etc
TEST_VARIANTS =
# params:
#
# 1: binary name component, e.g. "clang_O1_offset_4_whatever_else"
# 2: docker image to run compiler and binary in
# 3: full path to compiler, like "/usr/bin/clang-3.6" or "/usr/bin/gcc"
# 4: compiler flags
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
# params:
# 1: compiler to use, like "clang" or "gcc"
# 2: binary name component, typically the same as compiler: "clang" or "gcc"
# 3: additional compiler flags
define compile_test_with_compiler
$(eval $(call compile_test,$3,$1,$2,$4))
endef
# params:
# 1: optimization flag to use, like "-O0"
# 2: binary name component, like "O0" or whatever
# 3: additional compiler flags
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
# params:
# 1: flag to use, like "-DMJS_INIT_OFFSET_SIZE=0", or just an empty string
# 2: binary name component, like "offset_something"
# 3: additional compiler flags
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
# params:
# 1: flag to use, like "-DMJS_AGGRESSIVE_GC", or just an empty string
# 2: binary name component, like "offset_something"
# 3: additional compiler flags
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
# compile ALL tests
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))
# Run all tests from $(TEST_VARIANTS)
test_full: $(TEST_VARIANTS) $(PROG)
# for f in $(TEST_VARIANTS); do \
# echo ; echo running $$f; \
# $$f; \
# done
# Run just a single test (a first one from $(TEST_VARIANTS))
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
################################### Windows targets for wine, with MSVC6
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) /[email protected]
$(RD) mgos/$@ wine ./[email protected]