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 eb867b6ad9bb851755ff98492ada70948b5b0794
Author: Peter Kovacs <[email protected]>
AuthorDate: Wed Aug 5 22:10:26 2026 +0200

    test(testtools): bridgetest GREEN — C++ and Java UNO bridge round-trip
    
    Wires the UNO bridge round-trip suite: every construct the type system has
    (each simple type, strings, enums, structs, polymorphic structs, sequences,
    anys, interfaces, attributes, out/inout params, exceptions, multiple
    inheritance, current context, recursive and sequence-of-calls dispatch) 
pushed
    through a call chain and checked coming back.
    
      //main/testtools:bridgetest       CppTestObject,  ~1.1s
      //main/testtools:bridgetest_java  JavaTestObject, ~1.4s
      //main/testtools:bridgetest_tests both
    
    The Java half is the first verification that the java_uno JNI bridge 
MARSHALS
    correctly — cppuhelper/qa/propertysetmixin only proved a Java UNO component 
can
    be loaded.
    
    Not a GoogleTest, and deliberately not made into one (that would be a source
    change): three UNO components driven by the generic //main/cpputools 
uno.exe,
    which instantiates the -s service, queries XMain and calls run() with
    everything after "--".  run()'s return value is the exit code.  The driver
    takes the NAME of the object to test, which is exactly why one driver serves
    the C++, Java, Python and CLI objects.
    
    New reusable rule attr `run_args` on staged_run_test: a fixed command line
    baked into the launcher and token-expanded like `env`, so the test binary 
can
    be a generic tool the suite configures.  //build:jre.bzl centralizes the
    machine-specific, arch-select()ed test JRE, previously inline in cppuhelper.
    
    The C++ target is a fourth fixture kind: uno.exe -ro calls
    bootstrap_InitialComponentContext(REGISTRY), not defaultBootstrap, so there 
is
    no fundamental.ini and no uno_install.  Two facts fall out that contradict
    notes recorded elsewhere, both verified here:
      * the TEXTUAL (XML) registry works on this path — openRegistry passes
        (bReadOnly=true, bCreate=false), the combination configmgr/qa/unit 
cannot
        get from its one-argument createRegistryServiceFactory;
      * a relative component uri ("./cppobj.uno.dll") is resolved by
        textualservices.cxx with rtl::Uri::convertRelToAbs against the rdb 
FILE's
        own URL, so it needs no bootstrap variable and no env at all.
    
    LANDMINE, second and wider mechanism of "co-locating a core UNO DLL breaks 
the
    bootstrap": cppu::get_unorc() opens get_this_libpath()+"/uno.ini", i.e. 
uno.ini
    beside cppuhelper3MSC.dll, and uno.ini — not fundamental.ini — is where
    URE_INTERNAL_LIB_DIR is defined.  Every vnd.sun.star.expand: URI resolves
    through that handle, so a co-located cppuhelper3MSC.dll makes all of them
    silently expand to nothing.  It surfaced two layers away as jvmfwk's "The 
file:
    vnd.sun.star.expand:$URE_INTERNAL_LIB_DIR/sunjavaplugin.dll does not exist".
    Hence the two targets' runtime lists are opposites and both are correct.
    
    x86 green; x64 analysis-only checked (the mscx_uno select resolves).
    
    Co-Authored-By: Claude Opus 5 <[email protected]>
---
 CLAUDE.md                                          |  67 +++-
 build/jre.bzl                                      |  46 +++
 build/rules/gtest_test.bzl                         |  28 +-
 main/cppuhelper/BUILD.bazel                        |  40 +-
 main/testtools/BUILD.bazel                         | 420 +++++++++++++++++++++
 main/testtools/readme.md                           | 183 +++++++++
 .../testtools/source/bridgetest/bridgetest.uno.def |  11 +
 .../source/bridgetest/constructors.uno.def         |  11 +
 main/testtools/source/bridgetest/cppobj.uno.def    |  11 +
 9 files changed, 774 insertions(+), 43 deletions(-)

diff --git a/CLAUDE.md b/CLAUDE.md
index 040e2f783f..04cb651cab 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -110,6 +110,17 @@ test          🔨  C++ unit-test infra runnable — NOW THE 
FRONT-LINE TASK: br
                    component library failed: …/<test>.run/bootstrap.uno.dll"). 
 List
                    only test-only DLLs; the office closure is already on PATH 
