Miguel Young de la Sota | 0f91ad5 | 2022-03-29 14:59:12 -0400 | [diff] [blame] | 1 | # Copyright lowRISC contributors. |
| 2 | # Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| 3 | # SPDX-License-Identifier: Apache-2.0 |
| 4 | |
| 5 | """Rules for defining cross-platform libraries.""" |
| 6 | |
| 7 | def dual_inputs(shared = [], device = [], host = []): |
| 8 | """Constructs a cross-platform input for use with dual_cc_library.""" |
| 9 | return struct(shared = shared, device = device, host = host) |
| 10 | |
| 11 | def dual_cc_device_library_of(label): |
| 12 | """ |
| 13 | Given the label of a dual_cc_library, returns the label for the |
| 14 | on-device library. This library is private to the Bazel package that |
| 15 | defines it. |
| 16 | """ |
| 17 | return "{}_on_device_do_not_use_directly".format(label) |
| 18 | |
Miguel Young de la Sota | 3ba29fb | 2022-04-01 16:11:37 -0400 | [diff] [blame] | 19 | def _merge_and_split_inputs(inputs): |
| 20 | inputs = inputs if type(inputs) != "list" else dual_inputs(shared = inputs) |
| 21 | return inputs.shared + inputs.device, inputs.shared + inputs.host |
| 22 | |
Miguel Young de la Sota | 0f91ad5 | 2022-03-29 14:59:12 -0400 | [diff] [blame] | 23 | def dual_cc_library( |
| 24 | name, |
| 25 | on_device_config_setting = "//rules:opentitan_platform", |
| 26 | srcs = [], |
| 27 | hdrs = [], |
| 28 | deps = [], |
Miguel Young de la Sota | 3ba29fb | 2022-04-01 16:11:37 -0400 | [diff] [blame] | 29 | target_compatible_with = [], |
Miguel Young de la Sota | 0f91ad5 | 2022-03-29 14:59:12 -0400 | [diff] [blame] | 30 | **kwargs): |
| 31 | """ |
| 32 | Defines a cc_library whose contents are dependent on whether it is |
| 33 | depended on in an on-device or on-host setting. |
| 34 | |
| 35 | The macro takes the same arguments as cc_library, but has special |
| 36 | behavior for `hdrs`, `srcs`, and `deps`, which may either be a list of |
| 37 | labels that would usually be inputs to a cc_library, or a dual_inputs object. |
| 38 | The later case allows inputs to be designated as being shared, on-device-only, |
| 39 | or off-device-only. |
| 40 | |
| 41 | This rule only needs to be used when the sources for on-device are different |
| 42 | from on-host, such as for mockable interfaces. In this case, the on-device |
| 43 | library may still be used on-host via `dual_cc_device_library_of`, and it will |
| 44 | use the host-side versions of its dependencies. This is useful for testing |
| 45 | the on-device version using mocked dependencies. |
| 46 | |
| 47 | Args: |
| 48 | @param name: The name of this rule. |
| 49 | @param on_device_config_setting: A config_setting rule for determining what |
| 50 | "on device" means. |
| 51 | @param srcs: `cc_library()` sources; may be a list or a `dual_inputs()`. |
| 52 | @param hdrs: `cc_library()` headers; may be a list or a `dual_inputs()`. |
| 53 | @param deps: `cc_library()` dependencies; may be a list or a `dual_inputs()`. |
| 54 | @param **kwargs: Arguments to forward to each `cc_library()`. |
| 55 | |
| 56 | Emits rules: |
| 57 | cc_library named: dual_cc_device_library_of(<name>) |
| 58 | cc_library named: <unspecified> # Host-only library. |
| 59 | alias named: <name> |
| 60 | """ |
| 61 | |
Miguel Young de la Sota | 3ba29fb | 2022-04-01 16:11:37 -0400 | [diff] [blame] | 62 | hdrs_d, hdrs_h = _merge_and_split_inputs(hdrs) |
| 63 | srcs_d, srcs_h = _merge_and_split_inputs(srcs) |
| 64 | deps_d, deps_h = _merge_and_split_inputs(deps) |
| 65 | tgts_d, tgts_h = _merge_and_split_inputs(target_compatible_with) |
Miguel Young de la Sota | 0f91ad5 | 2022-03-29 14:59:12 -0400 | [diff] [blame] | 66 | |
| 67 | native.cc_library( |
| 68 | name = dual_cc_device_library_of(name), |
Miguel Young de la Sota | 3ba29fb | 2022-04-01 16:11:37 -0400 | [diff] [blame] | 69 | hdrs = hdrs_d, |
| 70 | srcs = srcs_d, |
| 71 | deps = deps_d, |
| 72 | target_compatible_with = tgts_d, |
Miguel Young de la Sota | 0f91ad5 | 2022-03-29 14:59:12 -0400 | [diff] [blame] | 73 | visibility = ["//visibility:private"], |
| 74 | **kwargs |
| 75 | ) |
| 76 | |
| 77 | off_device_name = "{}_on_host_do_not_use_directly".format(name) |
| 78 | native.cc_library( |
| 79 | name = off_device_name, |
Miguel Young de la Sota | 3ba29fb | 2022-04-01 16:11:37 -0400 | [diff] [blame] | 80 | hdrs = hdrs_h, |
| 81 | srcs = srcs_h, |
| 82 | deps = deps_h, |
| 83 | target_compatible_with = tgts_h, |
Miguel Young de la Sota | 0f91ad5 | 2022-03-29 14:59:12 -0400 | [diff] [blame] | 84 | visibility = ["//visibility:private"], |
| 85 | **kwargs |
| 86 | ) |
| 87 | |
| 88 | native.alias( |
| 89 | name = name, |
| 90 | actual = select({ |
| 91 | on_device_config_setting: dual_cc_device_library_of(name), |
| 92 | "//conditions:default": off_device_name, |
| 93 | }), |
| 94 | ) |