This is an automated email from the ASF dual-hosted git repository.

leginee pushed a commit to branch bazel-migration
in repository https://gitbox.apache.org/repos/asf/openoffice.git

commit 520c8961408a76ba12f05346b7c8998ac9527986
Author: Peter Kovacs <[email protected]>
AuthorDate: Sat Aug 1 16:17:04 2026 +0200

    build(test): fix R6034 in gtest_test exes — embed CRT manifest, stage UNO 
bridge
    
    Test exes that reach a cppu Mapping died under `bazel test` with an empty
    test.log and exit 0xC0000142 (STATUS_DLL_INIT_FAILED), after popping a modal
    R6034 dialog.  The same exe run by hand from a shell passed, so the
    discriminator was the environment, not the binary — easy to misread as
    flakiness.  Two coupled causes:
    
    1. The C++/UNO bridge DLL is a RUN-TIME dep that nothing links.
       cppu::getCaughtException()/throwException() — reached from any 
OWeakObject
       dispose path, OInterfaceContainerHelper, proxy marshalling — build a 
Mapping
       between the C++ and UNO environments, and cppu's uno_getMapping
       osl_loadModule()s the bridge on demand (cppu/source/uno/lbmap.cxx).  It 
is
       invisible to the linker, so it has to be named in runtime_dlls.  Left 
out,
       the loader either finds nothing (null mapping -> AV deep inside 
dispose(),
       looking like a source bug) or finds a stray copy elsewhere on PATH, whose
       CRT then loads outside the exe's activation context -> R6034.
    
    2. The staged external <exe>.manifest only reliably covers DLLs bound at
       process start.  A test that osl_loadModule()s a UNO DLL later needs the 
CRT
       activation context still in force, so compile the manifest into a .res 