via
                    program/ (svl_qa_test_URIHelper lists none, which is why it 
passed).
+                   SECOND, WIDER MECHANISM found 2026-08-05 via 
testtools/bridgetest_java
+                   — same cause, but it breaks MACRO EXPANSION rather than one 
DLL load,
+                   so the symptom can appear layers away with no mention of a 
DLL:
+                   cppu::get_unorc() opens get_this_libpath()+"/uno.ini", i.e. 
uno.ini
+                   BESIDE cppuhelper3MSC.dll, and uno.ini — NOT 
fundamental.ini — is where
+                   URE_INTERNAL_LIB_DIR is defined.  Every 
vnd.sun.star.expand: URI in the
+                   tree goes through that handle (bootstrap_expandUri →
+                   cppuhelper::detail::expandMacros), so a co-located 
cppuhelper3MSC.dll
+                   makes all of them silently expand to NOTHING.  It surfaced 
as jvmfwk's
+                   "The file: 
vnd.sun.star.expand:$URE_INTERNAL_LIB_DIR/sunjavaplugin.dll
+                   does not exist" + the catch-all "JRE could not be 
recognized".
                    CONSUMER NOTE: upstream's ONLY C++ user of the fixture,
                    xmlsecurity/qa/certext, CANNOT BUILD — it needs neon
                    (ne_ssl_cert_read) and AOO replaced neon with curl (no 
main/neon, no
@@ -253,8 +264,60 @@ test          🔨  C++ unit-test infra runnable — NOW THE 
FRONT-LINE TASK: br
                    not build: osl_process asserts an env ORDER Windows doesn't 
use;
                    rtl_Bootstrap expects the default ini to be testshl2.ini 
because the
                    testshl2-era process was literally testshl2.exe.
-testtools     ⬜  (bridgetest — pure-C++ UNO bridge round-trip; cli/pyuno/java 
variants
-                   need rules_java — see Java bucket)
+testtools     🔨  bridgetest GREEN 2026-08-05, BOTH halves — 
//main/testtools:bridgetest
+                   (C++ object, ~1.1s) and :bridgetest_java (Java object over 
the
+                   java_uno JNI bridge, ~1.4s); :bridgetest_tests runs both.  
This is
+                   the widest type-marshalling check in the tree (every simple 
type,
+                   string, enum, struct, POLYMORPHIC struct, sequence, any, 
interface,
+                   attribute, out/inout param, exception, multiple 
inheritance, current
+                   context, recursive + sequence-of-calls dispatch) and the 
Java half is
+                   the FIRST verification that the java_uno bridge marshals 
correctly —
+                   propertysetmixin only proved a Java component can be LOADED.
+                   NOT a gtest and must not become one (that would be a source 
change):
+                   it is 3 UNO components driven by the generic 
//main/cpputools uno.exe,
+                   which instantiates the -s service, queries XMain and calls 
run() with
+                   everything after "--"; the driver takes the NAME of the 
object to test,
+                   which is exactly why ONE driver serves the 
C++/Java/Python/CLI objects.
+                   run() 's return value IS the exit code, so no wrapper is 
needed.
+                   NEW general rule attr `run_args` (gtest_test.bzl, on 
staged_run_test):
+                   a FIXED command line baked into the launcher and 
token-expanded like
+                   `env`, so the "test binary" can be a generic tool the suite 
configures.
+                   FOURTH FIXTURE KIND (the C++ half): uno.exe -ro calls
+                   bootstrap_InitialComponentContext(REGISTRY), not 
defaultBootstrap —
+                   no fundamental.ini, no URE_BOOTSTRAP, NO uno_install, ~1s.  
Everything
+                   else is hardcoded in cppuhelper bootstrapInitialSF() out of
+                   bootstrap.uno.dll.  Two reusable facts: (1) the TEXTUAL 
(XML) registry
+                   WORKS on this path — openRegistry passes (bReadOnly=true,
+                   bCreate=false), exactly the combination configmgr/qa/unit 
cannot get
+                   from its 1-arg createRegistryServiceFactory; (2) a RELATIVE 
component
+                   uri ("./cppobj.uno.dll") is resolved by textualservices.cxx 
with
+                   rtl::Uri::convertRelToAbs against the RDB FILE's own URL, 
so "beside
+                   this rdb" needs no bootstrap variable and no env at all.
+                   LANDMINE — the co-located-UNO-DLL rule has a SECOND, bigger 
mechanism
+                   than the recorded one (bootstrap.uno.dll via 
get_this_libpath):
+                   cppu::get_unorc() opens get_this_libpath()+"/uno.ini", i.e. 
uno.ini
+                   BESIDE cppuhelper3MSC.dll, and uno.ini is where 
URE_INTERNAL_LIB_DIR
+                   is defined (fundamental.ini does NOT define it).  EVERY
+                   vnd.sun.star.expand: URI resolves through that one handle
+                   (bootstrap_expandUri → cppuhelper::detail::expandMacros).  
Co-locate
+                   cppuhelper3MSC.dll and the exe's dir wins the loader search 
⇒ lookup
+                   lands in the test dir ⇒ no uno.ini ⇒ every such macro 
silently expands
+                   to NOTHING.  Surfaced two layers away as jvmfwk's "The file:
+                   vnd.sun.star.expand:$URE_INTERNAL_LIB_DIR/sunjavaplugin.dll 
does not
+                   exist" + "could not be recognized".  So with uno_install, 
`runtime`
+                   must list ONLY test-only files: the C++ target lists the 
whole core
+                   stack and the Java one lists NONE — opposite, both correct.
+                   Also: the Java run needs the INSTALL's services.rdb as a 
3rd -ro
+                   (dmake's $(SOLARXMLDIR)/ure/services.rdb).  Registering 
just the two
+                   Java2-loader components instead does NOT work — javaloader 
resolves
+                   the component URL via com.sun.star.uri.UriReferenceFactory, 
itself a
+                   URE component (stoc uriproc), so it only moves the failure 
one service
+                   along.  Passed as a file:/// URL (unoexe convertToFileUrl 
takes it
+                   verbatim).  //build:jre.bzl now centralizes the 
machine-specific,
+                   arch-select()ed test JRE (was duplicated in cppuhelper).
+                   See main/testtools/readme.md.  STILL ⬜: cli + cliversioning 
+ qa/cli
+                   (cli_ure bucket), pyuno variant (reachable now), 
source/performance
+                   (a benchmark), and the socket-URP client/server variants.
 qadevOOo      🔨  OOoRunner.jar built (//main/qadevOOo:OOoRunner — qadevOOo QA
                    framework, ~2137 classes; classpath ridl/unoil/jurt/juh_jar/
                    java_uno_jar; .csv objdsc NOT jarred, manifest omitted).
diff --git a/build/jre.bzl b/build/jre.bzl
new file mode 100644
index 0000000000..05120073b9
--- /dev/null
+++ b/build/jre.bzl
@@ -0,0 +1,46 @@
+"""The JRE a *test* starts in-process, per target architecture.
+
+Any test that puts jvmfwk into DIRECT mode (UNO_JAVA_JFW_JREHOME) loads a
+jvm.dll into its OWN process, so the JRE has to match the TARGET arch, not the
+host's — a 32-bit default build cannot load the 64-bit JVM that $JAVA_HOME
+almost certainly points at, and one JAVA_HOME cannot be right for both arches
+anyway.  Hence a select(), and hence not the build JDK: @remotejdk21_win is the
+toolchain that COMPILES (and is x64-only), which is a different question from
+which JVM a test may load.
+
+This is machine-specific and the one genuinely unhermetic input in the test
+suite.  It lives here rather than in each BUILD file so that pointing the tree
+at a different JDK is a single edit; //main/bridges' java_run_test still takes
+its own `jvm_path_dirs` (it needs the DIRECTORY containing jvm.dll for PATH,
+not a home URL), so that is a related but distinct knob.
+
+A URL, not a path, and mind two encodings:
+  * forward slashes — every rtl::Bootstrap value is macro-expanded, where a
+    backslash is an ESCAPE character, so "C:\\Program" comes back "C:Program";
+  * %20 for spaces — osl's file-URL parsing requires it.
+And note the launcher doubles '%' for cmd before substituting (gtest_test.bzl
+_expand_tokens); without that "%20" reaches the test as "0".
+"""
+
+_JRE_X86 = 
"file:///C:/Program%20Files%20(x86)/Eclipse%20Adoptium/jdk-8.0.452.9-hotspot"
+_JRE_X64 = 
"file:///C:/Program%20Files/Eclipse%20Adoptium/jdk-8.0.452.9-hotspot"
+
+def jre_home_env():
+    """select() giving UNO_JAVA_JFW_JREHOME for the target arch.
+
+    Merge it into a gtest_test/staged_run_test `env` dict:
+
+        env = { ... } | jre_home_env()
+
+    Setting any UNO_JAVA_JFW_{JREHOME,ENV_JREHOME,CLASSPATH,PARAMETER_1} is 
what
+    selects jvmfwk's DIRECT mode (fwkbase.cxx getMode).  Its other mode,
+    JFW_MODE_APPLICATION, reads a javasettings_<os>_<arch>.xml recording which
+    JRE a human picked in Tools > Options > Java; a fixture has no such 
history,
+    so jfw_startVM() would return JFW_E_JAVA_DISABLED before looking for a JVM.
+    Direct mode skips only that settings layer — sunjavaplugin.dll still probes
+    the JRE, so vendor recognition is still exercised.
+    """
+    return select({
+        "//build:arch_x64": {"UNO_JAVA_JFW_JREHOME": _JRE_X64},
+        "//conditions:default": {"UNO_JAVA_JFW_JREHOME": _JRE_X86},
+    })
diff --git a/build/rules/gtest_test.bzl b/build/rules/gtest_test.bzl
index bfdd0b99b8..a5837a9689 100644
--- a/build/rules/gtest_test.bzl
+++ b/build/rules/gtest_test.bzl
@@ -114,6 +114,12 @@ def _env_lines(env):
     # where the author's ordering carries no meaning).
     return ['set "%s=%s"' % (k, _expand_tokens(env[k])) for k in sorted(env)]
 
+def _arg_string(run_args):
+    # Quoted so an argument containing a space survives cmd's tokenizing, and
+    # token-expanded like `env` values are — a fixed command line routinely has
+    # to name a staged file, which is only locatable at run time.
+    return "".join([' "%s"' % _expand_tokens(a) for a in run_args])
+
 def _prerun_lines(prerun):
     # `|| exit /b 1` on every one: a fixture that failed to build must fail the
     # test loudly, not leave the suite to report a confusing downstream error.
@@ -249,7 +255,9 @@ def _staged_gtest_test_impl(ctx):
     # a working directory, an environment, or a fixture built at run time.
     env = ctx.attr.env
     prerun = ctx.attr.prerun
-    values = env.values() + prerun
+    run_args = ctx.attr.run_args
+    argstr = _arg_string(run_args)
+    values = env.values() + prerun + run_args
     need_scratch = (ctx.attr.office_connection or
                     _uses_token(values, "$(SCRATCH"))
     if _uses_token(values, "$(PROGRAM)") and not uno_program_dir:
@@ -259,7 +267,7 @@ def _staged_gtest_test_impl(ctx):
              "ini, it does not supply the UNO DLL closure the test still 
loads.")
 
     executable = staged_exe
-    if (ctx.attr.run_in_staged_dir or uno_program_dir or env or prerun):
+    if (ctx.attr.run_in_staged_dir or uno_program_dir or env or prerun or 
run_args):
         launcher_dir = staged_exe.dirname  # the .bat sits beside the staged 
exe
         lines = ["@echo off", "setlocal"]
 
@@ -387,7 +395,8 @@ def _staged_gtest_test_impl(ctx):
                     'set "arg-soffice=path:%_SOFFICE:\\=\\\\%"',
                     'set "arg-user=%_SCRATCH:\\=\\\\%"',
                 ]
