blob: a30c7a3b30ec1ac37c386658288d265ab014b94a [file] [log] [blame] [edit]
# Copyright 2024 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
visibility("public")
SymlinkInfo = provider(fields = {
"link": "(File) The link generated by the symlink rule",
"target": "(File) The target of the link",
})
def _symlink_impl(ctx, include_target = True):
out = ctx.actions.declare_file(ctx.attr.out or ctx.label.name)
ctx.actions.symlink(output = out, target_file = ctx.file.actual)
files = [out]
if ctx.attr.include_target:
files.append(ctx.file.actual)
return [
DefaultInfo(
files = depset(files),
runfiles = ctx.runfiles(files),
),
SymlinkInfo(link = out, target = ctx.file.actual),
]
symlink = rule(
doc = """Symlink is similar to alias, but additionally generates a symlink.
This makes it compatible with bzlmod hub+spoke repos (since spoke repos don't
appear in the repo mapping, you can't reference them with an alias).""",
implementation = _symlink_impl,
attrs = dict(
actual = attr.label(allow_single_file = True),
out = attr.string(),
include_target = attr.bool(
default = True,
doc = """
This can be used to invoke symlink with makefile substitution (which requires
a single file).
Typical usage:
rule(
...
data = [":actual", ":symlink"],
flags = ["$(location :symlink)"],
)
""",
),
),
)