Fork objc_common.bzl
PiperOrigin-RevId: 791215594
Change-Id: I591ff202781aeea388cc1613f8419a114bd3a206
diff --git a/cc/private/rules_impl/objc_common.bzl b/cc/private/rules_impl/objc_common.bzl
new file mode 100644
index 0000000..682ab7b
--- /dev/null
+++ b/cc/private/rules_impl/objc_common.bzl
@@ -0,0 +1,242 @@
+# 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.
+
+"""Common functionality for Objc rules."""
+
+load("//cc/common:cc_common.bzl", "cc_common")
+load("//cc/common:cc_info.bzl", "CcInfo")
+load(":objc_compilation_context_info.bzl", "ObjcCompilationContextInfo")
+
+_ObjcInfo = apple_common.Objc
+_apple_toolchain = apple_common.apple_toolchain()
+
+CPP_SOURCES = [".cc", ".cpp", ".mm", ".cxx", ".C"]
+NON_CPP_SOURCES = [".m", ".c"]
+ASSEMBLY_SOURCES = [".s", ".S", ".asm"]
+OBJECT_FILE_SOURCES = [".o"]
+HEADERS = [".h", ".inc", ".hpp", ".hh"]
+
+COMPILABLE_SRCS = CPP_SOURCES + NON_CPP_SOURCES + ASSEMBLY_SOURCES
+SRCS = COMPILABLE_SRCS + OBJECT_FILE_SOURCES + HEADERS
+NON_ARC_SRCS = [".m", ".mm"]
+
+ios_cpus = struct(
+ IOS_SIMULATOR_TARGET_CPUS = ["ios_x86_64", "ios_i386", "ios_sim_arm64"],
+ IOS_DEVICE_TARGET_CPUS = ["ios_armv6", "ios_arm64", "ios_armv7", "ios_armv7s", "ios_arm64e"],
+ VISIONOS_SIMULATOR_TARGET_CPUS = ["visionos_sim_arm64"],
+ VISIONOS_DEVICE_TARGET_CPUS = ["visionos_arm64"],
+ WATCHOS_SIMULATOR_TARGET_CPUS = ["watchos_i386", "watchos_x86_64", "watchos_arm64"],
+ WATCHOS_DEVICE_TARGET_CPUS = ["watchos_armv7k", "watchos_arm64_32", "watchos_device_arm64", "watchos_device_arm64e"],
+ TVOS_SIMULATOR_TARGET_CPUS = ["tvos_x86_64", "tvos_sim_arm64"],
+ TVOS_DEVICE_TARGET_CPUS = ["tvos_arm64"],
+ CATALYST_TARGET_CPUS = ["catalyst_x86_64"],
+ MACOS_TARGET_CPUS = ["darwin_x86_64", "darwin_arm64", "darwin_arm64e"],
+)
+
+extensions = struct(
+ CPP_SOURCES = CPP_SOURCES,
+ NON_CPP_SOURCES = NON_CPP_SOURCES,
+ ASSEMBLY_SOURCES = ASSEMBLY_SOURCES,
+ HEADERS = HEADERS,
+ SRCS = SRCS,
+ NON_ARC_SRCS = NON_ARC_SRCS,
+)
+
+def _create_context_and_provider(
+ ctx,
+ compilation_attributes,
+ compilation_artifacts,
+ intermediate_artifacts,
+ has_module_map,
+ deps,
+ implementation_deps,
+ attr_linkopts,
+ direct_cc_compilation_contexts = [],
+ includes = []):
+ objc_providers = []
+ cc_compilation_contexts = []
+ cc_linking_contexts = []
+
+ for dep in deps:
+ if _ObjcInfo in dep:
+ objc_providers.append(dep[_ObjcInfo])
+
+ if CcInfo in dep:
+ cc_compilation_contexts.append(dep[CcInfo].compilation_context)
+ cc_linking_contexts.append(dep[CcInfo].linking_context)
+
+ implementation_cc_compilation_contexts = []
+ for impl_dep in implementation_deps:
+ implementation_cc_compilation_contexts.append(impl_dep[CcInfo].compilation_context)
+ cc_linking_contexts.append(impl_dep[CcInfo].linking_context)
+
+ sdk_linking_info = {
+ "sdk_dylib": [],
+ "sdk_framework": [],
+ "weak_sdk_framework": [],
+ }
+
+ # buildifier: disable=unsorted-dict-items
+ objc_provider_kwargs = {
+ "providers": objc_providers,
+ "umbrella_header": [],
+ "module_map": [],
+ "source": [],
+ }
+
+ # buildifier: disable=unsorted-dict-items
+ objc_compilation_context_kwargs = {
+ "providers": objc_providers,
+ "cc_compilation_contexts": cc_compilation_contexts,
+ "implementation_cc_compilation_contexts": implementation_cc_compilation_contexts,
+ "public_hdrs": [],
+ "private_hdrs": [],
+ "public_textual_hdrs": [],
+ "defines": [],
+ "includes": list(includes),
+ "direct_cc_compilation_contexts": direct_cc_compilation_contexts,
+ }
+
+ all_non_sdk_linkopts = []
+ non_sdk_linkopts = _add_linkopts(
+ sdk_linking_info,
+ cc_common.objc_expand_and_tokenize(ctx = ctx, attr = "linkopts", flags = attr_linkopts),
+ )
+ all_non_sdk_linkopts.extend(non_sdk_linkopts)
+
+ if compilation_attributes != None:
+ sdk_dir = _apple_toolchain.sdk_dir()
+ usr_include_dir = sdk_dir + "/usr/include/"
+ sdk_includes = []
+
+ for sdk_include in compilation_attributes.sdk_includes.to_list():
+ sdk_includes.append(usr_include_dir + sdk_include)
+
+ sdk_linking_info["sdk_framework"].extend(
+ compilation_attributes.sdk_frameworks.to_list(),
+ )
+ sdk_linking_info["weak_sdk_framework"].extend(
+ compilation_attributes.weak_sdk_frameworks.to_list(),
+ )
+ sdk_linking_info["sdk_dylib"].extend(compilation_attributes.sdk_dylibs.to_list())
+
+ objc_compilation_context_kwargs["public_hdrs"].extend(compilation_attributes.hdrs.to_list())
+ objc_compilation_context_kwargs["public_textual_hdrs"].extend(
+ compilation_attributes.textual_hdrs.to_list(),
+ )
+ objc_compilation_context_kwargs["defines"].extend(compilation_attributes.defines)
+ objc_compilation_context_kwargs["includes"].extend(sdk_includes)
+
+ if compilation_artifacts != None:
+ all_sources = _filter_out_by_extension(compilation_artifacts.srcs, OBJECT_FILE_SOURCES) + \
+ compilation_artifacts.non_arc_srcs
+
+ objc_provider_kwargs["source"].extend(all_sources)
+
+ objc_compilation_context_kwargs["public_hdrs"].extend(
+ compilation_artifacts.additional_hdrs,
+ )
+ objc_compilation_context_kwargs["private_hdrs"].extend(
+ _filter_by_extension(compilation_artifacts.srcs, HEADERS),
+ )
+
+ if has_module_map:
+ module_map = intermediate_artifacts.swift_module_map()
+ objc_provider_kwargs["module_map"].append(module_map.file())
+
+ objc_provider_kwargs_built = {}
+ for k, v in objc_provider_kwargs.items():
+ if k == "providers":
+ objc_provider_kwargs_built[k] = v
+ else:
+ objc_provider_kwargs_built[k] = depset(v)
+
+ objc_compilation_context = ObjcCompilationContextInfo(
+ **objc_compilation_context_kwargs
+ )
+
+ all_linkopts = all_non_sdk_linkopts
+ for sdk_framework in depset(sdk_linking_info["sdk_framework"]).to_list():
+ all_linkopts.append("-framework")
+ all_linkopts.append(sdk_framework)
+
+ for weak_sdk_framework in depset(sdk_linking_info["weak_sdk_framework"]).to_list():
+ all_linkopts.append("-weak_framework")
+ all_linkopts.append(weak_sdk_framework)
+
+ for sdk_dylib in depset(sdk_linking_info["sdk_dylib"]).to_list():
+ if sdk_dylib.startswith("lib"):
+ sdk_dylib = sdk_dylib[3:]
+ all_linkopts.append("-l%s" % sdk_dylib)
+
+ objc_linking_context = struct(
+ cc_linking_contexts = cc_linking_contexts,
+ linkopts = all_linkopts,
+ )
+
+ return (
+ _ObjcInfo(**objc_provider_kwargs_built),
+ objc_compilation_context,
+ objc_linking_context,
+ )
+
+def _filter_by_extension(file_list, extensions):
+ return [file for file in file_list if "." + file.extension in extensions]
+
+def _filter_out_by_extension(file_list, extensions):
+ return [file for file in file_list if "." + file.extension not in extensions]
+
+def _add_linkopts(sdk_linking_info, linkopts):
+ non_sdk_linkopts = []
+ i = 0
+ skip_next = False
+ for arg in linkopts:
+ if skip_next:
+ skip_next = False
+ i += 1
+ continue
+ if arg == "-framework" and i < len(linkopts) - 1:
+ sdk_linking_info["sdk_framework"].append(linkopts[i + 1])
+ skip_next = True
+ elif arg == "-weak_framework" and i < len(linkopts) - 1:
+ sdk_linking_info["weak_sdk_framework"].append(linkopts[i + 1])
+ skip_next = True
+ elif arg.startswith("-Wl,-framework,"):
+ sdk_linking_info["sdk_framework"].append(arg[len("-Wl,-framework,"):])
+ elif arg.startswith("-Wl,-weak_framework,"):
+ sdk_linking_info["weak_sdk_framework"].append(arg[len("-Wl,-weak_framework,"):])
+ elif arg.startswith("-l"):
+ sdk_linking_info["sdk_dylib"].append(arg[2:])
+ else:
+ non_sdk_linkopts.append(arg)
+ i += 1
+
+ return non_sdk_linkopts
+
+def _is_apple_platform(cpu):
+ return cpu in ios_cpus.IOS_SIMULATOR_TARGET_CPUS or \
+ cpu in ios_cpus.IOS_DEVICE_TARGET_CPUS or \
+ cpu in ios_cpus.VISIONOS_SIMULATOR_TARGET_CPUS or \
+ cpu in ios_cpus.VISIONOS_DEVICE_TARGET_CPUS or \
+ cpu in ios_cpus.WATCHOS_SIMULATOR_TARGET_CPUS or \
+ cpu in ios_cpus.WATCHOS_DEVICE_TARGET_CPUS or \
+ cpu in ios_cpus.TVOS_SIMULATOR_TARGET_CPUS or \
+ cpu in ios_cpus.TVOS_DEVICE_TARGET_CPUS or \
+ cpu in ios_cpus.CATALYST_TARGET_CPUS or \
+ cpu in ios_cpus.MACOS_TARGET_CPUS
+
+objc_common = struct(
+ create_context_and_provider = _create_context_and_provider,
+ is_apple_platform = _is_apple_platform,
+)
diff --git a/cc/private/rules_impl/objc_compilation_context_info.bzl b/cc/private/rules_impl/objc_compilation_context_info.bzl
new file mode 100644
index 0000000..d652fe0
--- /dev/null
+++ b/cc/private/rules_impl/objc_compilation_context_info.bzl
@@ -0,0 +1,72 @@
+# Copyright 2024 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.
+
+"""A collection of compilation information gathered for a particular rule.
+
+This is used to generate the compilation command line and to the supply information that goes
+into the compilation info provider.
+"""
+
+def _objc_compilation_context_info_init(
+ defines = [],
+ public_hdrs = [],
+ public_textual_hdrs = [],
+ private_hdrs = [],
+ includes = [],
+ system_includes = [],
+ quote_includes = [],
+ direct_cc_compilation_contexts = [],
+ cc_compilation_contexts = [],
+ implementation_cc_compilation_contexts = [],
+ providers = []):
+ strict_dependency_includes = [
+ path
+ for objc_provider in providers
+ for path in objc_provider.strict_include.to_list()
+ ]
+
+ # buildifier: disable=unsorted-dict-items
+ return {
+ "defines": defines,
+ "public_hdrs": public_hdrs,
+ "public_textual_hdrs": public_textual_hdrs,
+ "private_hdrs": private_hdrs,
+ "includes": includes,
+ "system_includes": system_includes,
+ "quote_includes": quote_includes,
+ "strict_dependency_includes": strict_dependency_includes,
+ "direct_cc_compilation_contexts": direct_cc_compilation_contexts,
+ "cc_compilation_contexts": cc_compilation_contexts,
+ "implementation_cc_compilation_contexts": implementation_cc_compilation_contexts,
+ }
+
+ObjcCompilationContextInfo, _new_objccompilationcontextinfo = provider(
+ "Provider about ObjC compilation information gathered for a particular rule.",
+ # buildifier: disable=unsorted-dict-items
+ fields = {
+ "defines": "",
+ "public_hdrs": """The list of public headers. We expect this to contain both the headers
+ from the src attribute, as well as any "additional" headers required for compilation.""",
+ "public_textual_hdrs": "",
+ "private_hdrs": "",
+ "includes": "",
+ "system_includes": "",
+ "quote_includes": "",
+ "strict_dependency_includes": "",
+ "direct_cc_compilation_contexts": "",
+ "cc_compilation_contexts": "",
+ "implementation_cc_compilation_contexts": "",
+ },
+ init = _objc_compilation_context_info_init,
+)