| # 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. |
| |
| """Builds the Objective-C provider""" |
| |
| objc_internal = _builtins.internal.objc_internal |
| CcInfo = _builtins.toplevel.CcInfo |
| apple_common = _builtins.toplevel.apple_common |
| |
| def _create_context_and_provider( |
| purpose, |
| ctx, |
| compilation_attributes, |
| compilation_artifacts, |
| intermediate_artifacts, |
| alwayslink, |
| has_module_map, |
| extra_import_libraries, |
| deps, |
| runtime_deps, |
| linkopts): |
| objc_providers = [] |
| cc_compilation_contexts_for_direct_fields = [] |
| cc_linking_contexts = [] |
| cc_compilation_contexts = [] |
| cc_linkstamp_contexts = [] |
| for dep in deps: |
| if apple_common.Objc in dep: |
| objc_providers.append(dep[apple_common.Objc]) |
| elif CcInfo in dep: |
| # This is the way we inject cc_library attributes into direct fields. |
| cc_compilation_contexts_for_direct_fields.append(dep[CcInfo].compilation_context) |
| |
| # We only use CcInfo's linking info if there is no ObjcProvider. |
| # This is required so that objc_library archives do not get treated |
| # as if they are from cc targets. |
| cc_linking_contexts.append(dep[CcInfo].linking_context) |
| |
| if CcInfo in dep: |
| cc_compilation_contexts.append(dep[CcInfo].compilation_context) |
| |
| # Temporary solution to specially handle linkstamps, so that they |
| # don't get dropped. When linking info has been fully migrated to |
| # CcInfo, we can drop this. |
| cc_linkstamp_contexts.append(dep[CcInfo].linking_context) |
| |
| runtime_objc_providers = [] |
| for runtime_dep in runtime_deps: |
| if apple_common.Objc in runtime_dep: |
| runtime_objc_providers.append(runtime_dep[apple_common.Objc]) |
| if CcInfo in runtime_dep: |
| cc_compilation_contexts.append(runtime_dep[CcInfo].compilation_context) |
| |
| link_order_keys = [ |
| "imported_library", |
| "cc_library", |
| "library", |
| "force_load_library", |
| "linkopt", |
| ] |
| objc_provider_kwargs = { |
| "imported_library": [depset(direct = extra_import_libraries, order = "topological")], |
| "header": [], |
| "weak_sdk_framework": [], |
| "sdk_dylib": [], |
| "linkopt": [], |
| "library": [], |
| "providers": objc_providers, |
| "cc_library": [], |
| "sdk_framework": [], |
| "linkstamp": [], |
| "force_load_library": [], |
| "umbrella_header": [], |
| "module_map": [], |
| "source": [], |
| } |
| |
| objc_compilation_context_kwargs = { |
| "providers": objc_providers + runtime_objc_providers, |
| "cc_compilation_contexts": cc_compilation_contexts, |
| "public_hdrs": [], |
| "private_hdrs": [], |
| "public_textual_hdrs": [], |
| "defines": [], |
| "includes": [], |
| } |
| |
| for header_provider in cc_compilation_contexts_for_direct_fields: |
| objc_provider_kwargs["header"].extend(header_provider.headers.to_list()) |
| |
| for link_provider in cc_linking_contexts: |
| link_opts = [] |
| libraries_to_link = [] |
| for linker_input in link_provider.linker_inputs.to_list(): |
| link_opts.extend(linker_input.user_link_flags) |
| libraries_to_link.extend(linker_input.libraries) |
| _add_linkopts(objc_provider_kwargs, link_opts) |
| |
| objc_provider_kwargs["cc_library"].append( |
| depset(direct = libraries_to_link, order = "topological"), |
| ) |
| |
| _add_linkopts( |
| objc_provider_kwargs, |
| objc_internal.expand_toolchain_and_ctx_variables(ctx = ctx, flags = linkopts), |
| ) |
| |
| for cc_linkstamp_context in cc_linkstamp_contexts: |
| objc_provider_kwargs["linkstamp"].extend(cc_linkstamp_context.linkstamps().to_list()) |
| |
| if compilation_attributes != None: |
| sdk_dir = apple_common.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) |
| |
| objc_provider_kwargs["sdk_framework"].extend( |
| compilation_attributes.sdk_frameworks.to_list(), |
| ) |
| objc_provider_kwargs["weak_sdk_framework"].extend( |
| compilation_attributes.weak_sdk_frameworks.to_list(), |
| ) |
| objc_provider_kwargs["sdk_dylib"].extend(compilation_attributes.sdk_dylibs.to_list()) |
| hdrs = compilation_attributes.hdrs.to_list() |
| objc_provider_kwargs["header"].extend(hdrs) |
| textual_hdrs = compilation_attributes.textual_hdrs.to_list() |
| objc_provider_kwargs["header"].extend(textual_hdrs) |
| |
| objc_compilation_context_kwargs["public_hdrs"].extend(hdrs) |
| objc_compilation_context_kwargs["public_textual_hdrs"].extend(textual_hdrs) |
| objc_compilation_context_kwargs["defines"].extend(compilation_attributes.defines) |
| objc_compilation_context_kwargs["includes"].extend( |
| compilation_attributes.header_search_paths( |
| genfiles_dir = ctx.genfiles_dir.path, |
| ).to_list(), |
| ) |
| objc_compilation_context_kwargs["includes"].extend(sdk_includes) |
| |
| if compilation_artifacts != None: |
| all_sources = [] |
| all_sources.extend(compilation_artifacts.srcs) |
| all_sources.extend(compilation_artifacts.non_arc_srcs) |
| all_sources.extend(compilation_artifacts.private_hdrs) |
| |
| if compilation_artifacts.archive != None: |
| objc_provider_kwargs["library"] = [ |
| depset([compilation_artifacts.archive], order = "topological"), |
| ] |
| objc_provider_kwargs["source"].extend(all_sources) |
| objc_provider_kwargs["header"].extend(compilation_artifacts.additional_hdrs.to_list()) |
| |
| objc_compilation_context_kwargs["public_hdrs"].extend( |
| compilation_artifacts.additional_hdrs.to_list(), |
| ) |
| objc_compilation_context_kwargs["private_hdrs"].extend(compilation_artifacts.private_hdrs) |
| |
| uses_cpp = False |
| arc_and_non_arc_srcs = [] |
| arc_and_non_arc_srcs.extend(compilation_artifacts.srcs) |
| arc_and_non_arc_srcs.extend(compilation_artifacts.non_arc_srcs) |
| for source_file in arc_and_non_arc_srcs: |
| uses_cpp = uses_cpp or _is_cpp_source(source_file) |
| |
| if uses_cpp: |
| objc_provider_kwargs["flag"] = ["uses_cpp"] |
| |
| if alwayslink: |
| direct = [] |
| if compilation_artifacts != None: |
| if compilation_artifacts.archive != None: |
| direct.append(compilation_artifacts.archive) |
| |
| direct.extend(extra_import_libraries) |
| |
| objc_provider_kwargs["force_load_library"] = [ |
| depset( |
| direct = direct, |
| transitive = objc_provider_kwargs["force_load_library"], |
| order = "topological", |
| ), |
| ] |
| |
| if has_module_map: |
| module_map = intermediate_artifacts.swift_module_map |
| umbrella_header = module_map.umbrella_header() |
| if umbrella_header != None: |
| objc_provider_kwargs["umbrella_header"].append(umbrella_header) |
| |
| 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 |
| elif k in link_order_keys: |
| objc_provider_kwargs_built[k] = depset(transitive = v, order = "topological") |
| else: |
| objc_provider_kwargs_built[k] = depset(v) |
| |
| objc_compilation_context = objc_internal.create_compilation_context( |
| **objc_compilation_context_kwargs |
| ) |
| |
| return (apple_common.new_objc_provider(**objc_provider_kwargs_built), objc_compilation_context) |
| |
| def _is_cpp_source(source_file): |
| return source_file.extension in ["cc", "cpp", "mm", "cxx", "C"] |
| |
| def _add_linkopts(objc_provider_kwargs, link_opts): |
| framework_link_opts = {} |
| non_framework_link_opts = [] |
| i = 0 |
| skip_next = False |
| for arg in link_opts: |
| if skip_next: |
| skip_next = False |
| i += 1 |
| continue |
| if arg == "-framework" and i < len(link_opts) - 1: |
| framework_link_opts[link_opts[i + 1]] = True |
| skip_next = True |
| else: |
| non_framework_link_opts.append(arg) |
| i += 1 |
| |
| objc_provider_kwargs["sdk_framework"].extend(framework_link_opts.keys()) |
| objc_provider_kwargs["linkopt"].append( |
| depset( |
| direct = non_framework_link_opts, |
| order = "topological", |
| ), |
| ) |
| |
| def _compilation_contexts_from_cc_infos(cc_infos): |
| cc_compilation_contexts = [] |
| for cc_info in cc_infos: |
| cc_compilation_contexts.append(cc_info.compilation_context) |
| |
| return cc_compilation_contexts |
| |
| objc_common = struct( |
| create_context_and_provider = _create_context_and_provider, |
| ) |