-            lines += _env_lines(env) + _prerun_lines(prerun) + ['"%_EXE%" %*']
+            lines += _env_lines(env) + _prerun_lines(prerun)
+            lines += ['"%_EXE%"' + argstr + " %*"]
         else:
             # Co-locating a data file with the exe is not enough for a test 
that
             # opens it by bare relative name: the working directory is the
@@ -398,7 +407,7 @@ def _staged_gtest_test_impl(ctx):
             if ctx.attr.run_in_staged_dir:
                 lines += ['cd /d "%~dp0" || exit /b 1']
             lines += _env_lines(env) + _prerun_lines(prerun)
-            lines += ['"%~dp0' + staged_exe.basename + '" %*']
+            lines += ['"%~dp0' + staged_exe.basename + '"' + argstr + " %*"]
 
         # Capture the exit code BEFORE any cleanup — rmdir would clobber it.
         lines += ['set "_RC=%ERRORLEVEL%"']
@@ -432,6 +441,7 @@ _staged_gtest_test = rule(
         "data_tree": attr.label_keyed_string_dict(allow_files = True),
         "env": attr.string_dict(),
         "prerun": attr.string_list(),
+        "run_args": attr.string_list(),
         "ure_bootstrap": attr.string(),
     },
 )
@@ -440,7 +450,15 @@ _staged_gtest_test = rule(
 # runtime DLLs + VC90 CRT + external manifest into one flat dir and runs it as 
a
 # test (pass/fail = process exit code).  Exposed for non-gtest runnable tests,
 # e.g. bridges' inter_libs_exc (a cross-DLL C++ exception smoke test whose exe
-# loads two sibling DLLs and exits 0 iff exception propagation works).
+# loads two sibling DLLs and exits 0 iff exception propagation works), and
+# testtools' bridgetest, where the "test binary" is the generic 
//main/cpputools
+# uno.exe and the suite is selected entirely by `run_args`.
+#
+# run_args: a FIXED command line baked into the launcher, token-expanded like
+# `env` (so it can name a staged file).  Anything passed on the `bazel test`
+# command line still follows it, via %*.  Deliberately not the native `args`
+# attribute: baking it in keeps `bazel run` on the target reproducing exactly
+# what `bazel test` ran.
 staged_run_test = _staged_gtest_test
 
 def gtest_test(
diff --git a/main/cppuhelper/BUILD.bazel b/main/cppuhelper/BUILD.bazel
index 272851d593..61d55ad0e7 100644
--- a/main/cppuhelper/BUILD.bazel
+++ b/main/cppuhelper/BUILD.bazel
@@ -5,6 +5,7 @@ load("@rules_java//java:defs.bzl", "java_import", 
"java_library")
 load("//build/rules:idl_pipeline.bzl", "idl_library")
 load("//build/rules:java_pipeline.bzl", "jar_from_directory", 
"javamaker_classes", "uno_jar")
 load("//build/rules:merge_rdb.bzl", "merge_rdb")
+load("//build:jre.bzl", "jre_home_env")
 load("//build/rules:gtest_test.bzl", "gtest_test")
 load("//main/postprocess:postprocess.bzl", "services_rdb")
 
@@ -439,41 +440,8 @@ gtest_test(
         # Where the vnd.sun.star.expand: URIs in psm_services.rdb resolve to.
         "OOO_INBUILD_SHAREDLIB_DIR": "file:///$(RUNDIR_URL)",
         "OOO_INBUILD_JAR_DIR": "file:///$(RUNDIR_URL)",
-        # Put jvmfwk in DIRECT mode with an explicit JRE.
-        #
-        # Its other mode, JFW_MODE_APPLICATION, reads a 
javasettings_<os>_<arch>
-        # .xml recording which JRE the user picked and whether Java is enabled 
—
-        # written by Tools > Options > Java, i.e. by a human, at some point in
-        # the past.  A test fixture has no such history, so jfw_startVM() would
-        # return JFW_E_JAVA_DISABLED before ever looking for a JVM.  Direct 
mode
-        # (any of UNO_JAVA_JFW_{JREHOME,ENV_JREHOME,CLASSPATH,PARAMETER_1} set 
—
-        # fwkbase.cxx getMode) skips the settings layer and takes what it is
-        # given.  sunjavaplugin.dll still inspects it, so that path is 
exercised.
-        #
-        # The JRE must match the TARGET arch: this test process is 32-bit for
-        # the default build and loads a 32-bit jvm.dll into itself.  That rules
-        # out the ENV_JREHOME/$JAVA_HOME form — one JAVA_HOME cannot be right
-        # for both arches, and bazel does not forward it to tests anyway.
-        #
-        # A URL, not a path, and forward slashes: UNO_JAVA_JFW_JREHOME is taken
-        # as-is (unlike ENV_JREHOME, which goes through
-        # getFileURLFromSystemPath), and every rtl::Bootstrap value is macro-
-        # expanded, where a backslash is an ESCAPE character — "C:\Program"
-        # would come back "C:Program".  Spaces must be %20-encoded for osl's
-        # file URL parsing.
-        #
-        # TODO: machine-specific, same as //main/bridges test_any_jni's
-        # jvm_path_dirs.  Both want one build setting for "the JRE for this
-        # arch".  Set below, per arch.
-    } | select({
-        "//build:arch_x64": {
-            "UNO_JAVA_JFW_JREHOME":
-                
"file:///C:/Program%20Files/Eclipse%20Adoptium/jdk-8.0.452.9-hotspot",
-        },
-        "//conditions:default": {
-            "UNO_JAVA_JFW_JREHOME":
-                
"file:///C:/Program%20Files%20(x86)/Eclipse%20Adoptium/jdk-8.0.452.9-hotspot",
-        },
-    }),
+        # Put jvmfwk in DIRECT mode with an explicit, arch-matched JRE — see
+        # //build:jre.bzl for why that is a select() and not $JAVA_HOME.
+    } | jre_home_env(),
     uno_install = "//main/staging:install",
 )
