forked from nearform/node-cephes
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMakefile
194 lines (157 loc) · 6.56 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
CEPHESDIR := cephes
BUILDDIR := build
JS_OBJS := $(patsubst %.c,%.bc,$(wildcard $(CEPHESDIR)/*.c)) build/malloc_free.bc
C_OBJS := $(patsubst %.c,%.o,$(wildcard $(CEPHESDIR)/*.c)) test/expected.o
CPROTOFILES := $(wildcard $(CEPHESDIR)/*.c)
GENERATEFILES := $(wildcard $(BUILDDIR)/*.js) $(wildcard $(BUILDDIR)/*.md)
CFLAGS:=-O2 -g3
LFLAGS:=-O3 -g3
.PHONY: download build test
build: index.js cephes.wasm.base64.json README.md
clean:
rm -f $(JS_OBJS)
rm -f $(C_OBJS)
rm -f cephes.wasm cephes.wast
rm -f index.js
test: test/expected.ndjson test/actual.test.js
npm test
cephes/:
mkdir cephes
download: | cephes/
rm -f $(CEPHESDIR)/*
@# Download main library
curl http://www.netlib.org/cephes/cmath.tgz | tar xz -C $(CEPHESDIR)
@# Download cprob extension
curl http://www.netlib.org/cephes/cprob.tgz | tar xz -C $(CEPHESDIR)
@# Download ellf extension
curl http://www.netlib.org/cephes/ellf.tgz | tar xz -C $(CEPHESDIR)
@# Download bessel extension
curl http://www.netlib.org/cephes/bessel.tgz | tar xz -C $(CEPHESDIR)
@# Download misc extension
curl http://www.netlib.org/cephes/misc.tgz | tar xz -C $(CEPHESDIR)
@# Download documentation
curl http://www.netlib.org/cephes/cephes.doc > $(CEPHESDIR)/cephes.txt
@# Remove compile files and instructions
cd $(CEPHESDIR) && \
rm -f *.mak *.MAK *.bat msc.rsp descrip.mms README *.doc protos.h ftilib.*
@# remove math functions that are too complicated to deal with
cd $(CEPHESDIR) && rm -f \
clog.c cmplx.c mod2pi.c drand.c dtestvec.c mtst.* polevl.asm setprbor.asm \
setprec.* setprelf.* ELLF.* ellf.* revers.c simpsn.c
@# remove mtherr.c error handling file, this is reimplemented in JavaScript
@# see the c-defs.js file.
cd $(CEPHESDIR) && rm -f mtherr.c
@# remove math functions that are too basic, as they are implemented natively
@# in WebAssembly (f64.abs, and f64.sqrt).
cd $(CEPHESDIR) && rm -f \
fabs.c sqrt.c
@# Rename (effectively remove) ceil, floor as they have native
@# WebAssembly equivalents (f64.ceil, and f64.floor).
@# It will continue to contain defintions for frexp, and ldexp
clang-rename \
-qualified-name=ceil -new-name=ignore_ceil \
-qualified-name=floor -new-name=ignore_floor \
-i $(CEPHESDIR)/floor.c
@# Configure cephes
sed -i '' -e 's/define HAVE_LONG_DOUBLE 1/define HAVE_LONG_DOUBLE 0/g' $(CEPHESDIR)/mconf.h
sed -i '' -e 's/define STDC_HEADERS 1/define STDC_HEADERS 0/g' $(CEPHESDIR)/mconf.h
sed -i '' -e 's/define HAVE_STRING_H 1/define HAVE_STRING_H 0/g' $(CEPHESDIR)/mconf.h
sed -i '' -e 's%#define UNK 1%/* #define UNK 1 */%g' $(CEPHESDIR)/mconf.h
sed -i '' -e 's%/\* #define IBMPC 1 \*/%#define IBMPC 1%g' $(CEPHESDIR)/mconf.h
@# Create renaming defs to prevent conflict with default symbols
echo '#ifndef CEPHES_NAMES_H' > $(CEPHESDIR)/cephes_names.h
echo '#define CEPHES_NAMES_H' >> $(CEPHESDIR)/cephes_names.h
echo '' >> $(CEPHESDIR)/cephes_names.h
cproto $(CEPHESDIR)/*.c | \
grep -v 'ignore_' | \
sed -E 's/^(int|double) ([a-z0-9_]+)[^\;]+;$$/#define \2 cephes_\2/g' \
>> $(CEPHESDIR)/cephes_names.h
echo '' >> $(CEPHESDIR)/cephes_names.h
echo '#endif' >> $(CEPHESDIR)/cephes_names.h
@# Add include for cephes_names.h statement to mconf.h
echo '' >> $(CEPHESDIR)/mconf.h
echo '/* rename defs to prevent conflict with default symbols */' >> $(CEPHESDIR)/mconf.h
echo '#include "cephes_names.h"' >> $(CEPHESDIR)/mconf.h
@# Create proto header file
echo '#ifndef CEPHES_H' > $(CEPHESDIR)/cephes.h
echo '#define CEPHES_H' >> $(CEPHESDIR)/cephes.h
echo '' >> $(CEPHESDIR)/cephes_names.h
cproto $(CEPHESDIR)/*.c | grep -v 'ignore_' >> $(CEPHESDIR)/cephes.h
echo '' >> $(CEPHESDIR)/cephes_names.h
echo '#endif' >> $(CEPHESDIR)/cephes.h
%.bc: %.c $(CEPHESDIR)/cephes_names.h $(CEPHESDIR)/mconf.h
@# Format the file so it looks readable
clang-format -style=llvm -i $<
@# Insert missing #include "mconf.h"
@if ! grep -q '#include "mconf.h"' $<; then \
printf '%s\n%s\n' '#include "mconf.h"' "$$(cat $<)" > $<; \
echo "Inserted missing mconf.h"; \
fi
@# Compile
emcc $(CFLAGS) $< -o $@
%.o: %.c $(CEPHESDIR)/cephes_names.h $(CEPHESDIR)/mconf.h
@# Insert missing #include "mconf.h"
@if ! grep -q '#include "mconf.h"' $<; then \
printf '%s\n%s\n' '#include "mconf.h"' "$$(cat $<)" > $<; \
echo "Inserted missing mconf.h"; \
fi
@# Compile
$(CC) $(CFLAGS) -c $< -o $@
test/expected.c: $(CPROTOFILES) $(GENERATEFILES)
cproto $(CEPHESDIR)/*.c | grep -v ignore_ | node $(BUILDDIR)/generate-c-tester.js > test/expected.c
test/expected.o: test/expected.c $(CEPHESDIR)/cephes_names.h $(CEPHESDIR)/mconf.h
$(CC) $(CFLAGS) -I $(CEPHESDIR) -c $< -o $@
test/expected: $(C_OBJS)
$(CC) $(LFLAGS) $^ -o $@
test/expected.ndjson: test/expected
test/expected > test/expected.ndjson
cephes.wasm: $(JS_OBJS)
emcc \
-s BINARYEN_ASYNC_COMPILATION=0 \
-s EXPORTED_FUNCTIONS="[$(shell \
cat $(CEPHESDIR)/cephes_names.h | \
grep cephes_ | \
sed -E "s/^#define ([a-z0-9]+) (cephes_[a-z0-9]+)$$/'_\2'/g" | \
tr '\n' ',' | \
sed 's/,$$//' \
)]" \
-s EXTRA_EXPORTED_RUNTIME_METHODS="['writeArrayToMemory', 'stackAlloc', 'stackSave', 'stackRestore', 'getValue']" \
-s DEFAULT_LIBRARY_FUNCS_TO_INCLUDE="[]" \
-s TOTAL_MEMORY=2MB \
-s TOTAL_STACK=1MB \
-s NO_FILESYSTEM=1 \
-s ENVIRONMENT='node' \
-s NODEJS_CATCH_EXIT=0 \
-s INVOKE_RUN=0 \
-s DISABLE_EXCEPTION_CATCHING=1 \
-s ASSERTIONS=0 \
--js-library $(BUILDDIR)/c-defs.js \
$(LFLAGS) $^ -o cephes-temp.js
rm cephes-temp.js
mv cephes-temp.wasm cephes.wasm
mv cephes-temp.wast cephes.wast
cephes.standalone.wasm: $(JS_OBJS)
@# Work In Progress: try and use the SIDE_MODULE options for a more
@# documented approach to stripping out the large and problematic
@# emscripten cephes.js file.
emcc \
-s BINARYEN_ASYNC_COMPILATION=0 \
-s EXPORTED_FUNCTIONS="[$(shell \
cat $(CEPHESDIR)/cephes_names.h | \
grep cephes_ | \
sed -E "s/^#define ([a-z0-9]+) (cephes_[a-z0-9]+)$$/'_\2'/g" | \
tr '\n' ',' | \
sed 's/,$$//' \
)]" \
-s SIDE_MODULE=1 \
--js-library $(BUILDDIR)/c-defs.js \
$(LFLAGS) $^ -o $@
cephes.wasm.base64.json: cephes.wasm
node -p "JSON.stringify(fs.readFileSync('$^', 'base64'))" > $@
index.js: cephes.wasm $(CPROTOFILES) $(GENERATEFILES)
cproto $(CEPHESDIR)/*.c | grep -v ignore_ | node $(BUILDDIR)/generate-interface.js > index.js
README.md: $(CEPHESDIR)/cephes.txt $(CPROTOFILES) $(GENERATEFILES)
cat $(BUILDDIR)/readme-header.md > README.md
cproto $(CEPHESDIR)/*.c | grep -v ignore_ | node $(BUILDDIR)/generate-readme-toc.js >> README.md
cproto $(CEPHESDIR)/*.c | grep -v ignore_ | node $(BUILDDIR)/generate-readme-jsdoc.js >> README.md
cat $(BUILDDIR)/readme-footer.md >> README.md