vercel-labs / vercel-labs/scriptc

No way to pass a linker flag (e.g. -mwindows for the Windows GUI subsystem)

Open
#259 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
4.9k
Forks
125
Avg merge
2h 14m
Merged PRs (30d)
95

Description

There is no way to pass a linker flag to the platform linker driver. Some flags change what kind of executable you get rather than what it links against, and -mwindows — which selects the Windows GUI subsystem — is the one that blocked us.

Version: scriptc 0.0.35, checked on macOS 26.5 arm64 and on windows-latest with llvm-mingw.

What I tried

system_libraries rejects it:

$ scriptc build main.ts --ffi ffi.json -o app
ffi.json:1:1 - error SC5001: FFI manifest invalid: 'system_libraries[0]' is not a library name: '-mwindows'

and it would not have worked anyway, since entries are mapped to -l${name} — the flag would arrive as -l-mwindows.

libraries is not a route either: entries must resolve to existing files ('libraries[i]' does not name a file), so a bare flag can't ride in there.

Nor is there an environment variable: the only ones the cc backend reads are SCRIPTC_CACHE_DIR, SCRIPTC_CACHE_MAX_MB, SCRIPTC_FETCH_CURL, plus SCRIPTC_TEST_*. SCRIPTC_CC selects the driver but takes no extra arguments.

Why it matters

A console-subsystem Windows binary makes the OS open a console window behind the app's real window. For anything with a GUI that is simply wrong, and -mwindows (or -Wl,--subsystem,windows) is the standard one-flag fix.

Our workaround, for reference

We patch the linked PE afterwards: locate the optional header via the MZ/PE offsets, validate the magic (0x10b/0x20b), and rewrite the Subsystem byte from IMAGE_SUBSYSTEM_WINDOWS_CUI (3) to IMAGE_SUBSYSTEM_WINDOWS_GUI (2), refusing to touch anything that doesn't look like the console-subsystem PE we just produced. It works, and CI runs the resulting binary to a clean exit, but rewriting a compiler's output is a strange thing to have to do for a documented linker flag.

Suggestion

Any one of these would be enough, in rough order of how small they seem:

  • an allowlist of safe passthrough flags in the FFI manifest (link_flags, validated against a known set)
  • a SCRIPTC_LDFLAGS environment variable, matching the existing SCRIPTC_CC escape hatch
  • a first-class --subsystem=windows|console option, since this particular flag is really a property of the executable being produced rather than a linking detail

Context

We're building janela, a Tauri-style desktop framework: TypeScript backend compiled by scriptc, OS webview for the window, no JS engine bundled. Windows support otherwise works well — thanks for a compiler that made that possible at all. (Related: #255 is still open and still reproduces on 0.0.35.)

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing the cc backend and the existing SCRIPTC_CC handling, then inspect how FFI manifest entries are validated and converted into linker arguments. The work is done when one supported mechanism passes a linker flag such as -mwindows to the platform linker, rejects unsafe or invalid input, and has coverage for the resulting Windows executable behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
build-system, compilers
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.