-
Notifications
You must be signed in to change notification settings - Fork 21
Expand file tree
/
Copy pathMakefile
More file actions
164 lines (149 loc) · 4.93 KB
/
Copy pathMakefile
File metadata and controls
164 lines (149 loc) · 4.93 KB
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
CFLAGS_CORE = -O1 -g -std=gnu11 -Wall -Wextra -Werror -Wno-shadow -Wno-unused-label
CFLAGS ?= $(CFLAGS_CORE) -fsanitize=address -fsanitize=undefined -fstack-protector-all -fno-omit-frame-pointer
LDLIBS ?= -lm
CLANG = clang
GCC_NATIVE = gcc-15
GCC_DOCKER = docker run --rm -v "$(shell pwd)":/src -w /src gcc:15.2.0
RISCV64 = docker run --rm --platform linux/riscv64 -v "$(shell pwd)":/src -w /src solod/riscv64
I386 = docker run --rm --platform linux/i386 -v "$(shell pwd)":/src -w /src solod/i386
EMCC = emcc
ZIG = zig cc
compiler =
OUT_NAME = main
RUN_CMD = ./build/main
# Set CC and CFLAGS based on the selected compiler.
ifeq ($(compiler), clang)
CC = $(CLANG)
else ifeq ($(compiler), gcc)
CC = $(GCC_NATIVE)
CFLAGS += -fanalyzer -D_FORTIFY_SOURCE=2
else ifeq ($(compiler), docker)
CC = $(GCC_DOCKER) gcc
CFLAGS += -fanalyzer -D_FORTIFY_SOURCE=2
RUN_CMD = $(GCC_DOCKER) ./build/main
else ifeq ($(compiler), bare)
CC = $(ZIG)
CFLAGS = $(CFLAGS_CORE) --target=wasm32-freestanding -nostdlib -Wl,--no-entry -Wl,--export=main -DSO_HEAP_SIZE=65536
LDLIBS =
OUT_NAME = main.wasm
RUN_CMD = wasmtime --invoke main ./build/main.wasm 0 0
else ifeq ($(compiler), riscv64)
CC = $(RISCV64) gcc
CFLAGS = $(CFLAGS_CORE)
RUN_CMD = $(RISCV64) ./build/main
else ifeq ($(compiler), i386)
CC = $(I386) gcc
CFLAGS = $(CFLAGS_CORE)
RUN_CMD = $(I386) ./build/main
else ifeq ($(compiler), wasm)
CC = $(EMCC)
CFLAGS = $(CFLAGS_CORE) -sSTANDALONE_WASM
OUT_NAME = main.wasm
RUN_CMD = wasmtime ./build/main.wasm
endif
# Preload mimalloc if available.
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Darwin)
MIMALLOC_LIB := $(shell ls /opt/homebrew/lib/libmimalloc.dylib /usr/local/lib/libmimalloc.dylib 2>/dev/null | head -1)
ifneq ($(MIMALLOC_LIB),)
MIMALLOC_PRELOAD := DYLD_INSERT_LIBRARIES=$(MIMALLOC_LIB)
endif
else ifeq ($(UNAME_S),Linux)
MIMALLOC_LIB := $(shell ls /usr/lib/libmimalloc.so /usr/local/lib/libmimalloc.so 2>/dev/null | head -1)
ifneq ($(MIMALLOC_LIB),)
MIMALLOC_PRELOAD := LD_PRELOAD=$(MIMALLOC_LIB)
endif
endif
inspect:
go run ./cmd/inspect -- $(path)
test:
@mkdir -p generated
@go test ./so/...
@go test ./internal/...
prepare-riscv64:
@printf 'FROM alpine:edge\nRUN apk add --no-cache gcc musl-dev\n' \
| docker build --platform=linux/riscv64 -t solod/riscv64 -
@docker run --rm -it --platform=linux/riscv64 -v $(shell pwd):/src solod/riscv64 uname -m
prepare-i386:
@printf 'FROM alpine:edge\nRUN apk add --no-cache gcc musl-dev\n' \
| docker build --platform=linux/i386 -t solod/i386 -
@docker run --rm -it --platform=linux/i386 -v $(shell pwd):/src solod/i386 uname -m
update-dst:
make run-case name=$(name)
cp generated/$(name)/main.* testdata/$(name)/dst
go test -run TestTranslate/$(name) ./internal/compiler
# Runs tests in every testdata/* subdirectory.
test-lang:
@mkdir -p generated
@failed=0; \
for dir in $$(ls -d testdata/*/); do \
name=$${dir#testdata/}; \
name=$${name%/}; \
if make run-case name=$$name > generated/so_test_out.txt 2>&1; then \
echo "PASS $$name"; \
else \
echo "FAIL $$name"; \
cat generated/so_test_out.txt; \
failed=1; \
fi; \
done; \
rm -f generated/so_test_out.txt; \
if [ $$failed -eq 0 ]; then \
echo "PASS"; \
else \
echo "FAIL"; \
exit 1; \
fi
# Runs tests in every stdlib package's "test" subdirectory.
test-std:
@mkdir -p generated
@failed=0; \
for dir in $$(find so -type d -name test | sort); do \
name=$${dir%/test}; \
if make run-test name=$$name > generated/so_test_out.txt 2>&1; then \
echo "PASS $$name"; \
else \
echo "FAIL $$name"; \
cat generated/so_test_out.txt; \
failed=1; \
fi; \
done; \
rm -f generated/so_test_out.txt; \
if [ $$failed -eq 0 ]; then \
echo "PASS"; \
else \
echo "FAIL"; \
exit 1; \
fi
# Transpiles, compiles and runs a single test case in testdata/$(name),
# leaving the generated C in generated/$(name) for inspection.
run-case:
@rm -rf generated/$(name)
@mkdir -p generated/$(name)
@cp testdata/$(name)/dst/*.ext.[ch] generated/$(name)/ 2>/dev/null || true
@go run ./cmd/so translate -o generated/$(name) testdata/$(name)/src
@make run-c path=generated/$(name)
# Transpiles, compiles and runs the tests in a package's "test" subdirectory
# (e.g. name=so/sync runs so/sync/test), leaving the generated C in
# generated/$(name)/test for inspection. It relies on the committed test
# runner (test/main.go); regenerate that with `so test` when tests change.
run-test:
@rm -rf generated/$(name)/test
@mkdir -p generated/$(name)/test
@go run ./cmd/so translate -o generated/$(name)/test $(name)/test
@make run-c path=generated/$(name)/test
run-c:
@mkdir -p build
@$(CC) $(CFLAGS) \
-I$(path) \
-o build/$(OUT_NAME) \
$(shell find $(path) -name "*.c") \
$(LDLIBS)
@$(RUN_CMD)
@rm -f build/$(OUT_NAME)
.PHONY: bench
bench:
@cd $(name)/bench && go test -bench=. -benchmem
@CFLAGS="-Ofast -march=native -flto -funroll-loops -DNDEBUG" \
$(MIMALLOC_PRELOAD) \
go run ./cmd/so bench ./$(name)