1# 2# QuickJS Javascript Engine 3# 4# Copyright (c) 2017-2020 Fabrice Bellard 5# Copyright (c) 2017-2020 Charlie Gordon 6# 7# Permission is hereby granted, free of charge, to any person obtaining a copy 8# of this software and associated documentation files (the "Software"), to deal 9# in the Software without restriction, including without limitation the rights 10# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11# copies of the Software, and to permit persons to whom the Software is 12# furnished to do so, subject to the following conditions: 13# 14# The above copyright notice and this permission notice shall be included in 15# all copies or substantial portions of the Software. 16# 17# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23# THE SOFTWARE. 24 25ifeq ($(shell uname -s),Darwin) 26CONFIG_DARWIN=y 27endif 28# Windows cross compilation from Linux 29#CONFIG_WIN32=y 30# use link time optimization (smaller and faster executables but slower build) 31#CONFIG_LTO=y 32# consider warnings as errors (for development) 33CONFIG_WERROR=y 34# force 32 bit build for some utilities 35#CONFIG_M32=y 36 37ifdef CONFIG_DARWIN 38# use clang instead of gcc 39CONFIG_CLANG=y 40CONFIG_DEFAULT_AR=y 41endif 42 43# installation directory 44prefix=/usr/local 45 46# use the gprof profiler 47#CONFIG_PROFILE=y 48# use address sanitizer 49#CONFIG_ASAN=y 50# include the code for BigInt/BigFloat/BigDecimal and math mode 51CONFIG_BIGNUM=y 52 53OBJDIR=.obj 54 55ifdef CONFIG_WIN32 56 ifdef CONFIG_M32 57 CROSS_PREFIX=i686-w64-mingw32- 58 else 59 CROSS_PREFIX=x86_64-w64-mingw32- 60 endif 61 EXE=.exe 62else 63 CROSS_PREFIX= 64 EXE= 65endif 66ifdef CONFIG_CLANG 67 HOST_CC=clang 68 CC=$(CROSS_PREFIX)clang 69 CFLAGS=-g -Wall -MMD -MF $(OBJDIR)/$(@F).d 70 CFLAGS += -Wextra 71 CFLAGS += -Wno-sign-compare 72 CFLAGS += -Wno-missing-field-initializers 73 CFLAGS += -Wundef -Wuninitialized 74 CFLAGS += -Wunused -Wno-unused-parameter 75 CFLAGS += -Wwrite-strings 76 CFLAGS += -Wchar-subscripts -funsigned-char 77 CFLAGS += -MMD -MF $(OBJDIR)/$(@F).d 78 ifdef CONFIG_DEFAULT_AR 79 AR=$(CROSS_PREFIX)ar 80 else 81 ifdef CONFIG_LTO 82 AR=$(CROSS_PREFIX)llvm-ar 83 else 84 AR=$(CROSS_PREFIX)ar 85 endif 86 endif 87else 88 HOST_CC=gcc 89 CC=$(CROSS_PREFIX)gcc 90 CFLAGS=-g -Wall -MMD -MF $(OBJDIR)/$(@F).d 91 CFLAGS += -Wno-array-bounds -Wno-format-truncation 92 ifdef CONFIG_LTO 93 AR=$(CROSS_PREFIX)gcc-ar 94 else 95 AR=$(CROSS_PREFIX)ar 96 endif 97endif 98STRIP=$(CROSS_PREFIX)strip 99ifdef CONFIG_WERROR 100CFLAGS+=-Werror 101endif 102DEFINES:=-D_GNU_SOURCE -DCONFIG_VERSION=\"$(shell cat VERSION)\" 103ifdef CONFIG_BIGNUM 104DEFINES+=-DCONFIG_BIGNUM 105endif 106ifdef CONFIG_WIN32 107DEFINES+=-D__USE_MINGW_ANSI_STDIO # for standard snprintf behavior 108endif 109 110CFLAGS+=$(DEFINES) 111CFLAGS_DEBUG=$(CFLAGS) -O0 112CFLAGS_SMALL=$(CFLAGS) -Os 113CFLAGS_OPT=$(CFLAGS) -O2 114CFLAGS_NOLTO:=$(CFLAGS_OPT) 115LDFLAGS=-g 116ifdef CONFIG_LTO 117CFLAGS_SMALL+=-flto 118CFLAGS_OPT+=-flto 119LDFLAGS+=-flto 120endif 121ifdef CONFIG_PROFILE 122CFLAGS+=-p 123LDFLAGS+=-p 124endif 125ifdef CONFIG_ASAN 126CFLAGS+=-fsanitize=address -fno-omit-frame-pointer 127LDFLAGS+=-fsanitize=address -fno-omit-frame-pointer 128endif 129ifdef CONFIG_WIN32 130LDEXPORT= 131else 132LDEXPORT=-rdynamic 133endif 134 135PROGS=qjs$(EXE) qjsc$(EXE) run-test262 136ifneq ($(CROSS_PREFIX),) 137QJSC_CC=gcc 138QJSC=./host-qjsc 139PROGS+=$(QJSC) 140else 141QJSC_CC=$(CC) 142QJSC=./qjsc$(EXE) 143endif 144ifndef CONFIG_WIN32 145PROGS+=qjscalc 146endif 147ifdef CONFIG_M32 148PROGS+=qjs32 qjs32_s 149endif 150PROGS+=libquickjs.a 151ifdef CONFIG_LTO 152PROGS+=libquickjs.lto.a 153endif 154 155# examples 156ifeq ($(CROSS_PREFIX),) 157ifdef CONFIG_ASAN 158PROGS+= 159else 160PROGS+=examples/hello examples/hello_module examples/test_fib 161ifndef CONFIG_DARWIN 162PROGS+=examples/fib.so examples/point.so 163endif 164endif 165endif 166 167all: $(OBJDIR) $(OBJDIR)/quickjs.check.o $(OBJDIR)/qjs.check.o $(PROGS) 168 169QJS_LIB_OBJS=$(OBJDIR)/quickjs.o $(OBJDIR)/libregexp.o $(OBJDIR)/libunicode.o $(OBJDIR)/cutils.o $(OBJDIR)/quickjs-libc.o 170 171QJS_OBJS=$(OBJDIR)/qjs.o $(OBJDIR)/repl.o $(QJS_LIB_OBJS) 172ifdef CONFIG_BIGNUM 173QJS_LIB_OBJS+=$(OBJDIR)/libbf.o 174QJS_OBJS+=$(OBJDIR)/qjscalc.o 175endif 176 177HOST_LIBS=-lm -ldl -lpthread 178LIBS=-lm 179ifndef CONFIG_WIN32 180LIBS+=-ldl -lpthread 181endif 182 183$(OBJDIR): 184 mkdir -p $(OBJDIR) $(OBJDIR)/examples $(OBJDIR)/tests 185 186qjs$(EXE): $(QJS_OBJS) 187 $(CC) $(LDFLAGS) $(LDEXPORT) -o $@ $^ $(LIBS) 188 189qjs-debug$(EXE): $(patsubst %.o, %.debug.o, $(QJS_OBJS)) 190 $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) 191 192qjsc$(EXE): $(OBJDIR)/qjsc.o $(QJS_LIB_OBJS) 193 $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) 194 195ifneq ($(CROSS_PREFIX),) 196 197$(QJSC): $(OBJDIR)/qjsc.host.o \ 198 $(patsubst %.o, %.host.o, $(QJS_LIB_OBJS)) 199 $(HOST_CC) $(LDFLAGS) -o $@ $^ $(HOST_LIBS) 200 201endif #CROSS_PREFIX 202 203QJSC_DEFINES:=-DCONFIG_CC=\"$(QJSC_CC)\" -DCONFIG_PREFIX=\"$(prefix)\" 204ifdef CONFIG_LTO 205QJSC_DEFINES+=-DCONFIG_LTO 206endif 207QJSC_HOST_DEFINES:=-DCONFIG_CC=\"$(HOST_CC)\" -DCONFIG_PREFIX=\"$(prefix)\" 208 209$(OBJDIR)/qjsc.o: CFLAGS+=$(QJSC_DEFINES) 210$(OBJDIR)/qjsc.host.o: CFLAGS+=$(QJSC_HOST_DEFINES) 211 212qjs32: $(patsubst %.o, %.m32.o, $(QJS_OBJS)) 213 $(CC) -m32 $(LDFLAGS) $(LDEXPORT) -o $@ $^ $(LIBS) 214 215qjs32_s: $(patsubst %.o, %.m32s.o, $(QJS_OBJS)) 216 $(CC) -m32 $(LDFLAGS) -o $@ $^ $(LIBS) 217 @size $@ 218 219qjscalc: qjs 220 ln -sf $< $@ 221 222ifdef CONFIG_LTO 223LTOEXT=.lto 224else 225LTOEXT= 226endif 227 228libquickjs$(LTOEXT).a: $(QJS_LIB_OBJS) 229 $(AR) rcs $@ $^ 230 231ifdef CONFIG_LTO 232libquickjs.a: $(patsubst %.o, %.nolto.o, $(QJS_LIB_OBJS)) 233 $(AR) rcs $@ $^ 234endif # CONFIG_LTO 235 236repl.c: $(QJSC) repl.js 237 $(QJSC) -c -o $@ -m repl.js 238 239qjscalc.c: $(QJSC) qjscalc.js 240 $(QJSC) -fbignum -c -o $@ qjscalc.js 241 242ifneq ($(wildcard unicode/UnicodeData.txt),) 243$(OBJDIR)/libunicode.o $(OBJDIR)/libunicode.m32.o $(OBJDIR)/libunicode.m32s.o \ 244 $(OBJDIR)/libunicode.nolto.o: libunicode-table.h 245 246libunicode-table.h: unicode_gen 247 ./unicode_gen unicode $@ 248endif 249 250run-test262: $(OBJDIR)/run-test262.o $(QJS_LIB_OBJS) 251 $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) 252 253run-test262-debug: $(patsubst %.o, %.debug.o, $(OBJDIR)/run-test262.o $(QJS_LIB_OBJS)) 254 $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) 255 256run-test262-32: $(patsubst %.o, %.m32.o, $(OBJDIR)/run-test262.o $(QJS_LIB_OBJS)) 257 $(CC) -m32 $(LDFLAGS) -o $@ $^ $(LIBS) 258 259# object suffix order: nolto, [m32|m32s] 260 261$(OBJDIR)/%.o: %.c | $(OBJDIR) 262 $(CC) $(CFLAGS_OPT) -c -o $@ $< 263 264$(OBJDIR)/%.host.o: %.c | $(OBJDIR) 265 $(HOST_CC) $(CFLAGS_OPT) -c -o $@ $< 266 267$(OBJDIR)/%.pic.o: %.c | $(OBJDIR) 268 $(CC) $(CFLAGS_OPT) -fPIC -DJS_SHARED_LIBRARY -c -o $@ $< 269 270$(OBJDIR)/%.nolto.o: %.c | $(OBJDIR) 271 $(CC) $(CFLAGS_NOLTO) -c -o $@ $< 272 273$(OBJDIR)/%.m32.o: %.c | $(OBJDIR) 274 $(CC) -m32 $(CFLAGS_OPT) -c -o $@ $< 275 276$(OBJDIR)/%.m32s.o: %.c | $(OBJDIR) 277 $(CC) -m32 $(CFLAGS_SMALL) -c -o $@ $< 278 279$(OBJDIR)/%.debug.o: %.c | $(OBJDIR) 280 $(CC) $(CFLAGS_DEBUG) -c -o $@ $< 281 282$(OBJDIR)/%.check.o: %.c | $(OBJDIR) 283 $(CC) $(CFLAGS) -DCONFIG_CHECK_JSVALUE -c -o $@ $< 284 285regexp_test: libregexp.c libunicode.c cutils.c 286 $(CC) $(LDFLAGS) $(CFLAGS) -DTEST -o $@ libregexp.c libunicode.c cutils.c $(LIBS) 287 288unicode_gen: $(OBJDIR)/unicode_gen.host.o $(OBJDIR)/cutils.host.o libunicode.c unicode_gen_def.h 289 $(HOST_CC) $(LDFLAGS) $(CFLAGS) -o $@ $(OBJDIR)/unicode_gen.host.o $(OBJDIR)/cutils.host.o 290 291clean: 292 rm -f repl.c qjscalc.c out.c 293 rm -f *.a *.o *.d *~ unicode_gen regexp_test $(PROGS) 294 rm -f hello.c test_fib.c 295 rm -f examples/*.so tests/*.so 296 rm -rf $(OBJDIR)/ *.dSYM/ qjs-debug 297 rm -rf run-test262-debug run-test262-32 298 299install: all 300 mkdir -p "$(DESTDIR)$(prefix)/bin" 301 $(STRIP) qjs qjsc 302 install -m755 qjs qjsc "$(DESTDIR)$(prefix)/bin" 303 ln -sf qjs "$(DESTDIR)$(prefix)/bin/qjscalc" 304 mkdir -p "$(DESTDIR)$(prefix)/lib/quickjs" 305 install -m644 libquickjs.a "$(DESTDIR)$(prefix)/lib/quickjs" 306ifdef CONFIG_LTO 307 install -m644 libquickjs.lto.a "$(DESTDIR)$(prefix)/lib/quickjs" 308endif 309 mkdir -p "$(DESTDIR)$(prefix)/include/quickjs" 310 install -m644 quickjs.h quickjs-libc.h "$(DESTDIR)$(prefix)/include/quickjs" 311 312############################################################################### 313# examples 314 315# example of static JS compilation 316HELLO_SRCS=examples/hello.js 317HELLO_OPTS=-fno-string-normalize -fno-map -fno-promise -fno-typedarray \ 318 -fno-typedarray -fno-regexp -fno-json -fno-eval -fno-proxy \ 319 -fno-date -fno-module-loader 320ifdef CONFIG_BIGNUM 321HELLO_OPTS+=-fno-bigint 322endif 323 324hello.c: $(QJSC) $(HELLO_SRCS) 325 $(QJSC) -e $(HELLO_OPTS) -o $@ $(HELLO_SRCS) 326 327ifdef CONFIG_M32 328examples/hello: $(OBJDIR)/hello.m32s.o $(patsubst %.o, %.m32s.o, $(QJS_LIB_OBJS)) 329 $(CC) -m32 $(LDFLAGS) -o $@ $^ $(LIBS) 330else 331examples/hello: $(OBJDIR)/hello.o $(QJS_LIB_OBJS) 332 $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) 333endif 334 335# example of static JS compilation with modules 336HELLO_MODULE_SRCS=examples/hello_module.js 337HELLO_MODULE_OPTS=-fno-string-normalize -fno-map -fno-promise -fno-typedarray \ 338 -fno-typedarray -fno-regexp -fno-json -fno-eval -fno-proxy \ 339 -fno-date -m 340examples/hello_module: $(QJSC) libquickjs$(LTOEXT).a $(HELLO_MODULE_SRCS) 341 $(QJSC) $(HELLO_MODULE_OPTS) -o $@ $(HELLO_MODULE_SRCS) 342 343# use of an external C module (static compilation) 344 345test_fib.c: $(QJSC) examples/test_fib.js 346 $(QJSC) -e -M examples/fib.so,fib -m -o $@ examples/test_fib.js 347 348examples/test_fib: $(OBJDIR)/test_fib.o $(OBJDIR)/examples/fib.o libquickjs$(LTOEXT).a 349 $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) 350 351examples/fib.so: $(OBJDIR)/examples/fib.pic.o 352 $(CC) $(LDFLAGS) -shared -o $@ $^ 353 354examples/point.so: $(OBJDIR)/examples/point.pic.o 355 $(CC) $(LDFLAGS) -shared -o $@ $^ 356 357############################################################################### 358# documentation 359 360DOCS=doc/quickjs.pdf doc/quickjs.html doc/jsbignum.pdf doc/jsbignum.html 361 362build_doc: $(DOCS) 363 364clean_doc: 365 rm -f $(DOCS) 366 367doc/%.pdf: doc/%.texi 368 texi2pdf --clean -o $@ -q $< 369 370doc/%.html.pre: doc/%.texi 371 makeinfo --html --no-headers --no-split --number-sections -o $@ $< 372 373doc/%.html: doc/%.html.pre 374 sed -e 's|</style>|</style>\n<meta name="viewport" content="width=device-width, initial-scale=1.0">|' < $< > $@ 375 376############################################################################### 377# tests 378 379ifndef CONFIG_DARWIN 380test: tests/bjson.so examples/point.so 381endif 382ifdef CONFIG_M32 383test: qjs32 384endif 385 386test: qjs 387 ./qjs tests/test_closure.js 388 ./qjs tests/test_language.js 389 ./qjs tests/test_builtin.js 390 ./qjs tests/test_loop.js 391 ./qjs tests/test_std.js 392 ./qjs tests/test_worker.js 393ifndef CONFIG_DARWIN 394ifdef CONFIG_BIGNUM 395 ./qjs --bignum tests/test_bjson.js 396else 397 ./qjs tests/test_bjson.js 398endif 399 ./qjs examples/test_point.js 400endif 401ifdef CONFIG_BIGNUM 402 ./qjs --bignum tests/test_op_overloading.js 403 ./qjs --bignum tests/test_bignum.js 404 ./qjs --qjscalc tests/test_qjscalc.js 405endif 406ifdef CONFIG_M32 407 ./qjs32 tests/test_closure.js 408 ./qjs32 tests/test_language.js 409 ./qjs32 tests/test_builtin.js 410 ./qjs32 tests/test_loop.js 411 ./qjs32 tests/test_std.js 412 ./qjs32 tests/test_worker.js 413ifdef CONFIG_BIGNUM 414 ./qjs32 --bignum tests/test_op_overloading.js 415 ./qjs32 --bignum tests/test_bignum.js 416 ./qjs32 --qjscalc tests/test_qjscalc.js 417endif 418endif 419 420stats: qjs qjs32 421 ./qjs -qd 422 ./qjs32 -qd 423 424microbench: qjs 425 ./qjs tests/microbench.js 426 427microbench-32: qjs32 428 ./qjs32 tests/microbench.js 429 430# ES5 tests (obsolete) 431test2o: run-test262 432 time ./run-test262 -m -c test262o.conf 433 434test2o-32: run-test262-32 435 time ./run-test262-32 -m -c test262o.conf 436 437test2o-update: run-test262 438 ./run-test262 -u -c test262o.conf 439 440# Test262 tests 441test2-default: run-test262 442 time ./run-test262 -m -c test262.conf 443 444test2: run-test262 445 time ./run-test262 -m -c test262.conf -a 446 447test2-32: run-test262-32 448 time ./run-test262-32 -m -c test262.conf -a 449 450test2-update: run-test262 451 ./run-test262 -u -c test262.conf -a 452 453test2-check: run-test262 454 time ./run-test262 -m -c test262.conf -E -a 455 456testall: all test microbench test2o test2 457 458testall-32: all test-32 microbench-32 test2o-32 test2-32 459 460testall-complete: testall testall-32 461 462bench-v8: qjs 463 make -C tests/bench-v8 464 ./qjs -d tests/bench-v8/combined.js 465 466tests/bjson.so: $(OBJDIR)/tests/bjson.pic.o 467 $(CC) $(LDFLAGS) -shared -o $@ $^ $(LIBS) 468 469-include $(wildcard $(OBJDIR)/*.d) 470