Skip to content

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

Description

@mmamedel

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.)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions