1*91144cd0SPeter<!-- 2*91144cd0SPeter Licensed to the Apache Software Foundation (ASF) under one 3*91144cd0SPeter or more contributor license agreements. See the NOTICE file 4*91144cd0SPeter distributed with this work for additional information 5*91144cd0SPeter regarding copyright ownership. The ASF licenses this file 6*91144cd0SPeter to you under the Apache License, Version 2.0 (the 7*91144cd0SPeter "License"); you may not use this file except in compliance 8*91144cd0SPeter with the License. You may obtain a copy of the License at 9*91144cd0SPeter 10*91144cd0SPeter http://www.apache.org/licenses/LICENSE-2.0 11*91144cd0SPeter 12*91144cd0SPeter Unless required by applicable law or agreed to in writing, 13*91144cd0SPeter software distributed under the License is distributed on an 14*91144cd0SPeter "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15*91144cd0SPeter KIND, either express or implied. See the License for the 16*91144cd0SPeter specific language governing permissions and limitations 17*91144cd0SPeter under the License. 18*91144cd0SPeter--> 19*91144cd0SPeter 20*91144cd0SPeter# `win10-msvc-trunk` — building trunk on Windows again 21*91144cd0SPeter 22*91144cd0SPeter**Status: the build is green, end to end.** On VS2019 14.29.30133 with Windows 23*91144cd0SPeterSDK 10.0.19041.0, `configure`, `bootstrap` and `build.pl` all run to 24*91144cd0SPetercompletion into a `wntmsci14.pro` output tree, and `instsetoo_native` produces 25*91144cd0SPeter 26*91144cd0SPeter openoffice450.msi 27*91144cd0SPeter openoffice450sdk.msi 28*91144cd0SPeter 29*91144cd0SPeterEvery bundled third-party library builds — including, for the first time on 30*91144cd0SPeterWindows, **Python**, which trunk has never built here at all. 31*91144cd0SPeter 32*91144cd0SPeterTwo things that headline does not say, and both matter more than it does. 33*91144cd0SPeter 34*91144cd0SPeter**Nothing has been run.** The MSI exists; nobody has installed it or started 35*91144cd0SPeterthe office. The single piece of runtime evidence points the wrong way: 36*91144cd0SPeter`testtools/source/bridgetest` fails with `getCaughtException() failed!`, which 37*91144cd0SPeteris UNO exception propagation through the x86 C++ bridge. See 38*91144cd0SPeter[The open defect](#the-open-defect). 39*91144cd0SPeter 40*91144cd0SPeter**Some of the green is subtraction.** The CLI/.NET binding is switched off 41*91144cd0SPeterentirely, and Python is built without `_ssl`, `_ctypes`, `_bz2`, `_lzma` and 42*91144cd0SPeter`_sqlite3`. Both are deliberate and both are described below, but a build that 43*91144cd0SPeteris green with those absent is a narrower claim than one that is green with 44*91144cd0SPeterthem present. 45*91144cd0SPeter 46*91144cd0SPeterThat is a different claim from the one this file made when it was written, and 47*91144cd0SPeterthe difference was expensive: **forty defects so far, every one of them found 48*91144cd0SPeterby building and none of them by reading.** 49*91144cd0SPeter[What building found](#what-building-found) groups the forty by cause; 50*91144cd0SPeter[Verification](#verification) says what is now measured and what is still only 51*91144cd0SPeterargued. 52*91144cd0SPeter 53*91144cd0SPeter## Why trunk does not build on Windows 54*91144cd0SPeter 55*91144cd0SPeterNot one regression — a scissors motion between two changes that were each 56*91144cd0SPeterreasonable alone. 57*91144cd0SPeter 58*91144cd0SPeter* `main/configure.ac` errors out on any compiler that is not VS2008: 59*91144cd0SPeter `Compiler too old. Use Microsoft C/C++ .NET 2008.` 60*91144cd0SPeter* Trunk's bundled dependencies moved past what VS2008 can compile. Boost is 61*91144cd0SPeter **1.84** (`main/boost/makefile.mk`), which requires C++11; VC9 has no C++11 62*91144cd0SPeter mode at all. Bundled Python is **3.11.15** (`main/python/pyversion.mk`), 63*91144cd0SPeter which requires VS2017 or newer to build on Windows. 64*91144cd0SPeter 65*91144cd0SPeterSo the configured compiler cannot build the configured dependencies, and there 66*91144cd0SPeteris no combination of the two that works. Every other platform moved: Linux and 67*91144cd0SPeterFreeBSD were raised to `gnu++11` in `7ce5b5df31`, macOS was already at C++11. 68*91144cd0SPeterWindows is the one that was left pinned. 69*91144cd0SPeter 70*91144cd0SPeterThe fix is to let Windows use a modern MSVC, which is what this branch does. 71*91144cd0SPeter 72*91144cd0SPeter## Where the work came from 73*91144cd0SPeter 74*91144cd0SPeterThe source half is **cherry-picked from `win10-64-minimal`**, a branch that 75*91144cd0SPeteralready did this against a Bazel build of the same tree and reached a product 76*91144cd0SPeterthat compiles and runs. That is the branch's value here: the conformance 77*91144cd0SPeterfailures a modern MSVC finds in this source have already been found, once, by 78*91144cd0SPeterbuilding — rather than being guessed at from a survey. 79*91144cd0SPeter 80*91144cd0SPeterEvery source commit carries its `(cherry picked from commit ...)` line. 81*91144cd0SPeter 82*91144cd0SPeter### What was taken, and what was dropped from each 83*91144cd0SPeter 84*91144cd0SPeterFour of the picked commits were mixed — Bazel `BUILD.bazel`/`.bzl` changes 85*91144cd0SPeteralongside source changes — and only the source half applies here. Their 86*91144cd0SPetermessages still describe the whole commit as it was on the other branch, so the 87*91144cd0SPeterreconciliation is here rather than rewritten into history: 88*91144cd0SPeter 89*91144cd0SPeter| commit | taken here | dropped | 90*91144cd0SPeter| --- | --- | --- | 91*91144cd0SPeter| `97bc46e96b` (M3) | `cppuhelper/factory.cxx` C2694 fix, `uwinapi/sntprintf.c` guard, the stlport shim split | 7 `BUILD.bazel` files, the toolchain config, `win10-minimal/README.md` | 92*91144cd0SPeter| `82bbd76e57` (M4) | `comphelper` C2694 + `<iterator>`, `tools/dirent.cxx` `<time.h>`, the stlport `_MSC_VER >= 1900` arms | 88 `BUILD.bazel` files — the Bazel-side `snprintf` sweep, which has no dmake equivalent | 93*91144cd0SPeter| `e5b57b0a09` | `bridges/.../except.cxx` `<typeinfo>`, `stoc/javavm.cxx` `_tzname` | the bzlmod overlays for libxml2, rasqal and redland — replaced here by `b0fbb14822`, see below | 94*91144cd0SPeter| `d01dcefb61` | 5,069 of 5,070 files | `bridges/test/cppuno_roundtrip_test.cxx`, which exists only on the Bazel branch | 95*91144cd0SPeter 96*91144cd0SPeterThree commits from that branch were **not** picked at all: 97*91144cd0SPeter 98*91144cd0SPeter* the Python 2.7.18 fixes (`b6f8696d08`, `8ee3bd8d0f`) — trunk is on Python 99*91144cd0SPeter 3.11, so they are moot; 100*91144cd0SPeter* the NSS `<stdint.h>` overlay (`c06bca0c46`) — that shim was the Bazel 101*91144cd0SPeter overlay's own invention. Trunk's `main/nss/nss_win.patch` already guards its 102*91144cd0SPeter `<stdint.h>` substitute on `_MSC_VER < 1600` and takes the real header on 103*91144cd0SPeter anything newer; 104*91144cd0SPeter* the Bazel-only commits (toolchain discovery, platform registration, the gtest 105*91144cd0SPeter tuple define), which have no counterpart in a dmake tree. 106*91144cd0SPeter 107*91144cd0SPeterThe toolchain half is new. `win10-64-minimal` expressed it as a third Bazel 108*91144cd0SPeter`cc_toolchain`; trunk needs it in `configure.ac`, `set_soenv.in` and 109*91144cd0SPeter`solenv/`, which share no code with that. 110*91144cd0SPeter 111*91144cd0SPeter## What is in the branch 112*91144cd0SPeter 113*91144cd0SPeter### The source conformance set (from `win10-64-minimal`) 114*91144cd0SPeter 115*91144cd0SPeterRoughly 64 files, all of it legal C++03 and inert on VC9. Five families: 116*91144cd0SPeter 117*91144cd0SPeter* **C2694 — a destructor's exception specification.** Under C++03 a 118*91144cd0SPeter destructor with nothing written carries no specification, so nothing could 119*91144cd0SPeter conflict. From C++11 on the compiler supplies one, and at any class 120*91144cd0SPeter inheriting from both a pre-UNO hierarchy and a UNO one, three promises meet 121*91144cd0SPeter and only one was written by a person. None of these destructors throws; it 122*91144cd0SPeter is a paperwork conflict, and the fix changes no generated code. Fixed at the 123*91144cd0SPeter base classes — `SfxBroadcaster`, `SfxListener`, `OWeakObject` and friends — 124*91144cd0SPeter so one edit covers every derived class, and with a forward declaration 125*91144cd0SPeter rather than a UNO include, so no coupling changes. 126*91144cd0SPeter* **C3848 — a comparator must be callable on a `const` comparator.** 127*91144cd0SPeter `std::set`'s const members hold the comparator by const reference. A 128*91144cd0SPeter standard requirement, not a modern-MSVC opinion; VC9's `<xtree>` reached it 129*91144cd0SPeter through a non-const path and never checked. Eight sites in `sd`, `sdext` 130*91144cd0SPeter and `sw`. 131*91144cd0SPeter* **C2280 — an output iterator must be CopyAssignable.** `chart2`'s 132*91144cd0SPeter `DialogModel.cxx` defines two custom output iterators holding their 133*91144cd0SPeter destination by reference, which deletes the implicit copy assignment. This 134*91144cd0SPeter is the one item that is a latent defect rather than paperwork: the type was 135*91144cd0SPeter never a conforming output iterator. Both now hold a pointer. 136*91144cd0SPeter* **Named includes.** `<time.h>` in `tools/dirent.cxx`, `<iterator>` in 137*91144cd0SPeter `comphelper`, `xmloff` and `xmlhelp` — headers the code already depends on 138*91144cd0SPeter and used to get transitively from VC9's `<algorithm>`. Only the ones a build 139*91144cd0SPeter actually named were added; a sweep found ~25 candidates and most still 140*91144cd0SPeter compile, so adding those would be churn in a diff meant to stay 141*91144cd0SPeter backportable. 142*91144cd0SPeter* **The `snprintf` guards**, in `sal/inc/systools/win32/snprintf.h` and in 143*91144cd0SPeter `uwinapi/sntprintf.c` — the declarations *and* the implementations, which 144*91144cd0SPeter are two sites of one root cause. 145*91144cd0SPeter 146*91144cd0SPeter### The exception-specification removal 147*91144cd0SPeter 148*91144cd0SPeter`d01dcefb61`, 5,069 files. Dynamic exception specifications with a type list 149*91144cd0SPeterare gone from the tree, together with the two generators that emitted them 150*91144cd0SPeter(`cppumaker`'s `dumpExceptionSpecification`, and the skeletonmaker in 151*91144cd0SPeter`unodevtools`). The empty specification — `throw()`, `SAL_THROW( () )`, 152*91144cd0SPeter`SAL_THROW_EXTERN_C()` — is untouched: MSVC implements that one as 153*91144cd0SPeter`__declspec(nothrow)` and it is worth keeping. 154*91144cd0SPeter 155*91144cd0SPeterThis is **not** required to compile: at `/std:c++14` the typed specifications 156*91144cd0SPeterare still legal. It is here because it is what the source branch actually 157*91144cd0SPeterships, and because it makes the whole C2694 family evaporate rather than 158*91144cd0SPeterneeding per-site annotation. 159*91144cd0SPeter 160*91144cd0SPeter`main/solenv/bin/throwspec.py` is the tool that did it, carried along so the 161*91144cd0SPeternext sweep does not have to re-derive the four rules that separate a 162*91144cd0SPeterspecification from a `throw` statement. Run against this branch it reports no 163*91144cd0SPeterremaining typed specification, 7,202 empty ones (the follow-up task), 16 real 164*91144cd0SPeterthrow statements, and the eight sites it rejects by design. 165*91144cd0SPeter 166*91144cd0SPeter### The toolchain 167*91144cd0SPeter 168*91144cd0SPeter`COMEX` gains the value **14**: the UCRT generation, VS2015 (`cl 19.00`) and 169*91144cd0SPetereverything since. One value rather than one per Visual Studio release, because 170*91144cd0SPeternothing in this tree distinguishes VS2017 from VS2022 — what they share, and 171*91144cd0SPeterwhat VC9 does not, is the CRT and the SDK layout. `COMEX` already selects the 172*91144cd0SPeterplatform makefile, the `CVER` define and the output tree, so 14 carries all 173*91144cd0SPeterthree (`CVER=M1900`, output tree `wntmsci14` / `wntmscx14`). 174*91144cd0SPeter 175*91144cd0SPeterFour shape differences, each handled where it belongs: 176*91144cd0SPeter 177*91144cd0SPeter| | VC9 | VS2015+ | 178*91144cd0SPeter| --- | --- | --- | 179*91144cd0SPeter| `cl.exe` | `VC/bin`, cross tools at `bin/amd64` | `bin/Host<host>/<target>` | 180*91144cd0SPeter| mspdb | elsewhere — `Common7/IDE`, or the SDK's bin | next to `cl.exe`, so the hunt is skipped | 181*91144cd0SPeter| headers | one `Include/`, one `Lib/` | four include trees (`ucrt`, `um`, `shared`, `winrt`), two lib trees, both under a version | 182*91144cd0SPeter| ATL/MFC | in the Platform SDK | in the toolset, with a per-architecture lib directory | 183*91144cd0SPeter 184*91144cd0SPeterSDK version selection is "newest complete", compared component by component as 185*91144cd0SPeterintegers — a string compare sorts `10.0.9xxxx` above `10.0.19041`, and 186*91144cd0SPetercompleteness matters because `bin/` routinely holds more versions than 187*91144cd0SPeter`Include/` and `Lib/` do, so choosing on `bin/` alone can pick a version with 188*91144cd0SPeterno headers at all. Either half can be pinned: 189*91144cd0SPeter`--with-windows-sdk-home`, `--with-windows-sdk-version`. 190*91144cd0SPeter 191*91144cd0SPeterWhich layout is in play is detected from the directory, and then cross-checked 192*91144cd0SPeteragainst what `cl.exe` reports: a `bin/Host*` tree whose compiler says VC9, or a 193*91144cd0SPeterVC9 tree whose compiler says 19.x, is an error rather than a guess. 194*91144cd0SPeter 195*91144cd0SPeter`solenv/inc/wntmsc14.mk` is the entire compiler delta, included at the end of 196*91144cd0SPeter`wntmsci11.mk` (x86) and `wntmscx.mk` (x64). It has no conditional inside it, 197*91144cd0SPeterbecause the file *is* the condition — which is what makes a VC9 build 198*91144cd0SPeterbyte-identical. `solenv/gbuild/platform/windows.mk` carries the same block for 199*91144cd0SPeterthe gbuild half; the two must agree, since a module built by one links against 200*91144cd0SPeterlibraries built by the other. 201*91144cd0SPeter 202*91144cd0SPeterThe one non-obvious flag choice is **`/std:c++14`, not 17**. Three things 203*91144cd0SPeterdepend on the dialect and all three say 14: `std::tr1`, which the MSVC library 204*91144cd0SPeterstill ships but only while `_HAS_CXX17` is 0 and which `boost/tr1` and the 205*91144cd0SPeterstlport shims name directly; the empty exception specification, deprecated in 206*91144cd0SPeterC++17 and removed in C++20, of which thousands remain; and 207*91144cd0SPeter`<hash_map>`/`<hash_set>`, which become a hard `#error` under C++17. There is 208*91144cd0SPeterno falling back further — a modern `cl` rejects `/std:c++03` outright (D9002), 209*91144cd0SPeterso C++14 is the floor whether or not it is chosen. 210*91144cd0SPeter 211*91144cd0SPeter### The STL shims 212*91144cd0SPeter 213*91144cd0SPeter`main/stlport/systemstl/` holds nine headers that pull STL types into `std`. 214*91144cd0SPeterSix of them **shadow** a standard header, and a shadowing header can only reach 215*91144cd0SPeterwhat it shadows through a path that resolves against the compiler's own include 216*91144cd0SPeterdirectory. VC9's spelling is `<../../VC/include/list>`; a modern toolset has no 217*91144cd0SPetersuch directory, so each of the six gained a `_MSC_VER >= 1900` arm spelling it 218*91144cd0SPeter`<../include/list>`. 219*91144cd0SPeter 220*91144cd0SPeter**Branch order is what makes that work, and it was wrong in three of them.** 221*91144cd0SPeter`map`, `set` and `numeric` tested `__cplusplus` before `_MSC_VER` — and with 222*91144cd0SPeter`/Zc:__cplusplus` that arm is now true, and it does `#include_next`, a GCC 223*91144cd0SPeterextension MSVC does not have. The modern arm is now first in all six. 224*91144cd0SPeter 225*91144cd0SPeterThis deliberately diverges from `win10-64-minimal`, which moved four of them 226*91144cd0SPeterinto a `vc9/` subdirectory kept off the modern include path. Trunk's 227*91144cd0SPeter`stlport/makefile.mk` carries its install rule as its first and only target, 228*91144cd0SPeterwhich is also the module's default goal, so splitting that rule in two is not a 229*91144cd0SPetersafe edit here. 230*91144cd0SPeter 231*91144cd0SPeterThe three that shadow nothing (`hash_map`, `hash_set`, `slist`) are untouched: 232*91144cd0SPeterthey forward to `<unordered_map>` and friends with a plain `#include`. 233*91144cd0SPeter 234*91144cd0SPeter### Third-party 235*91144cd0SPeter 236*91144cd0SPeter`redland` and `rasqal` ship hand-written win32 config headers full of shims for 237*91144cd0SPeterwhat old MSVC lacked. Three of those stopped being redundant and became 238*91144cd0SPeterharmful once the UCRT started **declaring** the real function, because a macro 239*91144cd0SPeterrewrites that declaration as it is being parsed. `round` is the instructive 240*91144cd0SPeterone: it is declared in `corecrt_math.h`, so `#define round(x) floor(x+0.5)` 241*91144cd0SPetermakes the header stop parsing with C2059/C2143, some distance from anything 242*91144cd0SPeterthat mentions `round`. 243*91144cd0SPeter 244*91144cd0SPeterDelivered as new `*.patch.ucrt` files listed after the existing 245*91144cd0SPeter`*.patch.win32`, so the base patches stay reviewable against upstream. 246*91144cd0SPeter 247*91144cd0SPeter`libxml2` needed nothing — 2.9.10 already guards its own `snprintf` shim on 248*91144cd0SPeter`_MSC_VER < 1900`. `nss` needed nothing either. 249*91144cd0SPeter 250*91144cd0SPeter## The old Platform SDK does not go away entirely 251*91144cd0SPeter 252*91144cd0SPeter`--with-frame-home` must keep pointing at the **Platform SDK v7.0**, whatever 253*91144cd0SPetercompiler is in use. It is checked by looking for `lib/mscoree.lib` 254*91144cd0SPeter([`configure.ac:2651`](../main/configure.ac)), and the Windows 10 SDK has no 255*91144cd0SPeter`mscoree.lib` anywhere in its `Lib/` tree — verified, not assumed. That library 256*91144cd0SPeteris the .NET Framework import library the CLI/managed parts link against, and it 257*91144cd0SPeternever moved into the new SDK. 258*91144cd0SPeter 259*91144cd0SPeterThe other two flags a build script typically derives from the same variable do 260*91144cd0SPetermove: 261*91144cd0SPeter 262*91144cd0SPeter| flag | on a modern toolset | 263*91144cd0SPeter| --- | --- | 264*91144cd0SPeter| `--with-frame-home` | **keep** on Platform SDK v7.0 — `lib/mscoree.lib` | 265*91144cd0SPeter| `--with-psdk-home` | drop; the Windows 10 SDK is found automatically, and pointing this at v7.0 now warns | 266*91144cd0SPeter| `--with-midl-path` | drop, so the Windows 10 SDK's `midl.exe` is used — it has to match the headers it is generating against | 267*91144cd0SPeter 268*91144cd0SPeter`$FRAME_HOME/lib` is the whole v7.0 library directory, so it does put a full set 269*91144cd0SPeterof old import libraries on `LIB`. That is safe by ordering rather than by luck: 270*91144cd0SPeter`set_soenv.in` places the SDK's `ucrt` and `um` directories **before** it, so the 271*91144cd0SPeterWindows 10 copies of `kernel32.lib` and friends win, and v7.0 supplies only what 272*91144cd0SPeterthe earlier directories do not have — which is `mscoree.lib`. 273*91144cd0SPeter 274*91144cd0SPeter## Known gap: the staged CRT is still VC90 275*91144cd0SPeter 276*91144cd0SPeter`bootstrap` calls `oowintool --msvc-copy-dlls`, which finds a compiler through 277*91144cd0SPeterthe pre-Windows-8 registry keys it knows about, and on a machine that still has 278*91144cd0SPeterVS2008 installed that is VS2008. So `main/external/msvcp90/` receives 279*91144cd0SPeter`msvcr90.dll`, `msvcp90.dll`, `msvcm90.dll` and `Microsoft.VC90.CRT.manifest`, 280*91144cd0SPeter`main/external/prj/d.lst` delivers them, and the installer ships them -- 281*91144cd0SPeterwhile everything else is now built against the UCRT. 282*91144cd0SPeter 283*91144cd0SPeterThis does **not** stop a build: the files exist, they are copied, nothing 284*91144cd0SPeterreferences them at link time. What it produces is an installation carrying 285*91144cd0SPeterthree dead VC90 DLLs and missing the runtime it actually needs 286*91144cd0SPeter(`vcruntime140.dll`, `msvcp140.dll`, and the UCRT). On a developer machine 287*91144cd0SPeterthat runs anyway, because installing Visual Studio installs the redistributable 288*91144cd0SPetersystem-wide; on a clean machine it would not. 289*91144cd0SPeter 290*91144cd0SPeterThe modern equivalent is `VC/Redist/MSVC/<toolset>/<arch>/Microsoft.VC142.CRT`, 291*91144cd0SPeterand note it is *not* a like-for-like swap: the UCRT is an operating-system 292*91144cd0SPetercomponent on Windows 10 rather than an application-private SxS assembly, so the 293*91144cd0SPetermanifest half of the old arrangement has no counterpart rather than a renamed 294*91144cd0SPeterone. 295*91144cd0SPeter 296*91144cd0SPeter`win10-64-minimal` drew its scope line in exactly the same place -- "this 297*91144cd0SPeterbranch targets compiling; the CRT/SxS story is the phase after" -- so this is 298*91144cd0SPeterinherited, not newly introduced. It is recorded here because it is invisible 299*91144cd0SPeteruntil someone installs the result on a machine without Visual Studio. 300*91144cd0SPeter 301*91144cd0SPeterRelated, same cause, harmless: `bootstrap` prints 302*91144cd0SPeter`Can't find MS Visual Studio / VC++ at ./oowintool line 228`. That is 303*91144cd0SPeter`find_msvs()`, which looks for the Visual Studio IDE through the same old 304*91144cd0SPeterregistry keys; VS2019 BuildTools registers none of them. Nothing downstream 305*91144cd0SPeterneeds the answer once `--with-cl-home` is given. 306*91144cd0SPeter 307*91144cd0SPeter## What building found 308*91144cd0SPeter 309*91144cd0SPeterForty defects, grouped by cause rather than by module and running roughly in 310*91144cd0SPeterthe order a build meets them. The grouping is the useful part: each family has 311*91144cd0SPetermore members further up the tree, and knowing the family is how the next one 312*91144cd0SPetergets recognised in one reading instead of three. 313*91144cd0SPeter 314*91144cd0SPeter**The toolchain has to be located before it can be wrong** (4). 315*91144cd0SPeter`--with-cl-home` and friends were being overridden by the branch's own guesses 316*91144cd0SPeterrather than winning over them; `ml.exe` moved into a per-host subdirectory 317*91144cd0SPeter(`bin/Hostx64/x86`) that no longer matches the flat VC9 layout; and the Windows 318*91144cd0SPeter10 SDK search found Platform SDK v7.0 first and accepted it. The SDK search is 319*91144cd0SPeternow one rule over an ordered candidate list. 320*91144cd0SPeter 321*91144cd0SPeter**The UCRT stopped declaring things** (2). `PATH_MAX` in `soltools/cpp`, 322*91144cd0SPeter`__iob_func` in ICU's `icuio`. Both had been supplied by the old CRT without 323*91144cd0SPeterbeing anyone's deliberate dependency. 324*91144cd0SPeter 325*91144cd0SPeter**A shim that became harmful** (1 more, 5 total on this branch). `libxmlsec` 326*91144cd0SPeterjoined `sal`, `uwinapi`, `redland` and `rasqal` in `#define`-ing away a name 327*91144cd0SPeterthe UCRT now declares for real. The guard is always `_MSC_VER < 1900`. 328*91144cd0SPeter 329*91144cd0SPeter**Tools and flags that no longer exist** (4). `/OPT:NOWIN98`; `vcbuild.exe`, 330*91144cd0SPeterwhich is why CoinMP went 1.7.6 → 1.8.4; `lib.exe -EXTRACT:/`, which is below 331*91144cd0SPeterbecause of *how* it fails; and `/clr:oldSyntax`, which is its own entry. 332*91144cd0SPeter 333*91144cd0SPeter**The build host is not the target** (1). NSPR took its architecture from 334*91144cd0SPeter`uname`, which on a 64-bit Cygwin building a 32-bit product is wrong. 335*91144cd0SPeter 336*91144cd0SPeter**Bundled third-party builds more than we need** (2). ICU's test programs and 337*91144cd0SPeter`icuio` both fail and neither is used. 338*91144cd0SPeter 339*91144cd0SPeter**Patch mechanics, not code** (4). A gtest patch reconstructed by un-applying 340*91144cd0SPeterit mentally was wrong by one blank line and its hunk rejected silently; the 341*91144cd0SPeterbundled tr1 tuple was forced tree-wide instead of where it is needed; git was 342*91144cd0SPeternormalising CRLF inside `*.patch` files, now held by `.gitattributes`; and 343*91144cd0SPeterCoinMP 1.8.4 ships an upstream packaging bug naming `.vcxproj` files under a 344*91144cd0SPeter`v9` directory. 345*91144cd0SPeter 346*91144cd0SPeter**The CRT split in three** (5). `-NODEFAULTLIB` means every part must be 347*91144cd0SPeternamed, and there turned out to be **three different ways to end up with one 348*91144cd0SPeterthird of it**: `sal`'s `kill` chooses the static CRT through `DYNAMIC_CRT` 349*91144cd0SPeterand got a mismatched pair; `embedserv`'s in-process server *replaces* `LIBCMT` 350*91144cd0SPeteroutright, so an append made earlier is lost; and `regpatchactivex` and 351*91144cd0SPeter`desktop`'s win32 setup never touch `LIBCMT` at all, appending `libcmt.lib` to 352*91144cd0SPetertheir own `SHL1STDLIBS`. Each needed a different fix. Plus the gbuild side and 353*91144cd0SPeterthe CoinMP link inputs. 354*91144cd0SPeter 355*91144cd0SPeter**Modern SDKs moved things, or dropped them** (3). The 64-bit shell extension 356*91144cd0SPetercomputes its own library paths and both layouts had moved — the SDK gained a 357*91144cd0SPeterversion level and split into `um/` and `ucrt/`, the toolset renamed `amd64/` 358*91144cd0SPeterto `x64/`. `mapix.h` is not in the Windows 10 SDK **at all**: extended MAPI 359*91144cd0SPeterwent to Outlook, and only simple MAPI stayed. Python 3 split its public 360*91144cd0SPeterheaders into `Include/` and `Include/cpython/`, and the delivery list only 361*91144cd0SPeterknew about the first. 362*91144cd0SPeter 363*91144cd0SPeter**An x64 source branch leaves x86 twins untouched** (1). The `<typeinfo.h>` 364*91144cd0SPeterfix was cherry-picked onto `msvc_win64_x86-64/except.cxx` and its message says 365*91144cd0SPeter"the file is the MSVC x64 bridge which no other platform compiles" — true 366*91144cd0SPeterwhere it came from. This build compiles `msvc_win32_intel`, which holds a 367*91144cd0SPetersecond copy of the same line. Expect more of these. 368*91144cd0SPeter 369*91144cd0SPeter**Includes VC9 supplied by accident** (2 sweeps, 42 files). `std::back_inserter` 370*91144cd0SPeterand the iterator types live in `<iterator>`, which VC9's containers dragged in 371*91144cd0SPeterand a modern MSVC's do not. Recorded as two entries because the first sweep 372*91144cd0SPeterwas wrong twice — see the note on sweeps below. 373*91144cd0SPeter 374*91144cd0SPeter**Deferred work coming due** (2). Two things trunk had explicitly parked until 375*91144cd0SPetera modern compiler existed, which is what this branch is. The CLI binding is 376*91144cd0SPeterManaged Extensions for C++ and needs `/clr:oldSyntax`, removed after VS2015 — 377*91144cd0SPeterswitched off here, and a C++/CLI port is its own piece of work. Python had its 378*91144cd0SPeterentire Windows half commented out with a note saying so; it now builds through 379*91144cd0SPeterPCbuild and MSBuild. 380*91144cd0SPeter 381*91144cd0SPeter**Building Python turned out to be four defects, not one** (4). `find_python.bat` 382*91144cd0SPeterprobes only `py -3.10` and `py -3.9` and otherwise **downloads** a Python 383*91144cd0SPeterthrough nuget, which offline cannot do — `HOST_PYTHON` is the documented way 384*91144cd0SPeterpast that. It must be a *native* Python: a cygwin one passes a version check 385*91144cd0SPeterand still reads the native paths PCbuild hands it as relative, prepending its 386*91144cd0SPeterown working directory. `IncludeExternals=false` looks like the way to stay 387*91144cd0SPeteroffline and also silently removes zlib from `pythoncore`, which then does not 388*91144cd0SPetercompile. And `pcbuild.sln` carries dependencies that are editorial rather than 389*91144cd0SPeterstructural — `python.vcxproj` declares one on `_ctypes` so the IDE yields a 390*91144cd0SPeterusable interpreter — so the projects are built individually instead. 391*91144cd0SPeter 392*91144cd0SPeter**An awk with a space in its path** (1). `configure.ac` spells `$AWK` 393*91144cd0SPeterunquoted in some forty places. On a Cygwin carrying `gawk-<version>.exe` but 394*91144cd0SPeterno plain `gawk`, the only `gawk` on `PATH` is Git for Windows' copy under 395*91144cd0SPeter`C:\Program Files`, and the build dies hundreds of lines away with 396*91144cd0SPeter`/cygdrive/c/Program: No such file`. Fixed by taking the 8.3 form, because the 397*91144cd0SPeterCygwin-side fix does not survive a Cygwin update. 398*91144cd0SPeter 399*91144cd0SPeter**Symbols a modern compiler adds** (1). `__xmm@<hex>` vector constants appear 400*91144cd0SPeterin archive symbol tables exactly as `__real@<hex>` always has. They are merged 401*91144cd0SPeterCOMDATs, not exports, and a `.def` naming one fails to link. 402*91144cd0SPeter 403*91144cd0SPeter### The most expensive shape: succeeding while doing nothing 404*91144cd0SPeter 405*91144cd0SPeterThree of the forty did not fail. They reported success, wrote a plausible 406*91144cd0SPeteroutput file, and left the damage to surface somewhere else entirely: 407*91144cd0SPeter 408*91144cd0SPeter* **`makedepend`** rejects `-std:c++14` — `-s` is one of its own options — and 409*91144cd0SPeter exits before scanning a single `#include`. It still creates the `.d` file, 410*91144cd0SPeter and that file still holds its target line, so make is satisfied. Every gbuild 411*91144cd0SPeter C++ object in the build had an **empty dependency list**. A clean build is 412*91144cd0SPeter unaffected, which is why it survived a full run; an incremental one silently 413*91144cd0SPeter stops rebuilding on header changes. 414*91144cd0SPeter* **`lib.exe -EXTRACT:/`** cannot extract an archive's linker member any more. 415*91144cd0SPeter It says so, writes nothing, and **exits 0**. The build fails later, in 416*91144cd0SPeter `ldump`, naming the `.def` rather than the step that broke. 417*91144cd0SPeter* **An external module's `so_built_*` flag** is not invalidated by editing its 418*91144cd0SPeter `BUILD_ACTION`. The first Python build after rewriting the whole Windows 419*91144cd0SPeter half did nothing at all and reported success. 420*91144cd0SPeter 421*91144cd0SPeterThe common thread is that none of them is visible from a green build. They are 422*91144cd0SPeterfound by reading the noise in a log that already succeeded, which is a habit 423*91144cd0SPeterworth keeping for the rest of the port. 424*91144cd0SPeter 425*91144cd0SPeter### A note on sweeps 426*91144cd0SPeter 427*91144cd0SPeterThe `<iterator>` sweep was wrong twice, and both times it looked complete. 428*91144cd0SPeterFirst it matched the factory functions (`std::back_inserter`) and not the 429*91144cd0SPetertypes they return, so it missed a file whose only use is 430*91144cd0SPeter`typedef back_insert_iterator<contents_t> inserter_t`. Widened to bare names 431*91144cd0SPeterfor files saying `using namespace std`, it missed the same file again, because 432*91144cd0SPeterthat line reads `using namespace ::std;` and the pattern did not allow the 433*91144cd0SPeterleading `::`. 434*91144cd0SPeter 435*91144cd0SPeterA criterion narrower than the defect finds a tidy subset and reads like 436*91144cd0SPetercompleteness. Both misses were found by the build rather than by re-reading 437*91144cd0SPeterthe pattern. 438*91144cd0SPeter 439*91144cd0SPeter## The open defect 440*91144cd0SPeter 441*91144cd0SPeter getCaughtException() failed! 442*91144cd0SPeter dmake: Error code 1, while making 'runtest' 443*91144cd0SPeter 444*91144cd0SPeter`testtools/source/bridgetest` is the only thing on this branch that has 445*91144cd0SPeteractually been *run*, and it fails. It exercises UNO exception propagation 446*91144cd0SPeteracross the C++ bridge, which is `cppu::getCaughtException()` reaching into 447*91144cd0SPeterMSVC's own exception machinery to recover the thrown object. 448*91144cd0SPeter 449*91144cd0SPeterThe implementation is 450*91144cd0SPeter`bridges/source/cpp_uno/msvc_win32_intel/except.cxx`, and it decodes MSVC's 451*91144cd0SPeter`ThrowInfo` / `CatchableTypeArray` structures using layout assumptions that 452*91144cd0SPeterwere true for VC9. `win10-64-minimal` rewrote the **x64** copy of that file 453*91144cd0SPeteragainst the modern layout — it carries its own SEH decoding and a long comment 454*91144cd0SPeterdiagramming `EXCEPTION_RECORD` — and the x86 copy never received the same 455*91144cd0SPetertreatment, because that branch never compiled it. 456*91144cd0SPeter 457*91144cd0SPeterSo this is the same family as the `<typeinfo.h>` miss, and a far deeper 458*91144cd0SPeterinstance of it. It is not a build fix and has not been attempted here. 459*91144cd0SPeter 460*91144cd0SPeterIt is worth being clear about the consequence: exception propagation is not a 461*91144cd0SPetercorner of this product. Until this works, a build that produces an installer 462*91144cd0SPetershould not be read as a product that runs. 463*91144cd0SPeter 464*91144cd0SPeter## Verification 465*91144cd0SPeter 466*91144cd0SPeterHonest accounting, because the gap still matters more than the list of changes. 467*91144cd0SPeter 468*91144cd0SPeter**Now measured, by building:** 469*91144cd0SPeter 470*91144cd0SPeter* `configure` runs and completes, and `configure.ac` therefore expands — 471*91144cd0SPeter `autoconf` was not available when this file was first written, so the whole 472*91144cd0SPeter file had never been through `m4`. 473*91144cd0SPeter* `bootstrap` runs, `set_soenv.in` produces a `winenv.set.sh` the build sources 474*91144cd0SPeter without complaint, and `COMEX=14` selects a `wntmsci14.pro` output tree. 475*91144cd0SPeter* Every bundled third-party library builds and delivers, Python included. 476*91144cd0SPeter* Every module builds and delivers, and `instsetoo_native` assembles both 477*91144cd0SPeter installers. 478*91144cd0SPeter* The awk fix is measured, not argued: `configure` now completes with Git for 479*91144cd0SPeter Windows on `PATH`, and logs 480*91144cd0SPeter `.../Program Files/Git/usr/bin/gawk has a space in it, using 481*91144cd0SPeter /cygdrive/c/PROGRA~1/Git/usr/bin/gawk.exe instead`. Both checks that used to 482*91144cd0SPeter die there — the environment sanity check and the GNU make version check — 483*91144cd0SPeter pass. 484*91144cd0SPeter* `-Zm500` and `-safeseh` are still accepted; `-NODEFAULTLIB` plus the named 485*91144cd0SPeter CRT libraries is the complete set in both the static and the dynamic model. 486*91144cd0SPeter* The `<../include/NAME>` retarget works. Four of the six shadowing headers — 487*91144cd0SPeter `list`, `map`, `set`, `vector` — have now been compiled through on this 488*91144cd0SPeter compiler, which the C4464 warnings in the log record by name. `map` and `set` 489*91144cd0SPeter are also two of the three whose branch order was wrong, so that fix is 490*91144cd0SPeter measured rather than argued. 491*91144cd0SPeter 492*91144cd0SPeter**Still only argued:** 493*91144cd0SPeter 494*91144cd0SPeter* **The product has never been started.** Building is not running, and the one 495*91144cd0SPeter runtime test that exists fails. See [The open defect](#the-open-defect). 496*91144cd0SPeter* **The CLI/.NET binding is absent**, not fixed. Six places had to be taught 497*91144cd0SPeter that — three `util/makefile.pmk` files, the SDK's file list, the SDK's 498*91144cd0SPeter checker, bridgetest's IDL, and the installer via `SCPDEFS`. 499*91144cd0SPeter* **Python is missing five extension modules**, because their sources are 500*91144cd0SPeter downloaded by `get_externals.bat` and an offline build cannot run it. 501*91144cd0SPeter* The **VC9 regression claim** is by construction, not by measurement: every 502*91144cd0SPeter toolchain edit adds a branch in front of existing code rather than rewriting 503*91144cd0SPeter it, and every source edit is legal C++03. Nothing on this branch has been 504*91144cd0SPeter compiled with VC9. That is a strong argument and not a green build. 505*91144cd0SPeter* `functional` and `numeric`, the other two shadowing headers, have not been 506*91144cd0SPeter reached yet. 507*91144cd0SPeter* Manifest handling (`mt.exe`, `_VC_MANIFEST_*`) — nothing built so far 508*91144cd0SPeter exercises it. 509*91144cd0SPeter* Nothing has been **run**. The build produces libraries; whether the product 510*91144cd0SPeter starts is a question this branch has not asked. See also 511*91144cd0SPeter [Known gap: the staged CRT is still VC90](#known-gap-the-staged-crt-is-still-vc90), 512*91144cd0SPeter which is a runtime problem by construction. 513*91144cd0SPeter 514*91144cd0SPeterThe rate is the useful number here. On `win10-64-minimal` the last mile was six 515*91144cd0SPeterdefects in four families; this branch took forty in a dozen to reach a green 516*91144cd0SPeterbuild, and a green build is not the finish line — it is the point at which the 517*91144cd0SPeterruntime questions start. 518