diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 96f4d3f..bec4a48 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,6 +37,44 @@ jobs: run: | make microbench + linux-lto: + name: Linux LTO + runs-on: ubuntu-latest + strategy: + fail-fast: false + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Build + run: | + make -j$(getconf _NPROCESSORS_ONLN) CONFIG_WERROR=y CONFIG_LTO=y + - name: Run built-in tests + run: | + make test + - name: Run microbench + run: | + make microbench + + linux-32bit: + name: Linux 32bit + runs-on: ubuntu-latest + strategy: + fail-fast: false + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Install gcc-multilib + run: | + sudo apt install -y gcc-multilib + - name: Build + run: | + make -j$(getconf _NPROCESSORS_ONLN) CONFIG_WERROR=y CONFIG_M32=y + - name: Run built-in tests + run: | + make CONFIG_M32=y test + linux-asan: runs-on: ubuntu-latest steps: @@ -142,6 +180,85 @@ jobs: ./qjs -qd gmake test + cosmopolitan: + name: Cosmopolitan + runs-on: ubuntu-latest + strategy: + fail-fast: false + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Install Cosmopolitan + run: | + mkdir ~/cosmocc + cd ~/cosmocc + wget https://cosmo.zip/pub/cosmocc/cosmocc.zip + unzip cosmocc.zip + echo "$HOME/cosmocc/bin" >> "$GITHUB_PATH" + - name: Build + run: | + make CONFIG_COSMO=y + - name: Run built-in tests + run: | + make CONFIG_COSMO=y test + + mingw-windows: + name: MinGW Windows target + runs-on: ubuntu-latest + strategy: + fail-fast: false + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Install MinGW and Wine + run: | + sudo apt install -y wine mingw-w64 + cp /usr/x86_64-w64-mingw32/lib/libwinpthread-1.dll . + - name: Setup Wine + run: | + wine --version + winecfg /v + # binfmt doesn't work in GitHub Actions + #sudo apt install -y binfmt-support wine-binfmt + #echo ":Wine:M::MZ::/usr/bin/wine:" > /etc/binfmt.d/wine.conf + #sudo systemctl restart systemd-binfmt + - name: Build + run: | + make CONFIG_WIN32=y + - name: Run built-in tests + run: | + # If binfmt support worked, could just run `make CONFIG_WIN32=y test` + make WINE=/usr/bin/wine CONFIG_WIN32=y test + + windows-msys: + name: Windows MSYS2 + runs-on: windows-latest + defaults: + run: + shell: msys2 {0} + steps: + - uses: actions/checkout@v4 + - uses: msys2/setup-msys2@v2 + with: + msystem: UCRT64 + update: true + install: git make mingw-w64-ucrt-x86_64-gcc mingw-w64-ucrt-x86_64-dlfcn + - name: Build + run: | + make -j$(getconf _NPROCESSORS_ONLN) CONFIG_WERROR=y + - name: Stats + run: | + ./qjs -qd + - name: Run built-in tests + run: | + make test + - name: Run microbench + run: | + make microbench + + qemu-alpine: runs-on: ubuntu-latest @@ -155,12 +272,14 @@ jobs: - linux/arm/v6 - linux/arm/v7 - linux/s390x + - linux/ppc64le steps: - uses: actions/checkout@v4 with: submodules: recursive - name: Get qemu - run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + # See https://github.com/tonistiigi/binfmt/issues/215#issuecomment-2613004741 + run: docker run --privileged --rm tonistiigi/binfmt:master --install all - name: Run tests on ${{ matrix.platform }} run: docker run --rm --interactive --mount type=bind,source=$(pwd),target=/host --platform ${{ matrix.platform }} alpine sh -c "apk add git patch make gcc libc-dev && cd /host && make test" diff --git a/.gitignore b/.gitignore index 5988f92..ba32a84 100644 --- a/.gitignore +++ b/.gitignore @@ -6,14 +6,20 @@ test_fib.c examples/*.so examples/hello examples/hello_module +examples/hello.exe +examples/test_fib.exe hello.c microbench*.txt qjs +qjs.exe qjsc +qjsc.exe +host-qjsc qjscalc qjscalc.c repl.c run-test262 +run-test262.exe test262 test262_*.txt test262o @@ -22,3 +28,4 @@ unicode unicode_gen run_octane run_sunspider_like +libwinpthread*.dll diff --git a/Makefile b/Makefile index 77886dd..d9aaad1 100644 --- a/Makefile +++ b/Makefile @@ -29,6 +29,9 @@ ifeq ($(shell uname -s),FreeBSD) CONFIG_FREEBSD=y endif # Windows cross compilation from Linux +# May need to have libwinpthread*.dll alongside the executable +# (On Ubuntu/Debian may be installed with mingw-w64-x86-64-dev +# to /usr/x86_64-w64-mingw32/lib/libwinpthread-1.dll) #CONFIG_WIN32=y # use link time optimization (smaller and faster executables but slower build) #CONFIG_LTO=y @@ -82,6 +85,10 @@ ifdef CONFIG_WIN32 CROSS_PREFIX?=x86_64-w64-mingw32- endif EXE=.exe +else ifdef MSYSTEM + CONFIG_WIN32=y + CROSS_PREFIX?= + EXE=.exe else CROSS_PREFIX?= EXE= @@ -189,11 +196,14 @@ endif ifndef CONFIG_COSMO ifndef CONFIG_DARWIN +ifndef CONFIG_WIN32 CONFIG_SHARED_LIBS=y # building shared libraries is supported endif endif +endif + +PROGS=qjs$(EXE) qjsc$(EXE) run-test262$(EXE) -PROGS=qjs$(EXE) qjsc$(EXE) run-test262 ifneq ($(CROSS_PREFIX),) QJSC_CC=gcc QJSC=./host-qjsc @@ -215,8 +225,10 @@ ifndef CONFIG_UBSAN PROGS+=examples/hello examples/test_fib # no -m32 option in qjsc ifndef CONFIG_M32 +ifndef CONFIG_WIN32 PROGS+=examples/hello_module endif +endif ifdef CONFIG_SHARED_LIBS PROGS+=examples/fib.so examples/point.so endif @@ -232,9 +244,9 @@ QJS_LIB_OBJS=$(OBJDIR)/quickjs.o $(OBJDIR)/dtoa.o $(OBJDIR)/libregexp.o $(OBJDIR QJS_OBJS=$(OBJDIR)/qjs.o $(OBJDIR)/repl.o $(QJS_LIB_OBJS) HOST_LIBS=-lm -ldl -lpthread -LIBS=-lm +LIBS=-lm -lpthread ifndef CONFIG_WIN32 -LIBS+=-ldl -lpthread +LIBS+=-ldl endif LIBS+=$(EXTRA_LIBS) @@ -305,7 +317,7 @@ libunicode-table.h: unicode_gen ./unicode_gen unicode $@ endif -run-test262: $(OBJDIR)/run-test262.o $(QJS_LIB_OBJS) +run-test262$(EXE): $(OBJDIR)/run-test262.o $(QJS_LIB_OBJS) $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) run-test262-debug: $(patsubst %.o, %.debug.o, $(OBJDIR)/run-test262.o $(QJS_LIB_OBJS)) @@ -348,8 +360,8 @@ clean: rm -f *.a *.o *.d *~ unicode_gen regexp_test fuzz_eval fuzz_compile fuzz_regexp $(PROGS) rm -f hello.c test_fib.c rm -f examples/*.so tests/*.so - rm -rf $(OBJDIR)/ *.dSYM/ qjs-debug - rm -rf run-test262-debug + rm -rf $(OBJDIR)/ *.dSYM/ qjs-debug$(EXE) + rm -rf run-test262-debug$(EXE) rm -f run_octane run_sunspider_like install: all @@ -427,25 +439,27 @@ ifdef CONFIG_SHARED_LIBS test: tests/bjson.so examples/point.so endif -test: qjs - ./qjs tests/test_closure.js - ./qjs tests/test_language.js - ./qjs --std tests/test_builtin.js - ./qjs tests/test_loop.js - ./qjs tests/test_bigint.js - ./qjs tests/test_std.js - ./qjs tests/test_worker.js - ./qjs tests/test_cyclic_import.js +test: qjs$(EXE) + $(WINE) ./qjs$(EXE) tests/test_closure.js + $(WINE) ./qjs$(EXE) tests/test_language.js + $(WINE) ./qjs$(EXE) --std tests/test_builtin.js + $(WINE) ./qjs$(EXE) tests/test_loop.js + $(WINE) ./qjs$(EXE) tests/test_bigint.js + $(WINE) ./qjs$(EXE) tests/test_cyclic_import.js + $(WINE) ./qjs$(EXE) tests/test_worker.js +ifndef CONFIG_WIN32 + $(WINE) ./qjs$(EXE) tests/test_std.js +endif ifdef CONFIG_SHARED_LIBS - ./qjs tests/test_bjson.js - ./qjs examples/test_point.js + $(WINE) ./qjs$(EXE) tests/test_bjson.js + $(WINE) ./qjs$(EXE) examples/test_point.js endif -stats: qjs - ./qjs -qd +stats: qjs$(EXE) + $(WINE) ./qjs$(EXE) -qd -microbench: qjs - ./qjs --std tests/microbench.js +microbench: qjs$(EXE) + $(WINE) ./qjs$(EXE) --std tests/microbench.js ifeq ($(wildcard test262o/tests.txt),) test2o test2o-update: