xref: /trunk/win10-msvc/README.md (revision 91144cd0085a7583d2099b982122deb2184ab956)
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* **C2694a 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/` treeverified, 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 havewhich 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.61.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 movedthe 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