blob: efc3c961d8a09b5b5272ae4f601aa56c865b276d [file] [log] [blame]
Miguel Young de la Sota0f91ad52022-03-29 14:59:12 -04001# 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
7def 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
11def 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 Sota3ba29fb2022-04-01 16:11:37 -040019def _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 Sota0f91ad52022-03-29 14:59:12 -040023def dual_cc_library(
24 name,
25 on_device_config_setting = "//rules:opentitan_platform",
26 srcs = [],
27 hdrs = [],
28 deps = [],
Miguel Young de la Sota3ba29fb2022-04-01 16:11:37 -040029 target_compatible_with = [],
Miguel Young de la Sota0f91ad52022-03-29 14:59:12 -040030 **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 Sota3ba29fb2022-04-01 16:11:37 -040062 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 Sota0f91ad52022-03-29 14:59:12 -040066
67 native.cc_library(
68 name = dual_cc_device_library_of(name),
Miguel Young de la Sota3ba29fb2022-04-01 16:11:37 -040069 hdrs = hdrs_d,
70 srcs = srcs_d,
71 deps = deps_d,
72 target_compatible_with = tgts_d,
Miguel Young de la Sota0f91ad52022-03-29 14:59:12 -040073 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 Sota3ba29fb2022-04-01 16:11:37 -040080 hdrs = hdrs_h,
81 srcs = srcs_h,
82 deps = deps_h,
83 target_compatible_with = tgts_h,
Miguel Young de la Sota0f91ad52022-03-29 14:59:12 -040084 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 )