diff --git a/main/testtools/BUILD.bazel b/main/testtools/BUILD.bazel
new file mode 100644
index 0000000000..80e71c46a2
--- /dev/null
+++ b/main/testtools/BUILD.bazel
@@ -0,0 +1,420 @@
+package(default_visibility = ["//visibility:public"])
+
+load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
+load("@rules_java//java:defs.bzl", "java_import", "java_library")
+load("//build:jre.bzl", "jre_home_env")
+load("//build/rules:gtest_test.bzl", "staged_run_test")
+load("//build/rules:idl_pipeline.bzl", "idl_library")
+load("//build/rules:java_pipeline.bzl", "jar_from_directory", 
"javamaker_classes", "uno_jar")
+load("//build/rules:merge_rdb.bzl", "merge_rdb")
+load("//main/postprocess:postprocess.bzl", "services_rdb")
+
+# ── testtools / bridgetest ────────────────────────────────────────────────
+# The UNO bridge round-trip suite: every IDL construct the type system has —
+# each simple type, strings, enums, structs, polymorphic structs, sequences,
+# anys, interfaces, attributes, out/inout parameters, exceptions, multiple
+# inheritance, the current context, recursive and sequence-of-calls dispatch —
+# driven through a call chain and checked on the way back.
+#
+# Unlike every other test in this tree it is NOT a GoogleTest binary.  It is
+# three UNO COMPONENTS, and the runner is the generic //main/cpputools uno.exe:
+#
+#   uno -ro uno_services.rdb -ro uno_types.rdb \
+#       -s com.sun.star.test.bridge.BridgeTest -- 
com.sun.star.test.bridge.CppTestObject
+#
+# uno.exe instantiates the service named by -s, casts it to XMain, and calls
+# run() with everything after "--" as arguments.  BridgeTest::run() therefore
+# receives the NAME of the object to test and instantiates it itself, which is
+# what makes one driver reusable across the C++, Java, Python and CLI test
+# objects — only that last argument changes.  Its exit code is the test result,
+# so no gtest wrapper is needed or wanted (source changes are out of scope).
+#
+# This is a self-contained UNO installation, NOT fixture (a): uno.exe's -ro
+# path calls bootstrap_InitialComponentContext(registry), not
+# defaultBootstrap_InitialComponentContext(), so there is no fundamental.ini
+# and no staged office involved.  Everything the service manager needs beyond
+# the two registries below is hardcoded in cppuhelper's
+# bootstrapInitialSF() — ORegistryServiceManager, DLLComponentLoader,
+# SimpleRegistry, NestedRegistry, TypeDescriptionManager and the rest, all
+# loaded out of bootstrap.uno.dll beside the exe.  Hence no uno_install, and
+# hence the test runs in seconds rather than depending on the whole office.
+
+_DEFINES = [
+    "WNT",
+    "GUI",
+    "WIN32",
+    "WINVER=0x0500",
+    "_WIN32_WINNT=0x0500",
+    "_WIN32_IE=0x0500",
+    "FULL_DESK",
+]
+
+_COPTS = [
+    # sal_Unicode is not VS2008's native wchar_t; every UNO string type depends
+    # on the two agreeing.
+    "/Zc:wchar_t-",
+    "/EHsc",
+    "/Imain/testtools/inc/pch",
+]
+
+_DEPS = [
+    "//main/sal:sal_headers",
+    "//main/cppu:cppu_headers",
+    "//main/cppuhelper:cppuhelper_headers",
+    "//main/udkapi:udkapi_idl_headers",
+    # osl/diagnose.hxx (the C++ header, as opposed to diagnose.h) declares an
+    # std::hash_set member, which VS2008's own STL does not have.
+    "//main/stlport:stlport",
+    ":bridgetest_idl_headers",
+]
+
+_LINKER_INPUTS = [
+    "//main/sal:sal_implib",
+    "//main/cppu:cppu3_implib",
+    "//main/cppuhelper:cppuhelper_implib",
+]
+
+_LINKOPTS = [
+    "$(execpath //main/sal:sal_implib)",
+    "$(execpath //main/cppu:cppu3_implib)",
+    "$(execpath //main/cppuhelper:cppuhelper_implib)",
+    "/MANIFEST:NO",
+]
+
+# ── The suite's private IDL ───────────────────────────────────────────────
+# test::testtools::bridgetest — the types actually under test.  It is a
+# deliberately exhaustive vocabulary, which is the whole point: a bridge that
+# mishandles one type class fails here and nowhere else.
+idl_library(
+    name = "bridgetest_idl",
+    srcs = ["source/bridgetest/idl/bridgetest.idl"],
+    include_dirs = ["main/udkapi"],
+    extra_rdbs = ["//main/udkapi:udkapi_idl"],
+    testonly = True,
+)
+
+cc_library(
+    name = "bridgetest_idl_headers",
+    hdrs = [":bridgetest_idl"],
+    includes = ["bridgetest_idl_inc"],
+    testonly = True,
+)
+
+# The type registry uno.exe is given.  dmake copies udkapi.rdb and regmerges
+# bridgetest.rdb into it at "/"; merge_rdb does both in one action.  Both
+# halves are needed — the private types reference com.sun.star.uno.XInterface
+# and friends, and the TypeDescriptionManager resolves them at run time.
+merge_rdb(
+    name = "bridgetest_uno_types",
+    out = "uno_types.rdb",
+    rdbs = [
+        "//main/udkapi:udkapi_idl",
+        ":bridgetest_idl",
+    ],
+    testonly = True,
+)
+
+# ── The three components ──────────────────────────────────────────────────
+# cppobj.uno — the object UNDER test: com.sun.star.test.bridge.CppTestObject,
+# a C++ implementation of XBridgeTest2 (and XMulti, and the current-context
+# checker).  This is what the driver bounces every type off.
+cc_binary(
+    name = "cppobj.uno",
+    srcs = [
+        "source/bridgetest/cppobj.cxx",
+        "source/bridgetest/currentcontextchecker.cxx",
+        "source/bridgetest/currentcontextchecker.hxx",
+        "source/bridgetest/multi.cxx",
+        "source/bridgetest/multi.hxx",
+    ],
+    copts = _COPTS,
+    defines = _DEFINES,
+    linkshared = True,
+    win_def_file = "source/bridgetest/cppobj.uno.def",
+    deps = _DEPS,
+    additional_linker_inputs = _LINKER_INPUTS,
+    linkopts = _LINKOPTS,
+    testonly = True,
+)
+
+# bridgetest.uno — the DRIVER: com.sun.star.test.bridge.BridgeTest, an XMain
+# whose run() performs the round trip and returns 0 on success.  It links its
+# own copies of multi/currentcontextchecker because both sides of the
+# comparison need them (dmake builds two static libs from the same objects).
+cc_binary(
+    name = "bridgetest.uno",
+    srcs = [
+        "source/bridgetest/bridgetest.cxx",
+        "source/bridgetest/currentcontextchecker.cxx",
+        "source/bridgetest/currentcontextchecker.hxx",
+        "source/bridgetest/multi.cxx",
+        "source/bridgetest/multi.hxx",
+    ],
+    copts = _COPTS,
+    defines = _DEFINES,
+    linkshared = True,
+    win_def_file = "source/bridgetest/bridgetest.uno.def",
+    deps = _DEPS,
+    additional_linker_inputs = _LINKER_INPUTS,
+    linkopts = _LINKOPTS,
+    testonly = True,
+)
+
+# constructors.uno — covers IDL service CONSTRUCTORS specifically (the
+# "new-style" services with named constructors and a rest parameter), which
+# the driver exercises through test.testtools.bridgetest.Constructors{,2}.
+cc_binary(
+    name = "constructors.uno",
+    srcs = ["source/bridgetest/constructors.cxx"],
+    copts = _COPTS,
+    defines = _DEFINES,
+    linkshared = True,
+    win_def_file = "source/bridgetest/constructors.uno.def",
+    deps = _DEPS,
+    additional_linker_inputs = _LINKER_INPUTS,
+    linkopts = _LINKOPTS,
+    testonly = True,
+)
+
+# The service registry.  The "./<dll>" URIs are dmake's, verbatim, and they are
+# the right choice rather than the vnd.sun.star.expand: form used elsewhere:
+# stoc's textualservices.cxx resolves a component uri with
+# rtl::Uri::convertRelToAbs() against the URL of the registry FILE, so a
+# relative URI simply means "beside this rdb" and needs no bootstrap variable
+# to point at the staged directory.
+services_rdb(
+    name = "bridgetest_uno_services",
+    components = {
+        "source/bridgetest/bridgetest.component": "./bridgetest.uno.dll",
+        "source/bridgetest/cppobj.component": "./cppobj.uno.dll",
+        "source/bridgetest/constructors.component": "./constructors.uno.dll",
+    },
+    out = "uno_services.rdb",
+    xslt = "//main/solenv/bin:packcomponents.xslt",
+    testonly = True,
+)
+
+# ── The test ──────────────────────────────────────────────────────────────
+# dmake's `runtest` target, which the ordinary build runs unconditionally on
+# every platform whose bridge is believed to work (see the OSX-PPC/Solaris
+# escape hatch in source/bridgetest/makefile.mk).
+#
+# The DLL closure is listed explicitly instead of borrowing the office's via
+# uno_install, because it is small and known: uno.exe links sal/cppu/
+# cppuhelper/salhelper, cppuhelper loads bootstrap.uno.dll from its OWN
+# directory, and bootstrap.uno pulls reg (→ store) and xmlreader.  Co-locating
+# them is correct HERE — the "co-located UNO DLL breaks the bootstrap"
+# landmine is specifically about doing it *alongside* uno_install, where
+# get_this_libpath() would then pick the test dir over program/.
+#
+# The bridge DLL is a pure runtime dependency that nothing links: any cppu
+# Mapping osl_loadModule()s it, and the driver's exception round-trip goes
+# through cppu::getCaughtException(). Unstaged it is an empty test.log.
+staged_run_test(
+    name = "bridgetest",
+    binary = "//main/cpputools:uno",
+    # Bare relative registry names, and the working directory set to the staged
+    # dir — exactly dmake's `cd $(DLLDEST) && uno -ro uno_services.rdb …`.  It
+    # also keeps the relative component URIs above meaningful.
+    run_args = [
+        "-ro",
+        "uno_services.rdb",
+        "-ro",
+        "uno_types.rdb",
+        "-s",
+        "com.sun.star.test.bridge.BridgeTest",
+        "--",
+        "com.sun.star.test.bridge.CppTestObject",
+    ],
+    run_in_staged_dir = True,
+    runtime = [
+        ":bridgetest.uno",
+        ":constructors.uno",
+        ":cppobj.uno",
+        ":bridgetest_uno_services",
+        ":bridgetest_uno_types",
+        "//main/cppu:cppu3",
+        "//main/cppuhelper:cppuhelper3MSC",
+        "//main/external/msvcp90:crt_dlls",
+        "//main/registry:reg",
+        "//main/sal:sal3",
+        "//main/salhelper:salhelper3MSC",
+        "//main/stoc:bootstrap.uno",
+        "//main/store:store",
+        "//main/xmlreader:xmlreader",
+    ] + select({
+        "//build:arch_x64": ["//main/bridges:mscx_uno"],
+        "//conditions:default": ["//main/bridges:msci_uno"],
+    }),
+    size = "small",
+)
+
+# ── The same round trip, through Java ─────────────────────────────────────
+# dmake's `bridgetest_inprocess_java`.  The driver, the assertions and the IDL
+# are all unchanged; only the object on the far side is swapped:
+#
+#   -s com.sun.star.test.bridge.BridgeTest -- 
com.sun.star.test.bridge.JavaTestObject
+#
+# so every type in bridgetest.idl now crosses the java_uno JNI bridge twice
+# (out and back) instead of staying in C++.  That makes this by far the widest
+# exercise of the Java bridge in the tree — cppuhelper/qa/propertysetmixin
+# proved a Java component can be LOADED at all; this one checks that the
+# marshalling is actually correct for every type class.
+#
+# "noCurrentContext" is the second argument the dmake recipe passes, and it is
+# not optional: the Java side has no XCurrentContext implementation to hand
+# back, so the driver skips that one sub-test (bridgetest.cxx run()).
+
+javamaker_classes(
+    name = "bridgetest_java_classes",
+    rdb = ":bridgetest_idl",
+    extra_rdb = "//main/udkapi:udkapi_idl",
+    testonly = True,
+)
+
+jar_from_directory(
+    name = "bridgetest_java_types_jar",
+    classes_dir = ":bridgetest_java_classes",
+    testonly = True,
+)
+
+java_import(
+    name = "bridgetest_java_types",
+    jars = [":bridgetest_java_types_jar"],
+    testonly = True,
+)
+
+# JARFILES in com/sun/star/comp/bridge/makefile.mk is ridl.jar jurt.jar 
juh.jar.
+# ridl covers both com.sun.star.uno.* and the udkapi types the object
+# implements beyond its own IDL — 
com.sun.star.test.performance.XPerformanceTest
+# (udkapi/com/sun/star/test/performance), which TestComponent also implements.
+java_library(
+    name = "bridgetest_testcomponent",
+    srcs = glob(["com/sun/star/comp/bridge/*.java"]),
+    javacopts = ["--release", "8", "-XepDisableAllChecks"],
+    deps = [
+        ":bridgetest_java_types",
+        "//main/javaunohelper:juh_jar",
+        "//main/jurt:jurt",
+        "//main/ridljar:ridl",
+    ],
+    testonly = True,
+)
+
+# Both class trees in one jar, as JARCLASSDIRS = $(PACKAGE) test/testtools/
+# bridgetest does.  RegistrationClassName is copied from the checked-in
+# com/sun/star/comp/bridge/manifest — it is how javaloader finds the class to
+# register, so it has to be a main manifest attribute, which is what uno_jar is
+# for (a plain java_library cannot express it).
+uno_jar(
+    name = "bridgetest_testcomponent_jar",
+    out = "testComponent.jar",
+    jars = [
+        ":bridgetest_testcomponent",
+        ":bridgetest_java_types_jar",
+    ],
+    manifest_lines = [
+        "RegistrationClassName: com.sun.star.comp.bridge.TestComponent",
+    ],
+    testonly = True,
+)
+
+# Only the test's OWN components.  The Java run additionally needs the two
+# halves of com.sun.star.loader.Java2 — javavm.uno (locates and starts a JVM
+# through jvmfwk) and javaloader.uno (builds a class loader over the jar and
+# calls its RegistrationClassName) — and those come, as in dmake, from a THIRD
+# registry: the installation's own services.rdb, nested in below.
+#
+# Registering them here instead does not work, and the reason is worth keeping:
+# javaloader resolves the component URL through
+# com.sun.star.uri.UriReferenceFactory, which is itself a URE component (stoc's
+# uriproc).  Naming the loaders without the registry that provides everything
+# they in turn need just moves the failure one service along.
+services_rdb(
+    name = "bridgetest_uno_services_java",
+    components = {
+        "source/bridgetest/bridgetest.component": "./bridgetest.uno.dll",
+        "source/bridgetest/cppobj.component": "./cppobj.uno.dll",
+        "source/bridgetest/constructors.component": "./constructors.uno.dll",
+        "source/bridgetest/testComponent.component": "./testComponent.jar",
+    },
+    out = "uno_services_java.rdb",
+    xslt = "//main/solenv/bin:packcomponents.xslt",
+    testonly = True,
+)
+
+# uno_install, unlike the C++ sibling — and here it earns its keep for the DATA
+# rather than the DLLs.  The Java2 loader's whole configuration lives in the
+# staged program/: URE_INTERNAL_JAVA_DIR (the five jars javavm.cxx opens by
+# HARDCODED NAME, starting with unoloader.jar), URE_MORE_JAVA_TYPES,
+# URE_INTERNAL_JAVA_CLASSPATH and URE_OVERRIDE_JAVA_JFW_{SHARED,USER}_DATA are
+# all keys in program/fundamental.ini, and jvmfwk.dll finds javavendors.xml,
+# jvmfwk3.ini, sunjavaplugin.dll and JREProperties.class beside itself there.
+# Pointing URE_BOOTSTRAP at that one ini supplies the lot, with no list to keep
+# in sync here.  It is also why the two loader components above use
+# $URE_INTERNAL_LIB_DIR rather than the "./" form: they come from program/.
+staged_run_test(
+    name = "bridgetest_java",
+    binary = "//main/cpputools:uno",
+    run_args = [
+        # dmake's third registry ($(SOLARXMLDIR)/ure/services.rdb, copied in as
+        # services.rdb).  Given as a file:/// URL so unoexe's convertToFileUrl
+        # passes it through untouched instead of going via
+        # getFileURLFromSystemPath.
+        "-ro",
+        "file:///$(PROGRAM_URL)/services.rdb",
+        "-ro",
+        "uno_services_java.rdb",
+        "-ro",
+        "uno_types.rdb",
+        "-s",
+        "com.sun.star.test.bridge.BridgeTest",
+        "--",
+        "com.sun.star.test.bridge.JavaTestObject",
+        "noCurrentContext",
+    ],
+    # Keeps the cwd on the staged dir (not program/), so the bare registry
+    # names above and the "./" component URIs still resolve.
+    run_in_staged_dir = True,
+    # ONLY the test-only artifacts — the exact INVERSE of the C++ sibling, and
+    # the "co-located UNO DLL breaks the bootstrap" landmine is why.  Its
+    # mechanism is precise: cppu::get_unorc() (cppuhelper/source/bootstrap.cxx)
+    # opens uno.ini at get_this_libpath() + "/uno.ini", i.e. beside
+    # cppuhelper3MSC.dll, and uno.ini is where URE_INTERNAL_LIB_DIR is defined 
—
+    # fundamental.ini does not define it.  Every vnd.sun.star.expand: URI in 
the
+    # tree goes through that handle (cppu::bootstrap_expandUri →
+    # cppuhelper::detail::expandMacros).  Co-locate cppuhelper3MSC.dll and the
+    # exe's own directory wins the loader search, so the lookup lands in the
+    # test dir, finds no uno.ini, and every such macro silently expands to
+    # nothing.  Here that surfaced as jvmfwk reporting
+    #   The file: vnd.sun.star.expand:$URE_INTERNAL_LIB_DIR/sunjavaplugin.dll
+    #   does not exist
+    # and then the catch-all "The JRE … could not be recognized".  Leave the
+    # core stack to program/ via PATH and it resolves.
+    runtime = [
+        ":bridgetest.uno",
+        ":constructors.uno",
+        ":cppobj.uno",
+        ":bridgetest_testcomponent_jar",
+        ":bridgetest_uno_services_java",
+        ":bridgetest_uno_types",
+        "//main/external/msvcp90:crt_dlls",
+    ],
+    env = {} | jre_home_env(),
+    uno_install = "//main/staging:install",
+    # Starting a JVM sounds like it should need "medium", but it does not: this
+    # is jvmfwk DIRECT mode over a tiny classpath, measured at ~1.4s, and
+    # //main/cppuhelper:cppuhelper_qa_propertysetmixin runs "small" for the 
same
+    # reason.  Only office_connection (a real soffice boot) needs "medium".
+    size = "small",
+)
+
+# Both halves of the round trip: the same driver and the same assertions, once
+# against a C++ object and once against a Java one.
+test_suite(
+    name = "bridgetest_tests",
+    tests = [
+        ":bridgetest",
+        ":bridgetest_java",
+    ],
+)
diff --git a/main/testtools/readme.md b/main/testtools/readme.md
new file mode 100644
index 0000000000..23953ac06d
--- /dev/null
+++ b/main/testtools/readme.md
@@ -0,0 +1,183 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+# Notes for testtools (bridgetest: C++ and Java green)
+
+`bridgetest` is the UNO bridge round-trip suite: every construct the type
+system has — each simple type, strings, enums, structs, polymorphic structs,
+sequences, anys, interfaces, attributes, out/inout parameters, exceptions,
+multiple inheritance, the current context, recursive and sequence-of-calls
+dispatch — pushed through a call chain and checked coming back.
+
+Two targets, one driver:
+
+| target | object under test | fixture | time |
+| --- | --- | --- | --- |
+| `//main/testtools:bridgetest` | `CppTestObject` (C++) | self-contained | 
~1.1 s |
+| `//main/testtools:bridgetest_java` | `JavaTestObject` (Java) | `uno_install` 
| ~1.4 s |
+
+`//main/testtools:bridgetest_tests` runs both.
+
+## It is not a GoogleTest, and should not be made into one
+
+Every other test in this tree is a gtest binary. This one is three UNO
+*components*, run by the generic `//main/cpputools` `uno.exe`:
+
+```
+uno -ro uno_services.rdb -ro uno_types.rdb \
+    -s com.sun.star.test.bridge.BridgeTest -- 
com.sun.star.test.bridge.CppTestObject
+```
+
+`uno.exe` instantiates the service named by `-s`, queries `XMain`, and calls
+`run()` with everything after `--`. So the driver receives the *name* of the
+object to test and instantiates it itself — which is exactly what lets one
+driver serve the C++, Java, Python and CLI test objects. Only that last
+argument changes between the two targets above. `run()`'s return value is the
+process exit code, so the pass/fail signal needs no wrapper, and wrapping it
+would mean changing source, which is out of scope.
+
+This is what `run_args` on `staged_run_test` was added for
+(`build/rules/gtest_test.bzl`): a fixed command line baked into the launcher
+and token-expanded like `env`, so the "test binary" can be a generic tool that
+a suite selects behaviour from. Anything passed on the `bazel test` command
+line still follows it via `%*`.
+
+## The C++ target is a fourth fixture kind
+
+Not fixture (a): `uno.exe`'s `-ro` path calls
+`bootstrap_InitialComponentContext(registry)`, **not**
+`defaultBootstrap_InitialComponentContext()`. There is no `fundamental.ini`, no
+`URE_BOOTSTRAP`, and no staged office — hence no `uno_install`, and hence a 
test
+that runs in about a second. Everything the service manager needs beyond the 
two
+registries is hardcoded in cppuhelper's `bootstrapInitialSF()`
+(`ORegistryServiceManager`, `DLLComponentLoader`, `SimpleRegistry`,
+`NestedRegistry`, `TypeDescriptionManager`, …), all loaded out of
+`bootstrap.uno.dll` beside the exe.
+
+Two consequences worth knowing before adding another registry-bootstrap test:
+
+- **The textual (XML) registry works here**, unlike in `configmgr/qa/unit`.
+  `openRegistry()` passes `(bReadOnly=true, bCreate=false)`, and
+  `SimpleRegistry::open()`'s textual branch requires exactly
+  `bReadOnly && !bCreate`. configmgr's suite is red because it goes through the
+  one-argument `createRegistryServiceFactory` overload, which defaults
+  `bReadOnly=false`. Same class of registry, opposite outcome, decided by two
+  booleans.
+- **Relative component URIs are the right choice**, not
+  `vnd.sun.star.expand:`. stoc's `textualservices.cxx` resolves a component
+  `uri` with `rtl::Uri::convertRelToAbs()` against the URL of the registry
+  *file*, so dmake's `./cppobj.uno.dll` just means "beside this rdb" and needs
+  no bootstrap variable pointing at the staged directory. That is why the C++
+  target sets no `env` at all.
+
+## The Java target, and the landmine that inverts the DLL rule
+
+`bridgetest_java` swaps in `com.sun.star.test.bridge.JavaTestObject` from
+`testComponent.jar`, so every type in `bridgetest.idl` now crosses the
+`java_uno` JNI bridge twice. `cppuhelper/qa/propertysetmixin` proved a Java UNO
+component can be *loaded*; this is the first thing to check that the
+marshalling is correct across the whole type vocabulary.
+
+`noCurrentContext` is the second argument dmake passes and it is not optional —
+the Java side has no `XCurrentContextChecker` to hand back, so the driver skips
+that sub-test.
+
+Three things differ from the C++ target, and each cost a debugging round:
+
+**1. `$URE_INTERNAL_LIB_DIR` is not in `fundamental.ini`.** Registering the
+Java2 loader halves with that macro yields the amputated
+`loading component library failed: /javaloader.uno.dll` — an undefined
+bootstrap macro expands to nothing rather than failing. The tree's convention
+is `$OOO_BASE_DIR/program/…` (`basis_native()`), and that macro *is* defined.
+
+**2. Co-locating the core UNO DLLs breaks the bootstrap — and the mechanism is
+`uno.ini`, not just `bootstrap.uno.dll`.** The existing note about
+`get_this_libpath()` covers only half of it. `cppu::get_unorc()`
+(`cppuhelper/source/bootstrap.cxx`) opens
+
+```
+get_this_libpath() + "/" + SAL_CONFIGFILE("uno")
+```
+
+that is, `uno.ini` **beside `cppuhelper3MSC.dll`** — and `uno.ini` is where
+`URE_INTERNAL_LIB_DIR` is defined. *Every* `vnd.sun.star.expand:` URI in the
+tree resolves through that one handle (`cppu::bootstrap_expandUri` →
+`cppuhelper::detail::expandMacros`). Stage `cppuhelper3MSC.dll` next to the exe
+and the exe's own directory wins the loader search, so the lookup lands in the
+test directory, finds no `uno.ini`, and every such macro silently expands to
+nothing. Here it surfaced two layers away, as
+
+```
+[Java framework] The file: 
vnd.sun.star.expand:$URE_INTERNAL_LIB_DIR/sunjavaplugin.dll does not exist.
+[Java framework] The JRE specified by … could not be recognized.
+```
+
+So with `uno_install`, `runtime` must list only genuinely test-only files. The
+C++ target lists the whole core stack and the Java one lists none — the
+opposite of the usual advice, and correct in both cases.
+
+**3. The third registry is not optional.** dmake adds
+`$(SOLARXMLDIR)/ure/services.rdb` and it is tempting to replace that with just
+the two Java2-loader components. That does not work: `javaloader` resolves the
+component URL through `com.sun.star.uri.UriReferenceFactory`, itself a URE
+component (stoc's `uriproc`), so naming the loaders without the registry
+providing what *they* need only moves the failure one service along. The
+installation's `program/services.rdb` is nested in as a `file:///` URL, which
+`unoexe`'s `convertToFileUrl` passes through untouched.
+
+`uno_install` here earns its keep for the **data**, not the DLLs: the Java2
+loader's entire configuration (`URE_INTERNAL_JAVA_DIR` and the five jars
+`javavm.cxx` opens by hardcoded name, `URE_MORE_JAVA_TYPES`,
+`URE_INTERNAL_JAVA_CLASSPATH`, `URE_OVERRIDE_JAVA_JFW_{SHARED,USER}_DATA`) is
+keys in `program/fundamental.ini`, and `jvmfwk.dll` finds `javavendors.xml`,
+`jvmfwk3.ini`, `sunjavaplugin.dll` and `JREProperties.class` beside itself
+there. One `URE_BOOTSTRAP` supplies the lot with no list to keep in sync.
+
+## Build notes
+
+- `/Zc:wchar_t-` throughout — `sal_Unicode` is not VS2008's native `wchar_t`.
+- `//main/stlport:stlport` — `osl/diagnose.hxx` (the C++ header, unlike
+  `diagnose.h`) declares an `std::hash_set` member.
+- Each component DLL exports **two** functions, not the usual three: none of
+  the three sources defines `component_canUnload`, so the `.def` files
+  converted from `solenv/src/component.map` list only
+  `component_getImplementationEnvironment` and `component_getFactory`.
+- `bridgetest.uno` and `cppobj.uno` each compile their own copy of
+  `multi.cxx` / `currentcontextchecker.cxx`; dmake builds two static libs from
+  the same objects for the same reason.
+- The JRE for the Java target comes from `//build:jre.bzl`, shared with
+  `cppuhelper/qa/propertysetmixin`. It is machine-specific and arch-selected —
+  the test loads `jvm.dll` into its own process, so a 32-bit build needs a
+  32-bit JRE and `$JAVA_HOME` cannot answer for both arches.
+
+## Not migrated
+
+- `source/bridgetest/cli` (C#/VB round trip) — blocked on the `cli_ure`
+  bucket's C# and C++/CLI toolchains.
+- `source/bridgetest/pyuno` — the Python variant of the same driver; reachable
+  now that pyuno is wired, not yet done.
+- `source/performance` (`perftest.uno`) — a benchmark, not a correctness test.
+  Note `TestComponent.java` *does* implement
+  `com.sun.star.test.performance.XPerformanceTest`, whose IDL lives in udkapi,
+  so the Java half of it is already compiled here.
+- `source/cliversioning`, `qa/cli`, `qa/cliversioning` — `cli_ure` bucket.
+- `bridgetest_server` / `bridgetest_client` / `bridgetest_javaserver` — the
+  socket-URP variants of the same driver. They need an acceptor and a second
+  process; the in-process targets cover the marshalling, and URP itself is
+  covered by `//main/binaryurp` and `//main/test:test_qa_officeconnection`.
diff --git a/main/testtools/source/bridgetest/bridgetest.uno.def 
b/main/testtools/source/bridgetest/bridgetest.uno.def
new file mode 100644
index 0000000000..41a0d8d208
--- /dev/null
+++ b/main/testtools/source/bridgetest/bridgetest.uno.def
@@ -0,0 +1,11 @@
+; Windows DEF equivalent of solenv/src/component.map, which
+; source/bridgetest/makefile.mk names as SHL2VERSIONMAP for this library.
+;
+; Two exports, not the usual three: bridgetest.cxx defines
+; component_getImplementationEnvironment and component_getFactory but no
+; component_canUnload, so listing it would be an unresolved-symbol link error.
+LIBRARY        bridgetest.uno.dll
+
+EXPORTS
+       component_getImplementationEnvironment
+       component_getFactory
diff --git a/main/testtools/source/bridgetest/constructors.uno.def 
b/main/testtools/source/bridgetest/constructors.uno.def
new file mode 100644
index 0000000000..b3aacfe1ea
--- /dev/null
+++ b/main/testtools/source/bridgetest/constructors.uno.def
@@ -0,0 +1,11 @@
+; Windows DEF equivalent of solenv/src/component.map, which
+; source/bridgetest/makefile.mk names as SHL3VERSIONMAP for this library.
+;
+; Two exports, not the usual three: constructors.cxx defines
+; component_getImplementationEnvironment and component_getFactory but no
+; component_canUnload, so listing it would be an unresolved-symbol link error.
+LIBRARY        constructors.uno.dll
+
+EXPORTS
+       component_getImplementationEnvironment
+       component_getFactory
diff --git a/main/testtools/source/bridgetest/cppobj.uno.def 
b/main/testtools/source/bridgetest/cppobj.uno.def
new file mode 100644
index 0000000000..6f1a5b1a76
--- /dev/null
+++ b/main/testtools/source/bridgetest/cppobj.uno.def
@@ -0,0 +1,11 @@
+; Windows DEF equivalent of solenv/src/component.map, which
+; source/bridgetest/makefile.mk names as SHL1VERSIONMAP for this library.
+;
+; Two exports, not the usual three: cppobj.cxx defines
+; component_getImplementationEnvironment and component_getFactory but no
+; component_canUnload, so listing it would be an unresolved-symbol link error.
+LIBRARY        cppobj.uno.dll
+
+EXPORTS
+       component_getImplementationEnvironment
+       component_getFactory

Reply via email to