Add linkopts to the Starlark implementation of cc_import

This change allows users to pass custom linking options when using Starlark version of cc_import rule (currently hidden behind '--experimental_starlark_cc_import' flag).

Co-authored-by: @oquenchil

Closes #11623.

PiperOrigin-RevId: 318254987
diff --git a/WORKSPACE b/WORKSPACE
index e0b2516..43991c2 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -1026,3 +1026,6 @@
 
 load("//tools/distributions/debian:deps.bzl", "debian_deps")
 debian_deps()
+
+load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
+bazel_skylib_workspace()
diff --git a/src/test/shell/bazel/BUILD b/src/test/shell/bazel/BUILD
index 4866f1b..14e54dd 100644
--- a/src/test/shell/bazel/BUILD
+++ b/src/test/shell/bazel/BUILD
@@ -880,6 +880,18 @@
 )
 
 sh_test(
+    name = "cc_import_starlark_test",
+    size = "medium",
+    srcs = ["cc_import_starlark_test.sh"],
+    data = [
+        ":test-deps",
+        "//tools/build_defs/cc:cc_import.bzl",
+        "//tools/build_defs/cc/tests:cc_import_tests_files",
+    ],
+    tags = ["no_windows"],
+)
+
+sh_test(
     name = "bazel_docker_sandboxing_test",
     srcs = ["bazel_docker_sandboxing_test.sh"],
     data = [
diff --git a/src/test/shell/bazel/cc_import_starlark_test.sh b/src/test/shell/bazel/cc_import_starlark_test.sh
new file mode 100755
index 0000000..d33eff7
--- /dev/null
+++ b/src/test/shell/bazel/cc_import_starlark_test.sh
@@ -0,0 +1,50 @@
+#!/bin/bash -eu
+#
+# Copyright 2016 The Bazel Authors. All rights reserved.
+#
+# Licensed 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.
+
+# 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.
+
+# Load the test setup defined in the parent directory
+CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+source "${CURRENT_DIR}/../integration_test_setup.sh" \
+  || { echo "integration_test_setup.sh not found!" >&2; exit 1; }
+
+function test_all_starlark_written_tests() {
+  local workspace_name="${FUNCNAME[0]}"
+  mkdir -p "${workspace_name}"
+
+  workspace_dir=$(pwd)/"$workspace_name"
+
+  TEST_FILES_DIR="$RUNFILES_DIR/io_bazel"
+  cd $TEST_FILES_DIR
+  # Using --parents breaks on Mac.
+  mkdir "$workspace_dir/tools"
+  mkdir "$workspace_dir/tools/build_defs"
+  mkdir "$workspace_dir/tools/build_defs/cc"
+  mkdir "$workspace_dir/tools/build_defs/cc/tests"
+  cp "tools/build_defs/cc/BUILD" "$workspace_dir/tools/build_defs/cc/BUILD"
+  cp "tools/build_defs/cc/cc_import.bzl" "$workspace_dir/tools/build_defs/cc/cc_import.bzl"
+  cp -r "tools/build_defs/cc/tests" "$workspace_dir/tools/build_defs/cc/"
+
+  cd "$workspace_dir"
+
+  setup_skylib_support
+
+  bazel test --experimental_starlark_cc_import tools/build_defs/cc/tests:cc_import_tests
+}
+
+run_suite "cc_import_starlark_test"
diff --git a/src/test/shell/integration/loading_phase_test.sh b/src/test/shell/integration/loading_phase_test.sh
index 9c33363..187af8b 100755
--- a/src/test/shell/integration/loading_phase_test.sh
+++ b/src/test/shell/integration/loading_phase_test.sh
@@ -460,7 +460,7 @@
   local -r pkg="${FUNCNAME[0]}"
   mkdir "$pkg" || fail "Could not mkdir $pkg"
   echo "filegroup(name = '$pkg')" > "$pkg/BUILD"
-
+  setup_skylib_support
   # Ensure bazel-<pkg> is created.
   bazel build --symlink_prefix="foo_prefix-" "//$pkg" || fail "build failed"
   [[ -d "foo_prefix-bin" ]] || fail "bazel-bin was not created"
diff --git a/src/test/shell/testenv.sh b/src/test/shell/testenv.sh
index 162cf13..3aa514f 100755
--- a/src/test/shell/testenv.sh
+++ b/src/test/shell/testenv.sh
@@ -468,6 +468,9 @@
     build_file_content = '',
     path='$skylib_root',
 )
+
+load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
+bazel_skylib_workspace()
 EOF
 }
 
diff --git a/tools/build_defs/BUILD b/tools/build_defs/BUILD
index ca1a47f..f46b5ff 100644
--- a/tools/build_defs/BUILD
+++ b/tools/build_defs/BUILD
@@ -6,6 +6,7 @@
         "//tools/build_defs/hash:srcs",
         "//tools/build_defs/pkg:srcs",
         "//tools/build_defs/repo:srcs",
