| # 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. |
| # LINT.IfChange(forked_exports) |
| """ |
| The cc_common.create_linking_context_from_compilation_outputs function. |
| |
| Used to prepare a single library for linking. See also: cc_common.link |
| """ |
| |
| load("//cc/private:cc_info.bzl", "create_linking_context", "merge_linking_contexts") |
| load("//cc/private:cc_internal.bzl", _cc_internal = "cc_internal") |
| load("//cc/private/link:cc_linking_helper.bzl", "create_cc_link_actions") |
| load("//cc/private/link:create_linker_input.bzl", "create_linker_input") |
| load("//cc/private/link:target_types.bzl", "LINKING_MODE", "LINK_TARGET_TYPE") |
| |
| # IMPORTANT: This function is public API exposed on cc_common module! |
| def create_linking_context_from_compilation_outputs( |
| *, |
| actions, |
| name, |
| feature_configuration, |
| cc_toolchain, |
| language = "c++", # buildifier: disable=unused-variable |
| disallow_static_libraries = False, |
| disallow_dynamic_library = False, |
| compilation_outputs, |
| linking_contexts = [], |
| user_link_flags = [], |
| alwayslink = False, |
| additional_inputs = [], |
| variables_extension = {}, |
| # Private: |
| stamp = 0, |
| linked_dll_name_suffix = "", |
| test_only_target = False): |
| """ |
| Links a single library. |
| |
| Should be used for creating library rules that can propagate information downstream in |
| order to be linked later by a top level rule that does transitive linking to |
| create an executable or a dynamic library. |
| |
| The function creates static libraries and "nodeps" dynamic library, using `name` to name them, |
| only linking the object files from `compilation_outputs`. Static libraries are produced in |
| nopic and/or pic version, depending on the configuration and if the toolchain supports pic. |
| |
| Disable either static or dynamic library using `disallow_static_libraries` or |
| `disallow_dynamic_library`. |
| |
| Callee may specify `user_link_flags`, `additional_inputs` to C++ linking action, and |
| custom `variables_extension`, which are passed to link command line. |
| |
| The exception are Windows, where "nodeps" dynamic library links also all the transitive |
| libraries from `linking_context`. |
| |
| TODO(b/338618120): during Starlarkification of rules several private parameters were introduced, |
| those parameters need to be eventually removed or made public. |
| |
| Args: |
| actions: (Actions) `actions` object. |
| name: (str) This is used for naming the output artifacts of actions created by this method. |
| feature_configuration: (FeatureConfiguration) `feature_configuration` to be queried. |
| language: ("cpp") Only C++ supported for now. Do not use this parameter. |
| cc_toolchain: (CcToolchainInfo) CcToolchainInfo provider to be used. |
| disallow_static_libraries: (bool) Whether static libraries should be created. |
| disallow_dynamic_library: (bool) Whether a dynamic library should be created. |
| compilation_outputs: (CompilationOutputs) Compilation outputs containing object files to link. |
| linking_contexts: (list[LinkingContext]) Libraries from dependencies. These libraries will |
| be linked into the output artifact of the link() call, be it a binary or a library. |
| user_link_flags: (list[str]) Additional list of linker options. |
| alwayslink: (bool) Whether this library should always be linked. |
| additional_inputs: (list[File]|depset[File]) For additional inputs to the linking action, |
| e.g.: linking scripts. |
| variables_extension: (dict[str, str|list[str]|depset[str]]) Additional variables to pass to |
| the toolchain configuration when creating link command line. |
| stamp: (bool) undocumented. |
| linked_dll_name_suffix: (str) undocumented. |
| test_only_target: (bool) undocumented. |
| |
| Returns: |
| (`CcLinkingContext`, `CcLinkingOutputs`) A pair. |
| """ |
| |
| # LINT.ThenChange(https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/cpp/CcModuleApi.java) |
| # TODO(b/202252560): Fix for swift_library's implicit output, remove rule_kind_cheat. |
| if alwayslink and _cc_internal.rule_class(_cc_internal.actions2ctx_cheat(actions)) != "swift_library": |
| static_link_type = LINK_TARGET_TYPE.ALWAYS_LINK_STATIC_LIBRARY |
| else: |
| static_link_type = LINK_TARGET_TYPE.STATIC_LIBRARY |
| if type(additional_inputs) == type([]): |
| additional_inputs = depset(additional_inputs) |
| |
| cc_linking_outputs = create_cc_link_actions( |
| _cc_internal.wrap_link_actions(actions), |
| name, |
| None if disallow_static_libraries else static_link_type, |
| None if disallow_dynamic_library else LINK_TARGET_TYPE.NODEPS_DYNAMIC_LIBRARY, |
| LINKING_MODE.DYNAMIC, |
| feature_configuration, |
| cc_toolchain, |
| compilation_outputs, |
| linking_contexts, |
| user_link_flags, # linkopts |
| stamp, |
| additional_inputs, # additional_linker_inputs |
| [], # linker_outputs |
| variables_extension, |
| alwayslink = alwayslink, |
| test_only_target = test_only_target, |
| linked_dll_name_suffix = linked_dll_name_suffix, |
| ) |
| |
| linker_input = create_linker_input( |
| # TODO(b/331164666): remove cheat, we always produce a file, file.owner gives us a label |
| owner = _cc_internal.actions2ctx_cheat(actions).label.same_package_label(name), |
| libraries = depset([cc_linking_outputs.library_to_link]) if cc_linking_outputs.library_to_link else None, |
| user_link_flags = user_link_flags, |
| additional_inputs = additional_inputs, |
| ) |
| direct_linking_context = create_linking_context( |
| linker_inputs = depset([linker_input]), |
| ) |
| linking_context = merge_linking_contexts( |
| linking_contexts = [direct_linking_context] + linking_contexts, |
| ) |
| return linking_context, cc_linking_outputs |