and
       link it at RT_MANIFEST id 1, which the loader always honours.
       //main/bridges:jni_test_launcher already did this by hand for the DLLs a
       hosted JVM loads; this generalises it to every gtest_test exe.
    
    Fixes //main/comphelper:comphelper_test_weakbag, which was red before this
    change.  The .rc is arch-selected rather than parameterised because RC.Exe
    takes the manifest path as a literal in the resource statement.
    
    Not handled: under --compilation_mode=dbg the exes link /MDd but this .res
    still carries the release CRT manifest.
    
    Both .gitignore files blanket-ignored main/external/msvcp90/*, which had
    silently kept that package's first-party Bazel build files (BUILD.bazel, the
    vc90_app*.manifest application manifests) out of the repo — a fresh clone 
could
    not build them.  Narrow the ignore to the Microsoft-shipped binaries and
    assembly manifests, which stay user-supplied per README_msvcX90.dll, and 
track
    the build files.
    
    Co-Authored-By: Claude Opus 5 <[email protected]>
---
 .gitignore                                       |  13 ++-
 build/rules/gtest_test.bzl                       |  17 +++-
 main/.gitignore                                  |  13 ++-
 main/comphelper/BUILD.bazel                      |  10 ++-
 main/external/msvcp90/BUILD.bazel                | 109 +++++++++++++++++++++++
 main/external/msvcp90/amd64/vc90_app.manifest    |  17 ++++
 main/external/msvcp90/vc90_app.manifest          |  17 ++++
 main/external/msvcp90/vc90_app_manifest.rc       |  13 +++
 main/external/msvcp90/vc90_app_manifest_amd64.rc |   6 ++
 main/external/msvcp90/vc90_debug_app.manifest    |  17 ++++
 10 files changed, 227 insertions(+), 5 deletions(-)

diff --git a/.gitignore b/.gitignore
index 147de8fca2..bca1479c5b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -62,7 +62,18 @@ TAGS
 # externals
 /main/external/dbghelp/*
 /main/external/gdiplus/*
-/main/external/msvcp90/*
+# VS2008 CRT redistributable — user-supplied, see
+# main/external/msvcp90/README_msvcX90.dll.  Only the Microsoft-shipped 
binaries
+# and their assembly manifests are ignored; the first-party Bazel build files 
in
+# that directory (BUILD.bazel, the vc90_app*.manifest application manifests and
+# the .rc files that embed them) ARE tracked.  This was a blanket
+# /main/external/msvcp90/* until 2026-08-01, which silently kept those build
+# files out of the repo.  Mirrored in main/.gitignore.
+/main/external/msvcp90/*.dll
+/main/external/msvcp90/amd64/*.dll
+/main/external/msvcp90/Microsoft.VC90.CRT.manifest
+/main/external/msvcp90/amd64/Microsoft.VC90.CRT.manifest
+/main/external/msvcp90/Microsoft.VC90.DebugCRT.manifest
 /main/external/msvcp100/*
 /main/external/unowinreg/unowinreg.dll
 /main/external/vcredist/*
diff --git a/build/rules/gtest_test.bzl b/build/rules/gtest_test.bzl
index 15577a9ccf..0cde3d9fcb 100644
--- a/build/rules/gtest_test.bzl
+++ b/build/rules/gtest_test.bzl
@@ -34,6 +34,14 @@ load("@rules_cc//cc:defs.bzl", "cc_binary")
 _CRT = "//main/external/msvcp90:crt_dlls"
 _APP_MANIFEST = "//main/external/msvcp90:vc90_app_manifest"
 
+# VC90-CRT manifest compiled to a .res, linked into every test exe so it sits 
in
+# the image at RT_MANIFEST id 1.  The staged external <exe>.manifest below only
+# covers DLLs bound at process start; a test that osl_loadModule()s a UNO DLL
+# later (any cppu Mapping pulls in the C++/UNO bridge on demand) needs the CRT
+# activation context to still apply at that point, or the late load resolves
+# msvcr90 loose → R6034 → DllMain fails → exit 0xC0000142.
+_APP_MANIFEST_RES = "//main/external/msvcp90:vc90_app_manifest_res"
+
 def _staged_gtest_test_impl(ctx):
     d = ctx.label.name + ".run"
     staged = []
@@ -114,8 +122,13 @@ def gtest_test(
         # mangle differently → LNK2019.
         copts = ["/Zc:wchar_t-"] + copts,
         defines = defines,
-        additional_linker_inputs = additional_linker_inputs,
-        linkopts = linkopts + ["/MANIFEST:NO"],
+        # /MANIFEST:NO keeps the LINKER from generating one; the .res supplies
+        # the manifest as a resource instead (see _APP_MANIFEST_RES).
+        additional_linker_inputs = additional_linker_inputs + 
[_APP_MANIFEST_RES],
+        linkopts = linkopts + [
+            "$(execpath %s)" % _APP_MANIFEST_RES,
+            "/MANIFEST:NO",
+        ],
         testonly = True,
         **kwargs
     )
diff --git a/main/.gitignore b/main/.gitignore
index c103abc9f9..e497bfddb7 100644
--- a/main/.gitignore
+++ b/main/.gitignore
@@ -56,7 +56,18 @@ TAGS
 
 # externals
 /external/unowinreg/unowinreg.dll
-/external/msvcp90/*
+
+# VS2008 CRT redistributable — user-supplied, see 
external/msvcp90/README_msvcX90.dll.
+# Only the Microsoft-shipped binaries and their assembly manifests are ignored;
+# the first-party Bazel build files in that directory (BUILD.bazel, the
+# vc90_app*.manifest application manifests and the .rc files that embed them)
+# ARE tracked.  This was a blanket /external/msvcp90/* until 2026-08-01, which
+# silently kept those build files out of the repo.
+/external/msvcp90/*.dll
+/external/msvcp90/amd64/*.dll
+/external/msvcp90/Microsoft.VC90.CRT.manifest
+/external/msvcp90/amd64/Microsoft.VC90.CRT.manifest
+/external/msvcp90/Microsoft.VC90.DebugCRT.manifest
 
 # $INPATH output directories
 /*/unxfbsd?
diff --git a/main/comphelper/BUILD.bazel b/main/comphelper/BUILD.bazel
index cd188f0fa1..855b3fdf9b 100644
--- a/main/comphelper/BUILD.bazel
+++ b/main/comphelper/BUILD.bazel
@@ -203,6 +203,11 @@ _QA_COPTS = [
     "/D_HAS_ITERATOR_DEBUGGING=0",
 ]
 
