Add Windows support to cc_shared_library

Disables tests for preloaded_deps for now which aren't passing on Windows.

PiperOrigin-RevId: 421813122
diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml
index 90e2bdd..845c7b5 100644
--- a/.bazelci/presubmit.yml
+++ b/.bazelci/presubmit.yml
@@ -26,6 +26,7 @@
     test_targets:
       - "//scripts/..."
       - "//src/java_tools/..."
+      - "//src/main/starlark/tests/builtins_bzl/..."
       - "//src/test/..."
       - "//src/tools/execlog/..."
       - "//src/tools/singlejar/..."
@@ -68,6 +69,7 @@
     test_targets:
       - "//scripts/..."
       - "//src/java_tools/..."
+      - "//src/main/starlark/tests/builtins_bzl/..."
       - "//src/test/..."
       - "//src/tools/execlog/..."
       - "//src/tools/singlejar/..."
@@ -130,6 +132,7 @@
     test_targets:
       - "//scripts/..."
       - "//src/java_tools/..."
+      - "//src/main/starlark/tests/builtins_bzl/..."
       - "//src/test/..."
       - "//src/tools/execlog/..."
       - "//src/tools/singlejar/..."
@@ -166,6 +169,7 @@
       - "--test_env=REMOTE_NETWORK_ADDRESS=bazel.build:80"
     test_targets:
       - "//scripts/..."
+      - "//src/main/starlark/tests/builtins_bzl/..."
       - "//src/test/..."
       - "//src/tools/execlog/..."
       - "//src/tools/singlejar/..."
@@ -203,6 +207,7 @@
       - "--test_env=TEST_REPOSITORY_HOME=$OUTPUT_BASE/external"
     test_targets:
       - "//src:embedded_tools_size_test"
+      - "//src/main/starlark/tests/builtins_bzl/..."
       - "//src/test/cpp/..."
       - "//src/test/java/com/google/devtools/build/android/..."
       - "//src/test/java/com/google/devtools/build/lib/..."
@@ -269,6 +274,7 @@
     test_targets:
       - "//scripts/..."
       - "//src/java_tools/..."
+      - "//src/main/starlark/tests/builtins_bzl/..."
       - "//src/test/..."
       - "//src/tools/execlog/..."
       - "//src/tools/singlejar/..."
