-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
alias.bzl
196 lines (179 loc) · 7.34 KB
/
alias.bzl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
load("//tools/skylark:py.bzl", "py_library")
load(
"@drake//tools/skylark:drake_cc.bzl",
"drake_cc_library",
)
load("//tools/workspace:generate_file.bzl", "generate_file")
def _combine_relative_labels(arg_list, arg_map):
# Merge the relative_labels= and relative_labels_map= arguments as seen in
# the public macros below. The result is a map where the arg_list items
# are twinned into matching key:key pairs, union'd with the arg_map. (Also
# double-checks that the keys and values are all relative labels.)
result = dict([(x, x) for x in arg_list])
result.update(arg_map)
for x in result.keys() + result.values():
if not x.startswith(":"):
fail("Expected relative_label, got " + x)
return result
def drake_cc_hdrs_forwarding_library(
name,
relative_labels = [],
relative_labels_map = {},
actual_subdir = "",
add_deprecation_warning = False,
tags = [],
**kwargs):
"""Generates a drake_cc_library filled with generated header files that
merely include other header files, optionally with a deprecation warning.
This automates the chore of adding compatibility headers when packages
move.
The relative_labels + relative_labels_map.keys() specify the header
filenames to generate. For each label name ':foo', this macro generates a
header named 'foo.h' that includes 'drake/{actual_subdir}/{new_foo}.h'
where new_foo for relative_labels is the same as foo, and new_foo for
relative_labels_map is the value for the foo key (without the leading
colon).
When add_deprecation_warning is true, the generated header will have a
#warning directive explaining the new location.
"""
actual_subdir or fail("Missing required actual_subdir")
# Generate one header file for each mapped label.
hdrs = []
mapping = _combine_relative_labels(relative_labels, relative_labels_map)
for stub_relative_label, actual_relative_label in mapping.items():
actual_include = "drake/{}/{}.h".format(
actual_subdir,
actual_relative_label[1:],
)
warning = "#warning This header is deprecated; use {} instead".format(
actual_include,
) if add_deprecation_warning else ""
basename = stub_relative_label[1:] + ".h"
generate_file(
name = basename,
content = "\n".join([
"#pragma once",
"{warning}",
"#include \"{actual_include}\"",
]).format(
warning = warning,
actual_include = actual_include,
),
)
hdrs.append(basename)
# Place all of the header files into a library.
drake_cc_library(
name = name,
hdrs = hdrs,
tags = tags + ["nolint"],
**kwargs
)
def drake_cc_library_aliases(
relative_labels = [],
relative_labels_map = {},
actual_subdir = "",
add_deprecation_warning = False,
tags = [],
deps = [],
**kwargs):
"""Generates aliases for drake_cc_library labels that have moved into a new
package. This is superior to native.alias() both for its brevity (it can
generate many aliases at once), and because the deprecation message
actually works (see https://github.com/bazelbuild/bazel/issues/5802).
The relative_labels + relative_labels_map specify the correspondence. For
each label name foo in the relative_labels and relative_labels_map.keys(),
this macro generates an alias to '//{actual_subdir}:{new_foo}' where
new_foo for relative_labels is the same as foo, and new_foo for
relative_labels_map is the value for the foo key.
When add_deprecation_warning is true, the generated label in this package
will have a deprecation warning explaining the new location. When using
this mode, the caller should probably set 'tags = ["manual"]' to avoid
spurious warnings during 'bazel build //...'.
"""
actual_subdir or fail("Missing required actual_subdir")
mapping = _combine_relative_labels(relative_labels, relative_labels_map)
for stub_relative_label, actual_relative_label in mapping.items():
actual_full_label = "//" + actual_subdir + actual_relative_label
if add_deprecation_warning:
deprecation = ("Use the label " + actual_full_label)
else:
deprecation = None
native.cc_library(
name = stub_relative_label[1:],
deps = deps + [actual_full_label],
tags = tags + ["nolint"],
deprecation = deprecation,
**kwargs
)
native.alias(
name = stub_relative_label[1:] + ".installed_headers",
actual = actual_full_label + ".installed_headers",
)
_PY_TEMPLATE_NOT_DEPRECATED = r'''"""
Warning:
This module is an alias that will soon be deprecated.
Please use ``{module}`` instead.
"""
from {module} import *
'''
_PY_TEMPLATE_DEPRECATED = r'''"""
Warning:
This module is deprecated and will be removed on or around
{deprecation_removal_date}. Please use ``{module}`` instead.
"""
from pydrake.common.deprecation import _warn_deprecated
from {module} import *
_warn_deprecated(
"This module is deprecated and will be removed on or around "
"{deprecation_removal_date}. Please use '{module}' instead.",
stacklevel=3)
'''
def _strip_py_suffix(label):
if not label.endswith("_py"):
fail("'{}' must end with '_py'".format(label))
return label[1:-len("_py")]
def drake_py_library_aliases(
relative_labels = [],
relative_labels_map = {},
actual_subdir = "",
add_deprecation_warning = False,
deprecation_removal_date = None,
tags = [],
**kwargs):
actual_subdir or fail("Missing required actual_subdir")
subdir_prefix = "bindings/pydrake/"
if not actual_subdir.startswith(subdir_prefix):
fail("'{}' must start with '{}'".format(actual_subdir, subdir_prefix))
if actual_subdir.endswith("/"):
fail("'{}' must not end with '/'".format(actual_subdir))
actual_package = actual_subdir[len("bindings/"):].replace("/", ".")
mapping = _combine_relative_labels(relative_labels, relative_labels_map)
for stub_relative_label, actual_relative_label in mapping.items():
stub_file = _strip_py_suffix(stub_relative_label) + ".py"
actual_name = _strip_py_suffix(actual_relative_label)
actual_module = actual_package + "." + actual_name
if add_deprecation_warning:
if deprecation_removal_date == None:
fail("`deprecation_removal_date` must be supplied.")
generate_file(
name = stub_file,
content = _PY_TEMPLATE_DEPRECATED.format(
module = actual_module,
deprecation_removal_date = deprecation_removal_date,
),
)
else:
generate_file(
name = stub_file,
content = _PY_TEMPLATE_NOT_DEPRECATED.format(
module = actual_module,
),
)
actual_full_label = "//" + actual_subdir + actual_relative_label
py_library(
name = stub_relative_label[1:],
deps = [actual_full_label],
srcs = [stub_file],
tags = tags + ["nolint"],
**kwargs
)