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) 31CONFIG_LTO=y 32# consider warnings as errors (for development) 33#CONFIG_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 51#CONFIG_BIGNUM=y 52 53OBJDIR=.obj 54 55ifdef CONFIG_WIN32 56 CROSS_PREFIX=i686-w64-mingw32- 57 EXE=.exe 58else 59 CROSS_PREFIX= 60 EXE= 61endif 62ifdef CONFIG_CLANG 63 HOST_CC=clang 64 CC=$(CROSS_PREFIX)clang 65 CFLAGS=-g -Wall -MMD -MF $(OBJDIR)/$(@F).d 66 CFLAGS += -Wextra 67 CFLAGS += -Wno-sign-compare 68 CFLAGS += -Wno-missing-field-initializers 69 CFLAGS += -Wundef -Wuninitialized 70 CFLAGS += -Wunused -Wno-unused-parameter 71 CFLAGS += -Wwrite-strings 72 CFLAGS += -Wchar-subscripts -funsigned-char 73 CFLAGS += -MMD -MF $(OBJDIR)/$(@F).d 74 ifdef CONFIG_DEFAULT_AR 75 AR=$(CROSS_PREFIX)ar 76 else 77 ifdef CONFIG_LTO 78 AR=$(CROSS_PREFIX)llvm-ar 79 else 80 AR=$(CROSS_PREFIX)ar 81 endif 82 endif 83else 84 HOST_CC=gcc 85 CC=$(CROSS_PREFIX)gcc 86 CFLAGS=-g -Wall -MMD -MF $(OBJDIR)/$(@F).d 87 CFLAGS += -Wno-array-bounds -Wno-format-truncation 88 ifdef CONFIG_LTO 89 AR=$(CROSS_PREFIX)gcc-ar 90 else 91 AR=$(CROSS_PREFIX)ar 92 endif 93endif 94STRIP=$(CROSS_PREFIX)strip 95ifdef CONFIG_WERROR 96CFLAGS+=-Werror 97endif 98DEFINES:=-D_GNU_SOURCE -DCONFIG_VERSION=\"$(shell cat VERSION)\" 99ifdef CONFIG_BIGNUM 100DEFINES+=-DCONFIG_BIGNUM 101endif 102ifdef CONFIG_WIN32 103DEFINES+=-D__USE_MINGW_ANSI_STDIO # for standard snprintf behavior 104endif 105 106CFLAGS+=$(DEFINES) 107CFLAGS_DEBUG=$(CFLAGS) -O0 108CFLAGS_SMALL=$(CFLAGS) -Os 109CFLAGS_OPT=$(CFLAGS) -O2 110CFLAGS_NOLTO:=$(CFLAGS_OPT) 111LDFLAGS=-g 112ifdef CONFIG_LTO 113CFLAGS_SMALL+=-flto 114CFLAGS_OPT+=-flto 115LDFLAGS+=-flto 116endif 117ifdef CONFIG_PROFILE 118CFLAGS+=-p 119LDFLAGS+=-p 120endif 121ifdef CONFIG_ASAN 122CFLAGS+=-fsanitize=address -fno-omit-frame-pointer 123LDFLAGS+=-fsanitize=address -fno-omit-frame-pointer 124endif 125ifdef CONFIG_WIN32 126LDEXPORT= 127else 128LDEXPORT=-rdynamic 129endif 130 131PROGS=qjs$(EXE) qjsc$(EXE) run-test262 132ifneq ($(CROSS_PREFIX),) 133QJSC_CC=gcc 134QJSC=./host-qjsc 135PROGS+=$(QJSC) 136else 137QJSC_CC=$(CC) 138QJSC=./qjsc$(EXE) 139endif 140ifndef CONFIG_WIN32 141PROGS+=qjscalc 142endif 143ifdef CONFIG_M32 144PROGS+=qjs32 qjs32_s 145endif 146PROGS+=libquickjs.a 147ifdef CONFIG_LTO 148PROGS+=libquickjs.lto.a 149endif 150 151# examples 152ifeq ($(CROSS_PREFIX),) 153ifdef CONFIG_ASAN 154PROGS+= 155else 156PROGS+=examples/hello examples/hello_module examples/test_fib 157ifndef CONFIG_DARWIN 158PROGS+=examples/fib.so examples/point.so 159endif 160endif 161endif 162 163all: $(OBJDIR) $(OBJDIR)/quickjs.check.o $(OBJDIR)/qjs.check.o $(PROGS) 164 165QJS_LIB_OBJS=$(OBJDIR)/quickjs.o $(OBJDIR)/libregexp.o $(OBJDIR)/libunicode.o $(OBJDIR)/cutils.o $(OBJDIR)/quickjs-libc.o 166 167QJS_OBJS=$(OBJDIR)/qjs.o $(OBJDIR)/repl.o $(QJS_LIB_OBJS) 168ifdef CONFIG_BIGNUM 169QJS_LIB_OBJS+=$(OBJDIR)/libbf.o 170QJS_OBJS+=$(OBJDIR)/qjscalc.o 171endif 172QJS_LIB_OBJS+=$(OBJDIR)/linux_jquick_mutex.o 173 174HOST_LIBS=-lm -ldl -lpthread 175LIBS=-lm 176ifndef CONFIG_WIN32 177LIBS+=-ldl -lpthread 178endif 179 180$(OBJDIR): 181 mkdir -p $(OBJDIR) $(OBJDIR)/examples $(OBJDIR)/tests 182 183qjs$(EXE): $(QJS_OBJS) 184 $(CC) $(LDFLAGS) $(LDEXPORT) -o $@ $^ $(LIBS) 185 186qjs-debug$(EXE): $(patsubst %.o, %.debug.o, $(QJS_OBJS)) 187 $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) 188 189qjsc$(EXE): $(OBJDIR)/qjsc.o $(QJS_LIB_OBJS) 190 $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) 191 192ifneq ($(CROSS_PREFIX),) 193 194$(QJSC): $(OBJDIR)/qjsc.host.o \ 195 $(patsubst %.o, %.host.o, $(QJS_LIB_OBJS)) 196 $(HOST_CC) $(LDFLAGS) -o $@ $^ $(HOST_LIBS) 197 198endif #CROSS_PREFIX 199 200QJSC_DEFINES:=-DCONFIG_CC=\"$(QJSC_CC)\" -DCONFIG_PREFIX=\"$(prefix)\" 201ifdef CONFIG_LTO 202QJSC_DEFINES+=-DCONFIG_LTO 203endif 204QJSC_HOST_DEFINES:=-DCONFIG_CC=\"$(HOST_CC)\" -DCONFIG_PREFIX=\"$(prefix)\" 205 206$(OBJDIR)/qjsc.o: CFLAGS+=$(QJSC_DEFINES) 207$(OBJDIR)/qjsc.host.o: CFLAGS+=$(QJSC_HOST_DEFINES) 208 209qjs32: $(patsubst %.o, %.m32.o, $(QJS_OBJS)) 210 $(CC) -m32 $(LDFLAGS) $(LDEXPORT) -o $@ $^ $(LIBS) 211 212qjs32_s: $(patsubst %.o, %.m32s.o, $(QJS_OBJS)) 213 $(CC) -m32 $(LDFLAGS) -o $@ $^ $(LIBS) 214 @size $@ 215 216qjscalc: qjs 217 ln -sf $< $@ 218 219ifdef CONFIG_LTO 220LTOEXT=.lto 221else 222LTOEXT= 223endif 224 225libquickjs$(LTOEXT).a: $(QJS_LIB_OBJS) 226 $(AR) rcs $@ $^ 227 228ifdef CONFIG_LTO 229libquickjs.a: $(patsubst %.o, %.nolto.o, $(QJS_LIB_OBJS)) 230 $(AR) rcs $@ $^ 231endif # CONFIG_LTO 232 233repl.c: $(QJSC) repl.js 234 $(QJSC) -c -o $@ -m repl.js 235 236qjscalc.c: $(QJSC) qjscalc.js 237 $(QJSC) -fbignum -c -o $@ qjscalc.js 238 239ifneq ($(wildcard unicode/UnicodeData.txt),) 240$(OBJDIR)/libunicode.o $(OBJDIR)/libunicode.m32.o $(OBJDIR)/libunicode.m32s.o \ 241 $(OBJDIR)/libunicode.nolto.o: libunicode-table.h 242 243libunicode-table.h: unicode_gen 244 ./unicode_gen unicode $@ 245endif 246 247run-test262: $(OBJDIR)/run-test262.o $(QJS_LIB_OBJS) 248 $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) 249 250run-test262-debug: $(patsubst %.o, %.debug.o, $(OBJDIR)/run-test262.o $(QJS_LIB_OBJS)) 251 $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) 252 253run-test262-32: $(patsubst %.o, %.m32.o, $(OBJDIR)/run-test262.o $(QJS_LIB_OBJS)) 254 $(CC) -m32 $(LDFLAGS) -o $@ $^ $(LIBS) 255 256# object suffix order: nolto, [m32|m32s] 257 258$(OBJDIR)/%.o: %.c | $(OBJDIR) 259 $(CC) $(CFLAGS_OPT) -c -o $@ $< 260 261$(OBJDIR)/%.host.o: %.c | $(OBJDIR) 262 $(HOST_CC) $(CFLAGS_OPT) -c -o $@ $< 263 264$(OBJDIR)/%.pic.o: %.c | $(OBJDIR) 265 $(CC) $(CFLAGS_OPT) -fPIC -DJS_SHARED_LIBRARY -c -o $@ $< 266 267$(OBJDIR)/%.nolto.o: %.c | $(OBJDIR) 268 $(CC) $(CFLAGS_NOLTO) -c -o $@ $< 269 270$(OBJDIR)/%.m32.o: %.c | $(OBJDIR) 271 $(CC) -m32 $(CFLAGS_OPT) -c -o $@ $< 272 273$(OBJDIR)/%.m32s.o: %.c | $(OBJDIR) 274 $(CC) -m32 $(CFLAGS_SMALL) -c -o $@ $< 275 276$(OBJDIR)/%.debug.o: %.c | $(OBJDIR) 277 $(CC) $(CFLAGS_DEBUG) -c -o $@ $< 278 279$(OBJDIR)/%.check.o: %.c | $(OBJDIR) 280 $(CC) $(CFLAGS) -DCONFIG_CHECK_JSVALUE -c -o $@ $< 281 282regexp_test: libregexp.c libunicode.c cutils.c 283 $(CC) $(LDFLAGS) $(CFLAGS) -DTEST -o $@ libregexp.c libunicode.c cutils.c $(LIBS) 284 285jscompress: jscompress.c 286 $(CC) $(LDFLAGS) $(CFLAGS) -o $@ jscompress.c 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 *~ jscompress 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