+# msci_uno/mscx_uno is a RUN-TIME dep nothing links: cppu::getCaughtException()
+# (reached from OWeakObject dispose paths, e.g. test_weakbag) builds a C++↔UNO
+# Mapping, and cppu's uno_getMapping osl_loadModule()s the bridge on demand.
+# Without it staged the loader grabs a stray copy off PATH whose CRT loads
+# outside this exe's activation context → R6034 → exit 0xC0000142.
 _QA_RUNTIME_DLLS = [
     "//main/sal:sal3",
     "//main/cppu:cppu3",
@@ -211,7 +216,10 @@ _QA_RUNTIME_DLLS = [
     "//main/ucbhelper:ucbhelperMSC",
     "//main/vos:vos3MSC",
     ":comphelpMSC",
-]
+] + select({
+    "//build:arch_x64": ["//main/bridges:mscx_uno"],
+    "//conditions:default": ["//main/bridges:msci_uno"],
+})
 
 _QA_LINKER_INPUTS = [
     "//main/sal:sal_implib",
diff --git a/main/external/msvcp90/BUILD.bazel 
b/main/external/msvcp90/BUILD.bazel
new file mode 100644
index 0000000000..592dd8e753
--- /dev/null
+++ b/main/external/msvcp90/BUILD.bazel
@@ -0,0 +1,109 @@
+filegroup(
+    name = "msvcp90",
+    srcs = [":crt_dlls"],
+    visibility = ["//visibility:public"],
+)
+
+# CRT DLLs + assembly manifest, arch-selected.  The select() resolves in the
+# CONSUMER's configuration, which is exactly what both use-sites need:
+#   * IDL/UNO build TOOLS (idl_pipeline.bzl, cfg="exec") pull this in the exec
+#     configuration = the x64 host, so they get the amd64 CRT — required now 
that
+#     the x86 toolchain correctly targets x86_32 and exec-config tools build 
x64.
+#   * Product STAGING pulls it in the target configuration → x86 CRT for the 
x86
+#     build, amd64 CRT for the --config=x64 build.
+# amd64/ holds the VC\redist\amd64\Microsoft.VC90.CRT copies (+ amd64 app 
manifest).
+filegroup(
+    name = "crt_dlls",
+    srcs = select({
+        "//build:arch_x64": [
+            "amd64/msvcr90.dll",
+            "amd64/msvcp90.dll",
+            "amd64/msvcm90.dll",
+            "amd64/Microsoft.VC90.CRT.manifest",
+        ],
+        "//conditions:default": [
+            "msvcr90.dll",
+            "msvcp90.dll",
+            "msvcm90.dll",
+            "Microsoft.VC90.CRT.manifest",
+        ],
+    }),
+    visibility = ["//visibility:public"],
+)
+
+# Generic application manifest declaring the VC90 CRT dependency.
+# Stage this alongside each /MD tool EXE as <exename>.manifest so that
+# Windows picks it up as an external manifest (no mt.exe embedding needed).
+# amd64 variant declares processorArchitecture="amd64" for x64 tools/binaries.
+filegroup(
+    name = "vc90_app_manifest",
+    srcs = select({
+        "//build:arch_x64": ["amd64/vc90_app.manifest"],
+        "//conditions:default": ["vc90_app.manifest"],
+    }),
+    visibility = ["//visibility:public"],
+)
+
+# ── Embedded (in-image) form of the app manifest ─────────────────────────────
+# vc90_app_manifest above is the EXTERNAL form, staged as <exe>.manifest.  That
+# is enough for DLLs bound at process start, but NOT for an exe that
+# osl_loadModule()s a UNO DLL later: the C++/UNO bridge (msci_uno/mscx_uno) is
+# pulled in on demand by any cppu Mapping, and if the CRT activation context is
+# not in force in the image itself, that late load resolves msvcr90 loose
+# instead of via the SxS assembly → R6034 → DllMain fails → exit 0xC0000142.
+#
+# Linking this .res into the exe embeds the manifest at RT_MANIFEST id 1, which
+# the loader always honours (and which supersedes the external file).  Used by
+# //build/rules:gtest_test.bzl for every staged test exe; //main/bridges'
+# jni_test_launcher does the same thing by hand for the JVM host.
+#
+# The .rc is arch-selected rather than parameterised because RC.Exe takes the
+# manifest path as a literal in the resource statement — the x64 one points at
+# amd64/, and both compile with /I main/external/msvcp90.
+filegroup(
+    name = "vc90_app_manifest_rc",
+    srcs = select({
+        "//build:arch_x64": ["vc90_app_manifest_amd64.rc"],
+        "//conditions:default": ["vc90_app_manifest.rc"],
+    }),
+)
+
+genrule(
+    name = "vc90_app_manifest_res",
+    srcs = [
+        ":vc90_app_manifest_rc",
+        ":vc90_app_manifest",
+    ],
+    outs = ["vc90_app_manifest.res"],
+    cmd_bat = (
+        "set \"_RC=C:\\Program Files\\Microsoft 
SDKs\\Windows\\v7.0\\Bin\\RC.Exe\"&&" +
+        "\"!_RC!\" /nologo /I \"main/external/msvcp90\"" +
+        " /fo \"$(OUTS)\" \"$(location :vc90_app_manifest_rc)\""
+    ),
+    visibility = ["//visibility:public"],
+)
+
+# ── Debug CRT (/MDd, --compilation_mode=dbg) ─────────────────────────────────
+# The debug analog of crt_dlls.  Under --compilation_mode=dbg the toolchain
+# links /MDd, so binaries import MSVCR90D.dll / MSVCP90D.dll / MSVCM90D.dll,
+# which are NOT in System32 or any redistributable.  @msvc_debug_crt copies 
them
+# from a VS2008 install (empty filegroup when unavailable — see
+# build/debug_crt_repo.bzl).  The private-assembly manifest lets the loader
+# resolve them from the app dir instead of WinSxS.  Mirrors the debug branch of
+# //main/staging:all_files.
+filegroup(
+    name = "debug_crt_dlls",
+    srcs = [
+        "@msvc_debug_crt//:dlls",
+        "Microsoft.VC90.DebugCRT.manifest",
+    ],
+    visibility = ["//visibility:public"],
+)
+
+# Debug analog of vc90_app_manifest: staged as <exe>.exe.manifest beside a /MDd
+# EXE so it declares the Microsoft.VC90.DebugCRT private-assembly dependency.
+filegroup(
+    name = "vc90_debug_app_manifest",
+    srcs = ["vc90_debug_app.manifest"],
+    visibility = ["//visibility:public"],
+)
diff --git a/main/external/msvcp90/amd64/vc90_app.manifest 
b/main/external/msvcp90/amd64/vc90_app.manifest
new file mode 100644
index 0000000000..4c413e8266
--- /dev/null
+++ b/main/external/msvcp90/amd64/vc90_app.manifest
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+    <security>
+      <requestedPrivileges>
+        <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
+      </requestedPrivileges>
+    </security>
+  </trustInfo>
+  <dependency>
+    <dependentAssembly>
+      <assemblyIdentity type="win32" name="Microsoft.VC90.CRT"
+        version="9.0.30729.1" processorArchitecture="amd64"
+        publicKeyToken="1fc8b3b9a1e18e3b"/>
+    </dependentAssembly>
+  </dependency>
+</assembly>
diff --git a/main/external/msvcp90/vc90_app.manifest 
b/main/external/msvcp90/vc90_app.manifest
new file mode 100644
index 0000000000..88e410189a
--- /dev/null
+++ b/main/external/msvcp90/vc90_app.manifest
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+    <security>
+      <requestedPrivileges>
+        <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
+      </requestedPrivileges>
+    </security>
+  </trustInfo>
+  <dependency>
+    <dependentAssembly>
+      <assemblyIdentity type="win32" name="Microsoft.VC90.CRT"
+        version="9.0.30729.1" processorArchitecture="x86"
+        publicKeyToken="1fc8b3b9a1e18e3b"/>
+    </dependentAssembly>
+  </dependency>
+</assembly>
diff --git a/main/external/msvcp90/vc90_app_manifest.rc 
b/main/external/msvcp90/vc90_app_manifest.rc
new file mode 100644
index 0000000000..4baec6c666
--- /dev/null
+++ b/main/external/msvcp90/vc90_app_manifest.rc
@@ -0,0 +1,13 @@
+// Embed the VC90-CRT dependency manifest as RT_MANIFEST (type 24), resource 
id 1
+// (CREATEPROCESS_MANIFEST_RESOURCE_ID — the EXE manifest slot).
+//
+// An external "<exe>.manifest" file only reliably supplies the activation
+// context for DLLs bound at process start.  Test exes that osl_loadModule() a
+// UNO DLL later (the C++/UNO bridge, pulled in by any cppu Mapping) need the
+// context to still be in force at that point — embedding it in the image is 
the
+// only way to guarantee that.  Without it the late-loaded DLL resolves the CRT
+// loose instead of via the SxS assembly → R6034 → DllMain fails → 0xC0000142.
+//
+// x86 variant: the manifest sits at the package root.  See
+// vc90_app_manifest_amd64.rc for the x64 one.
+1 24 "vc90_app.manifest"
diff --git a/main/external/msvcp90/vc90_app_manifest_amd64.rc 
b/main/external/msvcp90/vc90_app_manifest_amd64.rc
new file mode 100644
index 0000000000..29fa663396
--- /dev/null
+++ b/main/external/msvcp90/vc90_app_manifest_amd64.rc
@@ -0,0 +1,6 @@
+// x64 counterpart of vc90_app_manifest.rc (see there for why this exists).
+// Same RT_MANIFEST id 1 slot, but pointing at the amd64 app manifest, which
+// declares processorArchitecture="amd64" for the VC90 CRT assembly.
+// Both .rc files are compiled with /I main/external/msvcp90, so the path here
+// is relative to the package root.
+1 24 "amd64/vc90_app.manifest"
diff --git a/main/external/msvcp90/vc90_debug_app.manifest 
b/main/external/msvcp90/vc90_debug_app.manifest
new file mode 100644
index 0000000000..0d2d292bf0
--- /dev/null
+++ b/main/external/msvcp90/vc90_debug_app.manifest
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+    <security>
+      <requestedPrivileges>
+        <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
+      </requestedPrivileges>
+    </security>
+  </trustInfo>
+  <dependency>
+    <dependentAssembly>
+      <assemblyIdentity type="win32" name="Microsoft.VC90.DebugCRT"
+        version="9.0.30729.1" processorArchitecture="x86"
+        publicKeyToken="1fc8b3b9a1e18e3b"/>
+    </dependentAssembly>
+  </dependency>
+</assembly>

Reply via email to