+        "//tools/build_defs/cc/tests:cc_import_tests_files",
     ],
     visibility = ["//tools:__pkg__"],
 )
diff --git a/tools/build_defs/cc/cc_import.bzl b/tools/build_defs/cc/cc_import.bzl
index 4b2db01..9f07da8 100644
--- a/tools/build_defs/cc/cc_import.bzl
+++ b/tools/build_defs/cc/cc_import.bzl
@@ -82,7 +82,10 @@
 
 def _cc_import_impl(ctx):
     cc_toolchain = find_cpp_toolchain(ctx)
-    cc_common.check_experimental_starlark_cc_import(ctx.actions)
+    cc_common.check_experimental_starlark_cc_import(
+        actions = ctx.actions,
+    )
+
     feature_configuration = cc_common.configure_features(
         ctx = ctx,
         cc_toolchain = cc_toolchain,
@@ -113,7 +116,9 @@
 
     linking_context = cc_common.create_linking_context(
         libraries_to_link = [library_to_link],
+        user_link_flags = ctx.attr.linkopts,
     )
+
     (compilation_context, compilation_outputs) = cc_common.compile(
         actions = ctx.actions,
         feature_configuration = feature_configuration,
@@ -121,6 +126,7 @@
         public_hdrs = ctx.files.hdrs,
         name = ctx.label.name,
     )
+
     return [CcInfo(
         compilation_context = compilation_context,
         linking_context = linking_context,
@@ -137,6 +143,7 @@
         ),
         "system_provided": attr.bool(default = False),
         "alwayslink": attr.bool(default = False),
+        "linkopts": attr.string_list(),
         "_cc_toolchain": attr.label(default = "@bazel_tools//tools/cpp:current_cc_toolchain"),
     },
     toolchains = ["@rules_cc//cc:toolchain_type"],  # copybara-use-repo-external-label
diff --git a/tools/build_defs/cc/tests/BUILD b/tools/build_defs/cc/tests/BUILD
new file mode 100644
index 0000000..1808f72
--- /dev/null
+++ b/tools/build_defs/cc/tests/BUILD
@@ -0,0 +1,17 @@
+load(":cc_import_test.bzl", "cc_import_test_suite")
+
+licenses(["notice"])  # Apache 2.0
+
+cc_import_test_suite(
+    name = "cc_import_tests",
+)
+
+filegroup(
+    name = "cc_import_tests_files",
+    srcs = glob(["**"]),
+    visibility = [
+        "//src/test/shell/bazel:__pkg__",
+        "//tools/build_defs:__pkg__",
+        "//tools/build_defs/cc:__pkg__",
+    ],
+)
diff --git a/tools/build_defs/cc/tests/cc_import_test.bzl b/tools/build_defs/cc/tests/cc_import_test.bzl
new file mode 100644
index 0000000..8097c01
--- /dev/null
+++ b/tools/build_defs/cc/tests/cc_import_test.bzl
@@ -0,0 +1,72 @@
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# Licensed 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.
+#
+"""Tests for Starlark implementation of cc_import"""
+
+load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
+load("//tools/build_defs/cc:cc_import.bzl", "cc_import")
+
+TAGS = ["manual", "nobuilder"]
+
+def _cc_import_linkopts_test_impl(ctx):
+    env = analysistest.begin(ctx)
+
+    target_under_test = analysistest.target_under_test(env)
+    actions = analysistest.target_actions(env)
+
+    found = False
+    for action in actions:
+        if action.mnemonic == "CppLink":
+            for arg in action.argv:
+                if arg.find("-testlinkopt") != -1:
+                    found = True
+                    break
+    asserts.true(env, found, "'-testlinkopt' should be included in arguments passed to linked")
+
+    return analysistest.end(env)
+
+cc_import_linkopts_test = analysistest.make(_cc_import_linkopts_test_impl)
+
+def _test_cc_import_linkopts():
+    cc_import(
+        name = "cc_import_linkopts_test_import",
+        linkopts = ["-testlinkopt"],
+        hdrs = ["mylib.h"],
+        static_library = "libmylib.a",
+        tags = TAGS,
+    )
+
+    native.cc_binary(
+        name = "cc_import_linkopts_test_binary",
+        deps = [":cc_import_linkopts_test_import"],
+        srcs = ["source.cc"],
+        tags = TAGS,
+    )
+
+    cc_import_linkopts_test(
+        name = "cc_import_linkopts_test",
+        target_under_test = ":cc_import_linkopts_test_binary",
+        tags = TAGS,
+    )
+
+def cc_import_test_suite(name):
+    _test_cc_import_linkopts()
+
+    native.test_suite(
+        name = name,
+        tests = [
+            ":cc_import_linkopts_test",
+        ],
+        tags = TAGS,
+    )