Initial commit
This commit is contained in:
parent
394f900560
commit
bf35529fc9
|
@ -0,0 +1 @@
|
||||||
|
docs/*.md
|
|
@ -15,12 +15,12 @@ gazelle(
|
||||||
|
|
||||||
# This declares the release artifact users
|
# This declares the release artifact users
|
||||||
pkg_tar(
|
pkg_tar(
|
||||||
name = "rules_mylang-" + VERSION,
|
name = "bazel_lib-" + VERSION,
|
||||||
srcs = [
|
srcs = [
|
||||||
"LICENSE",
|
"LICENSE",
|
||||||
"README.md",
|
"README.md",
|
||||||
"version.bzl",
|
"version.bzl",
|
||||||
"//mylang:package_content",
|
"//lib:package_content",
|
||||||
],
|
],
|
||||||
extension = "tar.gz",
|
extension = "tar.gz",
|
||||||
# It is all source code, so make it read-only.
|
# It is all source code, so make it read-only.
|
||||||
|
|
|
@ -22,7 +22,7 @@ Run `bazel run //:gazelle` to keep them up-to-date.
|
||||||
## Using this as a development dependency of other rules
|
## Using this as a development dependency of other rules
|
||||||
|
|
||||||
You'll commonly find that you develop in another WORKSPACE, such as
|
You'll commonly find that you develop in another WORKSPACE, such as
|
||||||
some other ruleset that depends on rules_mylang, or in a nested
|
some other ruleset that depends on bazel_lib, or in a nested
|
||||||
WORKSPACE in the integration_tests folder.
|
WORKSPACE in the integration_tests folder.
|
||||||
|
|
||||||
To always tell Bazel to use this directory rather than some release
|
To always tell Bazel to use this directory rather than some release
|
||||||
|
@ -30,9 +30,9 @@ artifact or a version fetched from the internet, run this from this
|
||||||
directory:
|
directory:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
OVERRIDE="--override_repository=rules_mylang=$(pwd)/rules_mylang"
|
OVERRIDE="--override_repository=bazel_lib=$(pwd)/bazel_lib"
|
||||||
echo "build $OVERRIDE" >> ~/.bazelrc
|
echo "build $OVERRIDE" >> ~/.bazelrc
|
||||||
echo "query $OVERRIDE" >> ~/.bazelrc
|
echo "query $OVERRIDE" >> ~/.bazelrc
|
||||||
```
|
```
|
||||||
|
|
||||||
This means that any usage of `@rules_mylang` on your system will point to this folder.
|
This means that any usage of `@aspect_bazel_lib` on your system will point to this folder.
|
||||||
|
|
202
LICENSE
202
LICENSE
|
@ -1,202 +0,0 @@
|
||||||
|
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright [yyyy] [name of copyright owner]
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
48
README.md
48
README.md
|
@ -1,31 +1,9 @@
|
||||||
# Template for Bazel rules
|
# Aspect's Bazel helpers library
|
||||||
|
|
||||||
Copy this template to create a Bazel ruleset.
|
This is code we would contribute to bazel-skylib,
|
||||||
|
but the declared scope of that project is narrow
|
||||||
Features:
|
and it's very difficult to get anyone's attention
|
||||||
|
to review PRs there.
|
||||||
- follows the official style guide at https://docs.bazel.build/versions/main/skylark/deploying.html
|
|
||||||
- includes Bazel formatting as a pre-commit hook (using [buildifier])
|
|
||||||
- includes typical toolchain setup
|
|
||||||
- CI configured with GitHub Actions
|
|
||||||
- Release on GitHub Actions when pushing a tag
|
|
||||||
|
|
||||||
See https://docs.bazel.build/versions/main/skylark/deploying.html#readme
|
|
||||||
|
|
||||||
[buildifier]: https://github.com/bazelbuild/buildtools/tree/master/buildifier#readme
|
|
||||||
|
|
||||||
Ready to get started? Copy this repo, then
|
|
||||||
|
|
||||||
1. search for "com_myorg_rules_mylang" and replace with the name you'll use for your workspace
|
|
||||||
1. search for "mylang" and replace with the language/tool your rules are for
|
|
||||||
1. rename directory "mylang" similarly
|
|
||||||
1. run `pre-commit install` to get lints (see CONTRIBUTING.md)
|
|
||||||
1. if you don't need to fetch platform-dependent tools, then remove anything toolchain-related.
|
|
||||||
1. delete this section of the README (everything up to the SNIP).
|
|
||||||
|
|
||||||
---- SNIP ----
|
|
||||||
|
|
||||||
# Bazel rules for mylang
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
@ -34,22 +12,12 @@ Include this in your WORKSPACE file:
|
||||||
```starlark
|
```starlark
|
||||||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||||
http_archive(
|
http_archive(
|
||||||
name = "com_myorg_rules_mylang",
|
name = "aspect_bazel_lib",
|
||||||
url = "https://github.com/myorg/rules_mylang/releases/download/0.0.0/rules_mylang-0.0.0.tar.gz",
|
url = "https://github.com/myorg/bazel_lib/releases/download/0.0.0/bazel_lib-0.0.0.tar.gz",
|
||||||
sha256 = "",
|
sha256 = "",
|
||||||
)
|
)
|
||||||
|
|
||||||
load("@com_myorg_rules_mylang//mylang:repositories.bzl", "mylang_rules_dependencies")
|
|
||||||
|
|
||||||
# This fetches the rules_mylang dependencies, which are:
|
|
||||||
# - bazel_skylib
|
|
||||||
# If you want to have a different version of some dependency,
|
|
||||||
# you should fetch it *before* calling this.
|
|
||||||
# Alternatively, you can skip calling this function, so long as you've
|
|
||||||
# already fetched these dependencies.
|
|
||||||
rules_mylang_dependencies()
|
|
||||||
```
|
```
|
||||||
|
|
||||||
> note, in the above, replace the version and sha256 with the one indicated
|
> note, in the above, replace the version and sha256 with the one indicated
|
||||||
> in the release notes for rules_mylang
|
> in the release notes for bazel_lib
|
||||||
> In the future, our release automation should take care of this.
|
> In the future, our release automation should take care of this.
|
||||||
|
|
19
WORKSPACE
19
WORKSPACE
|
@ -1,27 +1,14 @@
|
||||||
# Declare the local Bazel workspace.
|
# Declare the local Bazel workspace.
|
||||||
# This is *not* included in the published distribution.
|
# This is *not* included in the published distribution.
|
||||||
workspace(
|
workspace(
|
||||||
# If your ruleset is "official"
|
|
||||||
# (i.e. is in the bazelbuild GitHub org)
|
|
||||||
# then this should just be named "rules_mylang"
|
|
||||||
# see https://docs.bazel.build/versions/main/skylark/deploying.html#workspace
|
# see https://docs.bazel.build/versions/main/skylark/deploying.html#workspace
|
||||||
name = "com_myorg_rules_mylang",
|
name = "aspect_bazel_lib",
|
||||||
)
|
)
|
||||||
|
|
||||||
load(":internal_deps.bzl", "rules_mylang_internal_deps")
|
load(":internal_deps.bzl", "bazel_lib_internal_deps")
|
||||||
|
|
||||||
# Fetch deps needed only locally for development
|
# Fetch deps needed only locally for development
|
||||||
rules_mylang_internal_deps()
|
bazel_lib_internal_deps()
|
||||||
|
|
||||||
load("//mylang:repositories.bzl", "mylang_register_toolchains", "rules_mylang_dependencies")
|
|
||||||
|
|
||||||
# Fetch our "runtime" dependencies which users need as well
|
|
||||||
rules_mylang_dependencies()
|
|
||||||
|
|
||||||
mylang_register_toolchains(
|
|
||||||
name = "mylang1_14",
|
|
||||||
mylang_version = "1.14.2",
|
|
||||||
)
|
|
||||||
|
|
||||||
############################################
|
############################################
|
||||||
# Gazelle, for generating bzl_library targets
|
# Gazelle, for generating bzl_library targets
|
||||||
|
|
|
@ -5,10 +5,11 @@ load("@bazel_skylib//rules:write_file.bzl", "write_file")
|
||||||
load("@io_bazel_stardoc//stardoc:stardoc.bzl", "stardoc")
|
load("@io_bazel_stardoc//stardoc:stardoc.bzl", "stardoc")
|
||||||
|
|
||||||
# Dictionary mapping from the label of a starlark module
|
# Dictionary mapping from the label of a starlark module
|
||||||
# (like //mylang:some.bzl) to the markdown file in this
|
# (like //lib:some.bzl) to the markdown file in this
|
||||||
# folder where the API docs are written.
|
# folder where the API docs are written.
|
||||||
_DOCS = {
|
_DOCS = {
|
||||||
"//mylang:defs.bzl": "rules.md",
|
"//lib:expand_make_vars.bzl": "expand_make_vars.md",
|
||||||
|
"//lib:params_file.bzl": "params_file.md",
|
||||||
}
|
}
|
||||||
|
|
||||||
[
|
[
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
<!-- Generated with Stardoc: http://skydoc.bazel.build -->
|
||||||
|
|
||||||
|
Public API for expanding variables
|
||||||
|
|
||||||
|
<a id="#expand_locations"></a>
|
||||||
|
|
||||||
|
## expand_locations
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
expand_locations(<a href="#expand_locations-ctx">ctx</a>, <a href="#expand_locations-input">input</a>, <a href="#expand_locations-targets">targets</a>)
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
Expand location templates.
|
||||||
|
|
||||||
|
Expands all `$(execpath ...)`, `$(rootpath ...)` and legacy `$(location ...)` templates in the
|
||||||
|
given string by replacing with the expanded path. Expansion only works for labels that point to direct dependencies
|
||||||
|
of this rule or that are explicitly listed in the optional argument targets.
|
||||||
|
|
||||||
|
See https://docs.bazel.build/versions/main/be/make-variables.html#predefined_label_variables.
|
||||||
|
|
||||||
|
Use `$(rootpath)` and `$(rootpaths)` to expand labels to the runfiles path that a built binary can use
|
||||||
|
to find its dependencies. This path is of the format:
|
||||||
|
- `./file`
|
||||||
|
- `path/to/file`
|
||||||
|
- `../external_repo/path/to/file`
|
||||||
|
|
||||||
|
Use `$(execpath)` and `$(execpaths)` to expand labels to the execroot (where Bazel runs build actions).
|
||||||
|
This is of the format:
|
||||||
|
- `./file`
|
||||||
|
- `path/to/file`
|
||||||
|
- `external/external_repo/path/to/file`
|
||||||
|
- `<bin_dir>/path/to/file`
|
||||||
|
- `<bin_dir>/external/external_repo/path/to/file`
|
||||||
|
|
||||||
|
The legacy `$(location)` and `$(locations)` expansions are deprecated as they return the runfiles manifest path of the
|
||||||
|
format `repo/path/to/file` which behave differently than the built-in `$(location)` expansion in args of *_binary
|
||||||
|
and *_test rules which returns the rootpath.
|
||||||
|
See https://docs.bazel.build/versions/main/be/common-definitions.html#common-attributes-binaries.
|
||||||
|
|
||||||
|
The legacy `$(location)` and `$(locations)` expansion also differs from how the builtin `ctx.expand_location()` expansions
|
||||||
|
of `$(location)` and `$(locations)` behave as that function returns either the execpath or rootpath depending on the context.
|
||||||
|
See https://docs.bazel.build/versions/main/be/make-variables.html#predefined_label_variables.
|
||||||
|
|
||||||
|
The behavior of `$(location)` and `$(locations)` expansion will be fixed in a future major release to match the
|
||||||
|
to default Bazel behavior and return the same path as `ctx.expand_location()` returns for these.
|
||||||
|
|
||||||
|
The recommended approach is to now use `$(rootpath)` where you previously used $(location). See the docstrings
|
||||||
|
of `nodejs_binary` or `params_file` for examples of how to use `$(rootpath)` in `templated_args` and `args` respectively.
|
||||||
|
|
||||||
|
|
||||||
|
**PARAMETERS**
|
||||||
|
|
||||||
|
|
||||||
|
| Name | Description | Default Value |
|
||||||
|
| :------------- | :------------- | :------------- |
|
||||||
|
| <a id="expand_locations-ctx"></a>ctx | context | none |
|
||||||
|
| <a id="expand_locations-input"></a>input | String to be expanded | none |
|
||||||
|
| <a id="expand_locations-targets"></a>targets | List of targets for additional lookup information. | <code>[]</code> |
|
||||||
|
|
||||||
|
**RETURNS**
|
||||||
|
|
||||||
|
The expanded path or the original path
|
||||||
|
|
||||||
|
|
||||||
|
<a id="#expand_variables"></a>
|
||||||
|
|
||||||
|
## expand_variables
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
expand_variables(<a href="#expand_variables-ctx">ctx</a>, <a href="#expand_variables-s">s</a>, <a href="#expand_variables-outs">outs</a>, <a href="#expand_variables-output_dir">output_dir</a>, <a href="#expand_variables-attribute_name">attribute_name</a>)
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
Expand make variables and substitute like genrule does.
|
||||||
|
|
||||||
|
This function is the same as ctx.expand_make_variables with the additional
|
||||||
|
genrule-like substitutions of:
|
||||||
|
|
||||||
|
- $@: The output file if it is a single file. Else triggers a build error.
|
||||||
|
- $(@D): The output directory. If there is only one file name in outs,
|
||||||
|
this expands to the directory containing that file. If there are multiple files,
|
||||||
|
this instead expands to the package's root directory in the bin tree,
|
||||||
|
even if all generated files belong to the same subdirectory!
|
||||||
|
- $(RULEDIR): The output directory of the rule, that is, the directory
|
||||||
|
corresponding to the name of the package containing the rule under the bin tree.
|
||||||
|
|
||||||
|
See https://docs.bazel.build/versions/main/be/general.html#genrule.cmd and
|
||||||
|
https://docs.bazel.build/versions/main/be/make-variables.html#predefined_genrule_variables
|
||||||
|
for more information of how these special variables are expanded.
|
||||||
|
|
||||||
|
|
||||||
|
**PARAMETERS**
|
||||||
|
|
||||||
|
|
||||||
|
| Name | Description | Default Value |
|
||||||
|
| :------------- | :------------- | :------------- |
|
||||||
|
| <a id="expand_variables-ctx"></a>ctx | starlark rule context | none |
|
||||||
|
| <a id="expand_variables-s"></a>s | expression to expand | none |
|
||||||
|
| <a id="expand_variables-outs"></a>outs | declared outputs of the rule, for expanding references to outputs | <code>[]</code> |
|
||||||
|
| <a id="expand_variables-output_dir"></a>output_dir | whether the rule is expected to output a directory (TreeArtifact) | <code>False</code> |
|
||||||
|
| <a id="expand_variables-attribute_name"></a>attribute_name | name of the attribute containing the expression | <code>"args"</code> |
|
||||||
|
|
||||||
|
**RETURNS**
|
||||||
|
|
||||||
|
s with the variables expanded
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
<!-- Generated with Stardoc: http://skydoc.bazel.build -->
|
||||||
|
|
||||||
|
params_file public API
|
||||||
|
|
||||||
|
<a id="#params_file"></a>
|
||||||
|
|
||||||
|
## params_file
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
params_file(<a href="#params_file-name">name</a>, <a href="#params_file-out">out</a>, <a href="#params_file-args">args</a>, <a href="#params_file-data">data</a>, <a href="#params_file-newline">newline</a>, <a href="#params_file-kwargs">kwargs</a>)
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
Generates a UTF-8 encoded params file from a list of arguments.
|
||||||
|
|
||||||
|
Handles variable substitutions for args.
|
||||||
|
|
||||||
|
|
||||||
|
**PARAMETERS**
|
||||||
|
|
||||||
|
|
||||||
|
| Name | Description | Default Value |
|
||||||
|
| :------------- | :------------- | :------------- |
|
||||||
|
| <a id="params_file-name"></a>name | Name of the rule. | none |
|
||||||
|
| <a id="params_file-out"></a>out | Path of the output file, relative to this package. | none |
|
||||||
|
| <a id="params_file-args"></a>args | Arguments to concatenate into a params file.<br><br>Subject to 'Make variable' substitution. See https://docs.bazel.build/versions/main/be/make-variables.html.<br><br>1. Subject to predefined source/output path variables substitutions.<br><br>The predefined variables <code>execpath</code>, <code>execpaths</code>, <code>rootpath</code>, <code>rootpaths</code>, <code>location</code>, and <code>locations</code> take label parameters (e.g. <code>$(execpath //foo:bar)</code>) and substitute the file paths denoted by that label.<br><br>See https://docs.bazel.build/versions/main/be/make-variables.html#predefined_label_variables for more info.<br><br>NB: This $(location) substition returns the manifest file path which differs from the *_binary & *_test args and genrule bazel substitions. This will be fixed in a future major release. See docs string of <code>expand_location_into_runfiles</code> macro in <code>internal/common/expand_into_runfiles.bzl</code> for more info.<br><br>2. Subject to predefined variables & custom variable substitutions.<br><br>Predefined "Make" variables such as $(COMPILATION_MODE) and $(TARGET_CPU) are expanded. See https://docs.bazel.build/versions/main/be/make-variables.html#predefined_variables.<br><br>Custom variables are also expanded including variables set through the Bazel CLI with --define=SOME_VAR=SOME_VALUE. See https://docs.bazel.build/versions/main/be/make-variables.html#custom_variables.<br><br>Predefined genrule variables are not supported in this context. | <code>[]</code> |
|
||||||
|
| <a id="params_file-data"></a>data | Data for $(location) expansions in args. | <code>[]</code> |
|
||||||
|
| <a id="params_file-newline"></a>newline | Line endings to use. One of ["auto", "unix", "windows"].<br><br>"auto" for platform-determined "unix" for LF "windows" for CRLF | <code>"auto"</code> |
|
||||||
|
| <a id="params_file-kwargs"></a>kwargs | undocumented named arguments | none |
|
||||||
|
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
<!-- Generated with Stardoc: http://skydoc.bazel.build -->
|
|
||||||
|
|
||||||
Public API re-exports
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ statement from these, that's a bug in our distribution.
|
||||||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||||
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
|
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
|
||||||
|
|
||||||
def rules_mylang_internal_deps():
|
def bazel_lib_internal_deps():
|
||||||
"Fetch deps needed for local development"
|
"Fetch deps needed for local development"
|
||||||
maybe(
|
maybe(
|
||||||
http_archive,
|
http_archive,
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
|
||||||
|
|
||||||
|
# For stardoc to reference the files
|
||||||
|
exports_files([
|
||||||
|
"expand_make_vars.bzl",
|
||||||
|
"params_file.bzl",
|
||||||
|
])
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "package_content",
|
||||||
|
srcs = glob([
|
||||||
|
"*.bzl",
|
||||||
|
"*.bazel",
|
||||||
|
]) + [
|
||||||
|
"//lib/private:package_content",
|
||||||
|
],
|
||||||
|
visibility = ["//:__pkg__"],
|
||||||
|
)
|
||||||
|
|
||||||
|
bzl_library(
|
||||||
|
name = "expand_make_vars",
|
||||||
|
srcs = ["expand_make_vars.bzl"],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = ["//lib/private:expand_make_vars"],
|
||||||
|
)
|
||||||
|
|
||||||
|
bzl_library(
|
||||||
|
name = "params_file",
|
||||||
|
srcs = ["params_file.bzl"],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = ["//lib/private:params_file"],
|
||||||
|
)
|
|
@ -0,0 +1,10 @@
|
||||||
|
"Public API for expanding variables"
|
||||||
|
|
||||||
|
load(
|
||||||
|
"//lib/private:expand_make_vars.bzl",
|
||||||
|
_expand_locations = "expand_locations",
|
||||||
|
_expand_variables = "expand_variables",
|
||||||
|
)
|
||||||
|
|
||||||
|
expand_locations = _expand_locations
|
||||||
|
expand_variables = _expand_variables
|
|
@ -0,0 +1,64 @@
|
||||||
|
"params_file public API"
|
||||||
|
|
||||||
|
load("//lib/private:params_file.bzl", _params_file = "params_file")
|
||||||
|
|
||||||
|
def params_file(
|
||||||
|
name,
|
||||||
|
out,
|
||||||
|
args = [],
|
||||||
|
data = [],
|
||||||
|
newline = "auto",
|
||||||
|
**kwargs):
|
||||||
|
"""Generates a UTF-8 encoded params file from a list of arguments.
|
||||||
|
|
||||||
|
Handles variable substitutions for args.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name: Name of the rule.
|
||||||
|
out: Path of the output file, relative to this package.
|
||||||
|
args: Arguments to concatenate into a params file.
|
||||||
|
|
||||||
|
Subject to 'Make variable' substitution. See https://docs.bazel.build/versions/main/be/make-variables.html.
|
||||||
|
|
||||||
|
1. Subject to predefined source/output path variables substitutions.
|
||||||
|
|
||||||
|
The predefined variables `execpath`, `execpaths`, `rootpath`, `rootpaths`, `location`, and `locations` take
|
||||||
|
label parameters (e.g. `$(execpath //foo:bar)`) and substitute the file paths denoted by that label.
|
||||||
|
|
||||||
|
See https://docs.bazel.build/versions/main/be/make-variables.html#predefined_label_variables for more info.
|
||||||
|
|
||||||
|
NB: This $(location) substition returns the manifest file path which differs from the *_binary & *_test
|
||||||
|
args and genrule bazel substitions. This will be fixed in a future major release.
|
||||||
|
See docs string of `expand_location_into_runfiles` macro in `internal/common/expand_into_runfiles.bzl`
|
||||||
|
for more info.
|
||||||
|
|
||||||
|
2. Subject to predefined variables & custom variable substitutions.
|
||||||
|
|
||||||
|
Predefined "Make" variables such as $(COMPILATION_MODE) and $(TARGET_CPU) are expanded.
|
||||||
|
See https://docs.bazel.build/versions/main/be/make-variables.html#predefined_variables.
|
||||||
|
|
||||||
|
Custom variables are also expanded including variables set through the Bazel CLI with --define=SOME_VAR=SOME_VALUE.
|
||||||
|
See https://docs.bazel.build/versions/main/be/make-variables.html#custom_variables.
|
||||||
|
|
||||||
|
Predefined genrule variables are not supported in this context.
|
||||||
|
|
||||||
|
data: Data for $(location) expansions in args.
|
||||||
|
newline: Line endings to use. One of ["auto", "unix", "windows"].
|
||||||
|
|
||||||
|
"auto" for platform-determined
|
||||||
|
"unix" for LF
|
||||||
|
"windows" for CRLF
|
||||||
|
**kwargs: undocumented named arguments
|
||||||
|
"""
|
||||||
|
_params_file(
|
||||||
|
name = name,
|
||||||
|
out = out,
|
||||||
|
args = args,
|
||||||
|
data = data,
|
||||||
|
newline = newline or "auto",
|
||||||
|
is_windows = select({
|
||||||
|
"@bazel_tools//src/conditions:host_windows": True,
|
||||||
|
"//conditions:default": False,
|
||||||
|
}),
|
||||||
|
**kwargs
|
||||||
|
)
|
|
@ -0,0 +1,23 @@
|
||||||
|
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "package_content",
|
||||||
|
srcs = glob([
|
||||||
|
"*.bzl",
|
||||||
|
"*.bazel",
|
||||||
|
]),
|
||||||
|
visibility = ["//lib:__pkg__"],
|
||||||
|
)
|
||||||
|
|
||||||
|
bzl_library(
|
||||||
|
name = "params_file",
|
||||||
|
srcs = ["params_file.bzl"],
|
||||||
|
visibility = ["//lib:__subpackages__"],
|
||||||
|
deps = [":expand_make_vars"],
|
||||||
|
)
|
||||||
|
|
||||||
|
bzl_library(
|
||||||
|
name = "expand_make_vars",
|
||||||
|
srcs = ["expand_make_vars.bzl"],
|
||||||
|
visibility = ["//lib:__subpackages__"],
|
||||||
|
)
|
|
@ -0,0 +1,164 @@
|
||||||
|
"Helpers to expand make variables"
|
||||||
|
|
||||||
|
# Convert an runfiles rootpath to a runfiles manifestpath.
|
||||||
|
# Runfiles rootpath is returned from ctx.expand_location $(rootpath) and $(rootpaths):
|
||||||
|
# - ./file
|
||||||
|
# - path/to/file
|
||||||
|
# - ../external_repo/path/to/file
|
||||||
|
# This is converted to the runfiles manifest path of:
|
||||||
|
# - repo/path/to/file
|
||||||
|
def _rootpath_to_runfiles_manifest_path(ctx, path, targets):
|
||||||
|
if path.startswith("../"):
|
||||||
|
return path[len("../"):]
|
||||||
|
if path.startswith("./"):
|
||||||
|
path = path[len("./"):]
|
||||||
|
return ctx.workspace_name + "/" + path
|
||||||
|
|
||||||
|
# Expand $(rootpath) and $(rootpaths) to runfiles manifest path.
|
||||||
|
# Runfiles manifest path is of the form:
|
||||||
|
# - repo/path/to/file
|
||||||
|
def _expand_rootpath_to_manifest_path(ctx, input, targets):
|
||||||
|
paths = ctx.expand_location(input, targets)
|
||||||
|
return " ".join([_rootpath_to_runfiles_manifest_path(ctx, p, targets) for p in paths.split(" ")])
|
||||||
|
|
||||||
|
def expand_locations(ctx, input, targets = []):
|
||||||
|
"""Expand location templates.
|
||||||
|
|
||||||
|
Expands all `$(execpath ...)`, `$(rootpath ...)` and legacy `$(location ...)` templates in the
|
||||||
|
given string by replacing with the expanded path. Expansion only works for labels that point to direct dependencies
|
||||||
|
of this rule or that are explicitly listed in the optional argument targets.
|
||||||
|
|
||||||
|
See https://docs.bazel.build/versions/main/be/make-variables.html#predefined_label_variables.
|
||||||
|
|
||||||
|
Use `$(rootpath)` and `$(rootpaths)` to expand labels to the runfiles path that a built binary can use
|
||||||
|
to find its dependencies. This path is of the format:
|
||||||
|
- `./file`
|
||||||
|
- `path/to/file`
|
||||||
|
- `../external_repo/path/to/file`
|
||||||
|
|
||||||
|
Use `$(execpath)` and `$(execpaths)` to expand labels to the execroot (where Bazel runs build actions).
|
||||||
|
This is of the format:
|
||||||
|
- `./file`
|
||||||
|
- `path/to/file`
|
||||||
|
- `external/external_repo/path/to/file`
|
||||||
|
- `<bin_dir>/path/to/file`
|
||||||
|
- `<bin_dir>/external/external_repo/path/to/file`
|
||||||
|
|
||||||
|
The legacy `$(location)` and `$(locations)` expansions are deprecated as they return the runfiles manifest path of the
|
||||||
|
format `repo/path/to/file` which behave differently than the built-in `$(location)` expansion in args of *_binary
|
||||||
|
and *_test rules which returns the rootpath.
|
||||||
|
See https://docs.bazel.build/versions/main/be/common-definitions.html#common-attributes-binaries.
|
||||||
|
|
||||||
|
The legacy `$(location)` and `$(locations)` expansion also differs from how the builtin `ctx.expand_location()` expansions
|
||||||
|
of `$(location)` and `$(locations)` behave as that function returns either the execpath or rootpath depending on the context.
|
||||||
|
See https://docs.bazel.build/versions/main/be/make-variables.html#predefined_label_variables.
|
||||||
|
|
||||||
|
The behavior of `$(location)` and `$(locations)` expansion will be fixed in a future major release to match the
|
||||||
|
to default Bazel behavior and return the same path as `ctx.expand_location()` returns for these.
|
||||||
|
|
||||||
|
The recommended approach is to now use `$(rootpath)` where you previously used $(location). See the docstrings
|
||||||
|
of `nodejs_binary` or `params_file` for examples of how to use `$(rootpath)` in `templated_args` and `args` respectively.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
ctx: context
|
||||||
|
input: String to be expanded
|
||||||
|
targets: List of targets for additional lookup information.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The expanded path or the original path
|
||||||
|
"""
|
||||||
|
target = "@%s//%s:%s" % (ctx.workspace_name, "/".join(ctx.build_file_path.split("/")[:-1]), ctx.attr.name)
|
||||||
|
|
||||||
|
# Loop through input an expand all predefined source/output path variables
|
||||||
|
# See https://docs.bazel.build/versions/main/be/make-variables.html#predefined_label_variables.
|
||||||
|
path = ""
|
||||||
|
length = len(input)
|
||||||
|
last = 0
|
||||||
|
for i in range(length):
|
||||||
|
# Support legacy $(location) and $(locations) expansions which return the runfiles manifest path
|
||||||
|
# in the format `repo/path/to/file`. This expansion is DEPRECATED. See docstring above.
|
||||||
|
# TODO: Change location to behave the same as the built-in $(location) expansion for args of *_binary
|
||||||
|
# and *_test rules. This would be a BREAKING CHANGE.
|
||||||
|
if input[i:].startswith("$(location ") or input[i:].startswith("$(locations "):
|
||||||
|
j = input.find(")", i) + 1
|
||||||
|
if (j == 0):
|
||||||
|
fail("invalid \"%s\" expansion in string \"%s\" part of target %s" % (input[i:j], input, target))
|
||||||
|
path += input[last:i]
|
||||||
|
path += _expand_rootpath_to_manifest_path(ctx, "$(rootpath" + input[i + 10:j], targets)
|
||||||
|
last = j
|
||||||
|
i = j
|
||||||
|
|
||||||
|
# Expand $(execpath) $(execpaths) $(rootpath) $(rootpaths) with plain ctx.expand_location()
|
||||||
|
if input[i:].startswith("$(execpath ") or input[i:].startswith("$(execpaths ") or input[i:].startswith("$(rootpath ") or input[i:].startswith("$(rootpaths "):
|
||||||
|
j = input.find(")", i) + 1
|
||||||
|
if (j == 0):
|
||||||
|
fail("invalid \"%s\" expansion in string \"%s\" part of target %s" % (input[i:j], input, target))
|
||||||
|
path += input[last:i]
|
||||||
|
path += ctx.expand_location(input[i:j], targets)
|
||||||
|
last = j
|
||||||
|
i = j
|
||||||
|
path += input[last:]
|
||||||
|
|
||||||
|
return path
|
||||||
|
|
||||||
|
def expand_variables(ctx, s, outs = [], output_dir = False, attribute_name = "args"):
|
||||||
|
"""Expand make variables and substitute like genrule does.
|
||||||
|
|
||||||
|
This function is the same as ctx.expand_make_variables with the additional
|
||||||
|
genrule-like substitutions of:
|
||||||
|
|
||||||
|
- $@: The output file if it is a single file. Else triggers a build error.
|
||||||
|
- $(@D): The output directory. If there is only one file name in outs,
|
||||||
|
this expands to the directory containing that file. If there are multiple files,
|
||||||
|
this instead expands to the package's root directory in the bin tree,
|
||||||
|
even if all generated files belong to the same subdirectory!
|
||||||
|
- $(RULEDIR): The output directory of the rule, that is, the directory
|
||||||
|
corresponding to the name of the package containing the rule under the bin tree.
|
||||||
|
|
||||||
|
See https://docs.bazel.build/versions/main/be/general.html#genrule.cmd and
|
||||||
|
https://docs.bazel.build/versions/main/be/make-variables.html#predefined_genrule_variables
|
||||||
|
for more information of how these special variables are expanded.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
ctx: starlark rule context
|
||||||
|
s: expression to expand
|
||||||
|
outs: declared outputs of the rule, for expanding references to outputs
|
||||||
|
output_dir: whether the rule is expected to output a directory (TreeArtifact)
|
||||||
|
attribute_name: name of the attribute containing the expression
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
s with the variables expanded
|
||||||
|
"""
|
||||||
|
rule_dir = [f for f in [
|
||||||
|
ctx.bin_dir.path,
|
||||||
|
ctx.label.workspace_root,
|
||||||
|
ctx.label.package,
|
||||||
|
] if f]
|
||||||
|
additional_substitutions = {}
|
||||||
|
|
||||||
|
if output_dir:
|
||||||
|
if s.find("$@") != -1 or s.find("$(@)") != -1:
|
||||||
|
fail("$@ substitution may only be used with output_dir=False.")
|
||||||
|
|
||||||
|
# We'll write into a newly created directory named after the rule
|
||||||
|
output_dir = [f for f in [
|
||||||
|
ctx.bin_dir.path,
|
||||||
|
ctx.label.workspace_root,
|
||||||
|
ctx.label.package,
|
||||||
|
ctx.label.name,
|
||||||
|
] if f]
|
||||||
|
else:
|
||||||
|
if s.find("$@") != -1 or s.find("$(@)") != -1:
|
||||||
|
if len(outs) > 1:
|
||||||
|
fail("$@ substitution may only be used with a single out.")
|
||||||
|
if len(outs) == 1:
|
||||||
|
additional_substitutions["@"] = outs[0].path
|
||||||
|
output_dir = outs[0].dirname.split("/")
|
||||||
|
else:
|
||||||
|
output_dir = rule_dir[:]
|
||||||
|
|
||||||
|
# The list comprehension removes empty segments like if we are in the root package
|
||||||
|
additional_substitutions["@D"] = "/".join([o for o in output_dir if o])
|
||||||
|
additional_substitutions["RULEDIR"] = "/".join([o for o in rule_dir if o])
|
||||||
|
|
||||||
|
return ctx.expand_make_variables(attribute_name, s, additional_substitutions)
|
|
@ -0,0 +1,57 @@
|
||||||
|
"params_file rule"
|
||||||
|
|
||||||
|
load("//lib/private:expand_make_vars.bzl", "expand_locations")
|
||||||
|
|
||||||
|
_DOC = """Generates a params file from a list of arguments."""
|
||||||
|
|
||||||
|
# See params_file macro below for docstrings
|
||||||
|
_ATTRS = {
|
||||||
|
"args": attr.string_list(),
|
||||||
|
"data": attr.label_list(allow_files = True),
|
||||||
|
"is_windows": attr.bool(mandatory = True),
|
||||||
|
"newline": attr.string(
|
||||||
|
values = ["unix", "windows", "auto"],
|
||||||
|
default = "auto",
|
||||||
|
),
|
||||||
|
"out": attr.output(mandatory = True),
|
||||||
|
}
|
||||||
|
|
||||||
|
def _expand_locations(ctx, s):
|
||||||
|
# `.split(" ")` is a work-around https://github.com/bazelbuild/bazel/issues/10309
|
||||||
|
# TODO: If the string has intentional spaces or if one or more of the expanded file
|
||||||
|
# locations has a space in the name, we will incorrectly split it into multiple arguments
|
||||||
|
return expand_locations(ctx, s, targets = ctx.attr.data).split(" ")
|
||||||
|
|
||||||
|
def _impl(ctx):
|
||||||
|
if ctx.attr.newline == "auto":
|
||||||
|
newline = "\r\n" if ctx.attr.is_windows else "\n"
|
||||||
|
elif ctx.attr.newline == "windows":
|
||||||
|
newline = "\r\n"
|
||||||
|
else:
|
||||||
|
newline = "\n"
|
||||||
|
|
||||||
|
expanded_args = []
|
||||||
|
|
||||||
|
# First expand predefined source/output path variables
|
||||||
|
for a in ctx.attr.args:
|
||||||
|
expanded_args += _expand_locations(ctx, a)
|
||||||
|
|
||||||
|
# Next expand predefined variables & custom variables
|
||||||
|
expanded_args = [ctx.expand_make_variables("args", e, {}) for e in expanded_args]
|
||||||
|
|
||||||
|
# ctx.actions.write creates a FileWriteAction which uses UTF-8 encoding.
|
||||||
|
ctx.actions.write(
|
||||||
|
output = ctx.outputs.out,
|
||||||
|
content = newline.join(expanded_args),
|
||||||
|
is_executable = False,
|
||||||
|
)
|
||||||
|
files = depset(direct = [ctx.outputs.out])
|
||||||
|
runfiles = ctx.runfiles(files = [ctx.outputs.out])
|
||||||
|
return [DefaultInfo(files = files, runfiles = runfiles)]
|
||||||
|
|
||||||
|
params_file = rule(
|
||||||
|
implementation = _impl,
|
||||||
|
provides = [DefaultInfo],
|
||||||
|
attrs = _ATTRS,
|
||||||
|
doc = _DOC,
|
||||||
|
)
|
|
@ -1,47 +0,0 @@
|
||||||
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
|
|
||||||
|
|
||||||
# For stardoc to reference the files
|
|
||||||
exports_files(["defs.bzl"])
|
|
||||||
|
|
||||||
# This is the target rule authors should put in their "toolchains"
|
|
||||||
# attribute in order to get a runtime for the correct platform.
|
|
||||||
# See https://docs.bazel.build/versions/main/toolchains.html#writing-rules-that-use-toolchains
|
|
||||||
toolchain_type(
|
|
||||||
name = "toolchain_type",
|
|
||||||
visibility = ["//visibility:public"],
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "package_content",
|
|
||||||
srcs = glob([
|
|
||||||
"*.bzl",
|
|
||||||
"*.bazel",
|
|
||||||
]) + [
|
|
||||||
"//mylang/private:package_content",
|
|
||||||
],
|
|
||||||
visibility = ["//:__pkg__"],
|
|
||||||
)
|
|
||||||
|
|
||||||
bzl_library(
|
|
||||||
name = "defs",
|
|
||||||
srcs = ["defs.bzl"],
|
|
||||||
visibility = ["//visibility:public"],
|
|
||||||
)
|
|
||||||
|
|
||||||
bzl_library(
|
|
||||||
name = "repositories",
|
|
||||||
srcs = ["repositories.bzl"],
|
|
||||||
visibility = ["//visibility:public"],
|
|
||||||
deps = [
|
|
||||||
"//mylang/private:toolchains_repo",
|
|
||||||
"//mylang/private:versions",
|
|
||||||
"@bazel_tools//tools/build_defs/repo:http.bzl",
|
|
||||||
"@bazel_tools//tools/build_defs/repo:utils.bzl",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
bzl_library(
|
|
||||||
name = "toolchain",
|
|
||||||
srcs = ["toolchain.bzl"],
|
|
||||||
visibility = ["//visibility:public"],
|
|
||||||
)
|
|
|
@ -1 +0,0 @@
|
||||||
"Public API re-exports"
|
|
|
@ -1,22 +0,0 @@
|
||||||
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "package_content",
|
|
||||||
srcs = glob([
|
|
||||||
"*.bzl",
|
|
||||||
"*.bazel",
|
|
||||||
]),
|
|
||||||
visibility = ["//mylang:__pkg__"],
|
|
||||||
)
|
|
||||||
|
|
||||||
bzl_library(
|
|
||||||
name = "toolchains_repo",
|
|
||||||
srcs = ["toolchains_repo.bzl"],
|
|
||||||
visibility = ["//mylang:__subpackages__"],
|
|
||||||
)
|
|
||||||
|
|
||||||
bzl_library(
|
|
||||||
name = "versions",
|
|
||||||
srcs = ["versions.bzl"],
|
|
||||||
visibility = ["//mylang:__subpackages__"],
|
|
||||||
)
|
|
|
@ -1,113 +0,0 @@
|
||||||
"""Create a repository to hold the toolchains
|
|
||||||
|
|
||||||
This follows guidance here:
|
|
||||||
https://docs.bazel.build/versions/main/skylark/deploying.html#registering-toolchains
|
|
||||||
"
|
|
||||||
Note that in order to resolve toolchains in the analysis phase
|
|
||||||
Bazel needs to analyze all toolchain targets that are registered.
|
|
||||||
Bazel will not need to analyze all targets referenced by toolchain.toolchain attribute.
|
|
||||||
If in order to register toolchains you need to perform complex computation in the repository,
|
|
||||||
consider splitting the repository with toolchain targets
|
|
||||||
from the repository with <LANG>_toolchain targets.
|
|
||||||
Former will be always fetched,
|
|
||||||
and the latter will only be fetched when user actually needs to build <LANG> code.
|
|
||||||
"
|
|
||||||
The "complex computation" in our case is simply downloading large artifacts.
|
|
||||||
This guidance tells us how to avoid that: we put the toolchain targets in the alias repository
|
|
||||||
with only the toolchain attribute pointing into the platform-specific repositories.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Add more platforms as needed to mirror all the binaries
|
|
||||||
# published by the upstream project.
|
|
||||||
PLATFORMS = {
|
|
||||||
"x86_64-apple-darwin": struct(
|
|
||||||
compatible_with = [
|
|
||||||
"@platforms//os:macos",
|
|
||||||
"@platforms//cpu:x86_64",
|
|
||||||
],
|
|
||||||
),
|
|
||||||
"aarch64-apple-darwin": struct(
|
|
||||||
compatible_with = [
|
|
||||||
"@platforms//os:macos",
|
|
||||||
"@platforms//cpu:aarch64",
|
|
||||||
],
|
|
||||||
),
|
|
||||||
"x86_64-unknown-linux-gnu": struct(
|
|
||||||
compatible_with = [
|
|
||||||
"@platforms//os:linux",
|
|
||||||
"@platforms//cpu:x86_64",
|
|
||||||
],
|
|
||||||
),
|
|
||||||
"x86_64-pc-windows-msvc": struct(
|
|
||||||
compatible_with = [
|
|
||||||
"@platforms//os:windows",
|
|
||||||
"@platforms//cpu:x86_64",
|
|
||||||
],
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
def _toolchains_repo_impl(repository_ctx):
|
|
||||||
# Expose a concrete toolchain which is the result of Bazel resolving the toolchain
|
|
||||||
# for the execution or target platform.
|
|
||||||
# Workaround for https://github.com/bazelbuild/bazel/issues/14009
|
|
||||||
starlark_content = """# Generated by toolchains_repo.bzl
|
|
||||||
|
|
||||||
# Forward all the providers
|
|
||||||
def _resolved_toolchain_impl(ctx):
|
|
||||||
toolchain_info = ctx.toolchains["@com_myorg_rules_mylang//mylang:toolchain_type"]
|
|
||||||
return [
|
|
||||||
toolchain_info,
|
|
||||||
toolchain_info.default,
|
|
||||||
toolchain_info.mylanginfo,
|
|
||||||
toolchain_info.template_variables,
|
|
||||||
]
|
|
||||||
|
|
||||||
# Copied from java_toolchain_alias
|
|
||||||
# https://cs.opensource.google/bazel/bazel/+/master:tools/jdk/java_toolchain_alias.bzl
|
|
||||||
resolved_toolchain = rule(
|
|
||||||
implementation = _resolved_toolchain_impl,
|
|
||||||
toolchains = ["@com_myorg_rules_mylang//mylang:toolchain_type"],
|
|
||||||
incompatible_use_toolchain_transition = True,
|
|
||||||
)
|
|
||||||
"""
|
|
||||||
repository_ctx.file("defs.bzl", starlark_content)
|
|
||||||
|
|
||||||
build_content = """# Generated by toolchains_repo.bzl
|
|
||||||
#
|
|
||||||
# These can be registered in the workspace file or passed to --extra_toolchains flag.
|
|
||||||
# By default all these toolchains are registered by the mylang_register_toolchains macro
|
|
||||||
# so you don't normally need to interact with these targets.
|
|
||||||
|
|
||||||
load(":defs.bzl", "resolved_toolchain")
|
|
||||||
|
|
||||||
resolved_toolchain(name = "resolved_toolchain", visibility = ["//visibility:public"])
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
for [platform, meta] in PLATFORMS.items():
|
|
||||||
build_content += """
|
|
||||||
toolchain(
|
|
||||||
name = "{platform}_toolchain",
|
|
||||||
exec_compatible_with = {compatible_with},
|
|
||||||
target_compatible_with = {compatible_with},
|
|
||||||
toolchain = "@{user_repository_name}_{platform}//:mylang_toolchain",
|
|
||||||
toolchain_type = "@com_myorg_rules_mylang//mylang:toolchain_type",
|
|
||||||
)
|
|
||||||
""".format(
|
|
||||||
platform = platform,
|
|
||||||
name = repository_ctx.attr.name,
|
|
||||||
user_repository_name = repository_ctx.attr.user_repository_name,
|
|
||||||
compatible_with = meta.compatible_with,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Base BUILD file for this repository
|
|
||||||
repository_ctx.file("BUILD.bazel", build_content)
|
|
||||||
|
|
||||||
toolchains_repo = repository_rule(
|
|
||||||
_toolchains_repo_impl,
|
|
||||||
doc = """Creates a repository with toolchain definitions for all known platforms
|
|
||||||
which can be registered or selected.""",
|
|
||||||
attrs = {
|
|
||||||
"user_repository_name": attr.string(doc = "what the user chose for the base name"),
|
|
||||||
},
|
|
||||||
)
|
|
|
@ -1,14 +0,0 @@
|
||||||
"""Mirror of release info
|
|
||||||
|
|
||||||
TODO: generate this file from GitHub API"""
|
|
||||||
|
|
||||||
# The integrity hashes can be computed with
|
|
||||||
# shasum -b -a 384 [downloaded file] | awk '{ print $1 }' | xxd -r -p | base64
|
|
||||||
TOOL_VERSIONS = {
|
|
||||||
"1.14.2": {
|
|
||||||
"x86_64-apple-darwin": "sha384-ws4+rANvv0YxM1SgIBUXSG9jT8dKw83nls6R5qYkEKzPUB+viBIEozSsyq2e6i+f",
|
|
||||||
"aarch64-apple-darwin": "sha384-HcvJbxoJtGSavkGu0e7CyD00cBlmDb0TBWJ4JSaNa70zuU3N7XlMOYm3bbQcAv2U",
|
|
||||||
"x86_64-pc-windows-msvc": "sha384-35YN6TKpT0L9qyRBmq48NucvyXEtHnkeC+txf2YZmmJTmOzrAKREA74BA0EZvpar",
|
|
||||||
"x86_64-unknown-linux-gnu": "sha384-QgGOwTaetxY0h5HWCKc/3ZtBs4N/fgaaORthn7UcEv++Idm9W+ntCCZRwvBdwHPD",
|
|
||||||
},
|
|
||||||
}
|
|
|
@ -1,88 +0,0 @@
|
||||||
"""Declare runtime dependencies
|
|
||||||
|
|
||||||
These are needed for local dev, and users must install them as well.
|
|
||||||
See https://docs.bazel.build/versions/main/skylark/deploying.html#dependencies
|
|
||||||
"""
|
|
||||||
|
|
||||||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
|
||||||
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
|
|
||||||
load("//mylang/private:toolchains_repo.bzl", "PLATFORMS", "toolchains_repo")
|
|
||||||
load("//mylang/private:versions.bzl", "TOOL_VERSIONS")
|
|
||||||
|
|
||||||
# WARNING: any changes in this function may be BREAKING CHANGES for users
|
|
||||||
# because we'll fetch a dependency which may be different from one that
|
|
||||||
# they were previously fetching later in their WORKSPACE setup, and now
|
|
||||||
# ours took precedence. Such breakages are challenging for users, so any
|
|
||||||
# changes in this function should be marked as BREAKING in the commit message
|
|
||||||
# and released only in semver majors.
|
|
||||||
def rules_mylang_dependencies():
|
|
||||||
# The minimal version of bazel_skylib we require
|
|
||||||
maybe(
|
|
||||||
http_archive,
|
|
||||||
name = "bazel_skylib",
|
|
||||||
sha256 = "c6966ec828da198c5d9adbaa94c05e3a1c7f21bd012a0b29ba8ddbccb2c93b0d",
|
|
||||||
urls = [
|
|
||||||
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.1.1/bazel-skylib-1.1.1.tar.gz",
|
|
||||||
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.1.1/bazel-skylib-1.1.1.tar.gz",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
_DOC = "TODO"
|
|
||||||
_ATTRS = {
|
|
||||||
"mylang_version": attr.string(mandatory = True, values = TOOL_VERSIONS.keys()),
|
|
||||||
"platform": attr.string(mandatory = True, values = PLATFORMS.keys()),
|
|
||||||
}
|
|
||||||
|
|
||||||
def _mylang_repo_impl(repository_ctx):
|
|
||||||
url = "https://github.com/someorg/someproject/releases/download/v{0}/mylang-{1}.zip".format(
|
|
||||||
repository_ctx.attr.mylang_version,
|
|
||||||
repository_ctx.attr.platform,
|
|
||||||
)
|
|
||||||
repository_ctx.download_and_extract(
|
|
||||||
url = url,
|
|
||||||
integrity = TOOL_VERSIONS[repository_ctx.attr.mylang_version][repository_ctx.attr.platform],
|
|
||||||
)
|
|
||||||
build_content = """#Generated by mylang/repositories.bzl
|
|
||||||
load("@com_myorg_rules_mylang//mylang:toolchain.bzl", "mylang_toolchain")
|
|
||||||
mylang_toolchain(name = "mylang_toolchain", target_tool = select({
|
|
||||||
"@bazel_tools//src/conditions:host_windows": "mylang_tool.exe",
|
|
||||||
"//conditions:default": "mylang_tool",
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Base BUILD file for this repository
|
|
||||||
repository_ctx.file("BUILD.bazel", build_content)
|
|
||||||
|
|
||||||
mylang_repositories = repository_rule(
|
|
||||||
_mylang_repo_impl,
|
|
||||||
doc = _DOC,
|
|
||||||
attrs = _ATTRS,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Wrapper macro around everything above, this is the primary API
|
|
||||||
def mylang_register_toolchains(name, **kwargs):
|
|
||||||
"""Convenience macro for users which does typical setup.
|
|
||||||
|
|
||||||
- create a repository for each built-in platform like "mylang_linux_amd64" -
|
|
||||||
this repository is lazily fetched when node is needed for that platform.
|
|
||||||
- TODO: create a convenience repository for the host platform like "mylang_host"
|
|
||||||
- create a repository exposing toolchains for each platform like "mylang_platforms"
|
|
||||||
- register a toolchain pointing at each platform
|
|
||||||
Users can avoid this macro and do these steps themselves, if they want more control.
|
|
||||||
Args:
|
|
||||||
name: base name for all created repos, like "mylang1_14"
|
|
||||||
**kwargs: passed to each node_repositories call
|
|
||||||
"""
|
|
||||||
for platform in PLATFORMS.keys():
|
|
||||||
mylang_repositories(
|
|
||||||
name = name + "_" + platform,
|
|
||||||
platform = platform,
|
|
||||||
**kwargs
|
|
||||||
)
|
|
||||||
native.register_toolchains("@%s_toolchains//:%s_toolchain" % (name, platform))
|
|
||||||
|
|
||||||
toolchains_repo(
|
|
||||||
name = name + "_toolchains",
|
|
||||||
user_repository_name = name,
|
|
||||||
)
|
|
|
@ -1,78 +0,0 @@
|
||||||
"""This module implements the language-specific toolchain rule.
|
|
||||||
"""
|
|
||||||
|
|
||||||
MylangInfo = provider(
|
|
||||||
doc = "Information about how to invoke the tool executable.",
|
|
||||||
fields = {
|
|
||||||
"target_tool_path": "Path to the tool executable for the target platform.",
|
|
||||||
"tool_files": """Files required in runfiles to make the tool executable available.
|
|
||||||
|
|
||||||
May be empty if the target_tool_path points to a locally installed tool binary.""",
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
# Avoid using non-normalized paths (workspace/../other_workspace/path)
|
|
||||||
def _to_manifest_path(ctx, file):
|
|
||||||
if file.short_path.startswith("../"):
|
|
||||||
return "external/" + file.short_path[3:]
|
|
||||||
else:
|
|
||||||
return ctx.workspace_name + "/" + file.short_path
|
|
||||||
|
|
||||||
def _mylang_toolchain_impl(ctx):
|
|
||||||
if ctx.attr.target_tool and ctx.attr.target_tool_path:
|
|
||||||
fail("Can only set one of target_tool or target_tool_path but both were set.")
|
|
||||||
if not ctx.attr.target_tool and not ctx.attr.target_tool_path:
|
|
||||||
fail("Must set one of target_tool or target_tool_path.")
|
|
||||||
|
|
||||||
tool_files = []
|
|
||||||
target_tool_path = ctx.attr.target_tool_path
|
|
||||||
|
|
||||||
if ctx.attr.target_tool:
|
|
||||||
tool_files = ctx.attr.target_tool.files.to_list()
|
|
||||||
target_tool_path = _to_manifest_path(ctx, tool_files[0])
|
|
||||||
|
|
||||||
# Make the $(tool_BIN) variable available in places like genrules.
|
|
||||||
# See https://docs.bazel.build/versions/main/be/make-variables.html#custom_variables
|
|
||||||
template_variables = platform_common.TemplateVariableInfo({
|
|
||||||
"MYLANG_BIN": target_tool_path,
|
|
||||||
})
|
|
||||||
default = DefaultInfo(
|
|
||||||
files = depset(tool_files),
|
|
||||||
runfiles = ctx.runfiles(files = tool_files),
|
|
||||||
)
|
|
||||||
mylanginfo = MylangInfo(
|
|
||||||
target_tool_path = target_tool_path,
|
|
||||||
tool_files = tool_files,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Export all the providers inside our ToolchainInfo
|
|
||||||
# so the resolved_toolchain rule can grab and re-export them.
|
|
||||||
toolchain_info = platform_common.ToolchainInfo(
|
|
||||||
mylanginfo = mylanginfo,
|
|
||||||
template_variables = template_variables,
|
|
||||||
default = default,
|
|
||||||
)
|
|
||||||
return [
|
|
||||||
default,
|
|
||||||
toolchain_info,
|
|
||||||
template_variables,
|
|
||||||
]
|
|
||||||
|
|
||||||
mylang_toolchain = rule(
|
|
||||||
implementation = _mylang_toolchain_impl,
|
|
||||||
attrs = {
|
|
||||||
"target_tool": attr.label(
|
|
||||||
doc = "A hermetically downloaded executable target for the target platform.",
|
|
||||||
mandatory = False,
|
|
||||||
allow_single_file = True,
|
|
||||||
),
|
|
||||||
"target_tool_path": attr.string(
|
|
||||||
doc = "Path to an existing executable for the target platform.",
|
|
||||||
mandatory = False,
|
|
||||||
),
|
|
||||||
},
|
|
||||||
doc = """Defines a mylang compiler/runtime toolchain.
|
|
||||||
|
|
||||||
For usage see https://docs.bazel.build/versions/main/toolchains.html#defining-toolchains.
|
|
||||||
""",
|
|
||||||
)
|
|
Loading…
Reference in New Issue