diff --git a/src/main/starlark/builtins_bzl/common/cc/experimental_cc_shared_library.bzl b/src/main/starlark/builtins_bzl/common/cc/experimental_cc_shared_library.bzl
index c78aebd..8adfc47 100644
--- a/src/main/starlark/builtins_bzl/common/cc/experimental_cc_shared_library.bzl
+++ b/src/main/starlark/builtins_bzl/common/cc/experimental_cc_shared_library.bzl
@@ -20,7 +20,7 @@
 """
 
 load(":common/cc/cc_helper.bzl", "cc_helper")
-load(":common/objc/semantics.bzl", "semantics")
+load(":common/cc/semantics.bzl", "semantics")
 
 CcInfo = _builtins.toplevel.CcInfo
 cc_common = _builtins.toplevel.cc_common
@@ -161,7 +161,9 @@
             feature_configuration = feature_configuration,
             cc_toolchain = cc_toolchain,
             static_library = old_library_to_link.static_library,
+            objects = old_library_to_link.objects,
             pic_static_library = old_library_to_link.pic_static_library,
+            pic_objects = old_library_to_link.pic_objects,
             alwayslink = True,
         )
         new_libraries_to_link.append(new_library_to_link)
@@ -377,7 +379,10 @@
     feature_configuration = cc_common.configure_features(
         ctx = ctx,
         cc_toolchain = cc_toolchain,
-        requested_features = ctx.features,
+        # This features enables behavior which creates a def file automatically
+        # for exporting all the symbols in a shared libary on Windows. If a
+        # custom def file is passed, this behavior doesn't apply.
+        requested_features = ctx.features + ["windows_export_all_symbols"],
         unsupported_features = ctx.disabled_features,
     )
 
@@ -431,9 +436,28 @@
     debug_files.append(exports_debug_file)
     debug_files.append(link_once_static_libs_debug_file)
 
+    win_def_file = None
+    if cc_common.is_enabled(feature_configuration = feature_configuration, feature_name = "targets_windows"):
+        object_files = []
+        for linker_input in linking_context.linker_inputs.to_list():
+            for library in linker_input.libraries:
+                if library.pic_static_library != None:
+                    if library.pic_objects != None:
+                        object_files.extend(library.pic_objects)
+                elif library.static_library != None:
+                    if library.objects != None:
+                        object_files.extend(library.objects)
+
+        def_parser = ctx.file._def_parser
+
+        generated_def_file = None
+        if def_parser != None:
+            generated_def_file = _generate_def_file(ctx, def_parser, object_files, ctx.label.name)
+        custom_win_def_file = ctx.file.win_def_file
+        win_def_file = _get_windows_def_file_for_linking(ctx, custom_win_def_file, generated_def_file, feature_configuration)
+
     additional_inputs = []
     additional_inputs.extend(ctx.files.additional_linker_inputs)
-
     linking_outputs = cc_common.link(
         actions = ctx.actions,
         feature_configuration = feature_configuration,
@@ -444,10 +468,15 @@
         name = ctx.label.name,
         output_type = "dynamic_library",
         main_output = main_output,
+        win_def_file = win_def_file,
     )
 
+    runfiles_files = []
+    if linking_outputs.library_to_link.resolved_symlink_dynamic_library != None:
+        runfiles_files.append(linking_outputs.library_to_link.resolved_symlink_dynamic_library)
+    runfiles_files.append(linking_outputs.library_to_link.dynamic_library)
     runfiles = ctx.runfiles(
-        files = [linking_outputs.library_to_link.resolved_symlink_dynamic_library, linking_outputs.library_to_link.dynamic_library],
+        files = runfiles_files,
     )
     transitive_debug_files = []
     for dep in ctx.attr.dynamic_deps:
@@ -487,6 +516,45 @@
         ),
     ]
 
+def _gen_empty_def_file(ctx):
+    trivial_def_file = ctx.actions.declare_file(ctx.label.name + ".gen.empty.def")
+    ctx.actions.write(trivial_def_file, "", False)
+    return trivial_def_file
+
+def _get_windows_def_file_for_linking(ctx, custom_def_file, generated_def_file, feature_configuration):
+    # 1. If a custom DEF file is specified in win_def_file attribute, use it.
+    # 2. If a generated DEF file is available and should be used, use it.
+    # 3. Otherwise, we use an empty DEF file to ensure the import library will be generated.
+    if custom_def_file != None:
+        return custom_def_file
+    elif generated_def_file != None and _should_generate_def_file(ctx, feature_configuration) == True:
+        return generated_def_file
+    else:
+        return _gen_empty_def_file(ctx)
+
+def _should_generate_def_file(ctx, feature_configuration):
+    windows_export_all_symbols_enabled = cc_common.is_enabled(feature_configuration = feature_configuration, feature_name = "windows_export_all_symbols")
+    no_windows_export_all_symbols_enabled = cc_common.is_enabled(feature_configuration = feature_configuration, feature_name = "no_windows_export_all_symbols")
+    return windows_export_all_symbols_enabled and (not no_windows_export_all_symbols_enabled) and (ctx.attr.win_def_file == None)
+
+def _generate_def_file(ctx, def_parser, object_files, dll_name):
+    def_file = ctx.actions.declare_file(ctx.label.name + ".gen.def")
+    argv = ctx.actions.args()
+    argv.add(def_file)
+    argv.add(dll_name)
+    for object_file in object_files:
+        argv.add(object_file.path)
+
+    ctx.actions.run(
+        mnemonic = "DefParser",
+        executable = def_parser,
+        arguments = [argv],
+        inputs = object_files,
+        outputs = [def_file],
+        use_default_shell_env = True,
+    )
+    return def_file
+
 def _graph_structure_aspect_impl(target, ctx):
     children = []
 
@@ -543,9 +611,11 @@
         "exports_filter": attr.string_list(),
         "permissions": attr.label_list(providers = [CcSharedLibraryPermissionsInfo]),
         "preloaded_deps": attr.label_list(providers = [CcInfo]),
+        "win_def_file": attr.label(allow_single_file = [".def"]),
         "roots": attr.label_list(providers = [CcInfo], aspects = [graph_structure_aspect]),
         "static_deps": attr.string_list(),
         "user_link_flags": attr.string_list(),
+        "_def_parser": semantics.get_def_parser(),
         "_cc_toolchain": attr.label(default = "@" + semantics.get_repo() + "//tools/cpp:current_cc_toolchain"),
     },
     toolchains = ["@" + semantics.get_repo() + "//tools/cpp:toolchain_type"],  # copybara-use-repo-external-label
diff --git a/src/main/starlark/builtins_bzl/common/cc/semantics.bzl b/src/main/starlark/builtins_bzl/common/cc/semantics.bzl
index 11b0199..62f33cc 100644
--- a/src/main/starlark/builtins_bzl/common/cc/semantics.bzl
+++ b/src/main/starlark/builtins_bzl/common/cc/semantics.bzl
@@ -13,7 +13,6 @@
 # limitations under the License.
 
 """Semantics for Bazel cc rules"""
-load(":common/cc/experimental_cc_shared_library.bzl", "CcSharedLibraryInfo")
 
 def _create_cc_launcher_info(cc_info, cc_compilation_outputs):
     return None
@@ -27,14 +26,11 @@
 def _determine_headers_checking_mode(ctx):
     return "strict"
 
-def _get_cc_shared_library_info(dep):
-    return dep[CcSharedLibraryInfo]
-
 def _get_semantics():
     return _builtins.internal.bazel_cc_internal.semantics
 
 def _get_repo():
-    return ""
+    return "bazel_tools"
 
 def _additional_fragments():
     return []
@@ -49,6 +45,13 @@
 def _get_loose_mode_in_hdrs_check_allowed_attr():
     return {}
 
+def _get_def_parser():
+    return attr.label(
+            default = "@bazel_tools//tools/def_parser:def_parser",
+            allow_single_file = True,
+            cfg = "exec",
+    )
+
 semantics = struct(
     ALLOWED_RULES_IN_DEPS = [
         "cc_library",
@@ -65,7 +68,6 @@
     validate_deps = _validate_deps,
     validate_attributes = _validate_attributes,
     determine_headers_checking_mode = _determine_headers_checking_mode,
-    get_cc_shared_library_info = _get_cc_shared_library_info,
     create_cc_launcher_info = _create_cc_launcher_info,
     get_semantics = _get_semantics,
     get_repo = _get_repo,
@@ -73,4 +75,5 @@
     get_distribs_attr = _get_distribs_attr,
     get_licenses_attr = _get_licenses_attr,
     get_loose_mode_in_hdrs_check_allowed_attr = _get_loose_mode_in_hdrs_check_allowed_attr,
+    get_def_parser = _get_def_parser,
 )
diff --git a/src/main/starlark/tests/builtins_bzl/BUILD b/src/main/starlark/tests/builtins_bzl/BUILD
index c9750ad..f5a6115 100644
--- a/src/main/starlark/tests/builtins_bzl/BUILD
+++ b/src/main/starlark/tests/builtins_bzl/BUILD
@@ -21,8 +21,8 @@
         ":builtin_test_setup",
         ":cc_builtin_test_files",
         "//src/test/shell/bazel:test-deps",
+        "@bazel_tools//tools/bash/runfiles",
     ],
-    tags = ["no_windows"],
 )
 
 sh_library(
diff --git a/src/main/starlark/tests/builtins_bzl/builtin_test_setup.sh b/src/main/starlark/tests/builtins_bzl/builtin_test_setup.sh
index c25f111..d1daa52 100644
--- a/src/main/starlark/tests/builtins_bzl/builtin_test_setup.sh
+++ b/src/main/starlark/tests/builtins_bzl/builtin_test_setup.sh
@@ -20,8 +20,7 @@
 
 function setup_tests() {
   setup_skylib_support
-
-  src="$TEST_SRCDIR/io_bazel/$1"
+  src=$(get_runfiles_dir $1)
   dest="${2:-$1}"
   if [ ! -e "$src" ]; then
     echo "copy_tests() - $src does not exist" 1>&2; exit 1
@@ -37,3 +36,12 @@
     mv $file ${file%%.builtin_test}
   done
 }
+
+function get_runfiles_dir() {
+  src="$TEST_SRCDIR/io_bazel/$1"
+  if [ -e "$src" ]; then
+      echo $src
+  elif [[ -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
+      echo $(grep -m1 "io_bazel/$1" "${RUNFILES_MANIFEST_FILE}" | cut -d' ' -f2 | sed "s|$1.*|$1|")
+  fi
+}
\ No newline at end of file
diff --git a/src/main/starlark/tests/builtins_bzl/cc/cc_shared_library/test_cc_shared_library/BUILD.builtin_test b/src/main/starlark/tests/builtins_bzl/cc/cc_shared_library/test_cc_shared_library/BUILD.builtin_test
index 0203888..03169ea 100644
--- a/src/main/starlark/tests/builtins_bzl/cc/cc_shared_library/test_cc_shared_library/BUILD.builtin_test
+++ b/src/main/starlark/tests/builtins_bzl/cc/cc_shared_library/test_cc_shared_library/BUILD.builtin_test
@@ -65,10 +65,12 @@
 
 cc_shared_library(
     name = "foo_so",
-    additional_linker_inputs = [
+    additional_linker_inputs = select({
+      "//src/conditions:linux": [
         ":foo.lds",
         ":additional_script.txt",
-    ],
+      ],
+      "//conditions:default": []}),
     dynamic_deps = ["bar_so"],
     preloaded_deps = ["preloaded_dep"],
     roots = [
@@ -81,11 +83,13 @@
         "//src/main/starlark/tests/builtins_bzl/cc/cc_shared_library/test_cc_shared_library:qux2",
         "//src/main/starlark/tests/builtins_bzl/cc/cc_shared_library/test_cc_shared_library:prebuilt",
     ],
-    user_link_flags = [
+    user_link_flags = select({
+      "//src/conditions:linux": [
         "-Wl,-rpath,kittens",
         "-Wl,--version-script=$(location :foo.lds)",
         "-Wl,--script=$(location :additional_script.txt)",
-    ],
+      ],
+      "//conditions:default": []}),
 )
 
 cc_library(
@@ -98,6 +102,10 @@
     name = "foo",
     srcs = ["foo.cc"],
     hdrs = ["foo.h"],
+    defines = select({
+      "//src/conditions:linux": ["IS_LINUX"],
+      "//conditions:default": [],
+    }),
     deps = [
         "preloaded_dep",
         "bar",
@@ -144,9 +152,9 @@
 
 cc_shared_library(
     name = "bar_so",
-    additional_linker_inputs = [
-        ":bar.lds",
-    ],
+    additional_linker_inputs = select({
+      "//src/conditions:linux": [":bar.lds",],
+      "//conditions:default": []}),
     exports_filter = [
         "bar3",  # Exported transitive dependency
         "//src/main/starlark/tests/builtins_bzl/cc/cc_shared_library/test_cc_shared_library3:bar",
@@ -166,9 +174,12 @@
         "@test_repo//:bar",
         "//src/main/starlark/tests/builtins_bzl/cc/cc_shared_library/test_cc_shared_library:qux2",
     ],
-    user_link_flags = [
+    user_link_flags = select({
+      "//src/conditions:linux": [
         "-Wl,--version-script=$(location :bar.lds)",
-    ],
+      ],
+      "//conditions:default": [],
+    }),
 )
 
 cc_library(
@@ -212,6 +223,10 @@
     srcs = [
         "cc_shared_library_integration_test.sh",
     ],
+    args = select({
+        "//src/conditions:linux": ["linux"],
+        "//conditions:default": ["non_linux"],
+    }),
     data = [
         "testenv.sh",
         ":bar_so",
@@ -219,7 +234,12 @@
         ":cc_test",
         ":debug_files",
         ":foo_so",
-    ],
+    ] +  select({
+        ":is_bazel": [
+           "@bazel_tools//tools/bash/runfiles",
+        ],
+        "//conditions:default": [
+        ],})
 )
 
 filegroup(
@@ -231,11 +251,19 @@
 linking_suffix_test(
     name = "linking_action_test",
     target_under_test = ":foo_so",
+    # TODO(bazel-team): Support this test on Windows and Mac.
+    is_linux = select({
+        "//src/conditions:linux": True,
+        "//conditions:default": False}),
 )
 
 additional_inputs_test(
     name = "additional_inputs_test",
     target_under_test = ":foo_so",
+    # TODO(bazel-team): Support this test on Windows and Mac.
+    is_linux = select({
+        "//src/conditions:linux": True,
+        "//conditions:default": False}),
 )
 
 build_failure_test(
@@ -266,13 +294,6 @@
     srcs = [":just_main_output"],
 )
 
-genrule(
-    name = "check_file_named_correctly",
-    srcs = ["just_main_output"],
-    outs = ["direct_so_file_copy.so"],
-    cmd = "cp $$(dirname $(location :just_main_output))/direct_so_file.so $@",
-)
-
 filegroup(
     name = "just_main_output",
     srcs = ["direct_so_file"],
@@ -284,7 +305,27 @@
     roots = [
         ":direct_so_file_cc_lib",
     ],
-    shared_lib_name = "direct_so_file.so",
+)
+
+genrule(
+    name = "check_file_named_correctly",
+    srcs = ["just_main_output_renamed"],
+    outs = ["renamed_so_file_copy.so"],
+    cmd = "cp $$(dirname $(location :just_main_output_renamed))/renamed_so_file.so $@",
+)
+
+filegroup(
+    name = "just_main_output_renamed",
+    srcs = ["renamed_so_file"],
+    output_group = "main_shared_library_output",
+)
+
+cc_shared_library(
+    name = "renamed_so_file",
+    roots = [
+        ":direct_so_file_cc_lib",
+    ],
+    shared_lib_name = "renamed_so_file.so",
 )
 
 cc_library(
diff --git a/src/main/starlark/tests/builtins_bzl/cc/cc_shared_library/test_cc_shared_library/cc_shared_library_integration_test.sh b/src/main/starlark/tests/builtins_bzl/cc/cc_shared_library/test_cc_shared_library/cc_shared_library_integration_test.sh
index 48788bf..a6b480b 100755
--- a/src/main/starlark/tests/builtins_bzl/cc/cc_shared_library/test_cc_shared_library/cc_shared_library_integration_test.sh
+++ b/src/main/starlark/tests/builtins_bzl/cc/cc_shared_library/test_cc_shared_library/cc_shared_library_integration_test.sh
@@ -15,6 +15,11 @@
 # limitations under the License.
 
 set -euo pipefail
+
+if [[ "$1" = "non_linux" ]]; then
+  exit 0
+fi
+
 CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
 source ${CURRENT_DIR}/testenv.sh
 
diff --git a/src/main/starlark/tests/builtins_bzl/cc/cc_shared_library/test_cc_shared_library/foo.cc b/src/main/starlark/tests/builtins_bzl/cc/cc_shared_library/test_cc_shared_library/foo.cc
index c1c06f0..cd14c25 100644
--- a/src/main/starlark/tests/builtins_bzl/cc/cc_shared_library/test_cc_shared_library/foo.cc
+++ b/src/main/starlark/tests/builtins_bzl/cc/cc_shared_library/test_cc_shared_library/foo.cc
@@ -20,6 +20,8 @@
   bar();
   baz();
   qux();
+#ifdef IS_LINUX
   preloaded_dep();
+#endif
   return 42;
 }
diff --git a/src/main/starlark/tests/builtins_bzl/cc/cc_shared_library/test_cc_shared_library/starlark_tests.bzl b/src/main/starlark/tests/builtins_bzl/cc/cc_shared_library/test_cc_shared_library/starlark_tests.bzl
index 457aed3..9e09906 100644
--- a/src/main/starlark/tests/builtins_bzl/cc/cc_shared_library/test_cc_shared_library/starlark_tests.bzl
+++ b/src/main/starlark/tests/builtins_bzl/cc/cc_shared_library/test_cc_shared_library/starlark_tests.bzl
@@ -44,33 +44,49 @@
 def _linking_suffix_test_impl(ctx):
     env = analysistest.begin(ctx)
 
-    target_under_test = analysistest.target_under_test(env)
-    actions = analysistest.target_actions(env)
+    if ctx.attr.is_linux:
+        target_under_test = analysistest.target_under_test(env)
+        actions = analysistest.target_actions(env)
 
-    args = actions[2].content.split("-Wl,-no-whole-archive")
-    asserts.true(env, "a_suffix" in args[-2].split("\n")[-2], "liba_suffix.a should be the last user library linked")
+        args = actions[2].content.split("\n")
+        user_libs = []
+        for arg in args:
+            if arg.endswith(".o"):
+                user_libs.append(arg)
+        asserts.true(env, user_libs[-1].endswith("a_suffix.pic.o"), "liba_suffix.pic.o should be the last user library linked")
 
     return analysistest.end(env)
 
-linking_suffix_test = analysistest.make(_linking_suffix_test_impl)
+linking_suffix_test = analysistest.make(
+    _linking_suffix_test_impl,
+    attrs = {
+        "is_linux": attr.bool(),
+    },
+)
 
 def _additional_inputs_test_impl(ctx):
     env = analysistest.begin(ctx)
 
-    target_under_test = analysistest.target_under_test(env)
-    actions = analysistest.target_actions(env)
+    if ctx.attr.is_linux:
+        target_under_test = analysistest.target_under_test(env)
+        actions = analysistest.target_actions(env)
 
-    found = False
-    for arg in actions[3].argv:
-        if arg.find("-Wl,--script=") != -1:
-            asserts.equals(env, "src/main/starlark/tests/builtins_bzl/cc/cc_shared_library/test_cc_shared_library/additional_script.txt", arg[13:])
-            found = True
-            break
-    asserts.true(env, found, "Should have seen option --script=")
+        found = False
+        for arg in actions[3].argv:
+            if arg.find("-Wl,--script=") != -1:
+                asserts.equals(env, "src/main/starlark/tests/builtins_bzl/cc/cc_shared_library/test_cc_shared_library/additional_script.txt", arg[13:])
+                found = True
+                break
+        asserts.true(env, found, "Should have seen option --script=")
 
     return analysistest.end(env)
 
-additional_inputs_test = analysistest.make(_additional_inputs_test_impl)
+additional_inputs_test = analysistest.make(
+    _additional_inputs_test_impl,
+    attrs = {
+        "is_linux": attr.bool(),
+    },
+)
 
 def _build_failure_test_impl(ctx):
     env = analysistest.begin(ctx)
diff --git a/src/main/starlark/tests/builtins_bzl/cc_builtin_tests.sh b/src/main/starlark/tests/builtins_bzl/cc_builtin_tests.sh
index 4d539a6..d49953d 100755
--- a/src/main/starlark/tests/builtins_bzl/cc_builtin_tests.sh
+++ b/src/main/starlark/tests/builtins_bzl/cc_builtin_tests.sh
@@ -14,18 +14,47 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# This integration test exists so that we can run our Starlark tests
-# for cc_import with Bazel built from head. Once the Stararlark
-# implementation can rely on release Bazel, we can add the tests directly.
+# --- begin runfiles.bash initialization ---
+set -euo pipefail
+if [[ ! -d "${RUNFILES_DIR:-/dev/null}" && ! -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
+    if [[ -f "$0.runfiles_manifest" ]]; then
+      export RUNFILES_MANIFEST_FILE="$0.runfiles_manifest"
+    elif [[ -f "$0.runfiles/MANIFEST" ]]; then
+      export RUNFILES_MANIFEST_FILE="$0.runfiles/MANIFEST"
+    elif [[ -f "$0.runfiles/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
+      export RUNFILES_DIR="$0.runfiles"
+    fi
+fi
+if [[ -f "${RUNFILES_DIR:-/dev/null}/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
+  source "${RUNFILES_DIR}/bazel_tools/tools/bash/runfiles/runfiles.bash"
+elif [[ -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
+  source "$(grep -m1 "^bazel_tools/tools/bash/runfiles/runfiles.bash " \
+            "$RUNFILES_MANIFEST_FILE" | cut -d ' ' -f 2-)"
+else
+  echo >&2 "ERROR: cannot find @bazel_tools//tools/bash/runfiles:runfiles.bash"
+  exit 1
+fi
+# --- end runfiles.bash initialization ---
 
-CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
-source "${TEST_SRCDIR}/io_bazel/src/test/shell/integration_test_setup.sh" \
+source "$(rlocation "io_bazel/src/test/shell/integration_test_setup.sh")" \
   || { echo "integration_test_setup.sh not found!" >&2; exit 1; }
-source "${CURRENT_DIR}/builtin_test_setup.sh" \
+source "$(rlocation "io_bazel/src/main/starlark/tests/builtins_bzl/builtin_test_setup.sh")" \
   || { echo "builtin_test_setup.sh not found!" >&2; exit 1; }
 
+case "$(uname -s | tr [:upper:] [:lower:])" in
+msys*)
+  # As of 2019-01-15, Bazel on Windows only supports MSYS Bash.
+  declare -r is_windows=true
+  ;;
+*)
+  declare -r is_windows=false
+  ;;
+esac
+
 function test_starlark_cc() {
   setup_tests src/main/starlark/tests/builtins_bzl/cc
+  mkdir -p "src/conditions"
+  cp "$(rlocation "io_bazel/src/conditions/BUILD")" "src/conditions/BUILD"
 
   cat >> WORKSPACE<<EOF
 local_repository(
@@ -33,12 +62,17 @@
     path = "src/main/starlark/tests/builtins_bzl/cc/cc_shared_library/test_cc_shared_library2",
 )
 EOF
+  if "$is_windows"; then
+    START_OPTS='--output_user_root=C:/tmp'
+  else
+    START_OPTS=''
+  fi
 
-  bazel test --define=is_bazel=true --test_output=streamed \
+  bazel $START_OPTS test --define=is_bazel=true --test_output=streamed \
     --experimental_cc_shared_library_debug \
     --experimental_link_static_libraries_once \
     --experimental_enable_target_export_check --experimental_cc_shared_library \
     //src/main/starlark/tests/builtins_bzl/cc/... || fail "expected success"
 }
 
-run_suite "cc_* built starlark test"
+run_suite "cc_* built starlark test"
\ No newline at end of file