This is an automated email from the ASF dual-hosted git repository. jimjag pushed a commit to branch msys2-dev-prototype in repository https://gitbox.apache.org/repos/asf/openoffice.git
commit 701dec87464d0ce6f48eadb1858c292758acfc4d Author: Jim Jagielski <[email protected]> AuthorDate: Tue Aug 11 13:01:20 2026 -0400 Add feasibility assessment for an MSYS2/clang Windows build --- MSYS2-WINDOWS-BUILD-FEASIBILITY.md | 339 +++++++++++++++++++++++++++++++++++++ 1 file changed, 339 insertions(+) diff --git a/MSYS2-WINDOWS-BUILD-FEASIBILITY.md b/MSYS2-WINDOWS-BUILD-FEASIBILITY.md new file mode 100644 index 0000000000..5bb9af9c7d --- /dev/null +++ b/MSYS2-WINDOWS-BUILD-FEASIBILITY.md @@ -0,0 +1,339 @@ +# MSYS2 / clang as an alternative Windows build for Apache OpenOffice + +Scope: x86_64 only, Windows 10+, **additive** — the existing MSVC path stays the +default and is not modified. Assessment against `trunk` as of 2026-08-11. + +Goal, restated: *reduce and contain* the Microsoft dependency, not eliminate it. Use +the Windows SDK where it is genuinely the cheapest correct answer; use mingw-w64 and +MSYS2 packages everywhere else. Optimise for a build that is easy to set up, easy to +run, and cheap to maintain. + +## Verdict + +Feasible. With the Windows SDK allowed back in for the few things it uniquely provides, +the project reduces to roughly **3.5–6 person-months**, and all but one phase is +routine build-system work. + +The single hard blocker remains: **there is no C++/UNO bridge for the Win64 calling +convention under the Itanium C++ ABI, and one must be written from scratch.** Everything +else is now either already in the tree, available as an MSYS2 package, or obtainable +from a standalone Windows SDK install. + +The maintenance argument is the strongest one for doing this at all. The current MSVC +path is pinned to `COMEX` ≤ 12 — VS2008 (`set_soenv.in:715-723`, `configure.ac:2245`). +An MSYS2 build tracks a rolling, self-updating toolchain and depends on the Windows SDK +only as a small, explicitly-declared set of components that installs standalone without +Visual Studio. + +## Where each dependency comes from + +| Need | Source | Notes | +|---|---|---| +| C/C++ compiler, linker, ar, strip | **MSYS2 CLANG64** | No MSVC, no MASM, no MSBuild, no VS install | +| Win32 API headers and import libs | **mingw-w64** | Covers the overwhelming majority of the API surface | +| C runtime | **UCRT** | In-box on Windows 10+; see the MSVCRT question below | +| Shell, perl, make, autotools, pkg-config | **MSYS2** | Replaces the Cygwin dependency | +| Most bundled third-party libraries | **MSYS2 packages** via `--with-system-*` | 38 such options already exist in `configure.ac` | +| **ATL** | **Windows SDK** | mingw-w64 has none and no free ATL exists | +| **MSI database tools** (`msidb`, `msitran`, `msiinfo`, `uuidgen`) | **Windows SDK** | `msitools`/WiX are not worth the effort | +| **`signtool`** | **Windows SDK** | Only if producing signed builds | +| ADO headers (`adoint.h`, `adodef.h`, …) | **Windows SDK** | Keeps the ADO database driver alive | +| `makecab`, `expand` | **Windows itself** | In-box, no SDK needed | +| IDL compilation | **mingw-w64 `widl`** | Easier than `midl.exe`, which wants `cl.exe` as its preprocessor | +| DirectShow / Direct3D headers | **mingw-w64** | Legacy DirectX SDK not needed | +| JDK | **native Windows JDK** | MSYS2 ships none | + +Net effect: **no Microsoft compiler or build tooling at all**, and the Windows SDK +reduced to four discrete, auditable items. That is the dependency reduction that +actually matters — the SDK is a stable, versioned, standalone download, whereas the +current dependency is on a specific ancient Visual Studio. + +## The UCRT vs MSVCRT question + +**Recommendation: stay on UCRT (CLANG64). Do not move to MSVCRT.** The chain of +reasoning is forced by the source tree, not by preference. + +Production code — not tests — uses two MSVC C++ extensions that GCC-mingw does not +implement at all: + +- `__uuidof` in 13 production files: `sal/inc/systools/win32/comptr.hxx`, + `fpicker/source/win32/filepicker/{comptr.hxx,PreviewCtrl.cxx}`, + `dtrans/source/win32/{dtobj,dnd,mtaole}/*` (6 files), `extensions/source/ole/*` + (3 files), `extensions/source/activex/main/SOActiveX.cpp`. +- `__declspec(uuid(...))` in `avmedia/source/win/interface.hxx:30,79,96`. + +Plus MSVC structured exception handling (`__try`/`__except`) at 17 sites in `vcl/win`, +`sal/osl/w32`, `dtrans` and the MSVC bridges — again supported by clang on mingw +targets, not by GCC. + +And now that we are deliberately consuming the SDK's ATL, a third reason appears: ATL +headers are MSVC C++ and need `-fms-extensions` / `-fms-compatibility` to parse. Clang +has those; GCC does not. This is precisely why the old +`external/mingwheaders/mingw_atl_headers.patch` had to be 1654 lines — it was patching +ATL to survive *GCC*. Under clang that patch should shrink to a small shim or vanish. + +So clang is required three times over. And MSYS2's x86_64 clang environment is +**CLANG64, which is UCRT-only** — there is no clang + MSVCRT environment (MINGW64 is +GCC + MSVCRT, UCRT64 is GCC + UCRT). Choosing MSVCRT therefore means choosing GCC, +which means: + +1. Rewriting ~15 SEH sites; +2. Replacing every `__uuidof` / `__declspec(uuid)` with explicit `IID_*` GUID + references across 14 production files; +3. Abandoning SDK ATL and going back to a full de-ATL port of `winaccessibility`, + `extensions/source/ole` and `embedserv` — the 6–10 week item this revision was + meant to delete. + +Independently of all that, UCRT is simply the better target here. It is the in-box CRT +on Windows 10+ (no redistributable), and modern Windows SDK components including ATL +are themselves built against UCRT + vcruntime. Pairing SDK-provided ATL with an +MSVCRT-based runtime would be a CRT mismatch — exactly the class of bug that is +painful to diagnose. **Increasing our use of the Windows SDK argues for UCRT, not +against it.** + +MSVCRT is documented here as a rejected option with a known cost, not as a fallback we +are holding in reserve. If it is ever forced, the three items above are the bill. + +## What already exists in the tree + +| Artifact | State | +|---|---| +| `solenv/inc/wntgcci.mk` | 211-line MinGW platform makefile, 32-bit | +| `solenv/gbuild/platform/winmingw.mk` | 753 lines, gbuild path | +| `bridges/source/cpp_uno/mingw_intel/` | 1932 LOC, **x86 32-bit only** | +| `configure.ac` `--with-mingwin` | Present, assumes Cygwin and `gcc -mno-cygwin` | +| `set_soenv.in` | `OUTPATH=wntgcci`, `COM=GCC`, MinGW lib/include probing | +| `sal/inc/sal/types.h:155` | Already handles `__MINGW32__` (`sal_Unicode` = `sal_uInt16`) | +| `__MINGW32__` conditionals | 100 files across the tree | +| `solenv/bin/addsym-mingw.sh`, `_tg_def.mk` MinGW branches | Export/`.def` handling present | +| ~20 external modules | Already have `WNT` + `COM=GCC` build recipes | +| `--with-system-*` | 38 options, none gated off on Windows | + +All of it is 32-bit and none has had functional work in years — every recent commit +touching these files is whitespace or mechanical. But the build system already +understands the concept of a GCC-flavoured Windows compiler, and `solenv/inc/wnt.mk:38` +shows exactly where the 64-bit gap is: dispatch exists for `GCCWNTI` only. + +Set **`COM=GCC`** (not `COM=CLANG`) for the MSYS2 build. The CLANG64 driver is +GCC-compatible, and `COM=GCC` reuses the existing `COM=="GCC"` branches in openssl, +nss, icu, curl, libxml2, libxslt, libxmlsec, graphite and python at no cost. Setting +`COM=CLANG`, as macOS does, would mean editing every one of them. + +## Remaining work + +### B1 — Win64 GNU-ABI UNO bridge (the only hard blocker) + +`bridges/source/cpp_uno/` has `msvc_win64_x86-64` (Win64 calling convention, MSVC C++ +ABI, MASM `call.asm`, MSVC RTTI/EH internals) and `gcc3_linux_x86-64` (SysV AMD64 +calling convention, Itanium ABI). The MSYS2 target needs the cross product: Win64 +calling convention with Itanium C++ ABI and clang unwinding. Neither can be reused +as-is. + +LibreOffice dropped MinGW Windows support around 2013 and never had a 64-bit MinGW +bridge, so there is nothing upstream to port. + +Composition, ~2000 LOC: + +- `uno2cpp.cxx` / `cpp2uno.cxx` — Win64 register allocation (RCX/RDX/R8/R9, XMM0–3, + 32-byte shadow space, structs > 8 bytes by hidden pointer). Structurally closer to + `msvc_win64_x86-64` than to the Linux bridge. +- `call.s` — GAS syntax rather than MASM; port the shape of `call.asm` (257 lines). +- `except.cxx` — Itanium `__cxa_throw` and dynamically-synthesised `_ZTI` type_info. + `mingw_intel/except.cxx` (309 LOC) is the one genuinely reusable piece of the old + 32-bit bridge. + +Direct precedent exists in this tree: the `s5abi_macosx_aarch64` bridge was the same +class of problem — new calling convention, Itanium ABI, RTTI visibility quirks — and is +done and shipped. + +**Risk: high. This is the go/no-go gate; prototype it before committing to the rest.** + +### B2 — ATL from the Windows SDK + +Four production modules need ATL: `winaccessibility/source/UAccCOM` (IAccessible2, +i.e. NVDA/JAWS support), `extensions/source/ole` (UNO ↔ OLE Automation), +`embedserv` (OLE embedding), `extensions/source/activex` (ActiveX control). + +With the SDK allowed, these are **kept, not ported**. Work reduces to: + +- A lean replacement for `external/mingwheaders` that adds the SDK's `include/atl` to + the include path and applies whatever residual shims clang still needs. Expect this + to be far smaller than the old 1654-line GCC-targeted patch; possibly empty. +- Compiling those four modules with `-fms-extensions -fms-compatibility`. +- Confirming ATL's static lib links cleanly against the UCRT-based mingw runtime. + +`shell/source/win32/shlxthandler` and `desktop/win32/source/setup` reference +`MFC_INCLUDE` only for **resource compilation** — zero MFC code usage. Include-path +fixes, not ports. + +`extensions/source/activex` (IE-era ActiveX control) remains a reasonable candidate to +exclude from this configuration if it fights back, since the MSVC build still produces +it. + +**Risk: medium — hinges on how cleanly clang parses current SDK ATL headers. Verify +early; it is cheap to test and it re-opens the 6–10 week de-ATL port if it fails.** + +### B3 — cli_ure / .NET bindings (unavoidable, and acceptable) + +`cli_ure` requires C++/CLI (`/clr`), which clang cannot compile. It is already gated +`w,vc7` in `cli_ure/prj/build.lst`, so it self-excludes under `COM=GCC` with no changes +needed. Same mechanism excludes `testtools/.../bridgetest/cli`. + +Since the MSVC build remains the default, official .NET-capable binaries still come +from that path. Document as a limitation of the MSYS2 configuration. + +### B4 — Externals via MSYS2 packages + +The biggest simplification available, and the one that most directly serves "easier and +more straightforward". `configure.ac` already exposes `--with-system-*` for nss, +openssl, icu, python, expat, libxml, libxslt, curl, boost, hunspell, hyphen, mythes, +graphite, redland, zlib, jpeg, mdds, vigra, libtextcat, cairo, coinmp and more — none +gated off on Windows, all pkg-config driven, and MSYS2 provides pkg-config and packages +for essentially all of them. + +This deletes most of what was going to be a 4–8 week phase, and in particular sidesteps +the worst single risk in the original assessment: **building the bundled Python 3 under +mingw.** CPython upstream does not support mingw builds; MSYS2 carries its own patch +set. Using `--with-system-python` avoids the problem entirely. + +Two consequences to plan for: + +- The installer must redistribute the MSYS2 DLLs it links against, plus CLANG64's + `libc++` and `libunwind`. Licensing is fine (all permissive or compatible), but the + packaging file lists need extending. +- Static linking against MSYS2's `.a` files is an alternative that shrinks the + redistribution list at the cost of binary size. Decide per library. + +Where a system package proves unsuitable, the existing `COM=GCC` bundled-build branches +are still there as a fallback. + +**Risk: low. Effort: moderate, mostly packaging.** + +### B5 — Host environment and configure + +- `configure.ac:1076` keys Windows detection on `build_os` matching `cygwin`. MSYS2's + `config.guess` reports `x86_64-pc-msys`; a parallel `msys*` branch is needed there + and at `configure.ac:1146` and `2274`. +- The `gcc -mno-cygwin` detection (`configure.ac:1709-1721`, `2258`) is dead. MSYS2 + compiler detection is a fresh code path, not a reuse of that one. +- `cygpath` exists in MSYS2, so `set_soenv.in` and the installer Perl modules that call + it largely carry over — but MSYS2 path-translation semantics differ from Cygwin's and + each call site needs checking. +- The Info-ZIP `zip.exe` check (`configure.ac:6037`) explicitly demands the Cygwin + build; needs an MSYS2 equivalent. +- `solenv/bin/guw.pl` exists to wrap MSVC tools with Unix paths; irrelevant here. +- `dmake` is built in-tree from source; MSYS2 can do this. + +Add a **single, explicit SDK entry point** — one `--with-windows-sdk=<path>` variable +plus a documented minimal component list — so the Microsoft dependency is declared in +one place and can be audited, version-pinned, and eventually shrunk further. + +**Risk: low-medium. Effort: moderate, touches many files.** + +### B6 — Odds and ends + +- IDL: replace `midl.exe` with mingw-w64 `widl` in `extensions/source/activex/msidl` + and `winaccessibility/source/UAccCOMIDL`. Chosen over `midl` because `midl` wants + `cl.exe` as its preprocessor, which would drag the MSVC compiler back in for no gain. +- `fpicker/source/win32/filepicker/platform_vista.h` uses `#pragma comment(linker, + "/manifestdependency:...")` for the common-controls v6 manifest. Clang-mingw ignores + it; embed the manifest as an `RT_MANIFEST` resource instead, or themed controls + silently regress. +- `connectivity/source/drivers/ado`: `comdef.h`/`_com_ptr_t` should come from + mingw-w64; the ADO headers themselves come from the SDK. Verify. +- `canvas/source/directx`, `avmedia/source/win`: use mingw-w64's d3d9/dshow headers; + the legacy DirectX SDK dependency should be droppable. Verify. +- Resources: `windres` or `llvm-rc` for `.rc`. +- STLport already defaults off, so libc++ is not fighting a bundled STL. It *is* a + divergence from the proven libstdc++ Linux build — expect some strictness fallout in + old C++ code. + +## Making it easy to run + +Deliverables that should be part of the work, not afterthoughts: + +1. A `pacman -S` one-liner package list, checked into the tree. +2. A bootstrap/build script following the pattern of the existing + `build_aoo64bit_on_macosarm.sh`, so a new machine is one script away from a build. +3. A documented minimal Windows SDK component selection (ATL + MSI tools + signtool), + with the standalone-installer link — no Visual Studio. +4. A single canonical `./configure` invocation for the MSYS2 build, favouring + `--with-system-*` by default. + +## Additive architecture + +Every item below is a new file or a new branch keyed on a new `COM`/`CPU`/OUTPATH +triple, so the MSVC build is untouched by construction: + +1. New configure switch, e.g. `--enable-msys2-build`, orthogonal to `--with-mingwin` + (leave the legacy 32-bit switch alone rather than overloading it). +2. New `OUTPATH=wntgccx` / `INPATH=wntgccx.pro`, with `CPU=X`, `CPUNAME=X86_64`, + `COM=GCC`, `GUI=WNT`. +3. New `solenv/inc/wntgccx.mk`, dispatched from `solenv/inc/wnt.mk` on + `$(COM)$(OS)$(CPU)` == `GCCWNTX`. Model the clang/Itanium side on + `unxmacc.mk`/`unxlngx.mk` and the Windows link/export side on `wntgcci.mk`. +4. New bridge directory `bridges/source/cpp_uno/mingw_x86-64/`. +5. New `solenv/gbuild/platform/winclang.mk` for gbuild-converted modules — branch from + `winmingw.mk` rather than editing it, since that file is 32-bit-shaped. +6. Replace `external/mingwheaders` with a minimal SDK-ATL include shim rather than + reviving its PSDK header-copying. + +## Phasing and effort + +| Phase | Content | Effort | +|---|---|---| +| 0 | Host env, `msys*` detection in configure, `set_soenv.in`, `wntgccx.mk`, dmake bootstrap, SDK entry point | 2–3 weeks | +| 1 | **Win64 GNU-ABI UNO bridge** + sal/cppu/cppuhelper building and `bridgetest` passing | 6–10 weeks | +| 2 | Externals via `--with-system-*`; packaging file lists for MSYS2 + libc++ runtime DLLs | 2–4 weeks | +| 3 | Windows integration modules against SDK ATL; `widl` migration; manifest fix | 2–4 weeks | +| 4 | Installer using SDK MSI tools; signing | 2–3 weeks | + +**Roughly 3.5–6 person-months**, down from 6–12 in the SDK-free version. Phase 1 +dominates and is the go/no-go gate. Phase 3's estimate assumes SDK ATL compiles under +clang with minimal shimming — cheap to test in a day, and worth testing during Phase 0 +because failure reinstates a 6–10 week de-ATL port. + +## Capability delta versus the MSVC build + +Permanently absent: +- .NET/CLI UNO bindings (`cli_ure`, `climaker`) — no C++/CLI in clang. Mitigated by + the MSVC build remaining the default. + +Retained by using SDK ATL (these were the at-risk items in the SDK-free plan): +- IAccessible2 accessibility bridge — screen-reader support. +- UNO ↔ OLE Automation bridge. +- OLE embedding server. +- ActiveX control, unless deliberately excluded. + +Undetermined pending verification: +- ADO database driver, DirectX canvas backend, DirectShow media backend. + +## What I verified versus what I asserted + +Verified by inspection of this tree: every file path, line number and LOC count; module +gating (`w,vc7`); the 17 SEH sites; the 13 production files using `__uuidof` and the +three `__declspec(uuid)` sites in `avmedia`; the ATL reference counts per module and +the fact that `shlxthandler`/`setup` use `MFC_INCLUDE` for resources only; the absence +of a 64-bit GCC dispatch in `wnt.mk`; the `__MINGW32__`/`sal_Unicode` handling; the PSDK +dependency in `external/mingwheaders`; the installer's required-tools list in +`control.pm:105`; the 38 `--with-system-*` options and their lack of Windows gating; the +`COMEX` ≤ 12 ceiling on the MSVC path; and the staleness of the MinGW files in git +history. + +Asserted from knowledge of the toolchains, **not** verified against a live MSYS2 or +Windows SDK install: + +- That MSYS2 CLANG64 targets `x86_64-w64-windows-gnu` with the Itanium C++ ABI, libc++ + and compiler-rt, and that no clang + MSVCRT environment exists for x86_64. +- That clang supports `__try`/`__except`, `__uuidof` and `__declspec(uuid)` on mingw + targets and GCC does not. +- That clang's `-fms-extensions`/`-fms-compatibility` are sufficient to parse current + Windows SDK ATL headers — **the highest-value thing to test first**, since it decides + Phase 3's size. +- That the Windows SDK installs standalone without Visual Studio and that ATL is + available in that installation. +- That mingw-w64 provides `comdef.h`, d3d9 and dshow headers, and that `widl` is an + adequate `midl` replacement. +- That MSYS2 packages exist and are usable for the `--with-system-*` set named above. + +No build was attempted; there is no Windows or MSYS2 host in this environment.
