Open source cc_import.bzl
This is guarded behind an experimental flag.
RELNOTES:none
PiperOrigin-RevId: 316442624
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java
index b73b009..a59ce1d 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java
@@ -693,6 +693,18 @@
}
@Override
+ public void checkExperimentalStarlarkCcImport(StarlarkActionFactory starlarkActionFactoryApi)
+ throws EvalException {
+ if (!starlarkActionFactoryApi
+ .getActionConstructionContext()
+ .getConfiguration()
+ .getFragment(CppConfiguration.class)
+ .experimentalStarlarkCcImport()) {
+ throw Starlark.errorf("Pass --experimental_starlark_cc_import to use cc_shared_library");
+ }
+ }
+
+ @Override
public CcLinkingContext createCcLinkingInfo(
Object linkerInputs,
Object librariesToLinkObject,
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java
index 2e37154..80e8c229 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java
@@ -729,4 +729,8 @@
public boolean appleGenerateDsym() {
return appleGenerateDsym;
}
+
+ public boolean experimentalStarlarkCcImport() {
+ return cppOptions.experimentalStarlarkCcImport;
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java
index 2cd08c8..56ff203 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java
@@ -961,6 +961,17 @@
help = "Whether to force enable generating debug symbol(.dSYM) file(s) for dbg builds.")
public boolean appleEnableAutoDsymDbg;
+ @Option(
+ name = "experimental_starlark_cc_import",
+ defaultValue = "false",
+ documentationCategory = OptionDocumentationCategory.BUILD_TIME_OPTIMIZATION,
+ effectTags = {
+ OptionEffectTag.LOADING_AND_ANALYSIS,
+ },
+ metadataTags = {OptionMetadataTag.EXPERIMENTAL},
+ help = "If enabled, the Starlark version of cc_import can be used.")
+ public boolean experimentalStarlarkCcImport;
+
/** See {@link #targetLibcTopLabel} documentation. * */
@Override
public FragmentOptions getNormalized() {
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcModuleApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcModuleApi.java
index 612d92fa..b80f83d 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcModuleApi.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcModuleApi.java
@@ -651,6 +651,21 @@
void checkExperimentalCcSharedLibrary(StarlarkThread thread) throws EvalException;
@StarlarkMethod(
+ name = "check_experimental_starlark_cc_import",
+ doc = "DO NOT USE. This is to guard use of cc_import.bzl",
+ documented = false,
+ parameters = {
+ @Param(
+ name = "actions",
+ type = StarlarkActionFactoryApi.class,
+ positional = false,
+ named = true,
+ doc = "<code>actions</code> object."),
+ })
+ void checkExperimentalStarlarkCcImport(StarlarkActionFactoryT starlarkActionFactoryApi)
+ throws EvalException;
+
+ @StarlarkMethod(
name = "create_linking_context",
doc = "Creates a <code>LinkingContext</code>.",
useStarlarkThread = true,
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/FakeCcModule.java b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/FakeCcModule.java
index 8ac2eff..b227c13 100644
--- a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/FakeCcModule.java
+++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/FakeCcModule.java
@@ -183,6 +183,10 @@
public void checkExperimentalCcSharedLibrary(StarlarkThread thread) {}
@Override
+ public void checkExperimentalStarlarkCcImport(
+ StarlarkActionFactoryApi starlarkActionFactoryApi) {}
+
+ @Override
public CcLinkingContextApi<FileApi> createCcLinkingInfo(
Object linkerInputs,
Object librariesToLinkObject,
diff --git a/tools/build_defs/BUILD b/tools/build_defs/BUILD
index e726001..ca1a47f 100644
--- a/tools/build_defs/BUILD
+++ b/tools/build_defs/BUILD
@@ -35,6 +35,7 @@
name = "bzl_srcs",
srcs = [
"//tools/build_defs/cc:action_names.bzl",
+ "//tools/build_defs/cc:cc_import.bzl",
"//tools/build_defs/hash:hash.bzl",
"//tools/build_defs/pkg:bzl_srcs",
"//tools/build_defs/repo:bzl_srcs",
diff --git a/tools/build_defs/cc/cc_import.bzl b/tools/build_defs/cc/cc_import.bzl
new file mode 100644
index 0000000..4b2db01
--- /dev/null
+++ b/tools/build_defs/cc/cc_import.bzl
@@ -0,0 +1,144 @@
+# 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.
+
+"""Starlark implementation of cc_import.
+
+We may change the implementation at any moment or even delete this file. Do not
+rely on this. Pass the flag --experimental_starlark_cc_import
+"""
+
+load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
+
+def _to_list(element):
+ if element == None:
+ return []
+ else:
+ return [element]
+
+def _to_depset(element):
+ if element == None:
+ return depset()
+ else:
+ return depset([element])
+
+def _is_shared_library_extension_valid(shared_library_name):
+ if (shared_library_name.endswith(".so") or
+ shared_library_name.endswith(".dll") or
+ shared_library_name.endswith(".dylib")):
+ return True
+
+ # validate against the regex "^.+\.so(\.\d\w*)+$" for versioned .so files
+ parts = shared_library_name.split(".")
+ extension = parts[1]
+ if extension != "so":
+ return False
+ version_parts = parts[2:]
+ for part in version_parts:
+ if not part[0].isdigit():
+ return False
+ for c in part[1:].elems():
+ if not (c.isalnum() or c == "_"):
+ return False
+ return True
+
+def _perform_error_checks(
+ system_provided,
+ shared_library_artifact,
+ interface_library_artifact):
+ # If the shared library will be provided by system during runtime, users are not supposed to
+ # specify shared_library.
+ if system_provided and shared_library_artifact != None:
+ fail("'shared_library' shouldn't be specified when 'system_provided' is true")
+
+ # If a shared library won't be provided by system during runtime and we are linking the shared
+ # library through interface library, the shared library must be specified.
+ if (not system_provided and shared_library_artifact == None and
+ interface_library_artifact != None):
+ fail("'shared_library' should be specified when 'system_provided' is false")
+
+ if (shared_library_artifact != None and
+ not _is_shared_library_extension_valid(shared_library_artifact.basename)):
+ fail("'shared_library' does not produce any cc_import shared_library files (expected .so, .dylib or .dll)")
+
+def _get_no_pic_and_pic_static_library(static_library):
+ if static_library == None:
+ return (None, None)
+
+ if static_library.extension == ".pic.a":
+ return (None, static_library)
+ else:
+ return (static_library, None)
+
+def _cc_import_impl(ctx):
+ cc_toolchain = find_cpp_toolchain(ctx)
+ cc_common.check_experimental_starlark_cc_import(ctx.actions)
+ feature_configuration = cc_common.configure_features(
+ ctx = ctx,
+ cc_toolchain = cc_toolchain,
+ requested_features = ctx.features,
+ unsupported_features = ctx.disabled_features,
+ )
+
+ _perform_error_checks(
+ ctx.attr.system_provided,
+ ctx.file.shared_library,
+ ctx.file.interface_library,
+ )
+
+ (no_pic_static_library, pic_static_library) = _get_no_pic_and_pic_static_library(
+ ctx.file.static_library,
+ )
+
+ library_to_link = cc_common.create_library_to_link(
+ actions = ctx.actions,
+ feature_configuration = feature_configuration,
+ cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo],
+ static_library = no_pic_static_library,
+ pic_static_library = pic_static_library,
+ dynamic_library = ctx.file.shared_library,
+ interface_library = ctx.file.interface_library,
+ alwayslink = ctx.attr.alwayslink,
+ )
+
+ linking_context = cc_common.create_linking_context(
+ libraries_to_link = [library_to_link],
+ )
+ (compilation_context, compilation_outputs) = cc_common.compile(
+ actions = ctx.actions,
+ feature_configuration = feature_configuration,
+ cc_toolchain = cc_toolchain,
+ public_hdrs = ctx.files.hdrs,
+ name = ctx.label.name,
+ )
+ return [CcInfo(
+ compilation_context = compilation_context,
+ linking_context = linking_context,
+ )]
+
+cc_import = rule(
+ implementation = _cc_import_impl,
+ attrs = {
+ "hdrs": attr.label_list(allow_files = [".h"]),
+ "static_library": attr.label(allow_single_file = [".a", ".lib", ".pic.a"]),
+ "shared_library": attr.label(allow_single_file = True),
+ "interface_library": attr.label(
+ allow_single_file = [".ifso", ".tbd", ".lib", ".so", ".dylib"],
+ ),
+ "system_provided": attr.bool(default = False),
+ "alwayslink": attr.bool(default = False),
+ "_cc_toolchain": attr.label(default = "@bazel_tools//tools/cpp:current_cc_toolchain"),
+ },
+ toolchains = ["@rules_cc//cc:toolchain_type"], # copybara-use-repo-external-label
+ fragments = ["cpp"],
+)