| # 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)"], |
| ) |
| """, |
| ), |
| ), |
| ) |