Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Add ability to create standalone binaries with qjs #739

Merged
merged 3 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,11 @@ jobs:
git submodule update --init --checkout --depth 1
time make test262

- name: test standalone
run: |
./build/qjs -c examples/hello.js -o hello
./hello

windows-msvc:
runs-on: windows-latest
strategy:
Expand All @@ -184,6 +189,10 @@ jobs:
build\${{matrix.buildType}}\qjs.exe examples\test_point.js
build\${{matrix.buildType}}\run-test262.exe -c tests.conf
build\${{matrix.buildType}}\function_source.exe
- name: test standalone
run: |
build\${{matrix.buildType}}\qjs.exe -c examples\hello.js -o hello.exe
.\hello.exe
- name: Set up Visual Studio shell
uses: egor-tensin/vs-shell@v2
with:
Expand Down Expand Up @@ -351,6 +360,10 @@ jobs:
- name: test
run: |
make test
- name: test standalone
run: |
./build/qjs -c examples/hello.js -o hello.exe
./hello
windows-mingw-shared:
runs-on: windows-latest
defaults:
Expand Down
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ target_link_libraries(qjsc qjs)

add_executable(qjs_exe
gen/repl.c
gen/standalone.c
qjs.c
)
add_qjs_libc_if_needed(qjs_exe)
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ clean:

codegen: $(QJSC)
$(QJSC) -ss -o gen/repl.c -m repl.js
$(QJSC) -ss -o gen/standalone.c -m standalone.js
$(QJSC) -e -o gen/function_source.c tests/function_source.js
$(QJSC) -e -o gen/hello.c examples/hello.js
$(QJSC) -e -o gen/hello_module.c -m examples/hello_module.js
Expand Down
36 changes: 35 additions & 1 deletion docs/docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@ usage: qjs [options] [file [args]]
-m --module load as ES6 module (default=autodetect)
--script load as ES6 script (default=autodetect)
-I --include file include an additional file
--std make 'std' and 'os' available to the loaded script
--std make 'std', 'os' and 'bjson' available to script
-T --trace trace memory allocation
-d --dump dump the memory usage stats
-D --dump-flags flags for dumping debug data (see DUMP_* defines)
-c --compile FILE compile the given JS file as a standalone executable
-o --out FILE output file for standalone executables
--exe select the executable to use as the base, defaults to the current one
--memory-limit n limit the memory usage to 'n' Kbytes
--stack-size n limit the stack size to 'n' Kbytes
--unhandled-rejection dump unhandled promise rejections
Expand Down Expand Up @@ -52,6 +55,37 @@ DUMP_ATOMS 0x40000 /* dump atoms in JS_FreeRuntime */
DUMP_SHAPES 0x80000 /* dump shapes in JS_FreeRuntime */
```

### Creating standalone executables

With the `qjs` CLI it's possible to create standalone executables that will bundle the given JavaScript file
alongside the binary.

```
$ qjs -c app.js -o app --exe qjs
```

The resulting `app` binary will have the same runtime dependencies as the `qjs` binary. This is acomplished
by compiling the target JavaScript file to bytecode and adding it a copy of the executable, with a little
trailer to help locate it.

Rather than using the current executable, it's possible to use the `--exe` switch to create standalone
executables for other platforms.

No JavaScript bundling is performed, the specified JS file cannot depend on other files. A bundler such
as `esbuild` can be used to generate an app bundle which can then be turned into the executable.

```
npx esbuild my-app/index.js \
--bundle \
--outfile=app.js \
--external:qjs:* \
--minify \
--target=es2023 \
--platform=neutral \
--format=esm \
--main-fields=main,module
```

## `qjsc` - The QuickJS JavaScript compiler

The `qjsc` executable runs the JavaScript compiler, it can generate bytecode from
Expand Down
Loading
Loading