diff options
author | Alberto Sartori <alberto.sartori@huawei.com> | 2024-06-24 15:49:36 +0200 |
---|---|---|
committer | Klaus Aehlig <klaus.aehlig@huawei.com> | 2024-06-24 15:49:36 +0200 |
commit | f87ad41f72ca4465a0c5b4ba9fd36a7b09e4d4f4 (patch) | |
tree | 24d4a3a5975df2046714c6bc114d5d050bdc61fc | |
download | rules-rust-f87ad41f72ca4465a0c5b4ba9fd36a7b09e4d4f4.tar.gz |
Initial commit
Co-authored-by: Klaus Aehlig <klaus.aehlig@huawei.com>
57 files changed, 5512 insertions, 0 deletions
@@ -0,0 +1,202 @@ + + 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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..cde19cc --- /dev/null +++ b/README.md @@ -0,0 +1,150 @@ +# Rust rules for the [`just`](https://github.com/just-buildsystem/justbuild) build system + +A collection of rules for building Rust libraries, binaries and unit tests. + +### `["rust", "binary"]` + + A Rust binary. + +| Field | Description | +| ----- | ----------- | +| `"build_script"` | The "build_script" target required to be built and run before compiling this binary. | +| `"cargo_features"` | List of cargo features this binary requires to be enabled. | +| `"crate_root"` | The crate to be fed to the Rust compiler. It must evaluate to a single artifact/file. | +| `"defaults"` | The Rust toolchain to use. | +| `"deps"` | Any other libraries this binary depends upon. | +| `"edition"` | The edition of the compiler to use during compilation. If unset, 2015 is used. | +| `"name"` | The name of the crate being built. | +| `"pkg_name"` | The name of the package the crate belongs to. It is exported to the CARGO_PKG_NAME environment variable. | +| `"srcs"` | The source files of the binary. | +| `"stage"` | The logical location of the resulting artifact. Elements are joined with "/". | +| `"version"` | The crate version. Elements are joined with "." and the first three elements are used for the major, minor, and patch number respectively. | + +### `["rust", "defaults"]` + + A rule to provide defaults. +All rust targets take their defaults for RUSTC, TARGET, compile +flags etc. + +| Field | Description | +| ----- | ----------- | +| `"ADD_RUSTC_FLAGS"` | Additional flags for rustc. The values are appended to the ones from "base". | +| `"CARGO_CFG_TARGET_ARCH"` | The CPU target architecture. It overwrites the value from "base". | +| `"CARGO_CFG_TARGET_ENDIAN"` | The CPU target endianness. It overwrites the value from "base". | +| `"CARGO_CFG_TARGET_ENV"` | The target environment ABI. It overwrites the value from "base". | +| `"CARGO_CFG_TARGET_FAMILY"` | The target family. It overwrites the value from "base". | +| `"CARGO_CFG_TARGET_FEATURE"` | List of CPU target features enabled. Elements are joined with ",". It overwrites the value from "base". | +| `"CARGO_CFG_TARGET_HAS_ATOMIC"` | List of atomics types (in bits) supported by the target CPU. Elements are joined with ",". It overwrites the value from "base". | +| `"CARGO_CFG_TARGET_OS"` | The target operating system. It overwrites the value from "base". | +| `"CARGO_CFG_TARGET_POINTER_WIDTH"` | The CPU pointer width. It overwrites the value from "base". | +| `"CARGO_CFG_TARGET_VENDOR"` | The target vendor. It overwrites the value from "base". | +| `"CARGO_CFG_UNIX"` | To be set on unix-like platforms. It overwrites the value from "base". | +| `"CARGO_CFG_WINDOWS"` | To be set on windows-like platforms. It overwrites the value from "base". | +| `"HOST"` | The host triple of the Rust compiler (e.g., "x86_64-unknown-linux-gnu"). It overwrites the value from "base". | +| `"LINKER"` | The value to pass to the "--linker" rustc flag. It overwrites the value from "base". | +| `"PATH"` | Environment variable for looking up compilers and linkers. Elements are joined with ":". The values are put in front of the ones from "base". | +| `"RUSTC"` | The Rust compiler to use. It overwrites the value from "base". | +| `"RUSTC_FLAGS"` | The rustc flags to use. It overwrites the value from "base". | +| `"TARGET"` | The target triple for which the code is compiled (e.g., "x86_64-unknown-linux-gnu"). It overwrites the value from "base". | +| `"base"` | Other targets of the very same type to inherit values from. If the same field is defined both targets, depending on the field, the value from "base" is extended or overwritten. | + +### `["rust", "library"]` + + A Rust library. Depending on the value of the fields "shared" +and "native", the `--crate-type` is inferred as follows: + +|shared|native|crate-type| +|------|------|----------| +| null | null | rlib | +| null |"true"| staticlib| +|"true"| null | dylib | +|"true"|"true"| cdylib | + +| Field | Description | +| ----- | ----------- | +| `"build_script"` | The "build_script" target required to be built and run before compiling this library. | +| `"c_hdrs"` | C headers that define the interface to this library. This field is ignored when this library is consumed by another Rust target. If non empty, a native library will be produced. | +| `"cargo_features"` | List of cargo features this library requires to be enabled. | +| `"crate_root"` | The crate to be fed to the Rust compiler. It must evaluate to a single artifact/file. | +| `"defaults"` | The Rust toolchain to use. | +| `"deps"` | Any other libraries this library depends upon. | +| `"edition"` | The edition of the compiler to use during compilation. If unset, 2015 is used. | +| `"name"` | The name of the crate being built. | +| `"native"` | If not null, a native library will be produced. Note that, when this target is consumed by another Rust target, it will be compiled to a Rust static library (.rlib). | +| `"pkg_name"` | The name of the package the crate belongs to. It is exported to the CARGO_PKG_NAME environment variable. | +| `"shared"` | If not null, a shared library will be produced. | +| `"srcs"` | The source files of the library. | +| `"stage"` | The logical location of the resulting artifact. Elements are joined with "/". | +| `"version"` | The crate version. Elements are joined with "." and the first three elements are used for the major, minor, and patch number respectively. | + +### `["rust", "proc-macro"]` + + A Rust procedural macro. As it is executed on the host system +during the compilation, it is always compiled according to the +host configuration. + +| Field | Description | +| ----- | ----------- | +| `"build_script"` | The "build_script" target required to be built and run before compiling this macro. | +| `"cargo_features"` | List of cargo features this macro requires to be enabled. | +| `"crate_root"` | The crate to be fed to the Rust compiler. It must evaluate to a single artifact/file. | +| `"defaults"` | The Rust toolchain to use. | +| `"deps"` | Any other libraries this macro depends upon. | +| `"edition"` | The edition of the compiler to use during compilation. If unset, 2015 is used. | +| `"name"` | The name of the crate being built. | +| `"pkg_name"` | The name of the package the crate belongs to. It is exported to the CARGO_PKG_NAME environment variable. | +| `"srcs"` | The source files of the procedural macro. | +| `"stage"` | The logical location of the resulting artifact. Elements are joined with "/". | +| `"version"` | The crate version. Elements are joined with "." and the first three elements are used for the major, minor, and patch number respectively. | + +### `["rust", "test"]` + + A Rust test. + +| Field | Description | +| ----- | ----------- | +| `"args"` | Additonal arguments to be passed when running the test. | +| `"cargo_features"` | List of cargo features this test requires to be enabled. | +| `"crate_root"` | The crate to be fed to the Rust compiler. It must evaluate to a single artifact/file. | +| `"data"` | Any files and directories the test binary needs when running. | +| `"defaults"` | The Rust toolchain to use. | +| `"deps"` | Any other libraries this test depends upon. | +| `"edition"` | The edition of the compiler to use during compilation. If unset, 2015 is used. | +| `"name"` | The name of the test being built. Note that during execution, the test binary will be restaged to "test". | +| `"pkg_name"` | The name of the package the crate belongs to. It is exported to the CARGO_PKG_NAME environment variable. | +| `"runner"` | The test runner to use, i.e., the binary that will launch the test binary and collect the output. | +| `"srcs"` | The source files of the test. | +| `"stage"` | The logical location of the resulting artifact. Elements are joined with "/". | +| `"version"` | The crate version. Elements are joined with "." and the first three elements are used for the major, minor, and patch number respectively. | + +### `["cargo", "build_script"]` + + The custom build script supported by cargo. This binary is +executed before compiling the other crates. Currently, only its +output is processed to augment the rustc flags. During a cross +compilation, since the build script must be run on the host +system, it is always compiled according to the configuration +provided by the "defaults" for the "HOST_ARCH". + +| Field | Description | +| ----- | ----------- | +| `"cargo_features"` | List of cargo features this binary requires to be enabled. | +| `"crate_root"` | The crate to be fed to the Rust compiler. It must evaluate to a single artifact/file. | +| `"defaults"` | The Rust toolchain to use. | +| `"deps"` | Any other libraries this binary depends upon. | +| `"edition"` | The edition of the compiler to use during compilation. If unset, 2015 is used. | +| `"name"` | The name of the crate being built. | +| `"pkg_name"` | The name of the package the crate belongs to. It is exported to the CARGO_PKG_NAME environment variable. | +| `"srcs"` | The source files of the binary. | +| `"stage"` | The logical location of the resulting artifact. Elements are joined with "/". | +| `"version"` | The crate version. Elements are joined with "." and the first three elements are used for the major, minor, and patch number respectively. | + +### `["cargo", "feature"]` + + A cargo feature. + +| Field | Description | +| ----- | ----------- | +| `"deps"` | Any other features or "[rust, library]" this feature depends on. | +| `"name"` | The feature name. The flag `--cfg feature=<name>` is passed to the Rust compiler. | + diff --git a/bin/hdump.py b/bin/hdump.py new file mode 100755 index 0000000..7998996 --- /dev/null +++ b/bin/hdump.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 + +import json +import sys +from typing import Any, Dict, List, Union + +JSON = Union[str, int, float, bool, None, Dict[str, 'JSON'], List['JSON']] + + +def is_simple(entry: JSON) -> bool: + if isinstance(entry, list): + return len(entry) == 0 + if isinstance(entry, dict): + return len(entry) == 0 + return True + + +def is_short(entry: Any, indent: int) -> bool: + return (len(json.dumps(entry)) + indent) < 80 + + +def hdumps(entry: JSON, *, _current_indent: int = 0) -> str: + if is_short(entry, _current_indent): + return json.dumps(entry) + if isinstance(entry, list) and entry: + result: str = "[ " + hdumps(entry[0], + _current_indent=_current_indent + 2) + for x in entry[1:]: + result += "\n" + " " * _current_indent + ", " + result += hdumps(x, _current_indent=_current_indent + 2) + result += "\n" + " " * _current_indent + "]" + return result + if isinstance(entry, dict) and entry: + result: str = "{ " + is_first: bool = True + for k in entry.keys(): + if not is_first: + result += "\n" + " " * _current_indent + ", " + result += json.dumps(k) + ":" + if is_simple(entry[k]): + result += " " + json.dumps(entry[k]) + elif is_short(entry[k], _current_indent + len(json.dumps(k)) + 4): + result += " " + json.dumps(entry[k]) + else: + result += "\n" + " " * _current_indent + " " + result += hdumps(entry[k], _current_indent=_current_indent + 2) + is_first = False + result += "\n" + " " * _current_indent + "}" + return result + return json.dumps(entry) + + +if __name__ == "__main__": + data = json.load(sys.stdin) + print(hdumps(data)) diff --git a/bin/just-import-cargo.py b/bin/just-import-cargo.py new file mode 100755 index 0000000..af59e7d --- /dev/null +++ b/bin/just-import-cargo.py @@ -0,0 +1,746 @@ +#!/usr/bin/env python3 +# Copyright 2024 Huawei Cloud Computing Technology Co., Ltd. +# +# 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. + +from argparse import ArgumentParser +from collections import defaultdict +import glob +from pprint import pprint +import re +import shutil +import sys +import subprocess +import json +import os +from hashlib import sha256 +from tempfile import TemporaryDirectory +from typing import Any, Dict, List, Optional, Tuple, Union, cast + +JSON = Union[str, int, float, bool, None, Dict[str, 'JSON'], List['JSON']] + +# ------- JSON formating ------------ +# inlined to have a self-contained binary +def is_simple(entry: JSON) -> bool: + if isinstance(entry, list): + return len(entry) == 0 + if isinstance(entry, dict): + return len(entry) == 0 + return True + + +def is_short(entry: Any, indent: int) -> bool: + return (len(json.dumps(entry)) + indent) < 80 + + +def hdumps(entry: JSON, *, _current_indent: int = 0) -> str: + if is_short(entry, _current_indent): + return json.dumps(entry) + if isinstance(entry, list) and entry: + result: str = "[ " + hdumps(entry[0], + _current_indent=_current_indent + 2) + for x in entry[1:]: + result += "\n" + " " * _current_indent + ", " + result += hdumps(x, _current_indent=_current_indent + 2) + result += "\n" + " " * _current_indent + "]" + return result + if isinstance(entry, dict) and entry: + result: str = "{ " + is_first: bool = True + for k in entry.keys(): + if not is_first: + result += "\n" + " " * _current_indent + ", " + result += json.dumps(k) + ":" + if is_simple(entry[k]): + result += " " + json.dumps(entry[k]) + elif is_short(entry[k], _current_indent + len(json.dumps(k)) + 4): + result += " " + json.dumps(entry[k]) + else: + result += "\n" + " " * _current_indent + " " + result += hdumps(entry[k], _current_indent=_current_indent + 2) + is_first = False + result += "\n" + " " * _current_indent + "}" + return result + return json.dumps(entry) + +# ------- end JSON formating ------------ + +my_directory = os.path.dirname(os.path.abspath(sys.argv[0])) + +HOME = os.environ.get("HOME", "/") +CACHE_ROOT = os.path.join(HOME, ".cache", "crate-index-just") + +# used to skip from circular dependencies +visited: Dict[str, bool] = {} + +# to generate the repos.json file +repos_json: JSON = dict() + +recompute_targets = False +recompute_repos = False +recompute_sources = False +compute_index = False +root_id = None +root_name = None +root_version = None +root_rep_name = None +root_dir = None +relative_path = "." +repo_root = "/" +IMPORTED_REPOS = set() + + +def split_id(id: str): + try: + # metadata provided by stable cargo, as of 2024-03-18 + name, version, source = id.split() + source = source[1:-1] + except Exception as e: + if id.startswith("registry"): + # "registry+https://github.com/rust-lang/crates.io-index#libc@0.2.153" + source, name_version = id.split("#") + name, version = name_version.split("@") + + elif id.startswith("path"): + # path+file:///home/username/opt/src/commonlibrary_rust_ylong_runtime#ylong_io@1.0.0 + source, name_version = id.split("#") + name, version = name_version.split("@") + else: + print(f"while processing {id=}: {e}", file=sys.stderr) + exit(1) + + return name, version, source + + +def abspath(x: str) -> str: + return os.path.abspath(x) + + +def cargo_metadata( + pkg_name: str, + root_dir: str, + cache_dir: Optional[str] = None, + traverse_dev: bool = False, +) -> JSON: + metadata_path: Optional[str] = None + + x = subprocess.run( + "cargo metadata --format-version 1".split(), + cwd=root_dir, + capture_output=True, + ) + + if x.returncode != 0: + print(f"Failed to run cargo: {x.returncode}: {x.stderr}", + file=sys.stderr) + exit(x.returncode) + d: JSON = json.loads(x.stdout) + if metadata_path: + with open(metadata_path, "w") as f: + print(hdumps(d), file=f) + print(f"stored metadata of {pkg_name} to {metadata_path}", + file=sys.stderr) + return d + + +def cache_entry_from_hash(hash: str) -> Tuple[str, bool]: + os.makedirs(CACHE_ROOT, exist_ok=True) + path = os.path.join(CACHE_ROOT, hash[:2], hash[2:]) + return path, os.path.exists(path) + + +def repo_name(name: str, version: str = "") -> str: + return "-".join((name, version)) + + +def bindings(nodes: Any, id: str, keep_dev: bool = True) -> JSON: + pkg: JSON = {} + for pkg in nodes: + if pkg["id"] == id: + break + b: JSON = {"rules": "rust-rules"} + global compute_index + if compute_index: + b["index"] = "index" + for d in pkg["deps"]: + d_name, d_version, _ = split_id(d["pkg"]) + is_dev = d["dep_kinds"][0]["kind"] == "dev" + if not is_dev or keep_dev: + b[d_name] = repo_name(d_name, d_version) + return b + + +def bindings_from_tree(key: str, tree_out: JSON) -> JSON: + b: JSON = {"rules": "rust-rules"} + global compute_index + if compute_index: + b["index"] = "index" + b.update(tree_out[key]["bindings"]) + return b + + +def cache_entry(name: str, version: str) -> Tuple[str, bool]: + key: str = repo_name(name, version) + hash = sha256(key.encode()).hexdigest() + return cache_entry_from_hash(hash) # returns (entry, present) + + +def fetch_crate_from_crates_io( + name: str, version: str, rep_name: str, tree_out: JSON +) -> str: + entry, present = cache_entry(name, version) + archive = f"{name}.tar.gz" + archive_path = os.path.join(entry, archive) + global recompute_repos, repos_json + if recompute_repos or not present: + fetch_url = f"https://crates.io/api/v1/crates/{name}/{version}/download" + tmp_dir = TemporaryDirectory(prefix="cargo-parser-") + print(f"retrieving: {repo_name(name,version)} from {fetch_url}", end="...", + file=sys.stderr) + curl = subprocess.run( + f"wget {fetch_url} --tries=10 -O {name}.tar.gz".split(), + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + cwd=tmp_dir.name, + ) + curl.check_returncode() + os.makedirs(entry, exist_ok=True) + shutil.copyfile(os.path.join(tmp_dir.name, archive), archive_path) + x = subprocess.check_output( + f"git hash-object {name}.tar.gz".split(), cwd=tmp_dir.name + ) + repo: JSON = { + "repository": dict( + type="archive", + fetch=fetch_url, + content=x.decode().split()[0], + subdir=rep_name, + distfile=f"{rep_name}.tar.gz", + ) + } + repos: JSON = dict() + repos[rep_name] = repo + repos[rep_name]["bindings"] = bindings_from_tree(rep_name, tree_out) + repos[rep_name]["target_root"] = "external-deps" + repos[rep_name]["target_file_name"] = f"TARGETS.{rep_name}" + with open(file=os.path.join(entry, "repos.json"), mode="w") as f: + print(hdumps(repos), file=f) + repos_json.update(repos) + print("done", file=sys.stderr) + else: + with open(file=os.path.join(entry, "repos.json")) as f: + d = json.load(f) + repos_json.update(d) + return archive_path + + +def local_repo( + name: str, + version: str, + rep_name: str, + tree_out: JSON, + is_main=False, + path: str = ".", +) -> str: + global repos_json + print(f"local: {repo_name(name,version)}", end="...", file=sys.stderr) + + repo: JSON = { + "repository": dict( + type="file", + path=path, + ) + } + repos: JSON = dict() + key = name if is_main else rep_name + repos[key] = repo + repos[key]["bindings"] = bindings_from_tree(rep_name, tree_out) + + repos_json.update(repos) + print("done", file=sys.stderr) + +def compute_srcs(root_dir: str, name: str, version: str) -> List[Any]: + entry, exists = cache_entry(name, version) + if not exists: + os.makedirs(entry) + srcs_file = os.path.join(entry, "srcs.json") + global recompute_sources + if not recompute_sources and os.path.exists(srcs_file): + with open(srcs_file) as f: + return json.load(f) + + srcs: List[Any] = list() + + for f in glob.glob(f"{root_dir}/**/*.rs", recursive=True): + f = os.path.relpath(f, root_dir) + if ( + not f.startswith("example") + and not f.startswith("test") + and not f.startswith("bench") + ): + srcs.append(f) + + with open(srcs_file, "w") as f: + print(json.dumps(srcs), file=f) + return srcs + + +def to_underscore(x: str): + return x.replace("-", "_") + + +def active_deps( + nodes: Any, pkg: JSON, tree_out: JSON, keep_dev: bool +) -> Tuple[List[Any], JSON]: + p: JSON = {} + for p in nodes: + if p["id"] == pkg["id"]: + break + + b: List[Any] = list() + for d in p["deps"]: + d_name, _, _ = split_id(d["pkg"]) + + is_dev: bool = d["dep_kinds"][0]["kind"] == "dev" + if not is_dev or keep_dev: + b.append(["@", d_name, "", d_name]) + return b, p["features"] + + +def active_deps_from_tree( + key: str, tree_out: JSON, root_name: str = None, is_dev: bool = False +) -> Tuple[List[Any], JSON]: + dep_names = tree_out[key]["bindings"].keys() + deps = [["@", x, "", to_underscore(x)] for x in dep_names] + if is_dev: + deps.append(root_name) + return deps, tree_out[key]["features"] + + +def compute_targets( + metadata: JSON, pkg: JSON, tree_out: JSON, dev: bool = False, is_main: bool = False +) -> JSON: + name, version, _ = split_id(pkg["id"]) + entry, _ = cache_entry(name, version) + targets_file = os.path.join(entry, f"TARGETS.{repo_name(name,version)}") + if os.path.exists(targets_file) and not recompute_targets: + with open(targets_file) as f: + return json.load(f) + root_dir: str = os.path.dirname(pkg["manifest_path"]) + targets: JSON = dict() + has_build_script = False + for t in pkg["targets"]: + t_kind = t["kind"][0] + if t_kind == "custom-build": + has_build_script = True + break + + config = ["ARCH", "HOST_ARCH", "TARGET_ARCH", "ENV", "TOOLCHAIN_CONFIG"] + t: JSON = {} + for t in pkg["targets"]: + t_kind = t["kind"][0] + is_dev_target = t_kind in ["test", "bench", "example"] + unsupported_target = t_kind in ["bench"] + d_build_script: Optional[JSON] = None + rep_name = repo_name_from_id(pkg["id"]) + version_lst = version.split(".") + if not dev and is_dev_target: + continue + if unsupported_target: + print(f"{t['name']}: rust {t_kind} target type not yet supported", + file=sys.stderr) + continue + + if t_kind == "custom-build": + # we will use foreign cargo rules to build + d_build_script = dict() + d_build_script["type"] = "@ rules cargo build_script".split() + d_build_script["name"] = ["build_script"] + crate_root = os.path.relpath(t["src_path"], root_dir) + d_build_script["crate_root"] = [crate_root] + d_build_script["arguments_config"] = config + d_build_script["edition"] = [t["edition"]] + d_build_script["stage"] = [rep_name] + d_build_script["deps"], d_build_script["cargo_features"] = ( + active_deps_from_tree(rep_name, tree_out) + ) + d_build_script["version"] = version_lst + d_build_script["pkg_name"] = [name] + targets["build_script"] = d_build_script + has_build_script = True + continue + + crate_root = os.path.relpath(t["src_path"], root_dir) + d: JSON = dict() + d["type"] = just_type(t, False) + d["name"] = [to_underscore(t["name"])] + d["crate_root"] = [crate_root] + if not is_dev_target: + d["srcs"] = compute_srcs(root_dir, name, version) + d["edition"] = [t["edition"]] + d["arguments_config"] = config + d["deps"], d["cargo_features"] = active_deps_from_tree( + rep_name, tree_out, to_underscore(name), is_dev_target + ) + d["stage"] = [rep_name] + d["version"] = version_lst + d["pkg_name"] = [name] + if not is_main and t["name"] == pkg["name"]: + internal_name = f"{to_underscore(t['name'])}-internal" + d["arguments_config"] = config + targets[to_underscore(t["name"])] = { + "type": "export", + "target": internal_name, + "flexible_config": config, + } + targets[internal_name] = d + if has_build_script: + targets[internal_name]["build_script"] = ["build_script"] + global compute_index + if compute_index: + targets["tree"] = { + "type": "install", + "dirs": [[["TREE", None, "."], rep_name]], + } + targets["cargo-srcs"] = { + "type": "generic", + "cmds": [f"mv index {rep_name}"], + "deps": ["tree", ["@", "index", "", "index"]], + "out_dirs": [rep_name], + } + targets["config.toml"] = { + "type": "generic", + "cmds": [ + f'echo "[source.crates-io]\\nreplace-with = \\"vendored-sources\\"\\n\\n[source.vendored-sources]\\ndirectory = \\"index\\"\\n" > config.toml' + ], + "outs": ["config.toml"], + } + targets["cargo-srcs"]["cmds"].append( + f"mkdir -p {rep_name}/.cargo && mv config.toml {rep_name}/.cargo" + ) + targets["cargo-srcs"]["deps"].append("config.toml") + continue + targets[t["name"]] = d + + for f, _ in pkg["features"].items(): + d = defaultdict(list) + d["type"] = ["@", "rules", "cargo", "feature"] + d["name"] = [f] + targets[f] = d + with open(targets_file, "w") as f: + print(hdumps(targets), file=f) + return targets + + +kinds: Dict[str, str] = dict(bin="binary", lib="library", example="binary") + + +def just_type(target: JSON, use_foreign_cargo: bool) -> List[str]: + if use_foreign_cargo: + return "@ rules cargo library".split() + t: List[str] = ["@", "rules", "rust"] + k: str = target["kind"][0] + return t + [kinds.get(k, k)] + + +def parse_metadata(metadata: JSON, tree_out: JSON) -> None: + nodes = metadata["resolve"]["nodes"] + global root_id, root_name, root_version, root_rep_name + root_id = metadata["resolve"]["root"] + if root_id: + root_name, root_version, _ = split_id(root_id) + root_rep_name = repo_name(root_name, root_version) + + # generate repos.json + for p in nodes: + name, version, source = split_id(p["id"]) + rep_name = repo_name(name, version) + if rep_name in tree_out: + if rep_name == root_rep_name: + local_repo(name, version, rep_name, tree_out, is_main=True, path=relative_path) + continue + + if source == "registry+https://github.com/rust-lang/crates.io-index": + fetch_crate_from_crates_io(name, version, rep_name, tree_out) + elif source.startswith("path+file"): + path = source.split("#")[0][12:] + local_repo( + name, + version, + rep_name, + tree_out, + path=os.path.relpath(path, repo_root), + is_main=True, + ) + + +def repo_name_from_id(id: str): + name, version, _ = split_id(id) + return repo_name(name, version) + + +def parse_tree_entry(x: str) -> Tuple[int, str, str, List[Any]]: + match = re.match(r"^\d+", x) + if not match: + print(f"failed to parse tree entry: {x}", file=sys.stderr) + exit(1) + depth = int(match.group()) + rest = x[match.span()[-1] :].replace('"', "").split() + rest = [x for x in rest if not x.startswith("(")] + name, version, features = split_tree_entry(rest) + return depth, name, version, features + + +def split_tree_entry(x: List[str]) -> Tuple[str, str, List[Any]]: + if len(x) < 2: + print(f"malformed tree entry: {x}", file=sys.stderr) + exit(1) + name: str = x[0] + version: str = x[1][1:] # drop the leading "v" + features: List[Any] = [] + if len(x) == 3: + features = x[2].split(",") + return name, version, features + + +def parse_cargo_tree(root_dir: str) -> JSON: + tree = subprocess.run( + ["cargo", "tree", "--prefix", "depth", "-f", '"{p} {f}"'], + cwd=root_dir, + capture_output=True, + ) + + if tree.returncode != 0: + print(f"Failed to run cargo: {tree.returncode}: {tree.stderr}", + file=sys.stderr) + exit(tree.returncode) + tree = tree.stdout.decode().split("\n") + deps: JSON = defaultdict(lambda: cast(JSON, dict(bindings={}))) + depth_package = {} + for l in tree: + # skip empty lines + if not l: + continue + depth, name, version, features = parse_tree_entry(l) + pkg = repo_name(name, version) + deps[pkg]["features"] = features + deps[pkg]["name"] = name + depth_package[depth] = pkg + if depth > 0: + parent = depth_package[depth - 1] + deps[parent]["bindings"].update({name: pkg}) + + return dict(deps) + +def merge_repos(base_config, new_repos, entry_point_name): + old_names = set(base_config["repositories"].keys()) + entry_name = entry_point_name + if entry_name in old_names: + count = 0 + entry_name = "%s (%d)" % (entry_point_name, count) + while entry_name in old_names: + count += 1 + entry_name = "%s (%d)" % (entry_point_name, count) + print("Adding to repository config the new rust repository %r with dependencies" + % (entry_name,), file=sys.stderr) + + name_mapping = {entry_point_name: entry_name} + for k in new_repos.keys(): + if k == entry_point_name: + continue + preferred_name = "%s/%s" % (entry_name, k) + if not preferred_name in old_names: + name_mapping[k] = preferred_name + old_names.add(preferred_name) + continue + count = 0 + new_name = "%s (%d)" % (preferred_name, count) + while new_name in old_names: + count += 1 + new_name = "%s (%d)" % (preferred_name, count) + name_mapping[k] = new_name + old_names.add(new_name) + renamed_repos = {} + for k, v in new_repos.items(): + if k in IMPORTED_REPOS: + # no renaming done within the definition this repository definition + renamed_repos[name_mapping[k]] = v + else: + if isinstance(v, str): + if v in name_mapping: + renamed_repos[name_mapping[k]] = name_mapping[v] + else: + renamed_repos[name_mapping[k]] = v + else: + # has to be a dict; rename bindings, and roots, if given + new_v = v + ws_root = new_v["repository"] + if isinstance(ws_root, str): + if ws_root in name_mapping: + new_v = dict(new_v, **{"repository": name_mapping[ws_root]}) + bindings = v.get("bindings", {}) + new_bindings = {} + for n, m in bindings.items(): + if m in name_mapping: + new_bindings[n] = name_mapping[m] + else: + new_bindings[n] = m + if new_bindings: + new_v = dict(new_v, **{"bindings": new_bindings}) + for root in ["target_root", "rule_root", "expression_root"]: + if root in new_v: + r_name = new_v[root] + if r_name in name_mapping: + new_v = dict(new_v, **{root: name_mapping[r_name]}) + renamed_repos[name_mapping[k]] = new_v + all_repos = dict(base_config["repositories"], **renamed_repos) + return dict(base_config, **{"repositories": all_repos}) + +def main(): + parser = ArgumentParser() + parser.add_argument( + "root_dir", help="directory where the Cargo.toml file is located; relative to repo_root" + ) + parser.add_argument("-t", "--recompute-targets", action="store_true") + parser.add_argument("-r", "--recompute-repos", action="store_true") + parser.add_argument("-s", "--recompute-sources", action="store_true") + parser.add_argument("-I", "--compute-index", action="store_true") + parser.add_argument( + "-g", + "--to-git", + action="store_true", + ) + parser.add_argument( + "--rules", dest="rules", + help="Rust-rules repository name in the base configuration", + metavar="name") + parser.add_argument("--local-crate-cache", dest="cache_root") + parser.add_argument("--repo-root", dest="repo_root") + args = parser.parse_args() + global repo_root, root_dir, relative_path + repo_root = args.repo_root or "." + repo_root = os.path.abspath(repo_root) + root_dir = os.path.join(repo_root, args.root_dir) + relative_path = os.path.relpath(root_dir, repo_root) + global CACHE_ROOT + if args.cache_root: + CACHE_ROOT = args.cache_root + + tree_out: JSON = parse_cargo_tree(root_dir) + global recompute_targets, recompute_repos, recompute_sources, compute_index, root_name, root_version + recompute_repos = args.recompute_repos + recompute_targets = args.recompute_targets + recompute_sources = args.recompute_sources + compute_index = args.compute_index + pprint(args, stream=sys.stderr) + + base_config = json.load(sys.stdin) + metadata = cargo_metadata( + os.path.basename(os.path.abspath(root_dir)), root_dir, cache_dir=root_dir + ) + parse_metadata(metadata, tree_out) + + if compute_index: + index = sorted(repos_json.keys()) + repos_json["index"] = { + "repository": {"type": "distdir", "repositories": index}, + "target_file_name": "TARGETS.index", + "target_root": "external-deps", + } + + repos_json["external-deps"] = { + "repository": {"type": "file", + "path": "etc/deps-rust"} + } + + if args.rules: + repos_json["rust-rules-root"] = base_config["repositories"][args.rules] + global IMPORTED_REPOS + IMPORTED_REPOS.add("rust-rules-root") + else: + print( + "Warning: adding local path to this checkout to the repository configuration", + file=sys.stderr) + repos_json["rust-rules-root"] = { + "repository": + {"type": "file", + "path": os.path.normpath(os.path.join(my_directory, "../rules")), + } + } + + repos_json["rust-rules-defaults"] = { + "repository": {"type": "file", + "path": "etc/defaults"} + } + + if args.to_git: + for k in ["external-deps", "rust-rules-root", "rust-rules-defaults"]: + repos_json[k]["repository"]["pragma"] = {"to_git": True} + + repos_json["rust-rules"] = { + "repository": "rust-rules-root", + "target_root": "rust-rules-defaults", + "rule_root": "rust-rules-root", + "bindings": {"orig-rules": "rust-rules-root"}, + } + + main_rep = repo_name(root_name, root_version) + print(hdumps(merge_repos(base_config, repos_json, root_name))) + + ext = os.path.join(repo_root, "etc", "deps-rust") + os.makedirs(ext, exist_ok=True) + + defaults_dict = { + "defaults": { + "type": "defaults", + "base": [["@", "orig-rules", "rust", "defaults"]], + } + } + + defaults_dir = os.path.join(repo_root, "etc", "defaults", "rust") + os.makedirs(defaults_dir, exist_ok=True) + with open(os.path.join(defaults_dir, "TARGETS"), "w") as f: + print(hdumps(defaults_dict), file=f) + + for pkg in metadata["packages"]: + rep_name = repo_name_from_id(pkg["id"]) + if rep_name in tree_out: + if rep_name == main_rep: + with open(os.path.join(root_dir, "TARGETS"), "w") as f: + print( + hdumps( + compute_targets( + metadata, pkg, tree_out, is_main=True, dev=True + ) + ), + file=f, + ) + continue + + if pkg["id"].startswith("path+file"): + path = pkg["id"].split("#")[0][12:] + with open(os.path.join(path, "TARGETS"), "w") as f: + print( + hdumps( + compute_targets( + metadata, pkg, tree_out, is_main=True, dev=True + ) + ), + file=f, + ) + + with open(os.path.join(ext, f"TARGETS.{rep_name}"), "w") as f: + print(hdumps(compute_targets(metadata, pkg, tree_out)), file=f) + + +main() diff --git a/etc/gen-repos.sh b/etc/gen-repos.sh new file mode 100755 index 0000000..a704bf8 --- /dev/null +++ b/etc/gen-repos.sh @@ -0,0 +1,29 @@ +#!/bin/sh +# Copyright 2024 Huawei Cloud Computing Technology Co., Ltd. +# +# 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. + +set -euo pipefail + +readonly ROOT=$(readlink -f $(dirname $0)/..) + +: ${RULES_CC_REPO:=https://github.com/just-buildsystem/rules-cc} +: ${RULES_CC_BRANCH:=master} + +just-import-git -C ${ROOT}/etc/repos.template.json \ + --as rules-cc -b ${RULES_CC_BRANCH} ${RULES_CC_REPO} rules \ + | \ + just-import-git -C - \ + --map test-rules test-rules \ + --as rules-test -b ${RULES_CC_BRANCH} ${RULES_CC_REPO} tests \ + | ${ROOT}/bin/hdump.py > ${ROOT}/etc/repos.json diff --git a/etc/gen_readme.py b/etc/gen_readme.py new file mode 100644 index 0000000..66618a3 --- /dev/null +++ b/etc/gen_readme.py @@ -0,0 +1,35 @@ +import json +import os +from typing import List + +def lines(doc:List[str]): + return '\n'.join(doc) + +def gen_doc(dir: str, f): + + with open(os.path.join(dir, "RULES")) as r: + rules = json.load(r) + + for k, v in sorted(rules.items()): + print(f"### `[\"{os.path.basename(dir)}\", \"{k}\"]`\n\n {lines(v['doc'])}\n", file=f) + print("| Field | Description |", file=f) + print("| ----- | ----------- |", file=f) + for field, doc in sorted(v["field_doc"].items()): + print(f"| `\"{field}\"` | {' '.join(doc)} |", file=f) + print(file=f) + + +def main(): + with open("README.md", "w") as f: + print( + """# Rust rules for the [`just`](https://github.com/just-buildsystem/justbuild) build system + +A collection of rules for building Rust libraries, binaries and unit tests. +""", + file=f, + ) + gen_doc("rules/rust", f) + gen_doc("rules/cargo", f) + + +main() diff --git a/etc/imports/rules.TARGETS b/etc/imports/rules.TARGETS new file mode 100644 index 0000000..5b41441 --- /dev/null +++ b/etc/imports/rules.TARGETS @@ -0,0 +1,6 @@ +{ "tree": + { "type": "install" + , "dirs": [[["TREE", null, "rules"], "rules"]] + , "tainted": ["test"] + } +} diff --git a/etc/repos.json b/etc/repos.json new file mode 100644 index 0000000..936a90b --- /dev/null +++ b/etc/repos.json @@ -0,0 +1,545 @@ +{ "main": "rust-rules" +, "repositories": + { "rust-rules": + { "repository": {"type": "file", "path": "."} + , "bindings": {"test-rules": "rules-test", "rules-cc": "rules-cc"} + } + , "imports": {"repository": {"type": "file", "path": "etc/imports"}} + , "test-rules": + { "repository": "rust-rules" + , "target_root": "imports" + , "target_file_name": "rules.TARGETS" + } + , "rules-cc": + { "repository": + { "type": "git" + , "repository": "https://github.com/just-buildsystem/rules-cc" + , "branch": "master" + , "commit": "ba89bf29f2dd7d13dbd659d5319232ee98070126" + , "subdir": "rules" + } + } + , "rules-test": + { "repository": + { "type": "git" + , "repository": "https://github.com/just-buildsystem/rules-cc" + , "branch": "master" + , "commit": "ba89bf29f2dd7d13dbd659d5319232ee98070126" + , "subdir": "tests" + } + , "bindings": + { "test-just": "rules-test/just" + , "test-rules": "test-rules" + , "test-libs": "rules-test/test-libs" + , "rules": "rules-test/rules" + } + } + , "rules-test/gtest": + { "repository": + { "type": "archive" + , "fetch": "https://github.com/google/googletest/archive/refs/tags/v1.13.0.tar.gz" + , "content": "cbd19f97df3ab86b174520cd850d238617c156e0" + , "sha256": "ad7fdba11ea011c1d925b3289cf4af2c66a352e18d4c7264392fead75e919363" + , "subdir": "googletest-1.13.0" + } + , "target_root": "rules-test/imports" + , "target_file_name": "gtest.TARGETS" + } + , "rules-test/just": + { "repository": + { "type": "git" + , "repository": "https://github.com/just-buildsystem/justbuild" + , "branch": "v1.4.0-alpha+20240619" + , "commit": "96158f57c36bbc649abcd9a213bf04df6cf8a1f5" + } + , "bindings": + { "rules": "rules-test/just/rules-just" + , "gsl": "rules-test/just/com_github_microsoft_gsl" + , "cli11": "rules-test/just/cli11" + , "json": "rules-test/just/json" + , "fmt": "rules-test/just/fmt" + , "ssl": "rules-test/just/ssl" + , "grpc": "rules-test/just/com_github_grpc_grpc" + , "googleapis": "rules-test/just/google_apis" + , "bazel_remote_apis": "rules-test/just/bazel_remote_apis" + , "libgit2": "rules-test/just/com_github_libgit2_libgit2" + , "protoc": "rules-test/just/protobuf" + , "libcurl": "rules-test/just/com_github_curl_curl" + , "libarchive": "rules-test/just/com_github_libarchive_libarchive" + } + } + , "rules-test/just/bazel_remote_apis": + { "repository": + { "type": "archive" + , "content": "da6d7d589ccd1924ba9840a4e329e438dfa27f86" + , "fetch": "https://github.com/bazelbuild/remote-apis/archive/e1fe21be4c9ae76269a5a63215bb3c72ed9ab3f0.tar.gz" + , "sha256": "7421abd5352ccf927c2050453a4dbfa1f7b1c7170ec3e8702b6fe2d39b8805fe" + , "sha512": "3042690ee4b17a27db92ca867b4225c25f3f16344dce5fe86695d72ddda531e1593a5f0f70a291283451ce1e9f606c2285d222df3787815cd8f4054e1113bc9d" + , "subdir": "remote-apis-e1fe21be4c9ae76269a5a63215bb3c72ed9ab3f0" + } + , "target_root": "rules-test/just/import targets" + , "target_file_name": "TARGETS.bazel_remote_apis" + , "bindings": + { "rules": "rules-test/just/rules" + , "google_apis": "rules-test/just/google_apis" + , "patches": "rules-test/just/patches" + } + } + , "rules-test/just/bzip2": + { "repository": + { "type": "archive" + , "content": "f9d91f2012aedeedcfd3bd918124ca11f0160373" + , "fetch": "https://github.com/libarchive/bzip2/archive/refs/tags/bzip2-1.0.8.tar.gz" + , "sha256": "db106b740252669664fd8f3a1c69fe7f689d5cd4b132f82ba82b9afba27627df" + , "sha512": "596d1b304f1f2d64b020d04845db10a2330c7f614a9fd0b5344afff65877d2141b3fcaa43d9e2dbc2f6a7929a1dab07df54d3d4bd69678b53906472958c7b80c" + , "subdir": "bzip2-bzip2-1.0.8" + } + , "target_root": "rules-test/just/import targets" + , "target_file_name": "TARGETS.bzip2" + , "bindings": {"rules": "rules-test/just/rules-bzip2"} + } + , "rules-test/just/cli11": + { "repository": + { "type": "archive" + , "content": "eb82119c62808a65bb2d15561f1968259ed50c95" + , "fetch": "https://github.com/CLIUtils/CLI11/archive/refs/tags/v2.4.1.tar.gz" + , "sha256": "73b7ec52261ce8fe980a29df6b4ceb66243bb0b779451dbd3d014cfec9fdbb58" + , "sha512": "965290d09977672d3bc3c57ca4b89a88c2c09461da6e866b18217d702d4d5a0977588fcb8fef1a3c3804e61ad80d276029f47469cc83dbfdc7021ee35f6b7269" + , "subdir": "CLI11-2.4.1" + } + , "target_root": "rules-test/just/import targets" + , "target_file_name": "TARGETS.cli11" + , "bindings": {"rules": "rules-test/just/rules"} + } + , "rules-test/just/com_github_cares_cares": + { "repository": + { "type": "archive" + , "content": "4237a53f7a5dc1cfb4d04a6b6374f8674c32e271" + , "fetch": "https://github.com/c-ares/c-ares/releases/download/cares-1_19_1/c-ares-1.19.1.tar.gz" + , "sha256": "321700399b72ed0e037d0074c629e7741f6b2ec2dda92956abe3e9671d3e268e" + , "sha512": "466a94efda626e815a6ef7a890637056339f883d549ea6055e289fd8cd2391130e5682c905c0fb3bd7e955af7f6deb793562c170eb0ee066a4a62085a82ba470" + , "subdir": "c-ares-1.19.1" + } + , "target_root": "rules-test/just/import targets" + , "target_file_name": "TARGETS.cares" + , "bindings": + { "rules": "rules-test/just/rules" + , "grpc": "rules-test/just/com_github_grpc_grpc" + } + } + , "rules-test/just/com_github_curl_curl": + { "repository": + { "type": "archive" + , "content": "7b7ace4d7cc7d4059163bbd789ef7071e5d326e5" + , "fetch": "https://github.com/curl/curl/releases/download/curl-8_6_0/curl-8.6.0.tar.gz" + , "sha256": "9c6db808160015f30f3c656c0dec125feb9dc00753596bf858a272b5dd8dc398" + , "sha512": "43fdb6b81b394f3382d353d5f57673b2b3d26cfe34b25d08a526bc0597f508d5298e5a7088d0736d1f139cad19cd922affa51533c3a5a4bb5f2de68891c2958d" + , "subdir": "curl-8.6.0" + } + , "target_root": "rules-test/just/import targets" + , "target_file_name": "TARGETS.curl" + , "bindings": + { "rules": "rules-test/just/rules-curl" + , "zlib": "rules-test/just/zlib" + , "ssl": "rules-test/just/ssl" + , "cares": "rules-test/just/com_github_cares_cares" + } + } + , "rules-test/just/com_github_grpc_grpc": + { "repository": + { "type": "archive" + , "content": "d89bbef10ae30b511e062e6aa36520a2805e0f97" + , "fetch": "https://github.com/grpc/grpc/archive/refs/tags/v1.62.1.tar.gz" + , "sha256": "c9f9ae6e4d6f40464ee9958be4068087881ed6aa37e30d0e64d40ed7be39dd01" + , "sha512": "3224ad2617c18156f90c54c1ebf1f2015e405a6f12546e8709e0c905f52508c9f1a13b4d5a6cc7a35abf58b429985b5b504c9062f50c0d3d6aa163180a61047a" + , "subdir": "grpc-1.62.1" + , "pragma": {"special": "ignore"} + } + , "target_root": "rules-test/just/import targets" + , "target_file_name": "TARGETS.grpc" + , "rule_file_name": "RULES.grpc" + , "bindings": + { "rules": "rules-test/just/rules-grpc" + , "protobuf": "rules-test/just/protobuf" + , "ssl": "rules-test/just/ssl" + , "absl": "rules-test/just/com_google_absl" + , "zlib": "rules-test/just/zlib" + , "re2": "rules-test/just/re2" + , "cares": "rules-test/just/com_github_cares_cares" + , "google_apis": "rules-test/just/google_apis" + } + } + , "rules-test/just/com_github_libarchive_libarchive": + { "repository": + { "type": "archive" + , "content": "50abf77b7226df46a33013f278464c1588b0ceea" + , "fetch": "https://github.com/libarchive/libarchive/releases/download/v3.7.4/libarchive-3.7.4.tar.gz" + , "sha256": "7875d49596286055b52439ed42f044bd8ad426aa4cc5aabd96bfe7abb971d5e8" + , "sha512": "a37006350c2a61a35ecbe638c3168661bef5cbcb7dd3e5ec9a14af1a9aa89ec1be23902cdd17c60bf15859ba1e41bad8456dee9df686bc2d825b30d453cb2e44" + , "subdir": "libarchive-3.7.4" + } + , "target_root": "rules-test/just/import targets" + , "target_file_name": "TARGETS.archive" + , "bindings": + { "rules": "rules-test/just/rules-archive" + , "zlib": "rules-test/just/zlib" + , "ssl": "rules-test/just/ssl" + , "bzip2": "rules-test/just/bzip2" + , "lzma": "rules-test/just/lzma" + } + } + , "rules-test/just/com_github_libgit2_libgit2": + { "repository": + { "type": "archive" + , "content": "80f999c62e8da8da7d64fe543c8eeb9953bf6974" + , "fetch": "https://github.com/libgit2/libgit2/archive/refs/tags/v1.7.2.tar.gz" + , "sha256": "de384e29d7efc9330c6cdb126ebf88342b5025d920dcb7c645defad85195ea7f" + , "sha512": "825737e4a1991fba50ea535f15b0e560ebe76ead752e04aeba36925b944d0da77fe9826a70980a1aa3d0bf9afbedfab79dd92e799c9252931384c89ebec9b012" + , "subdir": "libgit2-1.7.2" + } + , "target_root": "rules-test/just/import targets" + , "target_file_name": "TARGETS.git2" + , "bindings": + { "rules": "rules-test/just/rules-git2" + , "zlib": "rules-test/just/zlib" + , "ssl": "rules-test/just/ssl" + } + } + , "rules-test/just/com_github_microsoft_gsl": + { "repository": + { "type": "archive" + , "content": "386f0a89a47763481223a63d5026215af8d3c827" + , "fetch": "https://github.com/microsoft/GSL/archive/refs/tags/v4.0.0.tar.gz" + , "sha256": "f0e32cb10654fea91ad56bde89170d78cfbf4363ee0b01d8f097de2ba49f6ce9" + , "sha512": "7fa7446796c6bf82fb3bff09f86a69c446a27be528bef3b17c8bc5ad2f24d5cf86bdb3d3813ecb44726e8f395020180e97e41027330d1fbf545cc0f0b44aac29" + , "subdir": "GSL-4.0.0/include/gsl" + } + , "target_root": "rules-test/just/import targets" + , "target_file_name": "TARGETS.gsl" + , "bindings": {"rules": "rules-test/just/rules"} + } + , "rules-test/just/com_google_absl": + { "repository": + { "type": "archive" + , "content": "e9bacd5f3a5c3a51f4f0f50e9ed963464714caa7" + , "fetch": "https://github.com/abseil/abseil-cpp/releases/download/20240116.0/abseil-cpp-20240116.0.tar.gz" + , "sha256": "338420448b140f0dfd1a1ea3c3ce71b3bc172071f24f4d9a57d59b45037da440" + , "sha512": "018488e69cca472ef118631bd79bca4ef0cf1363432e79b81532942168d305511e4cdf4dc72611275e9a9de00cd71c0245be4ec287ff36147248e218218bf825" + , "subdir": "abseil-cpp-20240116.0" + , "mirrors": + [ "https://storage.googleapis.com/grpc-bazel-mirror/github.com/abseil/abseil-cpp/archive/20240116.0.tar.gz" + ] + } + , "target_root": "rules-test/just/import targets" + , "target_file_name": "TARGETS.absl" + , "bindings": + { "rules": "rules-test/just/rules-absl" + , "patches": "rules-test/just/patches" + } + } + , "rules-test/just/fmt": + { "repository": + { "type": "zip" + , "content": "c54a3ec3cba9177c0be51051b762a74449ea1466" + , "fetch": "https://github.com/fmtlib/fmt/releases/download/10.2.1/fmt-10.2.1.zip" + , "sha256": "312151a2d13c8327f5c9c586ac6cf7cddc1658e8f53edae0ec56509c8fa516c9" + , "sha512": "1cf0e3dd09c7d87e0890b8743559159d3be2a8f33c135516962d17c4eeb7b00659e6acd74518bd5566ee4e83ddaba155fecb4c229f90cd258b3b832e72ad82cd" + , "subdir": "fmt-10.2.1" + } + , "target_root": "rules-test/just/import targets" + , "target_file_name": "TARGETS.fmt" + , "bindings": {"rules": "rules-test/just/rules"} + } + , "rules-test/just/google_apis": + { "repository": + { "type": "archive" + , "content": "5d9001f3dff8dec1880c06c0de100a0c2fc65094" + , "fetch": "https://github.com/googleapis/googleapis/archive/2f9af297c84c55c8b871ba4495e01ade42476c92.tar.gz" + , "sha256": "5bb6b0253ccf64b53d6c7249625a7e3f6c3bc6402abd52d3778bfa48258703a0" + , "sha512": "cdeefae807df7097174b4bb28c0900b06a68d424c00ebba4ff5add260c9c651351d5e429bfc5de42f95ebb75dadec313f7bd3991c2fa476c9104f9ea656acad4" + , "subdir": "googleapis-2f9af297c84c55c8b871ba4495e01ade42476c92" + , "mirrors": + [ "https://storage.googleapis.com/grpc-bazel-mirror/github.com/googleapis/googleapis/archive/2f9af297c84c55c8b871ba4495e01ade42476c92.tar.gz" + ] + } + , "target_root": "rules-test/just/import targets" + , "target_file_name": "TARGETS.google_apis" + , "bindings": + {"rules": "rules-test/just/rules", "patches": "rules-test/just/patches"} + } + , "rules-test/just/json": + { "repository": + { "type": "zip" + , "content": "733571f96614cc01fcebf76c8359f52706677c61" + , "fetch": "https://github.com/nlohmann/json/releases/download/v3.11.3/include.zip" + , "sha256": "a22461d13119ac5c78f205d3df1db13403e58ce1bb1794edc9313677313f4a9d" + , "sha512": "8d923e2586acf736fc1886bf1839ca0126444ec60ce93a4bd18c21eef4475dff6f608203e42bf4968878dc50727a8c20c517dd8c1ac5c6b0bb6a95f2dce5546e" + , "subdir": "include/nlohmann" + } + , "target_root": "rules-test/just/import targets" + , "target_file_name": "TARGETS.json" + , "bindings": {"rules": "rules-test/just/rules"} + } + , "rules-test/just/lzma": + { "repository": + { "type": "archive" + , "content": "6dae9322046ff66b7074c33b24be9a98f5cee42a" + , "fetch": "https://github.com/xz-mirror/xz/archive/refs/tags/v5.4.0.tar.gz" + , "sha256": "26ec069c41e5dfae221825b9f28a4934cb6ce3bedd3f55bc0a08073f7c2e42fd" + , "sha512": "60aba20197d329a1e0d86b32de8a9727a98e5ff6f1eda6111c5ddf85086edeefcf9e2cc3998d237e248bf4af7cf746923b45d236e6b47d88f63cf3d57cae9e8f" + , "subdir": "xz-5.4.0" + } + , "target_root": "rules-test/just/import targets" + , "target_file_name": "TARGETS.lzma" + , "bindings": {"rules": "rules-test/just/rules-lzma"} + } + , "rules-test/just/patches": + { "repository": + { "type": "git" + , "repository": "https://github.com/just-buildsystem/justbuild" + , "branch": "v1.4.0-alpha+20240619" + , "commit": "96158f57c36bbc649abcd9a213bf04df6cf8a1f5" + , "subdir": "etc/patches" + } + } + , "rules-test/just/protobuf": + { "repository": + { "type": "archive" + , "content": "989aa1fec35687ab84229fa84099582dd8f0246a" + , "fetch": "https://github.com/protocolbuffers/protobuf/releases/download/v25.1/protobuf-25.1.tar.gz" + , "sha256": "9bd87b8280ef720d3240514f884e56a712f2218f0d693b48050c836028940a42" + , "sha512": "d2fad2188118ced2cd951bdb472d72cc9e9b2158c88eeca652c76332a884b5b5b4b58628f7777272fa693140753823584ea9c7924f1655b1d5a363f59bdf7a4c" + , "subdir": "protobuf-25.1" + } + , "target_root": "rules-test/just/import targets" + , "target_file_name": "TARGETS.protobuf" + , "bindings": + { "rules": "rules-test/just/rules-protobuf" + , "zlib": "rules-test/just/zlib" + , "absl": "rules-test/just/com_google_absl" + } + } + , "rules-test/just/re2": + { "repository": + { "type": "archive" + , "content": "8eebd70d7ebd33ac5d736090cecd7cfe1831b9e3" + , "fetch": "https://github.com/google/re2/archive/refs/tags/2022-04-01.tar.gz" + , "sha256": "1ae8ccfdb1066a731bba6ee0881baad5efd2cd661acd9569b689f2586e1a50e9" + , "sha512": "fc3d7cc1ee6bd771719845566d83ffc8c4e19d838748e842a1e19c7564473c9a0a061bebb3966ffa82de6515346f9bbddc2d94ceb3de89233f58826774bd7ce7" + , "subdir": "re2-2022-04-01" + , "mirrors": + [ "https://storage.googleapis.com/grpc-bazel-mirror/github.com/google/re2/archive/2022-04-01.tar.gz" + ] + } + , "target_root": "rules-test/just/import targets" + , "target_file_name": "TARGETS.re2" + , "bindings": {"rules": "rules-test/just/rules-re2"} + } + , "rules-test/just/rules": + { "repository": + { "type": "git" + , "repository": "https://github.com/just-buildsystem/justbuild" + , "branch": "v1.4.0-alpha+20240619" + , "commit": "96158f57c36bbc649abcd9a213bf04df6cf8a1f5" + , "subdir": "rules" + } + , "target_root": "rules-test/just/defaults" + , "rule_root": "rules-test/just/rules" + , "bindings": {"toolchain": "rules-test/just/toolchain"} + } + , "rules-test/just/rules-absl": + { "repository": "rules-test/just/rules" + , "target_root": "rules-test/just/defaults" + , "rule_root": "rules-test/just/rules" + , "target_file_name": "TARGETS.absl" + , "bindings": {"base": "rules-test/just/rules"} + } + , "rules-test/just/rules-archive": + { "repository": "rules-test/just/rules" + , "target_root": "rules-test/just/defaults" + , "rule_root": "rules-test/just/rules" + , "target_file_name": "TARGETS.archive" + , "bindings": {"base": "rules-test/just/rules"} + } + , "rules-test/just/rules-boringssl": + { "repository": "rules-test/just/rules" + , "target_root": "rules-test/just/defaults" + , "rule_root": "rules-test/just/rules" + , "target_file_name": "TARGETS.boringssl" + , "bindings": {"base": "rules-test/just/rules"} + } + , "rules-test/just/rules-bzip2": + { "repository": "rules-test/just/rules" + , "target_root": "rules-test/just/defaults" + , "rule_root": "rules-test/just/rules" + , "target_file_name": "TARGETS.bzip2" + , "bindings": {"base": "rules-test/just/rules"} + } + , "rules-test/just/rules-curl": + { "repository": "rules-test/just/rules" + , "target_root": "rules-test/just/defaults" + , "rule_root": "rules-test/just/rules" + , "target_file_name": "TARGETS.curl" + , "bindings": {"base": "rules-test/just/rules"} + } + , "rules-test/just/rules-git2": + { "repository": "rules-test/just/rules" + , "target_root": "rules-test/just/defaults" + , "rule_root": "rules-test/just/rules" + , "target_file_name": "TARGETS.git2" + , "bindings": {"base": "rules-test/just/rules"} + } + , "rules-test/just/rules-grpc": + { "repository": "rules-test/just/rules" + , "target_root": "rules-test/just/defaults" + , "rule_root": "rules-test/just/rules" + , "target_file_name": "TARGETS.grpc" + , "bindings": + {"base": "rules-test/just/rules", "protoc": "rules-test/just/protobuf"} + } + , "rules-test/just/rules-just": + { "repository": "rules-test/just/rules" + , "target_root": "rules-test/just/defaults" + , "rule_root": "rules-test/just/rules" + , "target_file_name": "TARGETS.just" + , "bindings": + { "base": "rules-test/just/rules" + , "protoc": "rules-test/just/protobuf" + , "grpc": "rules-test/just/com_github_grpc_grpc" + } + } + , "rules-test/just/rules-lzma": + { "repository": "rules-test/just/rules" + , "target_root": "rules-test/just/defaults" + , "rule_root": "rules-test/just/rules" + , "target_file_name": "TARGETS.lzma" + , "bindings": {"base": "rules-test/just/rules"} + } + , "rules-test/just/rules-protobuf": + { "repository": "rules-test/just/rules" + , "target_root": "rules-test/just/defaults" + , "rule_root": "rules-test/just/rules" + , "target_file_name": "TARGETS.protobuf" + , "bindings": {"base": "rules-test/just/rules"} + } + , "rules-test/just/rules-re2": + { "repository": "rules-test/just/rules" + , "target_root": "rules-test/just/defaults" + , "rule_root": "rules-test/just/rules" + , "target_file_name": "TARGETS.re2" + , "bindings": {"base": "rules-test/just/rules"} + } + , "rules-test/just/ssl": + { "repository": + { "type": "archive" + , "content": "7b7deaf147baf61c8efdc8a4ac79a16ba70b216e" + , "fetch": "https://github.com/google/boringssl/archive/ae72a4514c7afd150596b0a80947f3ca9b8363b5.tar.gz" + , "sha256": "057f662b0e85931a84945b2e89ba201fd44b0583da827c948fe443593690fb83" + , "sha512": "757a2727a2ab0e45656c22d807ea1217c74c276f51fa721a87f92b59a4d040d9931586e912b4558f57330340cc3af6361f1694b1479b764635c6a111b356afc4" + , "subdir": "boringssl-ae72a4514c7afd150596b0a80947f3ca9b8363b5" + , "mirrors": + [ "https://storage.googleapis.com/grpc-bazel-mirror/github.com/google/boringssl/archive/ae72a4514c7afd150596b0a80947f3ca9b8363b5.tar.gz" + ] + } + , "target_root": "rules-test/just/import targets" + , "target_file_name": "TARGETS.boringssl" + , "bindings": + { "rules": "rules-test/just/rules-boringssl" + , "patches": "rules-test/just/patches" + } + } + , "rules-test/just/toolchain": + { "repository": + { "type": "git" + , "repository": "https://github.com/just-buildsystem/justbuild" + , "branch": "v1.4.0-alpha+20240619" + , "commit": "96158f57c36bbc649abcd9a213bf04df6cf8a1f5" + , "subdir": "etc/toolchain" + } + , "rule_root": "rules-test/just/rules" + } + , "rules-test/just/zlib": + { "repository": + { "type": "archive" + , "content": "88faf0fca21e0d82de44366fdd52aaadbab2e6b6" + , "fetch": "https://github.com/madler/zlib/releases/download/v1.3/zlib-1.3.tar.gz" + , "sha256": "ff0ba4c292013dbc27530b3a81e1f9a813cd39de01ca5e0f8bf355702efa593e" + , "sha512": "185795044461cd78a5545250e06f6efdb0556e8d1bfe44e657b509dd6f00ba8892c8eb3febe65f79ee0b192d6af857f0e0055326d33a881449f3833f92e5f8fb" + , "subdir": "zlib-1.3" + } + , "target_root": "rules-test/just/import targets" + , "target_file_name": "TARGETS.zlib" + , "bindings": {"rules": "rules-test/just/rules"} + } + , "rules-test/libcurl": + { "repository": + { "type": "archive" + , "content": "540b4de2edfa015b894ad86d51b33a55f451ac99" + , "fetch": "https://github.com/curl/curl/releases/download/curl-8_0_1/curl-8.0.1.tar.gz" + , "sha256": "5fd29000a4089934f121eff456101f0a5d09e2a3e89da1d714adf06c4be887cb" + , "sha512": "87d945e65176613c6296f8b130bd6c5355e3ca3c62ee4010edd481950cad9760482fd3be8a84e51501c118c29ebc284b8f87c49b06f9d248e9da5819fda38f8f" + , "subdir": "curl-8.0.1" + } + , "target_root": "rules-test/imports" + , "target_file_name": "libcurl.TARGETS" + , "bindings": {"libz": "rules-test/libz"} + } + , "rules-test/libz": + { "repository": + { "type": "archive" + , "content": "d115fc690fa59d3be51b3442158876536140b6c2" + , "fetch": "https://github.com/madler/zlib/releases/download/v1.2.13/zlib-1.2.13.tar.gz" + , "sha256": "b3a24de97a8fdbc835b9833169501030b8977031bcb54b3b3ac13740f846ab30" + , "sha512": "99f0e843f52290e6950cc328820c0f322a4d934a504f66c7caa76bd0cc17ece4bf0546424fc95135de85a2656fed5115abb835fd8d8a390d60ffaf946c8887ad" + , "subdir": "zlib-1.2.13" + } + , "target_root": "rules-test/imports" + , "target_file_name": "libz.TARGETS" + } + , "rules-test/rules": + { "repository": + { "type": "git" + , "repository": "https://github.com/just-buildsystem/rules-cc" + , "branch": "master" + , "commit": "ba89bf29f2dd7d13dbd659d5319232ee98070126" + , "subdir": "rules" + } + } + , "rules-test/test-libs": + { "repository": "rules-test/imports" + , "target_file_name": "libs.TARGETS" + , "bindings": + { "gtest": "rules-test/gtest" + , "libz": "rules-test/libz" + , "libcurl": "rules-test/libcurl" + } + } + , "rules-test/imports": + { "repository": + { "type": "git" + , "repository": "https://github.com/just-buildsystem/rules-cc" + , "branch": "master" + , "commit": "ba89bf29f2dd7d13dbd659d5319232ee98070126" + , "subdir": "etc/imports" + } + } + , "rules-test/just/defaults": + { "repository": + { "type": "git" + , "repository": "https://github.com/just-buildsystem/justbuild" + , "branch": "v1.4.0-alpha+20240619" + , "commit": "96158f57c36bbc649abcd9a213bf04df6cf8a1f5" + , "subdir": "etc/defaults" + } + } + , "rules-test/just/import targets": + { "repository": + { "type": "git" + , "repository": "https://github.com/just-buildsystem/justbuild" + , "branch": "v1.4.0-alpha+20240619" + , "commit": "96158f57c36bbc649abcd9a213bf04df6cf8a1f5" + , "subdir": "etc/import" + } + } + } +} diff --git a/etc/repos.template.json b/etc/repos.template.json new file mode 100644 index 0000000..2bf98e9 --- /dev/null +++ b/etc/repos.template.json @@ -0,0 +1,14 @@ +{ "main": "rust-rules" +, "repositories": + { "rust-rules": + { "repository": {"type": "file", "path": "."} + , "bindings": {"test-rules": "rules-test", "rules-cc": "rules-cc"} + } + , "imports": {"repository": {"type": "file", "path": "etc/imports"}} + , "test-rules": + { "repository": "rust-rules" + , "target_root": "imports" + , "target_file_name": "rules.TARGETS" + } + } +} diff --git a/rules/EXPRESSIONS b/rules/EXPRESSIONS new file mode 100644 index 0000000..101af7b --- /dev/null +++ b/rules/EXPRESSIONS @@ -0,0 +1,194 @@ +{ "default_from_base": + { "doc": + [ "If the \"value\" is evaluated as null, the value associated to" + , "\"key\" is retrieved from the \"base\" targets." + ] + , "vars": ["base", "transition", "key", "value"] + , "imports": {"flatten_from_provides": "flatten_from_provides"} + , "expression": + { "type": "if" + , "cond": {"type": "var", "name": "value"} + , "then": {"type": "var", "name": "value"} + , "else": + { "type": "let*" + , "bindings": [["range", {"type": "var", "name": "base"}]] + , "body": {"type": "CALL_EXPRESSION", "name": "flatten_from_provides"} + } + } + } +, "disjoint_map_from_provides": + { "doc": + [ "Performs a disjoint map union of the maps contained in the" + , "provides map of each element in the \"range\" under the key \"key\"." + ] + , "vars": ["range", "transition", "key"] + , "expression": + { "type": "let*" + , "bindings": + [ [ "transition" + , { "type": "var" + , "name": "transition" + , "default": {"type": "empty_map"} + } + ] + ] + , "body": + { "type": "disjoint_map_union" + , "$1": + { "type": "foreach" + , "var": "x" + , "range": {"type": "var", "name": "range"} + , "body": + { "type": "DEP_PROVIDES" + , "dep": {"type": "var", "name": "x"} + , "provider": {"type": "var", "name": "key"} + , "default": {"type": "empty_map"} + , "transition": {"type": "var", "name": "transition"} + } + } + } + } + } +, "flatten_from_provides": + { "doc": + [ "Flatten the lists contained in the provides map of each element" + , "in the \"range\" under the key \"key\"." + ] + , "vars": ["range", "transition", "key"] + , "expression": + { "type": "let*" + , "bindings": + [ [ "transition" + , { "type": "var" + , "name": "transition" + , "default": {"type": "empty_map"} + } + ] + ] + , "body": + { "type": "++" + , "$1": + { "type": "foreach" + , "var": "x" + , "range": {"type": "var", "name": "range"} + , "body": + { "type": "DEP_PROVIDES" + , "dep": {"type": "var", "name": "x"} + , "provider": {"type": "var", "name": "key"} + , "transition": {"type": "var", "name": "transition"} + } + } + } + } + } +, "get_artifacts": + { "vars": ["field_content", "transition"] + , "expression": + { "type": "disjoint_map_union" + , "$1": + { "type": "foreach" + , "var": "x" + , "range": {"type": "var", "name": "field_content"} + , "body": + { "type": "DEP_ARTIFACTS" + , "dep": {"type": "var", "name": "x"} + , "transition": + { "type": "var" + , "name": "transition" + , "default": {"type": "empty_map"} + } + } + } + } + } +, "get_runfiles": + { "vars": ["field_content", "transition"] + , "expression": + { "type": "disjoint_map_union" + , "$1": + { "type": "foreach" + , "var": "x" + , "range": {"type": "var", "name": "field_content"} + , "body": + { "type": "DEP_RUNFILES" + , "dep": {"type": "var", "name": "x"} + , "transition": + { "type": "var" + , "name": "transition" + , "default": {"type": "empty_map"} + } + } + } + } + } +, "get_unique_artifact": + { "doc": + [ "Retrive the unique artifact. Asserts double checks that the" + , "\"field_content\" evaluates to a single artifact." + ] + , "vars": ["field_name", "field_content", "transition"] + , "imports": {"get_artifacts": "get_artifacts"} + , "expression": + { "type": "let*" + , "bindings": + [ [ "_" + , { "type": "assert_non_empty" + , "msg": + { "type": "join" + , "$1": + [ "Please define field " + , { "type": "json_encode" + , "$1": {"type": "var", "name": "field_name"} + } + , ". It cannot be empty." + ] + , "separator": "" + } + , "$1": {"type": "var", "name": "field_content"} + } + ] + , ["artifacts", {"type": "CALL_EXPRESSION", "name": "get_artifacts"}] + , [ "_" + , { "type": "assert" + , "msg": + { "type": "join" + , "$1": + [ { "type": "json_encode" + , "$1": {"type": "var", "name": "field_name"} + } + , " must evaluate to exactly one artifact but found " + , { "type": "json_encode" + , "$1": {"type": "var", "name": "artifacts"} + } + ] + , "separator": "" + } + , "predicate": + { "type": "==" + , "$1": {"type": "length", "$1": {"type": "var", "name": "_"}} + , "$2": 1 + } + , "$1": {"type": "keys", "$1": {"type": "var", "name": "artifacts"}} + } + ] + ] + , "body": {"type": "var", "name": "artifacts"} + } + } +, "stage_unique_artifact": + { "vars": ["artifact", "name"] + , "expression": + { "type": "disjoint_map_union" + , "$1": + { "type": "foreach" + , "var": "x" + , "range": {"type": "values", "$1": {"type": "var", "name": "artifact"}} + , "body": + { "type": "singleton_map" + , "key": {"type": "var", "name": "name"} + , "value": {"type": "var", "name": "x"} + } + } + } + } +} diff --git a/rules/TARGETS b/rules/TARGETS new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/rules/TARGETS @@ -0,0 +1 @@ +{} diff --git a/rules/cargo/RULES b/rules/cargo/RULES new file mode 100644 index 0000000..19d961b --- /dev/null +++ b/rules/cargo/RULES @@ -0,0 +1,374 @@ +{ "build_script": + { "doc": + [ "The custom build script supported by cargo. This binary is" + , "executed before compiling the other crates. Currently, only its" + , "output is processed to augment the rustc flags. During a cross" + , "compilation, since the build script must be run on the host" + , "system, it is always compiled according to the configuration" + , "provided by the \"defaults\" for the \"HOST_ARCH\"." + ] + , "string_fields": ["name", "edition", "stage", "version", "pkg_name"] + , "target_fields": ["crate_root", "srcs", "deps", "cargo_features"] + , "field_doc": + { "name": ["The name of the crate being built."] + , "cargo_features": + ["List of cargo features this binary requires to be enabled."] + , "crate_root": + [ "The crate to be fed to the Rust compiler. It must evaluate to" + , "a single artifact/file." + ] + , "defaults": ["The Rust toolchain to use."] + , "deps": ["Any other libraries this binary depends upon."] + , "edition": + [ "The edition of the compiler to use during compilation. If" + , "unset, 2015 is used." + ] + , "pkg_name": + [ "The name of the package the crate belongs to. It is" + , "exported to the CARGO_PKG_NAME environment variable." + ] + , "srcs": ["The source files of the binary."] + , "stage": + [ "The logical location of the resulting artifact. Elements are" + , "joined with \"/\"." + ] + , "version": + [ "The crate version. Elements are joined with \".\" and the first" + , "three elements are used for the major, minor, and patch" + , "number respectively." + ] + } + , "config_vars": ["ARCH", "HOST_ARCH", "ENV"] + , "config_doc": + { "ARCH": + [ "Default value for both HOST_ARCH and TARGET_ARCH. It is user's" + , "responsibility to adapt the \"defaults\" according to the" + , "provided value." + ] + , "ENV": + [ "Additional environment variables (besides ones provided by" + , "the \"defaults\" target) to be set for each action. If the" + , "same variable is set here and in the \"defaults\", the former" + , "is taken." + ] + , "HOST_ARCH": + [ "The host CPU architecture. It is user's responsibility to" + , "adapt the \"defaults\" according to the provided value." + ] + } + , "config_transitions": + { "cargo_features": + [{"type": "CALL_EXPRESSION", "name": "for host as rlib"}] + , "crate_root": [{"type": "CALL_EXPRESSION", "name": "for host"}] + , "defaults": [{"type": "CALL_EXPRESSION", "name": "for host"}] + , "deps": [{"type": "CALL_EXPRESSION", "name": "for host as rlib"}] + , "srcs": [{"type": "CALL_EXPRESSION", "name": "for host"}] + } + , "imports": + { "call rustc artifact": ["./", "../rust", "call rustc artifact"] + , "for host": ["./", "../rust", "for host"] + , "for host as rlib": ["./", "../rust", "for host as rlib"] + , "get_runfiles": ["./", "..", "get_runfiles"] + } + , "implicit": {"defaults": [["./", "../rust", "defaults"]]} + , "expression": + { "type": "let*" + , "bindings": + [ ["crate_name", {"type": "FIELD", "name": "name"}] + , ["crate_type", "bin"] + , [ "stage" + , { "type": "if" + , "cond": {"type": "FIELD", "name": "stage"} + , "then": + { "type": "join" + , "$1": {"type": "FIELD", "name": "stage"} + , "separator": "/" + } + , "else": "." + } + ] + , ["crate_root", {"type": "FIELD", "name": "crate_root"}] + , ["edition", {"type": "FIELD", "name": "edition"}] + , ["srcs", {"type": "FIELD", "name": "srcs"}] + , ["deps", {"type": "FIELD", "name": "deps"}] + , ["cargo_features", {"type": "FIELD", "name": "cargo_features"}] + , ["emit", "link"] + , ["is_custom_build_script", true] + , ["transition", {"type": "CALL_EXPRESSION", "name": "for host"}] + , [ "deps-transition" + , {"type": "CALL_EXPRESSION", "name": "for host as rlib"} + ] + , ["version", {"type": "FIELD", "name": "version"}] + , ["pkg_name", {"type": "FIELD", "name": "pkg_name"}] + , ["defaults", {"type": "FIELD", "name": "defaults"}] + , [ "artifact result" + , {"type": "CALL_EXPRESSION", "name": "call rustc artifact"} + ] + , [ "exe" + , { "type": "assert" + , "msg": + { "type": "join" + , "$1": + [ "Expected single executable but found " + , {"type": "json_encode", "$1": {"type": "var", "name": "_"}} + ] + } + , "predicate": + { "type": "==" + , "$1": + { "type": "length" + , "$1": {"type": "keys", "$1": {"type": "var", "name": "_"}} + } + , "$2": 1 + } + , "$1": + { "type": "lookup" + , "key": "artifact" + , "map": {"type": "var", "name": "artifact result"} + } + } + ] + , [ "exe_name" + , { "type": "lookup" + , "key": "artifact-name" + , "map": {"type": "var", "name": "artifact result"} + } + ] + , [ "out_name" + , { "type": "join" + , "$1": [{"type": "var", "name": "stage"}, "out"] + , "separator": "/" + } + ] + , [ "out" + , { "type": "ACTION" + , "outs": [{"type": "var", "name": "out_name"}] + , "inputs": {"type": "var", "name": "exe"} + , "cmd": + [ "sh" + , "-ce" + , { "type": "join" + , "$1": + [ { "type": "join_cmd" + , "$1": [{"type": "var", "name": "exe_name"}] + } + , " > " + , {"type": "var", "name": "out_name"} + , " && " + , { "type": "join_cmd" + , "$1": ["cat", {"type": "var", "name": "out_name"}] + } + , " | " + , { "type": "join_cmd" + , "$1": + [ "xargs" + , "printf" + , { "type": "join" + , "$1": + ["[", {"type": "var", "name": "stage"}, "] ", "%s\n"] + , "separator": "" + } + ] + } + ] + , "separator": "" + } + ] + , "env": + { "type": "lookup" + , "key": "env" + , "map": {"type": "var", "name": "artifact result"} + } + } + ] + , [ "file_args_name" + , { "type": "join" + , "$1": [{"type": "var", "name": "stage"}, "file_args"] + , "separator": "/" + } + ] + , [ "file_args" + , { "type": "ACTION" + , "outs": [{"type": "var", "name": "file_args_name"}] + , "inputs": {"type": "var", "name": "out"} + , "cmd": + [ "sh" + , "-c" + , { "type": "join" + , "$1": + [ { "type": "join_cmd" + , "$1": ["cat", {"type": "var", "name": "out_name"}] + } + , " | " + , { "type": "join_cmd" + , "$1": + [ "awk" + , { "type": "join" + , "$1": + [ "/rustc-cfg/ {split($0,x,\"=\"); printf \"--cfg\\n%s\\n\", x[2]}" + , "/rustc-link-arg/ {split($0,x,\"=\"); printf \"-Clink-arg=%s\\n\", x[2]}" + ] + , "separator": " " + } + ] + } + , " > " + , {"type": "var", "name": "file_args_name"} + ] + , "separator": "" + } + ] + } + ] + , [ "args" + , { "type": "join" + , "$1": ["@", {"type": "var", "name": "file_args_name"}] + , "separator": "" + } + ] + ] + , "body": + { "type": "RESULT" + , "artifacts": + { "type": "map_union" + , "$1": + [ {"type": "var", "name": "exe"} + , {"type": "var", "name": "file_args"} + , {"type": "var", "name": "out"} + ] + } + , "provides": + { "type": "map_union" + , "$1": + [ { "type": "singleton_map" + , "key": "rust-compile-artifacts" + , "value": {"type": "var", "name": "file_args"} + } + , { "type": "singleton_map" + , "key": "rust-link-artifacts" + , "value": {"type": "var", "name": "file_args"} + } + , { "type": "singleton_map" + , "key": "rustc-compile-args" + , "value": [{"type": "var", "name": "args"}] + } + , { "type": "singleton_map" + , "key": "rustc-link-args" + , "value": [{"type": "var", "name": "args"}] + } + ] + } + } + } + } +, "feature": + { "doc": ["A cargo feature."] + , "string_fields": ["name"] + , "target_fields": ["deps"] + , "field_doc": + { "name": + [ "The feature name. The flag `--cfg feature=<name>` is passed to" + , "the Rust compiler." + ] + , "deps": + ["Any other features or \"[rust, library]\" this feature depends", "on."] + } + , "imports": + { "disjoint_map_from_provides": ["./", "..", "disjoint_map_from_provides"] + , "flatten_from_provides": ["./", "..", "flatten_from_provides"] + } + , "expression": + { "type": "let*" + , "bindings": + [ [ "feature_name" + , {"type": "[]", "index": 0, "list": {"type": "FIELD", "name": "name"}} + ] + , [ "my_feature_arg" + , [ "--cfg" + , { "type": "join" + , "$1": + ["feature=\"", {"type": "var", "name": "feature_name"}, "\""] + } + ] + ] + , ["deps", {"type": "FIELD", "name": "deps"}] + , ["range", {"type": "var", "name": "deps"}] + , [ "compile-deps" + , { "type": "let*" + , "bindings": [["key", "rust-compile-artifacts"]] + , "body": + {"type": "CALL_EXPRESSION", "name": "disjoint_map_from_provides"} + } + ] + , [ "link-deps" + , { "type": "let*" + , "bindings": [["key", "rust-link-artifacts"]] + , "body": + {"type": "CALL_EXPRESSION", "name": "disjoint_map_from_provides"} + } + ] + , [ "compile-deps-args" + , { "type": "let*" + , "bindings": [["key", "rustc-compile-args"]] + , "body": + {"type": "CALL_EXPRESSION", "name": "flatten_from_provides"} + } + ] + , [ "link-deps-args" + , { "type": "let*" + , "bindings": [["key", "rustc-link-args"]] + , "body": + {"type": "CALL_EXPRESSION", "name": "flatten_from_provides"} + } + ] + , [ "stage-deps-args" + , { "type": "let*" + , "bindings": [["key", "stage-args"]] + , "body": + {"type": "CALL_EXPRESSION", "name": "flatten_from_provides"} + } + ] + ] + , "body": + { "type": "RESULT" + , "provides": + { "type": "map_union" + , "$1": + [ { "type": "singleton_map" + , "key": "rust-compile-artifacts" + , "value": {"type": "var", "name": "compile-deps"} + } + , { "type": "singleton_map" + , "key": "rust-link-artifacts" + , "value": {"type": "var", "name": "link-deps"} + } + , { "type": "singleton_map" + , "key": "rustc-compile-args" + , "value": + { "type": "++" + , "$1": + [ {"type": "var", "name": "my_feature_arg"} + , {"type": "var", "name": "compile-deps-args"} + ] + } + } + , { "type": "singleton_map" + , "key": "rustc-link-args" + , "value": + { "type": "++" + , "$1": + [ {"type": "var", "name": "my_feature_arg"} + , {"type": "var", "name": "link-deps-args"} + ] + } + } + , { "type": "singleton_map" + , "key": "stage-args" + , "value": {"type": "var", "name": "stage-deps-args"} + } + ] + } + } + } + } +} diff --git a/rules/rust/EXPRESSIONS b/rules/rust/EXPRESSIONS new file mode 100644 index 0000000..3f23d41 --- /dev/null +++ b/rules/rust/EXPRESSIONS @@ -0,0 +1,1319 @@ +{ "call rustc": + { "vars": ["cmd", "inputs", "outs", "out_dirs", "env"] + , "expression": + { "type": "ACTION" + , "outs": {"type": "var", "name": "outs", "default": []} + , "inputs": {"type": "var", "name": "inputs"} + , "cmd": {"type": "var", "name": "cmd"} + , "env": {"type": "var", "name": "env"} + , "out_dirs": {"type": "var", "name": "out_dirs", "default": []} + } + } +, "call rustc artifact": + { "doc": + [ "The artifact produced by the calling of the Rust compiler. The" + , "expression \"call rustc result\" first calls this expression." + ] + , "vars": + [ "crate_root" + , "crate_name" + , "deps" + , "crate_type" + , "srcs" + , "edition" + , "cargo_features" + , "stage" + , "build_script" + , "emit" + , "rmeta" + , "runner" + , "transition" + , "deps-transition" + , "version" + , "test" + , "defaults" + , "pkg_name" + , "ENV" + ] + , "imports": + { "call rustc": "call rustc" + , "disjoint_map_from_provides": ["./", "..", "disjoint_map_from_provides"] + , "flatten_from_provides": ["./", "..", "flatten_from_provides"] + , "for host": "for host" + , "get_artifacts": ["./", "..", "get_artifacts"] + , "get_runfiles": ["./", "..", "get_runfiles"] + , "get_unique_artifact": ["./", "..", "get_unique_artifact"] + } + , "expression": + { "type": "let*" + , "bindings": + [ [ "crate_root" + , { "type": "let*" + , "bindings": + [ [ "transition" + , { "type": "var" + , "name": "transition" + , "default": {"type": "empty_map"} + } + ] + , ["field_name", "crate_root"] + , ["field_content", {"type": "var", "name": "crate_root"}] + ] + , "body": {"type": "CALL_EXPRESSION", "name": "get_unique_artifact"} + } + ] + , [ "crate_root_name" + , { "type": "join" + , "$1": {"type": "keys", "$1": {"type": "var", "name": "crate_root"}} + } + ] + , [ "crate_name" + , {"type": "join", "$1": {"type": "var", "name": "crate_name"}} + ] + , [ "srcs" + , { "type": "let*" + , "bindings": + [ [ "transition" + , { "type": "var" + , "name": "transition" + , "default": {"type": "empty_map"} + } + ] + , ["field_content", {"type": "var", "name": "srcs"}] + ] + , "body": {"type": "CALL_EXPRESSION", "name": "get_artifacts"} + } + ] + , [ "c-deps" + , { "type": "let*" + , "bindings": + [ [ "transition" + , { "type": "var" + , "name": "deps-transition" + , "default": {"type": "empty_map"} + } + ] + , ["field_content", {"type": "var", "name": "deps"}] + , [ "artifacts" + , {"type": "CALL_EXPRESSION", "name": "get_artifacts"} + ] + , ["runfiles", {"type": "CALL_EXPRESSION", "name": "get_runfiles"}] + , ["range", {"type": "var", "name": "deps"}] + , [ "compile-deps" + , { "type": "let*" + , "bindings": [["key", "compile-deps"]] + , "body": + { "type": "CALL_EXPRESSION" + , "name": "disjoint_map_from_provides" + } + } + ] + , [ "link-deps" + , { "type": "let*" + , "bindings": [["key", "link-deps"]] + , "body": + { "type": "CALL_EXPRESSION" + , "name": "disjoint_map_from_provides" + } + } + ] + ] + , "body": + { "type": "map_union" + , "$1": + [ {"type": "var", "name": "runfiles"} + , {"type": "var", "name": "artifacts"} + , {"type": "var", "name": "compile-deps"} + , {"type": "var", "name": "link-deps"} + ] + } + } + ] + , [ "run-libs" + , { "type": "let*" + , "bindings": + [ [ "transition" + , { "type": "var" + , "name": "deps-transition" + , "default": {"type": "empty_map"} + } + ] + , ["range", {"type": "var", "name": "deps"}] + , ["key", "run-libs"] + ] + , "body": + {"type": "CALL_EXPRESSION", "name": "disjoint_map_from_provides"} + } + ] + , [ "c-deps-link-args" + , { "type": "let*" + , "bindings": + [ ["range", {"type": "var", "name": "deps"}] + , [ "transition" + , { "type": "var" + , "name": "deps-transition" + , "default": {"type": "empty_map"} + } + ] + , ["key", "link-args"] + ] + , "body": + {"type": "CALL_EXPRESSION", "name": "flatten_from_provides"} + } + ] + , [ "c-deps-run-libs-args" + , { "type": "let*" + , "bindings": + [ [ "transition" + , { "type": "var" + , "name": "deps-transition" + , "default": {"type": "empty_map"} + } + ] + , ["range", {"type": "var", "name": "deps"}] + , ["key", "run-libs-args"] + ] + , "body": + {"type": "CALL_EXPRESSION", "name": "flatten_from_provides"} + } + ] + , [ "range" + , { "type": "++" + , "$1": + [ {"type": "var", "name": "deps"} + , {"type": "var", "name": "cargo_features"} + , {"type": "var", "name": "build_script", "default": []} + ] + } + ] + , [ "compile-deps" + , { "type": "map_union" + , "$1": + [ {"type": "var", "name": "c-deps"} + , {"type": "var", "name": "run-libs"} + , { "type": "let*" + , "bindings": + [ [ "transition" + , { "type": "var" + , "name": "deps-transition" + , "default": {"type": "empty_map"} + } + ] + , ["key", "rust-compile-artifacts"] + ] + , "body": + { "type": "CALL_EXPRESSION" + , "name": "disjoint_map_from_provides" + } + } + ] + } + ] + , [ "link-deps" + , { "type": "map_union" + , "$1": + [ {"type": "var", "name": "c-deps"} + , {"type": "var", "name": "run-libs"} + , { "type": "let*" + , "bindings": + [ [ "transition" + , { "type": "var" + , "name": "deps-transition" + , "default": {"type": "empty_map"} + } + ] + , ["key", "rust-link-artifacts"] + ] + , "body": + { "type": "CALL_EXPRESSION" + , "name": "disjoint_map_from_provides" + } + } + ] + } + ] + , [ "compile-deps-args" + , { "type": "let*" + , "bindings": + [ [ "transition" + , { "type": "var" + , "name": "deps-transition" + , "default": {"type": "empty_map"} + } + ] + , ["key", "rustc-compile-args"] + ] + , "body": + {"type": "CALL_EXPRESSION", "name": "flatten_from_provides"} + } + ] + , [ "link-deps-args" + , { "type": "let*" + , "bindings": + [ [ "transition" + , { "type": "var" + , "name": "deps-transition" + , "default": {"type": "empty_map"} + } + ] + , ["key", "rustc-link-args"] + ] + , "body": + {"type": "CALL_EXPRESSION", "name": "flatten_from_provides"} + } + ] + , [ "stage-deps-args" + , { "type": "let*" + , "bindings": + [ [ "transition" + , { "type": "var" + , "name": "deps-transition" + , "default": {"type": "empty_map"} + } + ] + , ["key", "stage-args"] + ] + , "body": + {"type": "CALL_EXPRESSION", "name": "flatten_from_provides"} + } + ] + , ["range", {"type": "var", "name": "defaults"}] + , [ "transition" + , { "type": "var" + , "name": "transition" + , "default": {"type": "empty_map"} + } + ] + , [ "TARGET" + , { "type": "join" + , "$1": + { "type": "let*" + , "bindings": [["key", "TARGET"]] + , "body": + {"type": "CALL_EXPRESSION", "name": "flatten_from_provides"} + } + } + ] + , [ "HOST" + , { "type": "join" + , "$1": + { "type": "let*" + , "bindings": [["key", "HOST"]] + , "body": + {"type": "CALL_EXPRESSION", "name": "flatten_from_provides"} + } + } + ] + , [ "RUSTC" + , { "type": "join" + , "$1": + { "type": "let*" + , "bindings": [["key", "RUSTC"]] + , "body": + {"type": "CALL_EXPRESSION", "name": "flatten_from_provides"} + } + } + ] + , [ "RUSTC_FLAGS" + , { "type": "let*" + , "bindings": [["key", "RUSTC_FLAGS"]] + , "body": + {"type": "CALL_EXPRESSION", "name": "flatten_from_provides"} + } + ] + , [ "ADD_RUSTC_FLAGS" + , { "type": "let*" + , "bindings": [["key", "ADD_RUSTC_FLAGS"]] + , "body": + {"type": "CALL_EXPRESSION", "name": "flatten_from_provides"} + } + ] + , [ "PATH" + , { "type": "join" + , "$1": + { "type": "let*" + , "bindings": [["key", "PATH"]] + , "body": + {"type": "CALL_EXPRESSION", "name": "flatten_from_provides"} + } + , "separator": ":" + } + ] + , [ "CARGO_CFG_TARGET_ARCH" + , { "type": "join" + , "$1": + { "type": "let*" + , "bindings": [["key", "CARGO_CFG_TARGET_ARCH"]] + , "body": + {"type": "CALL_EXPRESSION", "name": "flatten_from_provides"} + } + } + ] + , [ "CARGO_CFG_TARGET_ENDIAN" + , { "type": "join" + , "$1": + { "type": "let*" + , "bindings": [["key", "CARGO_CFG_TARGET_ENDIAN"]] + , "body": + {"type": "CALL_EXPRESSION", "name": "flatten_from_provides"} + } + } + ] + , [ "CARGO_CFG_TARGET_ENV" + , { "type": "join" + , "$1": + { "type": "let*" + , "bindings": [["key", "CARGO_CFG_TARGET_ENV"]] + , "body": + {"type": "CALL_EXPRESSION", "name": "flatten_from_provides"} + } + } + ] + , [ "CARGO_CFG_TARGET_FAMILY" + , { "type": "join" + , "$1": + { "type": "let*" + , "bindings": [["key", "CARGO_CFG_TARGET_FAMILY"]] + , "body": + {"type": "CALL_EXPRESSION", "name": "flatten_from_provides"} + } + } + ] + , [ "CARGO_CFG_TARGET_FEATURE" + , { "type": "join" + , "$1": + { "type": "let*" + , "bindings": [["key", "CARGO_CFG_TARGET_FEATURE"]] + , "body": + {"type": "CALL_EXPRESSION", "name": "flatten_from_provides"} + } + , "separator": "," + } + ] + , [ "CARGO_CFG_TARGET_HAS_ATOMIC" + , { "type": "join" + , "$1": + { "type": "let*" + , "bindings": [["key", "CARGO_CFG_TARGET_HAS_ATOMIC"]] + , "body": + {"type": "CALL_EXPRESSION", "name": "flatten_from_provides"} + } + , "separator": "," + } + ] + , [ "CARGO_CFG_TARGET_OS" + , { "type": "join" + , "$1": + { "type": "let*" + , "bindings": [["key", "CARGO_CFG_TARGET_OS"]] + , "body": + {"type": "CALL_EXPRESSION", "name": "flatten_from_provides"} + } + } + ] + , [ "CARGO_CFG_TARGET_POINTER_WIDTH" + , { "type": "join" + , "$1": + { "type": "let*" + , "bindings": [["key", "CARGO_CFG_TARGET_POINTER_WIDTH"]] + , "body": + {"type": "CALL_EXPRESSION", "name": "flatten_from_provides"} + } + } + ] + , [ "CARGO_CFG_TARGET_VENDOR" + , { "type": "join" + , "$1": + { "type": "let*" + , "bindings": [["key", "CARGO_CFG_TARGET_VENDOR"]] + , "body": + {"type": "CALL_EXPRESSION", "name": "flatten_from_provides"} + } + } + ] + , [ "CARGO_CFG_UNIX" + , { "type": "join" + , "$1": + { "type": "let*" + , "bindings": [["key", "CARGO_CFG_UNIX"]] + , "body": + {"type": "CALL_EXPRESSION", "name": "flatten_from_provides"} + } + } + ] + , [ "CARGO_CFG_WINDOWS" + , { "type": "join" + , "$1": + { "type": "let*" + , "bindings": [["key", "CARGO_CFG_WINDOWS"]] + , "body": + {"type": "CALL_EXPRESSION", "name": "flatten_from_provides"} + } + } + ] + , [ "CARGO_ENCODED_RUSTFLAGS" + , { "type": "join" + , "$1": + { "type": "let*" + , "bindings": [["key", "CARGO_ENCODED_RUSTFLAGS"]] + , "body": + {"type": "CALL_EXPRESSION", "name": "flatten_from_provides"} + } + } + ] + , [ "edition" + , { "type": "if" + , "cond": {"type": "var", "name": "edition"} + , "then": {"type": "join", "$1": {"type": "var", "name": "edition"}} + , "else": "2015" + } + ] + , [ "cmd" + , [ "sh" + , "-c" + , { "type": "join" + , "$1": + [ { "type": "join_cmd" + , "$1": + { "type": "++" + , "$1": + [ [ { "type": "var" + , "name": "runner" + , "default": {"type": "var", "name": "RUSTC"} + } + , {"type": "var", "name": "crate_root_name"} + , "--crate-name" + , {"type": "var", "name": "crate_name"} + , "--crate-type" + , {"type": "var", "name": "crate_type"} + , "--emit" + , {"type": "var", "name": "emit"} + , "--edition" + , {"type": "var", "name": "edition"} + , "--out-dir" + , {"type": "var", "name": "stage"} + ] + , {"type": "var", "name": "RUSTC_FLAGS"} + , {"type": "var", "name": "ADD_RUSTC_FLAGS"} + , { "type": "if" + , "cond": {"type": "var", "name": "TARGET"} + , "then": ["--target", {"type": "var", "name": "TARGET"}] + , "else": [] + } + , { "type": "if" + , "cond": {"type": "var", "name": "LINKER"} + , "then": + [ "-C" + , { "type": "join" + , "$1": + ["linker=", {"type": "var", "name": "LINKER"}] + } + ] + , "else": [] + } + , { "type": "if" + , "cond": {"type": "var", "name": "test"} + , "then": ["--test"] + , "else": [] + } + , { "type": "case" + , "case": + { "bin": {"type": "var", "name": "link-deps-args"} + , "cdylib": {"type": "var", "name": "link-deps-args"} + , "dylib": {"type": "var", "name": "link-deps-args"} + , "proc-macro": + {"type": "var", "name": "link-deps-args"} + , "rlib": {"type": "var", "name": "compile-deps-args"} + , "staticlib": + {"type": "var", "name": "link-deps-args"} + } + , "expr": {"type": "var", "name": "crate_type"} + } + , { "type": "if" + , "cond": + { "type": "==" + , "$1": {"type": "var", "name": "crate_type"} + , "$2": "proc-macro" + } + , "then": ["--extern", "proc_macro"] + , "else": [] + } + , { "type": "if" + , "cond": {"type": "var", "name": "c-deps-link-args"} + , "then": + { "type": "let*" + , "bindings": + [ [ "args" + , { "type": "++" + , "$1": + [ ["-Clink-arg=-Wl"] + , {"type": "var", "name": "c-deps-link-args"} + ] + } + ] + ] + , "body": + [ { "type": "join" + , "$1": {"type": "var", "name": "args"} + , "separator": "," + } + ] + } + , "else": [] + } + , { "type": "if" + , "cond": {"type": "var", "name": "c-deps-run-libs-args"} + , "then": + { "type": "let*" + , "bindings": + [ [ "args" + , { "type": "++" + , "$1": + [ ["-Clink-arg=-Wl"] + , { "type": "var" + , "name": "c-deps-run-libs-args" + } + ] + } + ] + ] + , "body": + [ { "type": "join" + , "$1": {"type": "var", "name": "args"} + , "separator": "," + } + ] + } + , "else": [] + } + ] + } + } + , "--remap-path-prefix" + , "\"${PWD}=\"" + ] + , "separator": " " + } + ] + ] + , [ "inputs" + , { "type": "map_union" + , "$1": + [ {"type": "var", "name": "crate_root"} + , {"type": "var", "name": "srcs"} + , { "type": "case" + , "case": + { "bin": {"type": "var", "name": "link-deps"} + , "cdylib": {"type": "var", "name": "link-deps"} + , "dylib": {"type": "var", "name": "link-deps"} + , "proc-macro": {"type": "var", "name": "link-deps"} + , "rlib": {"type": "var", "name": "compile-deps"} + , "staticlib": {"type": "var", "name": "link-deps"} + } + , "expr": {"type": "var", "name": "crate_type"} + } + ] + } + ] + , [ "outs" + , { "type": "if" + , "cond": {"type": "var", "name": "rmeta"} + , "then": + [ { "type": "join" + , "$1": + [ {"type": "var", "name": "stage"} + , { "type": "join" + , "$1": + ["lib", {"type": "var", "name": "crate_name"}, ".rmeta"] + , "separator": "" + } + ] + , "separator": "/" + } + ] + , "else": + { "type": "case" + , "case": + { "bin": + [ { "type": "join" + , "$1": + [ {"type": "var", "name": "stage"} + , {"type": "var", "name": "crate_name"} + ] + , "separator": "/" + } + ] + , "cdylib": + [ { "type": "join" + , "$1": + [ {"type": "var", "name": "stage"} + , { "type": "join" + , "$1": + ["lib", {"type": "var", "name": "crate_name"}, ".so"] + , "separator": "" + } + ] + , "separator": "/" + } + ] + , "dylib": + [ { "type": "join" + , "$1": + [ {"type": "var", "name": "stage"} + , { "type": "join" + , "$1": + ["lib", {"type": "var", "name": "crate_name"}, ".so"] + , "separator": "" + } + ] + , "separator": "/" + } + ] + , "proc-macro": + [ { "type": "join" + , "$1": + [ {"type": "var", "name": "stage"} + , { "type": "join" + , "$1": + ["lib", {"type": "var", "name": "crate_name"}, ".so"] + , "separator": "" + } + ] + , "separator": "/" + } + ] + , "rlib": + [ { "type": "join" + , "$1": + [ {"type": "var", "name": "stage"} + , { "type": "join" + , "$1": + ["lib", {"type": "var", "name": "crate_name"}, ".rlib"] + , "separator": "" + } + ] + , "separator": "/" + } + ] + , "staticlib": + [ { "type": "join" + , "$1": + [ {"type": "var", "name": "stage"} + , { "type": "join" + , "$1": + ["lib", {"type": "var", "name": "crate_name"}, ".a"] + , "separator": "" + } + ] + , "separator": "/" + } + ] + } + , "expr": {"type": "var", "name": "crate_type"} + } + } + ] + , ["OUT_DIR", {"type": "var", "name": "stage"}] + , [ "TARGET" + , { "type": "if" + , "cond": {"type": "var", "name": "TARGET"} + , "then": {"type": "var", "name": "TARGET"} + , "else": "" + } + ] + , [ "HOST" + , { "type": "if" + , "cond": {"type": "var", "name": "HOST"} + , "then": {"type": "var", "name": "HOST"} + , "else": "" + } + ] + , [ "CARGO_PKG_VERSION" + , { "type": "join" + , "$1": {"type": "var", "name": "version", "default": []} + , "separator": "." + } + ] + , [ "CARGO_PKG_VERSION_MAJOR" + , { "type": "[]" + , "index": 0 + , "list": {"type": "var", "name": "version", "default": []} + , "default": "" + } + ] + , [ "CARGO_PKG_VERSION_MINOR" + , { "type": "[]" + , "index": 1 + , "list": {"type": "var", "name": "version", "default": []} + , "default": "" + } + ] + , [ "CARGO_PKG_VERSION_PATCH" + , { "type": "[]" + , "index": 2 + , "list": {"type": "var", "name": "version", "default": []} + , "default": "" + } + ] + , [ "CARGO_PKG_NAME" + , {"type": "join", "$1": {"type": "var", "name": "pkg_name"}} + ] + , [ "env" + , { "type": "map_union" + , "$1": + [ { "type": "env" + , "vars": + [ "RUSTC" + , "PATH" + , "OUT_DIR" + , "HOST" + , "TARGET" + , "CARGO_PKG_NAME" + , "CARGO_PKG_VERSION" + , "CARGO_PKG_VERSION_MAJOR" + , "CARGO_PKG_VERSION_MINOR" + , "CARGO_PKG_VERSION_PATCH" + ] + } + , { "type": "if" + , "cond": {"type": "var", "name": "CARGO_CFG_TARGET_ARCH"} + , "then": + { "type": "singleton_map" + , "key": "CARGO_CFG_TARGET_ARCH" + , "value": {"type": "var", "name": "CARGO_CFG_TARGET_ARCH"} + } + , "else": {"type": "empty_map"} + } + , { "type": "if" + , "cond": {"type": "var", "name": "CARGO_CFG_TARGET_ENDIAN"} + , "then": + { "type": "singleton_map" + , "key": "CARGO_CFG_TARGET_ENDIAN" + , "value": {"type": "var", "name": "CARGO_CFG_TARGET_ENDIAN"} + } + , "else": {"type": "empty_map"} + } + , { "type": "if" + , "cond": {"type": "var", "name": "CARGO_CFG_TARGET_ENV"} + , "then": + { "type": "singleton_map" + , "key": "CARGO_CFG_TARGET_ENV" + , "value": {"type": "var", "name": "CARGO_CFG_TARGET_ENV"} + } + , "else": {"type": "empty_map"} + } + , { "type": "if" + , "cond": {"type": "var", "name": "CARGO_CFG_TARGET_FAMILY"} + , "then": + { "type": "singleton_map" + , "key": "CARGO_CFG_TARGET_FAMILY" + , "value": {"type": "var", "name": "CARGO_CFG_TARGET_FAMILY"} + } + , "else": {"type": "empty_map"} + } + , { "type": "if" + , "cond": {"type": "var", "name": "CARGO_CFG_TARGET_FEATURE"} + , "then": + { "type": "singleton_map" + , "key": "CARGO_CFG_TARGET_FEATURE" + , "value": {"type": "var", "name": "CARGO_CFG_TARGET_FEATURE"} + } + , "else": {"type": "empty_map"} + } + , { "type": "if" + , "cond": {"type": "var", "name": "CARGO_CFG_TARGET_HAS_ATOMIC"} + , "then": + { "type": "singleton_map" + , "key": "CARGO_CFG_TARGET_HAS_ATOMIC" + , "value": + {"type": "var", "name": "CARGO_CFG_TARGET_HAS_ATOMIC"} + } + , "else": {"type": "empty_map"} + } + , { "type": "if" + , "cond": {"type": "var", "name": "CARGO_CFG_TARGET_OS"} + , "then": + { "type": "singleton_map" + , "key": "CARGO_CFG_TARGET_OS" + , "value": {"type": "var", "name": "CARGO_CFG_TARGET_OS"} + } + , "else": {"type": "empty_map"} + } + , { "type": "if" + , "cond": + {"type": "var", "name": "CARGO_CFG_TARGET_POINTER_WIDTH"} + , "then": + { "type": "singleton_map" + , "key": "CARGO_CFG_TARGET_POINTER_WIDTH" + , "value": + {"type": "var", "name": "CARGO_CFG_TARGET_POINTER_WIDTH"} + } + , "else": {"type": "empty_map"} + } + , { "type": "if" + , "cond": {"type": "var", "name": "CARGO_CFG_TARGET_VENDOR"} + , "then": + { "type": "singleton_map" + , "key": "CARGO_CFG_TARGET_VENDOR" + , "value": {"type": "var", "name": "CARGO_CFG_TARGET_VENDOR"} + } + , "else": {"type": "empty_map"} + } + , { "type": "if" + , "cond": {"type": "var", "name": "CARGO_CFG_UNIX"} + , "then": + { "type": "singleton_map" + , "key": "CARGO_CFG_UNIX" + , "value": {"type": "var", "name": "CARGO_CFG_UNIX"} + } + , "else": {"type": "empty_map"} + } + , { "type": "if" + , "cond": {"type": "var", "name": "CARGO_CFG_WINDOWS"} + , "then": + { "type": "singleton_map" + , "key": "CARGO_CFG_WINDOWS" + , "value": {"type": "var", "name": "CARGO_CFG_WINDOWS"} + } + , "else": {"type": "empty_map"} + } + , {"type": "var", "name": "ENV", "default": {"type": "empty_map"}} + ] + } + ] + , ["artifact", {"type": "CALL_EXPRESSION", "name": "call rustc"}] + , [ "artifact-name" + , {"type": "join", "$1": {"type": "var", "name": "outs"}} + ] + ] + , "body": + { "type": "map_union" + , "$1": + [ { "type": "env" + , "vars": + [ "artifact" + , "artifact-name" + , "stage-args" + , "link-deps" + , "compile-deps" + , "stage-deps-args" + , "run-libs" + , "c-deps-link-args" + , "c-deps-run-libs-args" + ] + } + , { "type": "singleton_map" + , "key": "env" + , "value": {"type": "var", "name": "env"} + } + ] + } + } + } +, "call rustc result": + { "doc": ["The RESULT from the invocation of rustc."] + , "vars": + [ "crate_root" + , "crate_name" + , "deps" + , "crate_type" + , "srcs" + , "edition" + , "cargo_features" + , "stage" + , "build_script" + , "transition" + , "deps-transition" + , "version" + , "defaults" + , "pkg_name" + , "c_hdrs" + , "ENV" + ] + , "imports": + { "call rustc artifact": "call rustc artifact" + , "stage_unique_artifact": ["./", "..", "stage_unique_artifact"] + } + , "expression": + { "type": "let*" + , "bindings": + [ ["emit", "metadata,link"] + , [ "rmeta result" + , { "type": "if" + , "cond": + { "type": "==" + , "$1": {"type": "var", "name": "crate_type"} + , "$2": "bin" + } + , "then": {"type": "empty_map"} + , "else": + { "type": "let*" + , "bindings": [["rmeta", true]] + , "body": + {"type": "CALL_EXPRESSION", "name": "call rustc artifact"} + } + } + ] + , [ "link result" + , {"type": "CALL_EXPRESSION", "name": "call rustc artifact"} + ] + , ["emit", "metadata,link"] + , [ "crate_name" + , {"type": "join", "$1": {"type": "var", "name": "crate_name"}} + ] + , [ "stage_args" + , { "type": "++" + , "$1": + [ ["-L", {"type": "var", "name": "stage"}] + , { "type": "lookup" + , "key": "stage-deps-args" + , "map": {"type": "var", "name": "link result"} + } + ] + } + ] + , [ "link_arg_rmeta" + , { "type": "cond" + , "cond": + [ [ { "type": "==" + , "$1": {"type": "var", "name": "crate_type"} + , "$2": "bin" + } + , [] + ] + , [ true + , { "type": "++" + , "$1": + [ {"type": "var", "name": "stage_args"} + , [ "--extern" + , { "type": "join" + , "$1": + [ {"type": "var", "name": "crate_name"} + , "=" + , { "type": "lookup" + , "key": "artifact-name" + , "map": {"type": "var", "name": "rmeta result"} + } + ] + } + ] + ] + } + ] + ] + } + ] + , [ "link_arg_rlib" + , { "type": "cond" + , "cond": + [ [ { "type": "==" + , "$1": {"type": "var", "name": "crate_type"} + , "$2": "bin" + } + , [] + ] + , [ true + , { "type": "++" + , "$1": + [ {"type": "var", "name": "stage_args"} + , [ "--extern" + , { "type": "join" + , "$1": + [ {"type": "var", "name": "crate_name"} + , "=" + , { "type": "lookup" + , "key": "artifact-name" + , "map": {"type": "var", "name": "link result"} + } + ] + } + ] + ] + } + ] + ] + } + ] + , [ "run-libs-map" + , { "type": "singleton_map" + , "key": "run-libs" + , "value": + { "type": "map_union" + , "$1": + [ { "type": "lookup" + , "key": "run-libs" + , "map": {"type": "var", "name": "link result"} + } + , { "type": "case" + , "case": + { "bin": {"type": "empty_map"} + , "cdylib": + { "type": "lookup" + , "key": "artifact" + , "map": {"type": "var", "name": "link result"} + } + , "dylib": + { "type": "lookup" + , "key": "artifact" + , "map": {"type": "var", "name": "link result"} + } + , "proc-macro": {"type": "empty_map"} + , "rlib": {"type": "empty_map"} + , "staticlib": {"type": "empty_map"} + } + , "expr": {"type": "var", "name": "crate_type"} + } + ] + } + } + ] + ] + , "body": + { "type": "RESULT" + , "artifacts": + { "type": "map_union" + , "$1": + [ { "type": "lookup" + , "key": "artifact" + , "map": {"type": "var", "name": "link result"} + } + ] + } + , "runfiles": + {"type": "var", "name": "c_hdrs", "default": {"type": "empty_map"}} + , "provides": + { "type": "cond" + , "cond": + [ [ { "type": "==" + , "$1": {"type": "var", "name": "crate_type"} + , "$2": "bin" + } + , {"type": "var", "name": "run-libs-map"} + ] + , [ true + , { "type": "map_union" + , "$1": + [ {"type": "var", "name": "run-libs-map"} + , { "type": "singleton_map" + , "key": "rust-compile-artifacts" + , "value": + { "type": "if" + , "cond": + { "type": "==" + , "$1": {"type": "var", "name": "crate_type"} + , "$2": "proc-macro" + } + , "then": + { "type": "map_union" + , "$1": + [ { "type": "lookup" + , "key": "artifact" + , "map": {"type": "var", "name": "link result"} + } + , { "type": "lookup" + , "key": "link-deps" + , "map": {"type": "var", "name": "link result"} + } + ] + } + , "else": + { "type": "map_union" + , "$1": + [ { "type": "lookup" + , "key": "artifact" + , "map": {"type": "var", "name": "rmeta result"} + } + , { "type": "lookup" + , "key": "compile-deps" + , "map": {"type": "var", "name": "rmeta result"} + } + ] + } + } + } + , { "type": "singleton_map" + , "key": "rust-link-artifacts" + , "value": + { "type": "map_union" + , "$1": + [ { "type": "lookup" + , "key": "artifact" + , "map": {"type": "var", "name": "link result"} + } + , { "type": "lookup" + , "key": "link-deps" + , "map": {"type": "var", "name": "link result"} + } + ] + } + } + , { "type": "singleton_map" + , "key": "rustc-compile-args" + , "value": + { "type": "if" + , "cond": + { "type": "==" + , "$1": {"type": "var", "name": "crate_type"} + , "$2": "proc-macro" + } + , "then": + { "type": "++" + , "$1": [{"type": "var", "name": "link_arg_rlib"}] + } + , "else": + { "type": "++" + , "$1": [{"type": "var", "name": "link_arg_rmeta"}] + } + } + } + , { "type": "singleton_map" + , "key": "rustc-link-args" + , "value": + { "type": "++" + , "$1": [{"type": "var", "name": "link_arg_rlib"}] + } + } + , { "type": "singleton_map" + , "key": "stage-args" + , "value": + { "type": "++" + , "$1": + [ ["-L", {"type": "var", "name": "stage"}] + , { "type": "lookup" + , "key": "stage-deps-args" + , "map": {"type": "var", "name": "link result"} + } + ] + } + } + , { "type": "if" + , "cond": + { "type": "==" + , "$1": {"type": "var", "name": "crate_type"} + , "$2": "cdylib" + } + , "then": + { "type": "let*" + , "bindings": + [ [ "basename" + , { "type": "basename" + , "$1": + { "type": "lookup" + , "key": "artifact-name" + , "map": {"type": "var", "name": "link result"} + } + } + ] + , [ "run-libs" + , { "type": "singleton_map" + , "key": "run-libs" + , "value": + { "type": "let*" + , "bindings": + [ [ "artifact" + , { "type": "lookup" + , "key": "artifact" + , "map": + {"type": "var", "name": "link result"} + } + ] + , ["name", {"type": "var", "name": "basename"}] + ] + , "body": + { "type": "CALL_EXPRESSION" + , "name": "stage_unique_artifact" + } + } + } + ] + , [ "run-libs-args" + , { "type": "singleton_map" + , "key": "run-libs-args" + , "value": [{"type": "var", "name": "basename"}] + } + ] + ] + , "body": + { "type": "map_union" + , "$1": + [ {"type": "var", "name": "run-libs"} + , {"type": "var", "name": "run-libs-args"} + ] + } + } + , "else": {"type": "empty_map"} + } + , { "type": "if" + , "cond": + { "type": "==" + , "$1": {"type": "var", "name": "crate_type"} + , "$2": "staticlib" + } + , "then": + { "type": "singleton_map" + , "key": "link-args" + , "value": + { "type": "++" + , "$1": + [ [ { "type": "lookup" + , "key": "artifact-name" + , "map": {"type": "var", "name": "link result"} + } + ] + , { "type": "lookup" + , "key": "c-deps-link-args" + , "map": {"type": "var", "name": "link result"} + } + , { "type": "lookup" + , "key": "c-deps-run-libs-args" + , "map": {"type": "var", "name": "link result"} + } + ] + } + } + , "else": {"type": "empty_map"} + } + ] + } + ] + ] + } + } + } + } +, "for host": + { "doc": ["Transition to host required while cross-compiling."] + , "vars": ["ARCH", "HOST_ARCH", "TARGET_ARCH"] + , "expression": + { "type": "let*" + , "bindings": + [ [ "TARGET_ARCH" + , { "type": "var" + , "name": "HOST_ARCH" + , "default": {"type": "var", "name": "ARCH", "default": ""} + } + ] + ] + , "body": {"type": "env", "vars": ["TARGET_ARCH"]} + } + } +, "for host as rlib": + { "vars": ["ARCH", "HOST_ARCH", "TARGET_ARCH"] + , "imports": {"for host": "for host", "to rlib": "to rlib"} + , "expression": + { "type": "disjoint_map_union" + , "$1": + [ {"type": "CALL_EXPRESSION", "name": "for host"} + , {"type": "CALL_EXPRESSION", "name": "to rlib"} + ] + } + } +, "to rlib": + { "doc": ["Transition to rlib required for all rust deps."] + , "expression": + { "type": "let*" + , "bindings": [["RLIB", true]] + , "body": {"type": "env", "vars": ["RLIB"]} + } + } +} diff --git a/rules/rust/RULES b/rules/rust/RULES new file mode 100644 index 0000000..ebdf34e --- /dev/null +++ b/rules/rust/RULES @@ -0,0 +1,906 @@ +{ "binary": + { "doc": ["A Rust binary."] + , "string_fields": ["name", "edition", "stage", "version", "pkg_name"] + , "target_fields": + ["crate_root", "srcs", "deps", "cargo_features", "build_script"] + , "field_doc": + { "name": ["The name of the crate being built."] + , "build_script": + [ "The \"build_script\" target required to be built and run before" + , "compiling this binary." + ] + , "cargo_features": + ["List of cargo features this binary requires to be enabled."] + , "crate_root": + [ "The crate to be fed to the Rust compiler. It must evaluate to" + , "a single artifact/file." + ] + , "defaults": ["The Rust toolchain to use."] + , "deps": ["Any other libraries this binary depends upon."] + , "edition": + [ "The edition of the compiler to use during compilation. If" + , "unset, 2015 is used." + ] + , "pkg_name": + [ "The name of the package the crate belongs to. It is" + , "exported to the CARGO_PKG_NAME environment variable." + ] + , "srcs": ["The source files of the binary."] + , "stage": + [ "The logical location of the resulting artifact. Elements are" + , "joined with \"/\"." + ] + , "version": + [ "The crate version. Elements are joined with \".\" and the first" + , "three elements are used for the major, minor, and patch" + , "number respectively." + ] + } + , "config_vars": ["ENV"] + , "config_doc": + { "ENV": + [ "Additional environment variables (besides ones provided by" + , "the \"defaults\" target) to be set for each action. If the" + , "same variable is set here and in the \"defaults\", the former" + , "is taken." + ] + } + , "config_transitions": + { "build_script": [{"type": "CALL_EXPRESSION", "name": "to rlib"}] + , "cargo_features": [{"type": "CALL_EXPRESSION", "name": "to rlib"}] + , "deps": [{"type": "CALL_EXPRESSION", "name": "to rlib"}] + } + , "imports": {"call rustc": "call rustc result", "to rlib": "to rlib"} + , "implicit": {"defaults": ["defaults"]} + , "expression": + { "type": "let*" + , "bindings": + [ ["crate_name", {"type": "FIELD", "name": "name"}] + , ["crate_type", "bin"] + , ["deps-transition", {"type": "CALL_EXPRESSION", "name": "to rlib"}] + , [ "stage" + , { "type": "if" + , "cond": {"type": "FIELD", "name": "stage"} + , "then": + { "type": "join" + , "$1": {"type": "FIELD", "name": "stage"} + , "separator": "/" + } + , "else": "." + } + ] + , ["crate_root", {"type": "FIELD", "name": "crate_root"}] + , ["edition", {"type": "FIELD", "name": "edition"}] + , ["srcs", {"type": "FIELD", "name": "srcs"}] + , ["deps", {"type": "FIELD", "name": "deps"}] + , ["build_script", {"type": "FIELD", "name": "build_script"}] + , ["cargo_features", {"type": "FIELD", "name": "cargo_features"}] + , ["version", {"type": "FIELD", "name": "version"}] + , ["pkg_name", {"type": "FIELD", "name": "pkg_name"}] + , ["defaults", {"type": "FIELD", "name": "defaults"}] + ] + , "body": {"type": "CALL_EXPRESSION", "name": "call rustc"} + } + } +, "defaults": + { "doc": + [ "A rule to provide defaults." + , "All rust targets take their defaults for RUSTC, TARGET, compile" + , "flags etc." + ] + , "string_fields": + [ "ADD_RUSTC_FLAGS" + , "HOST" + , "LINKER" + , "PATH" + , "RUSTC" + , "RUSTC_FLAGS" + , "TARGET" + , "CARGO_CFG_TARGET_ARCH" + , "CARGO_CFG_TARGET_ENDIAN" + , "CARGO_CFG_TARGET_ENV" + , "CARGO_CFG_TARGET_FAMILY" + , "CARGO_CFG_TARGET_FEATURE" + , "CARGO_CFG_TARGET_HAS_ATOMIC" + , "CARGO_CFG_TARGET_OS" + , "CARGO_CFG_TARGET_POINTER_WIDTH" + , "CARGO_CFG_TARGET_VENDOR" + , "CARGO_CFG_UNIX" + , "CARGO_CFG_WINDOWS" + ] + , "target_fields": ["base"] + , "field_doc": + { "ADD_RUSTC_FLAGS": + [ "Additional flags for rustc. The values are appended to the ones" + , "from \"base\"." + ] + , "CARGO_CFG_TARGET_ARCH": + [ "The CPU target architecture. It overwrites the value from" + , "\"base\"." + ] + , "CARGO_CFG_TARGET_ENDIAN": + ["The CPU target endianness. It overwrites the value from \"base\"."] + , "CARGO_CFG_TARGET_ENV": + ["The target environment ABI. It overwrites the value from", "\"base\"."] + , "CARGO_CFG_TARGET_FAMILY": + ["The target family. It overwrites the value from \"base\"."] + , "CARGO_CFG_TARGET_FEATURE": + [ "List of CPU target features enabled. Elements are joined with" + , "\",\". It overwrites the value from \"base\"." + ] + , "CARGO_CFG_TARGET_HAS_ATOMIC": + [ "List of atomics types (in bits) supported by the target" + , "CPU. Elements are joined with \",\". It overwrites the value from" + , "\"base\"." + ] + , "CARGO_CFG_TARGET_OS": + [ "The target operating system. It overwrites the value from" + , "\"base\"." + ] + , "CARGO_CFG_TARGET_POINTER_WIDTH": + ["The CPU pointer width. It overwrites the value from \"base\"."] + , "CARGO_CFG_TARGET_VENDOR": + ["The target vendor. It overwrites the value from \"base\"."] + , "CARGO_CFG_UNIX": + [ "To be set on unix-like platforms. It overwrites the value from" + , "\"base\"." + ] + , "CARGO_CFG_WINDOWS": + [ "To be set on windows-like platforms. It overwrites the value" + , "from \"base\"." + ] + , "HOST": + [ "The host triple of the Rust compiler (e.g.," + , "\"x86_64-unknown-linux-gnu\"). It overwrites the value from" + , "\"base\"." + ] + , "LINKER": + [ "The value to pass to the \"--linker\" rustc flag. It overwrites" + , "the value from \"base\"." + ] + , "PATH": + [ "Environment variable for looking up compilers and" + , "linkers. Elements are joined with \":\". The values are put in" + , "front of the ones from \"base\"." + ] + , "RUSTC": + ["The Rust compiler to use. It overwrites the value from \"base\"."] + , "RUSTC_FLAGS": + ["The rustc flags to use. It overwrites the value from \"base\"."] + , "TARGET": + [ "The target triple for which the code is compiled (e.g.," + , "\"x86_64-unknown-linux-gnu\"). It overwrites the value from" + , "\"base\"." + ] + , "base": + [ "Other targets of the very same type to inherit values from. If" + , "the same field is defined both targets, depending on the field," + , "the value from \"base\" is extended or overwritten." + ] + } + , "config_vars": ["ARCH", "HOST_ARCH", "TARGET_ARCH"] + , "config_doc": + { "ARCH": + [ "Default value for both HOST_ARCH and TARGET_ARCH. It is user's" + , "responsibility to adapt the \"defaults\" according to the" + , "provided value." + ] + , "HOST_ARCH": + [ "The host CPU architecture. It is user's responsibility to" + , "adapt the \"defaults\" according to the provided value." + ] + , "TARGET_ARCH": + [ "The target CPU architecture. It is user's responsibility to" + , "adapt the \"defaults\" according to the provided value." + ] + } + , "imports": + { "default_from_base": ["./", "..", "default_from_base"] + , "flatten_from_provides": ["./", "..", "flatten_from_provides"] + } + , "expression": + { "type": "let*" + , "bindings": + [ ["base", {"type": "FIELD", "name": "base"}] + , [ "ADD_RUSTC_FLAGS" + , { "type": "++" + , "$1": + [ { "type": "let*" + , "bindings": [["key", "ADD_RUSTC_FLAGS"]] + , "body": + {"type": "CALL_EXPRESSION", "name": "default_from_base"} + } + , {"type": "FIELD", "name": "ADD_RUSTC_FLAGS"} + ] + } + ] + , [ "HOST" + , { "type": "let*" + , "bindings": + [["key", "HOST"], ["value", {"type": "FIELD", "name": "HOST"}]] + , "body": {"type": "CALL_EXPRESSION", "name": "default_from_base"} + } + ] + , [ "LINKER" + , { "type": "let*" + , "bindings": + [["key", "LINKER"], ["value", {"type": "FIELD", "name": "LINKER"}]] + , "body": {"type": "CALL_EXPRESSION", "name": "default_from_base"} + } + ] + , [ "PATH" + , { "type": "++" + , "$1": + [ {"type": "FIELD", "name": "PATH"} + , { "type": "let*" + , "bindings": [["key", "PATH"]] + , "body": + {"type": "CALL_EXPRESSION", "name": "default_from_base"} + } + ] + } + ] + , [ "RUSTC" + , { "type": "let*" + , "bindings": + [["key", "RUSTC"], ["value", {"type": "FIELD", "name": "RUSTC"}]] + , "body": {"type": "CALL_EXPRESSION", "name": "default_from_base"} + } + ] + , [ "RUSTC_FLAGS" + , { "type": "let*" + , "bindings": + [ ["key", "RUSTC_FLAGS"] + , ["value", {"type": "FIELD", "name": "RUSTC_FLAGS"}] + ] + , "body": {"type": "CALL_EXPRESSION", "name": "default_from_base"} + } + ] + , [ "TARGET" + , { "type": "let*" + , "bindings": + [["key", "TARGET"], ["value", {"type": "FIELD", "name": "TARGET"}]] + , "body": {"type": "CALL_EXPRESSION", "name": "default_from_base"} + } + ] + , [ "CARGO_CFG_TARGET_ARCH" + , { "type": "let*" + , "bindings": + [ ["key", "CARGO_CFG_TARGET_ARCH"] + , ["value", {"type": "FIELD", "name": "CARGO_CFG_TARGET_ARCH"}] + ] + , "body": {"type": "CALL_EXPRESSION", "name": "default_from_base"} + } + ] + , [ "CARGO_CFG_TARGET_ENDIAN" + , { "type": "let*" + , "bindings": + [ ["key", "CARGO_CFG_TARGET_ENDIAN"] + , ["value", {"type": "FIELD", "name": "CARGO_CFG_TARGET_ENDIAN"}] + ] + , "body": {"type": "CALL_EXPRESSION", "name": "default_from_base"} + } + ] + , [ "CARGO_CFG_TARGET_ENV" + , { "type": "let*" + , "bindings": + [ ["key", "CARGO_CFG_TARGET_ENV"] + , ["value", {"type": "FIELD", "name": "CARGO_CFG_TARGET_ENV"}] + ] + , "body": {"type": "CALL_EXPRESSION", "name": "default_from_base"} + } + ] + , [ "CARGO_CFG_TARGET_FAMILY" + , { "type": "let*" + , "bindings": + [ ["key", "CARGO_CFG_TARGET_FAMILY"] + , ["value", {"type": "FIELD", "name": "CARGO_CFG_TARGET_FAMILY"}] + ] + , "body": {"type": "CALL_EXPRESSION", "name": "default_from_base"} + } + ] + , [ "CARGO_CFG_TARGET_FEATURE" + , { "type": "let*" + , "bindings": + [ ["key", "CARGO_CFG_TARGET_FEATURE"] + , ["value", {"type": "FIELD", "name": "CARGO_CFG_TARGET_FEATURE"}] + ] + , "body": {"type": "CALL_EXPRESSION", "name": "default_from_base"} + } + ] + , [ "CARGO_CFG_TARGET_HAS_ATOMIC" + , { "type": "let*" + , "bindings": + [ ["key", "CARGO_CFG_TARGET_HAS_ATOMIC"] + , [ "value" + , {"type": "FIELD", "name": "CARGO_CFG_TARGET_HAS_ATOMIC"} + ] + ] + , "body": {"type": "CALL_EXPRESSION", "name": "default_from_base"} + } + ] + , [ "CARGO_CFG_TARGET_OS" + , { "type": "let*" + , "bindings": + [ ["key", "CARGO_CFG_TARGET_OS"] + , ["value", {"type": "FIELD", "name": "CARGO_CFG_TARGET_OS"}] + ] + , "body": {"type": "CALL_EXPRESSION", "name": "default_from_base"} + } + ] + , [ "CARGO_CFG_TARGET_POINTER_WIDTH" + , { "type": "let*" + , "bindings": + [ ["key", "CARGO_CFG_TARGET_POINTER_WIDTH"] + , [ "value" + , {"type": "FIELD", "name": "CARGO_CFG_TARGET_POINTER_WIDTH"} + ] + ] + , "body": {"type": "CALL_EXPRESSION", "name": "default_from_base"} + } + ] + , [ "CARGO_CFG_TARGET_VENDOR" + , { "type": "let*" + , "bindings": + [ ["key", "CARGO_CFG_TARGET_VENDOR"] + , ["value", {"type": "FIELD", "name": "CARGO_CFG_TARGET_VENDOR"}] + ] + , "body": {"type": "CALL_EXPRESSION", "name": "default_from_base"} + } + ] + , [ "CARGO_CFG_UNIX" + , { "type": "let*" + , "bindings": + [ ["key", "CARGO_CFG_UNIX"] + , ["value", {"type": "FIELD", "name": "CARGO_CFG_UNIX"}] + ] + , "body": {"type": "CALL_EXPRESSION", "name": "default_from_base"} + } + ] + , [ "CARGO_CFG_WINDOWS" + , { "type": "let*" + , "bindings": + [ ["key", "CARGO_CFG_WINDOWS"] + , ["value", {"type": "FIELD", "name": "CARGO_CFG_WINDOWS"}] + ] + , "body": {"type": "CALL_EXPRESSION", "name": "default_from_base"} + } + ] + ] + , "body": + { "type": "RESULT" + , "provides": + { "type": "env" + , "vars": + [ "ADD_RUSTC_FLAGS" + , "HOST" + , "LINKER" + , "PATH" + , "RUSTC" + , "RUSTC_FLAGS" + , "TARGET" + , "CARGO_CFG_TARGET_ARCH" + , "CARGO_CFG_TARGET_ENDIAN" + , "CARGO_CFG_TARGET_ENV" + , "CARGO_CFG_TARGET_FAMILY" + , "CARGO_CFG_TARGET_FEATURE" + , "CARGO_CFG_TARGET_HAS_ATOMIC" + , "CARGO_CFG_TARGET_OS" + , "CARGO_CFG_TARGET_POINTER_WIDTH" + , "CARGO_CFG_TARGET_VENDOR" + , "CARGO_CFG_UNIX" + , "CARGO_CFG_WINDOWS" + ] + } + } + } + } +, "library": + { "doc": + [ "A Rust library. Depending on the value of the fields \"shared\"" + , "and \"native\", the `--crate-type` is inferred as follows:" + , "" + , "|shared|native|crate-type|" + , "|------|------|----------|" + , "| null | null | rlib |" + , "| null |\"true\"| staticlib|" + , "|\"true\"| null | dylib |" + , "|\"true\"|\"true\"| cdylib |" + ] + , "string_fields": + ["name", "edition", "stage", "version", "pkg_name", "shared", "native"] + , "target_fields": + ["crate_root", "srcs", "deps", "cargo_features", "build_script", "c_hdrs"] + , "field_doc": + { "name": ["The name of the crate being built."] + , "build_script": + [ "The \"build_script\" target required to be built and run before" + , "compiling this library." + ] + , "c_hdrs": + [ "C headers that define the interface to this library." + , "This field is ignored when this library is consumed by another" + , "Rust target." + , "" + , "If non empty, a native library will be produced." + ] + , "cargo_features": + ["List of cargo features this library requires to be enabled."] + , "crate_root": + [ "The crate to be fed to the Rust compiler. It must evaluate to" + , "a single artifact/file." + ] + , "defaults": ["The Rust toolchain to use."] + , "deps": ["Any other libraries this library depends upon."] + , "edition": + [ "The edition of the compiler to use during compilation." + , "If unset, 2015 is used." + ] + , "native": + [ "If not null, a native library will be produced." + , "" + , "Note that, when this target is consumed by another Rust target," + , "it will be compiled to a Rust static library (.rlib)." + ] + , "pkg_name": + [ "The name of the package the crate belongs to. It is" + , "exported to the CARGO_PKG_NAME environment variable." + ] + , "shared": ["If not null, a shared library will be produced."] + , "srcs": ["The source files of the library."] + , "stage": + [ "The logical location of the resulting artifact." + , "Elements are joined with \"/\"." + ] + , "version": + [ "The crate version. Elements are joined with \".\" and the first" + , "three elements are used for the major, minor, and patch" + , "number respectively." + ] + } + , "config_vars": ["ENV", "RLIB"] + , "config_doc": + { "ENV": + [ "Additional environment variables (besides ones provided by" + , "the \"defaults\" target) to be set for each action. If the" + , "same variable is set here and in the \"defaults\", the former" + , "is taken." + ] + , "RLIB": + [ "If evaluates to true, the \"shared\" and \"native\" fields are" + , "ignored and the crate type will be set to rlib." + ] + } + , "config_transitions": + { "build_script": [{"type": "CALL_EXPRESSION", "name": "to rlib"}] + , "cargo_features": [{"type": "CALL_EXPRESSION", "name": "to rlib"}] + , "deps": [{"type": "CALL_EXPRESSION", "name": "to rlib"}] + } + , "imports": + { "call rustc": "call rustc result" + , "get_artifacts": ["./", "..", "get_artifacts"] + , "to rlib": "to rlib" + } + , "implicit": {"defaults": ["defaults"]} + , "expression": + { "type": "let*" + , "bindings": + [ ["crate_name", {"type": "FIELD", "name": "name"}] + , [ "native" + , { "type": "or" + , "$1": + [ {"type": "FIELD", "name": "c_hdrs"} + , {"type": "FIELD", "name": "native"} + ] + } + ] + , [ "crate_type" + , { "type": "if" + , "cond": {"type": "var", "name": "RLIB"} + , "then": "rlib" + , "else": + { "type": "if" + , "cond": {"type": "FIELD", "name": "shared"} + , "then": + { "type": "if" + , "cond": {"type": "var", "name": "native"} + , "then": "cdylib" + , "else": "dylib" + } + , "else": + { "type": "if" + , "cond": {"type": "var", "name": "native"} + , "then": "staticlib" + , "else": "rlib" + } + } + } + ] + , ["deps-transition", {"type": "CALL_EXPRESSION", "name": "to rlib"}] + , [ "stage" + , { "type": "if" + , "cond": {"type": "FIELD", "name": "stage"} + , "then": + { "type": "join" + , "$1": {"type": "FIELD", "name": "stage"} + , "separator": "/" + } + , "else": "." + } + ] + , [ "c_hdrs" + , { "type": "to_subdir" + , "subdir": {"type": "var", "name": "stage"} + , "flat": false + , "$1": + { "type": "let*" + , "bindings": + [ [ "field_content" + , { "type": "if" + , "cond": {"type": "var", "name": "RLIB"} + , "then": [] + , "else": {"type": "FIELD", "name": "c_hdrs"} + } + ] + ] + , "body": {"type": "CALL_EXPRESSION", "name": "get_artifacts"} + } + } + ] + , ["crate_root", {"type": "FIELD", "name": "crate_root"}] + , ["edition", {"type": "FIELD", "name": "edition"}] + , ["srcs", {"type": "FIELD", "name": "srcs"}] + , ["deps", {"type": "FIELD", "name": "deps"}] + , ["build_script", {"type": "FIELD", "name": "build_script"}] + , ["cargo_features", {"type": "FIELD", "name": "cargo_features"}] + , ["version", {"type": "FIELD", "name": "version"}] + , ["pkg_name", {"type": "FIELD", "name": "pkg_name"}] + , ["defaults", {"type": "FIELD", "name": "defaults"}] + ] + , "body": {"type": "CALL_EXPRESSION", "name": "call rustc"} + } + } +, "proc-macro": + { "doc": + [ "A Rust procedural macro. As it is executed on the host system" + , "during the compilation, it is always compiled according to the" + , "host configuration." + ] + , "string_fields": ["name", "edition", "stage", "version", "pkg_name"] + , "target_fields": + ["crate_root", "srcs", "deps", "cargo_features", "build_script"] + , "field_doc": + { "name": ["The name of the crate being built."] + , "build_script": + [ "The \"build_script\" target required to be built and run before" + , "compiling this macro." + ] + , "cargo_features": + ["List of cargo features this macro requires to be enabled."] + , "crate_root": + [ "The crate to be fed to the Rust compiler. It must evaluate to" + , "a single artifact/file." + ] + , "defaults": ["The Rust toolchain to use."] + , "deps": ["Any other libraries this macro depends upon."] + , "edition": + [ "The edition of the compiler to use during compilation. If" + , "unset, 2015 is used." + ] + , "pkg_name": + [ "The name of the package the crate belongs to. It is" + , "exported to the CARGO_PKG_NAME environment variable." + ] + , "srcs": ["The source files of the procedural macro."] + , "stage": + [ "The logical location of the resulting artifact. Elements are" + , "joined with \"/\"." + ] + , "version": + [ "The crate version. Elements are joined with \".\" and the first" + , "three elements are used for the major, minor, and patch" + , "number respectively." + ] + } + , "config_vars": ["ARCH", "HOST_ARCH", "ENV"] + , "config_doc": + { "ARCH": + [ "Default value for both HOST_ARCH and TARGET_ARCH. It is user's" + , "responsibility to adapt the \"defaults\" according to the" + , "provided value." + ] + , "ENV": + [ "Additional environment variables (besides ones provided by" + , "the \"defaults\" target) to be set for each action. If the" + , "same variable is set here and in the \"defaults\", the former" + , "is taken." + ] + , "HOST_ARCH": + [ "The host CPU architecture. It is user's responsibility to" + , "adapt the \"defaults\" according to the provided value." + ] + } + , "config_transitions": + { "build_script": [{"type": "CALL_EXPRESSION", "name": "for host as rlib"}] + , "cargo_features": + [{"type": "CALL_EXPRESSION", "name": "for host as rlib"}] + , "crate_root": [{"type": "CALL_EXPRESSION", "name": "for host"}] + , "defaults": [{"type": "CALL_EXPRESSION", "name": "for host"}] + , "deps": [{"type": "CALL_EXPRESSION", "name": "for host as rlib"}] + , "srcs": [{"type": "CALL_EXPRESSION", "name": "for host"}] + } + , "imports": + { "call rustc": "call rustc result" + , "for host": "for host" + , "for host as rlib": ["./", "../rust", "for host as rlib"] + , "to rlib": "to rlib" + } + , "implicit": {"defaults": ["defaults"]} + , "expression": + { "type": "let*" + , "bindings": + [ ["crate_name", {"type": "FIELD", "name": "name"}] + , ["crate_type", "proc-macro"] + , [ "stage" + , { "type": "if" + , "cond": {"type": "FIELD", "name": "stage"} + , "then": + { "type": "join" + , "$1": {"type": "FIELD", "name": "stage"} + , "separator": "/" + } + , "else": "." + } + ] + , ["crate_root", {"type": "FIELD", "name": "crate_root"}] + , ["edition", {"type": "FIELD", "name": "edition"}] + , ["srcs", {"type": "FIELD", "name": "srcs"}] + , ["deps", {"type": "FIELD", "name": "deps"}] + , [ "deps-transition" + , {"type": "CALL_EXPRESSION", "name": "for host as rlib"} + ] + , ["transition", {"type": "CALL_EXPRESSION", "name": "for host"}] + , ["version", {"type": "FIELD", "name": "version"}] + , ["pkg_name", {"type": "FIELD", "name": "pkg_name"}] + , ["build_script", {"type": "FIELD", "name": "build_script"}] + , ["cargo_features", {"type": "FIELD", "name": "cargo_features"}] + , ["defaults", {"type": "FIELD", "name": "defaults"}] + ] + , "body": {"type": "CALL_EXPRESSION", "name": "call rustc"} + } + } +, "test": + { "doc": ["A Rust test."] + , "string_fields": + ["name", "edition", "stage", "version", "args", "pkg_name"] + , "target_fields": ["crate_root", "srcs", "deps", "cargo_features", "data"] + , "field_doc": + { "name": + [ "The name of the test being built. Note that during execution," + , "the test binary will be restaged to \"test\"." + ] + , "args": ["Additonal arguments to be passed when running the test."] + , "cargo_features": + ["List of cargo features this test requires to be enabled."] + , "crate_root": + [ "The crate to be fed to the Rust compiler. It must evaluate to" + , "a single artifact/file." + ] + , "data": ["Any files and directories the test binary needs when running."] + , "defaults": ["The Rust toolchain to use."] + , "deps": ["Any other libraries this test depends upon."] + , "edition": + [ "The edition of the compiler to use during compilation. If" + , "unset, 2015 is used." + ] + , "pkg_name": + [ "The name of the package the crate belongs to. It is" + , "exported to the CARGO_PKG_NAME environment variable." + ] + , "runner": + [ "The test runner to use, i.e., the binary that will launch the" + , "test binary and collect the output." + ] + , "srcs": ["The source files of the test."] + , "stage": + [ "The logical location of the resulting artifact. Elements are" + , "joined with \"/\"." + ] + , "version": + [ "The crate version. Elements are joined with \".\" and the first" + , "three elements are used for the major, minor, and patch" + , "number respectively." + ] + } + , "config_vars": ["RUST_TEST_LAUNCHER", "ARCH", "HOST_ARCH", "ENV"] + , "config_doc": + { "ARCH": + [ "Default value for both HOST_ARCH and TARGET_ARCH. It is user's" + , "responsibility to adapt the \"defaults\" according to the" + , "provided value." + ] + , "ENV": + [ "Additional environment variables (besides ones provided by" + , "the \"defaults\" target) to be set for each action. If the" + , "same variable is set here and in the \"defaults\", the former" + , "is taken." + ] + , "HOST_ARCH": + [ "The host CPU architecture. It is user's responsibility to" + , "adapt the \"defaults\" according to the provided value." + ] + , "RUST_TEST_LAUNCHER": + [ "List of strings representing the launcher that is prepended to" + , "the command line for running the test binary." + ] + } + , "config_transitions": + { "cargo_features": + [{"type": "CALL_EXPRESSION", "name": "for host as rlib"}] + , "crate_root": [{"type": "CALL_EXPRESSION", "name": "for host"}] + , "data": [{"type": "CALL_EXPRESSION", "name": "for host"}] + , "defaults": [{"type": "CALL_EXPRESSION", "name": "for host"}] + , "deps": [{"type": "CALL_EXPRESSION", "name": "for host as rlib"}] + , "runner": [{"type": "CALL_EXPRESSION", "name": "for host"}] + , "srcs": [{"type": "CALL_EXPRESSION", "name": "for host"}] + } + , "imports": + { "call rustc artifact": "call rustc artifact" + , "for host": "for host" + , "for host as rlib": ["./", "../rust", "for host as rlib"] + , "get_artifacts": ["./", "..", "get_artifacts"] + , "get_runfiles": ["./", "..", "get_runfiles"] + , "get_unique_artifact": ["./", "..", "get_unique_artifact"] + , "stage_unique_artifact": ["./", "..", "stage_unique_artifact"] + } + , "implicit": {"defaults": ["defaults"], "runner": ["runner.py"]} + , "expression": + { "type": "let*" + , "bindings": + [ ["crate_name", {"type": "FIELD", "name": "name"}] + , ["crate_type", "bin"] + , [ "stage" + , { "type": "if" + , "cond": {"type": "FIELD", "name": "stage"} + , "then": + { "type": "join" + , "$1": {"type": "FIELD", "name": "stage"} + , "separator": "/" + } + , "else": "." + } + ] + , ["crate_root", {"type": "FIELD", "name": "crate_root"}] + , ["edition", {"type": "FIELD", "name": "edition"}] + , ["srcs", {"type": "FIELD", "name": "srcs"}] + , ["deps", {"type": "FIELD", "name": "deps"}] + , ["cargo_features", {"type": "FIELD", "name": "cargo_features"}] + , ["emit", "link"] + , [ "deps-transition" + , {"type": "CALL_EXPRESSION", "name": "for host as rlib"} + ] + , ["transition", {"type": "CALL_EXPRESSION", "name": "for host"}] + , ["test", true] + , ["version", {"type": "FIELD", "name": "version"}] + , ["pkg_name", {"type": "FIELD", "name": "pkg_name"}] + , ["defaults", {"type": "FIELD", "name": "defaults"}] + , [ "artifact result" + , {"type": "CALL_EXPRESSION", "name": "call rustc artifact"} + ] + , [ "test" + , { "type": "let*" + , "bindings": + [ [ "artifact" + , { "type": "lookup" + , "key": "artifact" + , "map": {"type": "var", "name": "artifact result"} + } + ] + , ["name", "test"] + ] + , "body": + {"type": "CALL_EXPRESSION", "name": "stage_unique_artifact"} + } + ] + , [ "runner" + , { "type": "let*" + , "bindings": + [ [ "artifact" + , { "type": "let*" + , "bindings": + [ ["field_name", "runner"] + , ["field_content", {"type": "FIELD", "name": "runner"}] + ] + , "body": + {"type": "CALL_EXPRESSION", "name": "get_unique_artifact"} + } + ] + , ["name", "runner"] + ] + , "body": + {"type": "CALL_EXPRESSION", "name": "stage_unique_artifact"} + } + ] + , ["field_content", {"type": "FIELD", "name": "data"}] + , [ "test-data" + , { "type": "to_subdir" + , "subdir": "work" + , "flat": false + , "$1": + { "type": "disjoint_map_union" + , "$1": + [ {"type": "CALL_EXPRESSION", "name": "get_artifacts"} + , {"type": "CALL_EXPRESSION", "name": "get_runfiles"} + ] + } + } + ] + , [ "test-launcher" + , { "type": "singleton_map" + , "key": "test-launcher.json" + , "value": + { "type": "BLOB" + , "data": + { "type": "json_encode" + , "$1": + {"type": "var", "name": "RUST_TEST_LAUNCHER", "default": []} + } + } + } + ] + , [ "test-args" + , { "type": "singleton_map" + , "key": "test-args.json" + , "value": + { "type": "BLOB" + , "data": + {"type": "json_encode", "$1": {"type": "FIELD", "name": "args"}} + } + } + ] + , [ "test-name" + , {"type": "join", "$1": {"type": "var", "name": "crate_name"}} + ] + , [ "test-results" + , { "type": "ACTION" + , "outs": ["result", "stdout", "stderr", "time-start", "time-stop"] + , "inputs": + { "type": "map_union" + , "$1": + [ {"type": "var", "name": "test"} + , {"type": "var", "name": "runner"} + , {"type": "var", "name": "test-data"} + , {"type": "var", "name": "test-launcher"} + , {"type": "var", "name": "test-args"} + ] + } + , "cmd": ["./runner"] + , "env": + { "type": "lookup" + , "key": "env" + , "map": {"type": "var", "name": "artifact result"} + } + , "may_fail": ["test"] + , "fail_message": + { "type": "join" + , "$1": + ["rust test", {"type": "var", "name": "test-name"}, "failed"] + , "separator": " " + } + } + ] + ] + , "body": + { "type": "RESULT" + , "artifacts": {"type": "var", "name": "test-results"} + , "runfiles": + { "type": "singleton_map" + , "key": {"type": "var", "name": "test-name"} + , "value": + {"type": "TREE", "$1": {"type": "var", "name": "test-results"}} + } + } + } + , "tainted": ["test"] + } +} diff --git a/rules/rust/TARGETS b/rules/rust/TARGETS new file mode 100644 index 0000000..9a80409 --- /dev/null +++ b/rules/rust/TARGETS @@ -0,0 +1,171 @@ +{ "aarch64-unknown-linux-gnu": + { "type": "defaults" + , "CARGO_CFG_TARGET_ARCH": ["aarch64"] + , "CARGO_CFG_TARGET_ENDIAN": ["little"] + , "CARGO_CFG_TARGET_ENV": ["gnu"] + , "CARGO_CFG_TARGET_FAMILY": ["unix"] + , "CARGO_CFG_TARGET_FEATURE": ["neon"] + , "CARGO_CFG_TARGET_HAS_ATOMIC": ["128,16,32,64,8,ptr"] + , "CARGO_CFG_TARGET_OS": ["linux"] + , "CARGO_CFG_TARGET_POINTER_WIDTH": ["64"] + , "CARGO_CFG_TARGET_VENDOR": ["unkwnown"] + , "CARGO_CFG_UNIX": ["true"] + , "TARGET": ["aarch64-unknown-linux-gnu"] + } +, "defaults": + { "type": "defaults" + , "arguments_config": + ["DEBUG", "ARCH", "TARGET_ARCH", "HOST_ARCH", "TOOLCHAIN_CONFIG", "ENV"] + , "PATH": ["/usr/bin", "/bin"] + , "RUSTC": + [ { "type": "lookup" + , "key": "RUSTC" + , "map": + { "type": "lookup" + , "key": "RUST" + , "map": + { "type": "var" + , "name": "TOOLCHAIN_CONFIG" + , "default": {"type": "empty_map"} + } + , "default": {"type": "empty_map"} + } + , "default": + { "type": "let*" + , "bindings": + [ [ "rustup-home" + , { "type": "lookup" + , "key": "RUSTUP_HOME" + , "map": + { "type": "lookup" + , "key": "RUST" + , "map": + { "type": "var" + , "name": "TOOLCHAIN_CONFIG" + , "default": {"type": "empty_map"} + } + , "default": {"type": "empty_map"} + } + } + ] + , [ "toolchain" + , { "type": "lookup" + , "key": "TOOLCHAIN" + , "map": + { "type": "lookup" + , "key": "RUST" + , "map": + { "type": "var" + , "name": "TOOLCHAIN_CONFIG" + , "default": {"type": "empty_map"} + } + , "default": {"type": "empty_map"} + } + } + ] + , [ "rustc" + , { "type": "if" + , "cond": {"type": "var", "name": "rustup-home"} + , "then": + { "type": "join" + , "$1": + [ {"type": "var", "name": "rustup-home"} + , "toolchains" + , { "type": "join" + , "$1": + [ { "type": "var" + , "name": "toolchain" + , "default": "stable" + } + , { "type": "var" + , "name": "HOST_ARCH" + , "default": + { "type": "var" + , "name": "ARCH" + , "default": + { "type": "fail" + , "msg": + { "type": "join" + , "$1": + [ "To properly select a Rust compiler under the RUSTUP_HOME directory \"" + , {"type": "var", "name": "rustup-home"} + , "\" please provide either ARCH or HOST_ARCH." + ] + , "separator": "" + } + } + } + } + , "unknown" + , "linux" + , "gnu" + ] + , "separator": "-" + } + , "bin" + , "rustc" + ] + , "separator": "/" + } + , "else": "rustc" + } + ] + ] + , "body": {"type": "var", "name": "rustc"} + } + } + ] + , "RUSTC_FLAGS": + { "type": "++" + , "$1": + [ ["--color=always", "--cap-lints=warn"] + , { "type": "if" + , "cond": {"type": "var", "name": "DEBUG"} + , "then": [] + , "else": + ["-Copt-level=2", "--codegen=debuginfo=0", "-Cembed-bitcode=no"] + } + ] + } + , "base": + { "type": "case" + , "case": + { "": [] + , "aarch64": ["aarch64-unknown-linux-gnu"] + , "wasm32": ["wasm32-unknown-unknown"] + , "x86_64": ["x86_64-unknown-linux-gnu"] + } + , "expr": + { "type": "var" + , "name": "TARGET_ARCH" + , "default": {"type": "var", "name": "ARCH", "default": ""} + } + } + } +, "wasm32-unknown-unknown": + { "type": "defaults" + , "CARGO_CFG_TARGET_ARCH": ["wasm32"] + , "CARGO_CFG_TARGET_ENDIAN": ["little"] + , "CARGO_CFG_TARGET_ENV": [""] + , "CARGO_CFG_TARGET_FAMILY": ["wasm"] + , "CARGO_CFG_TARGET_HAS_ATOMIC": ["16,32,64,8,ptr"] + , "CARGO_CFG_TARGET_OS": ["unknown"] + , "CARGO_CFG_TARGET_POINTER_WIDTH": ["32"] + , "CARGO_CFG_TARGET_VENDOR": ["unkwnown"] + , "TARGET": ["wasm32-unknown-unknown"] + } +, "x86_64-unknown-linux-gnu": + { "type": "defaults" + , "CARGO_CFG_TARGET_ARCH": ["x86_64"] + , "CARGO_CFG_TARGET_ENDIAN": ["little"] + , "CARGO_CFG_TARGET_ENV": ["gnu"] + , "CARGO_CFG_TARGET_FAMILY": ["unix"] + , "CARGO_CFG_TARGET_FEATURE": ["fxsr,sse,sse2"] + , "CARGO_CFG_TARGET_HAS_ATOMIC": ["16,32,64,8,ptr"] + , "CARGO_CFG_TARGET_OS": ["linux"] + , "CARGO_CFG_TARGET_POINTER_WIDTH": ["64"] + , "CARGO_CFG_TARGET_VENDOR": ["unkwnown"] + , "CARGO_CFG_UNIX": ["true"] + , "TARGET": ["x86_64-unknown-linux-gnu"] + } +} diff --git a/rules/rust/runner.py b/rules/rust/runner.py new file mode 100755 index 0000000..bfa06ac --- /dev/null +++ b/rules/rust/runner.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python3 +# Copyright 2024 Huawei Cloud Computing Technology Co., Ltd. +# +# 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. + +import json +import os +import subprocess +import time + +time_start: float = 0 +time_stop: float = 0 +result: str = "UNKNOWN" +stderr: str = None +stdout: str = None + + +def end(x): + return "\n" if x else "" + + +def dump_results() -> None: + global time_start, time_stop, result, stdout, stderr + with open("result", "w") as f: + print(f"{result}", file=f) + with open("time-start", "w") as f: + print(f"{time_start:.3f}", file=f) + with open("time-stop", "w") as f: + print(f"{time_stop:.3f}", file=f) + with open("stdout", "w") as f: + print(f"{stdout}", file=f, end=end(stdout)) + with open("stderr", "w") as f: + print(f"{stderr}", file=f, end=end(stderr)) + + +class dumper: + def __enter__(self): + global time_start + time_start = time.time() + + def __exit__(self, type, value, traceback): + dump_results() + + +with dumper(): + TEMP_DIR = os.path.realpath("scratch") + os.makedirs(TEMP_DIR, exist_ok=True) + + WORK_DIR = os.path.realpath("work") + os.makedirs(WORK_DIR, exist_ok=True) + + ENV = dict(os.environ, TEST_TMPDIR=TEMP_DIR, TMPDIR=TEMP_DIR, TERM="xterm-256color") + + with open("test-launcher.json") as f: + test_launcher = json.load(f) + + with open("test-args.json") as f: + test_args = json.load(f) + + ret = subprocess.run( + test_launcher + ["../test", "--color", "always"] + test_args, + cwd=WORK_DIR, + env=ENV, + capture_output=True, + ) + time_stop = time.time() + result = "PASS" if ret.returncode == 0 else "FAIL" + stdout = ret.stdout.decode("utf-8") + stderr = ret.stderr.decode("utf-8") + + if result != "PASS": + exit(1) diff --git a/share/man/import-cargo.1.md b/share/man/import-cargo.1.md new file mode 100644 index 0000000..d52aece --- /dev/null +++ b/share/man/import-cargo.1.md @@ -0,0 +1,75 @@ +% JUST-IMPORT-CARGO(1) | General Commands Manual + +NAME +==== + +just-import-cargo - import the cargo dependencies of one crate + +SYNOPSIS +======== + +**`just-import-cargo`** \[*`OPTION`*]... *`relative-crate-location`* + +DESCRIPTION +=========== + +Given a physical repository where one sudirectory has the file +layout of a crate and a **`just-mr-repository-config`**(5) on +standard input, + - extend the repository configuration by a logical repsitory for + that cate, as well as logical repositories for all the transitive + dependencies as reported by **`cargo`**(1) when asked for the + development dependencies of the given crate, + - generate the needed target files in the directory *`etc/deps-rust`* + of the physical repository, and + - add appropriate rust default targets in the directory *`etc/defaults`* + of the physical repository. + +OPTIONS +======= + +**`-h`**, **`--help`** +Output a usage message and exit. + +**`--rules`** *`name`* +Assume the rust rules are the logical repository *`name`* in the +configuration provided on standard input. Typically, the rust rules +would be imported first via **`just-import-git`**(1). If this option +is not given, as last resort, a *`"file"`* repository for the rules +is created pointing to the directory `../rules` relative to location +of this binary. This is correct, if **`just-import-cargo`** is called +from a (persistent) checkout of `rules-rust`, but hardly ever useful. + +**`--repo-root`** *`root`* +Specify the root of the physical directory the configuration read from +standard input refers to. If not given, it is assumed that the current +working directory is the root of the physical repository. + +**`--local-crate-cache`** *`cache-root`* +Specify the location where to cache the information about non-local crates. +If not given, `~/.cache/crate-index-just` is used. + +**`-g`**, **`--to-git`** +Add the `"to_git"` pragma to the generated repositories that are non +content-fixed anyway. + +**`-t`**, **`--recompute-targets`** +Recompute all target files, even if cached. + +**`-r`**, **`--recomptue-repos`** +Recompute all repositories, even if cached. + +**`-s`**, **`--recompute-sources`** +Recompute all source descriptions, even if cached. + +**`-I`**, **`--compute-index`** +Add an index repository. + +See also +======== + +**`cargo`**(1), +**`just-deduplicate-repos`**(1), +**`just-import-git`**(1), +**`just-mr-repository-config`**(5), +**`just-mr`**(1) diff --git a/test/TARGETS b/test/TARGETS new file mode 100644 index 0000000..5115bdf --- /dev/null +++ b/test/TARGETS @@ -0,0 +1,98 @@ +{ "static": + { "type": ["@", "test-rules", "test_rules", "test_case"] + , "name": ["static"] + , "targets": + [ "+baz-lib" + , "+bar-lib" + , "-bar-missing-baz" + , "+foo-lib" + , "+main" + , "-main-wrong-dep" + , "-main-missing-dep" + ] + , "asserts": + [ "test -f baz-lib/baz/libbaz.rlib" + , "! test -f baz-lib/baz/libbaz.rmeta" + , "test -f bar-lib/bar/libbar.rlib" + , "test -f main/bin/main" + , "./main/bin/main | grep baz" + , "./main/bin/main | grep bar" + , "./main/bin/main | grep foo" + ] + , "data": [["TREE", null, "static"]] + } +, "static-native": + { "type": ["@", "test-rules", "test_rules", "test_case"] + , "name": ["static-native"] + , "targets": + [ "+baz-lib" + , "+bar-lib" + , "-bar-missing-baz" + , "+foo-lib" + , "+main" + , "-main-wrong-dep" + , "-main-missing-dep" + ] + , "asserts": + [ "test -f baz-lib/baz/libbaz.a" + , "! test -f baz-lib/baz/libbaz.rmeta" + , "! test -f baz-lib/baz/libbaz.rlib" + , "test -f bar-lib/bar/libbar.rlib" + , "test -f foo-lib/foo/libfoo.a" + , "test -f main/bin/main" + , "./main/bin/main | grep baz" + , "./main/bin/main | grep bar" + , "./main/bin/main | grep foo" + ] + , "data": [["TREE", null, "static-native"]] + } +, "dynamic": + { "type": ["@", "test-rules", "test_rules", "test_case"] + , "name": ["dynamic"] + , "targets": + [ "+baz-lib" + , "+bar-lib" + , "-bar-missing-baz" + , "+foo-lib" + , "+main" + , "-main-wrong-dep" + , "-main-missing-dep" + ] + , "asserts": + [ "test -f baz-lib/baz/libbaz.rlib" + , "! test -f baz-lib/baz/libbaz.rmeta" + , "test -f bar-lib/bar/libbar.rlib" + , "test -f main/bin/main" + , "./main/bin/main | grep baz" + , "./main/bin/main | grep bar" + , "./main/bin/main | grep foo" + ] + , "data": [["TREE", null, "dynamic"]] + } +, "build-script": + { "type": ["@", "test-rules", "test_rules", "test_case"] + , "name": ["build-script"] + , "targets": ["+build_script", "+main"] + , "asserts": + [ "test -f build_script/bar/build_script" + , "test -f build_script/bar/file_args" + , "test -f build_script/bar/out" + , "! ./main/bin/main | grep bar" + , "./main/bin/main | grep \"build script\"" + , "./main/bin/main | grep foo" + ] + , "data": [["TREE", null, "build-script"]] + } +, "ALL": + { "type": "install" + , "deps": + [ "static" + , "static-native" + , "dynamic" + , "build-script" + , ["./", "c-from-rust", "c-from-rust"] + ] + , "dirs": [[["./", "rust-from-c", "TESTS"], "rust-from-c"]] + , "tainted": ["test"] + } +} diff --git a/test/build-script/TARGETS b/test/build-script/TARGETS new file mode 100644 index 0000000..b896499 --- /dev/null +++ b/test/build-script/TARGETS @@ -0,0 +1,61 @@ +{ "baz-lib": + { "type": ["@", "rules", "rust", "library"] + , "name": ["baz"] + , "stage": ["baz"] + , "crate_root": ["baz.rs"] + , "edition": ["2021"] + , "version": ["1", "2", "3", "rc-1"] + } +, "build_script": + { "type": ["@", "rules", "cargo", "build_script"] + , "name": ["build_script"] + , "crate_root": ["build.rs"] + , "edition": ["2018"] + , "stage": ["bar"] + , "deps": ["baz-lib"] + } +, "bar-lib": + { "type": ["@", "rules", "rust", "library"] + , "name": ["bar"] + , "stage": ["bar"] + , "build_script": ["build_script"] + , "deps": ["baz-lib"] + , "crate_root": ["bar.rs"] + , "edition": ["2021"] + } +, "bar-missing-baz": + { "type": ["@", "rules", "rust", "library"] + , "name": ["bar"] + , "stage": ["bar"] + , "crate_root": ["bar.rs"] + , "edition": ["2021"] + } +, "foo-lib": + { "type": ["@", "rules", "rust", "library"] + , "name": ["foo"] + , "stage": ["foo"] + , "crate_root": ["foo.rs"] + , "edition": ["2021"] + , "deps": ["bar-lib"] + } +, "main": + { "type": ["@", "rules", "rust", "binary"] + , "name": ["main"] + , "stage": ["bin"] + , "crate_root": ["main.rs"] + , "deps": ["foo-lib"] + } +, "main-wrong-dep": + { "type": ["@", "rules", "rust", "binary"] + , "name": ["main"] + , "stage": ["bin"] + , "crate_root": ["main.rs"] + , "deps": ["bar-lib"] + } +, "main-missing-dep": + { "type": ["@", "rules", "rust", "binary"] + , "name": ["main"] + , "stage": ["bin"] + , "crate_root": ["main.rs"] + } +} diff --git a/test/build-script/bar.rs b/test/build-script/bar.rs new file mode 100644 index 0000000..30de275 --- /dev/null +++ b/test/build-script/bar.rs @@ -0,0 +1,15 @@ + +#[cfg(not(bar))] +pub fn hello(){ + println!("hello bar"); +} + +#[cfg(bar)] +pub fn hello(){ + println!("hello build script"); +} + +pub fn add(a: i32, b: i32) -> i32 { + a + b +} + diff --git a/test/build-script/baz.rs b/test/build-script/baz.rs new file mode 100644 index 0000000..4222589 --- /dev/null +++ b/test/build-script/baz.rs @@ -0,0 +1,5 @@ + +pub fn hello(){ + +println!("hello baz"); + }
\ No newline at end of file diff --git a/test/build-script/build.rs b/test/build-script/build.rs new file mode 100644 index 0000000..35a358c --- /dev/null +++ b/test/build-script/build.rs @@ -0,0 +1,7 @@ + + +fn main() { + +println!("cargo:rustc-cfg=bar"); + +} diff --git a/test/build-script/foo.rs b/test/build-script/foo.rs new file mode 100644 index 0000000..c2dca08 --- /dev/null +++ b/test/build-script/foo.rs @@ -0,0 +1,6 @@ +extern crate bar; +pub fn hello(){ + +bar::hello(); + println!("hello foo"); + }
\ No newline at end of file diff --git a/test/build-script/main.rs b/test/build-script/main.rs new file mode 100644 index 0000000..6da0e2e --- /dev/null +++ b/test/build-script/main.rs @@ -0,0 +1,6 @@ +extern crate foo; + +fn main() { + +foo::hello(); +} diff --git a/test/c-from-rust/TARGETS b/test/c-from-rust/TARGETS new file mode 100644 index 0000000..7da2055 --- /dev/null +++ b/test/c-from-rust/TARGETS @@ -0,0 +1,13 @@ +{ "main": + { "type": ["rules/rust", "binary"] + , "name": ["main"] + , "crate_root": ["main.rs"] + , "deps": [["./", "clib", "foo"]] + } +, "c-from-rust": + { "type": ["@", "rules-cc", "shell/test", "script"] + , "name": ["c-from-rust"] + , "test": ["check_ints.sh"] + , "deps": ["main"] + } +} diff --git a/test/c-from-rust/check_ints.sh b/test/c-from-rust/check_ints.sh new file mode 100644 index 0000000..00780c3 --- /dev/null +++ b/test/c-from-rust/check_ints.sh @@ -0,0 +1,5 @@ +set -e + +for i in `seq 1 42`; do + ./main -$i | grep " -$i is $i" +done diff --git a/test/c-from-rust/clib/TARGETS b/test/c-from-rust/clib/TARGETS new file mode 100644 index 0000000..c72e90b --- /dev/null +++ b/test/c-from-rust/clib/TARGETS @@ -0,0 +1,19 @@ +{ "foo": + { "type": ["@", "rules-cc", "CC", "library"] + , "pure C": ["true"] + , "name": ["foo"] + , "srcs": ["foo.c"] + , "hdrs": ["foo.h"] + , "stage": ["foo"] + , "deps": ["bar"] + } +, "bar": + { "type": ["@", "rules-cc", "CC", "library"] + , "pure C": ["true"] + , "name": ["bar"] + , "srcs": ["bar.c"] + , "hdrs": ["bar.h"] + , "ldflags": ["-lm"] + , "stage": ["bar"] + } +} diff --git a/test/c-from-rust/clib/bar.c b/test/c-from-rust/clib/bar.c new file mode 100644 index 0000000..5ad792c --- /dev/null +++ b/test/c-from-rust/clib/bar.c @@ -0,0 +1,5 @@ +#include <math.h> + +int bar(int x){ + return sqrt(x); +} diff --git a/test/c-from-rust/clib/bar.h b/test/c-from-rust/clib/bar.h new file mode 100644 index 0000000..1c88e77 --- /dev/null +++ b/test/c-from-rust/clib/bar.h @@ -0,0 +1,3 @@ +#pragma once + +int bar(int); diff --git a/test/c-from-rust/clib/foo.c b/test/c-from-rust/clib/foo.c new file mode 100644 index 0000000..5306a9c --- /dev/null +++ b/test/c-from-rust/clib/foo.c @@ -0,0 +1,5 @@ +#include "bar/bar.h" + +int c_func(int x){ + return bar(x*x); +} diff --git a/test/c-from-rust/clib/foo.h b/test/c-from-rust/clib/foo.h new file mode 100644 index 0000000..6ce2745 --- /dev/null +++ b/test/c-from-rust/clib/foo.h @@ -0,0 +1,3 @@ +#pragma once +int c_func(int); + diff --git a/test/c-from-rust/main.rs b/test/c-from-rust/main.rs new file mode 100644 index 0000000..961150a --- /dev/null +++ b/test/c-from-rust/main.rs @@ -0,0 +1,20 @@ +use std::env; + +extern "C" { + fn c_func(input: i32) -> i32; +} + +fn c_call(i:i32) -> i32{ + unsafe { + return c_func(i); + } +} + +fn main() { + let args: Vec<String> = env::args().collect(); + match args[1].parse::<i32>() { + Ok(i) => println!("Absolute value of {} is {}",i, c_call(i)), + Err(..) => println!("Wrong argument {}",args[1]), + }; + +} diff --git a/test/dynamic/TARGETS b/test/dynamic/TARGETS new file mode 100644 index 0000000..556176e --- /dev/null +++ b/test/dynamic/TARGETS @@ -0,0 +1,53 @@ +{ "baz-lib": + { "type": ["@", "rules", "rust", "library"] + , "name": ["baz"] + , "stage": ["baz"] + , "crate_root": ["baz.rs"] + , "edition": ["2021"] + , "version": ["1", "2", "3", "rc-1"] + } +, "bar-lib": + { "type": ["@", "rules", "rust", "library"] + , "name": ["bar"] + , "stage": ["bar"] + , "crate_root": ["bar.rs"] + , "edition": ["2021"] + , "deps": ["baz-lib"] + } +, "bar-missing-baz": + { "type": ["@", "rules", "rust", "library"] + , "name": ["bar"] + , "stage": ["bar"] + , "crate_root": ["bar.rs"] + , "edition": ["2021"] + } +, "foo-lib": + { "type": ["@", "rules", "rust", "library"] + , "shared": ["true"] + , "name": ["foo"] + , "stage": ["foo"] + , "crate_root": ["foo.rs"] + , "edition": ["2021"] + , "deps": ["bar-lib"] + } +, "main": + { "type": ["@", "rules", "rust", "binary"] + , "name": ["main"] + , "stage": ["bin"] + , "crate_root": ["main.rs"] + , "deps": ["foo-lib"] + } +, "main-wrong-dep": + { "type": ["@", "rules", "rust", "binary"] + , "name": ["main"] + , "stage": ["bin"] + , "crate_root": ["main.rs"] + , "deps": ["bar-lib"] + } +, "main-missing-dep": + { "type": ["@", "rules", "rust", "binary"] + , "name": ["main"] + , "stage": ["bin"] + , "crate_root": ["main.rs"] + } +} diff --git a/test/dynamic/bar.rs b/test/dynamic/bar.rs new file mode 100644 index 0000000..6a0afce --- /dev/null +++ b/test/dynamic/bar.rs @@ -0,0 +1,11 @@ + +extern crate baz; +pub fn hello(){ + baz::hello(); + println!("hello bar"); +} + +pub fn add(a: i32, b: i32) -> i32 { + a + b +} + diff --git a/test/dynamic/baz.rs b/test/dynamic/baz.rs new file mode 100644 index 0000000..4222589 --- /dev/null +++ b/test/dynamic/baz.rs @@ -0,0 +1,5 @@ + +pub fn hello(){ + +println!("hello baz"); + }
\ No newline at end of file diff --git a/test/dynamic/foo.rs b/test/dynamic/foo.rs new file mode 100644 index 0000000..c2dca08 --- /dev/null +++ b/test/dynamic/foo.rs @@ -0,0 +1,6 @@ +extern crate bar; +pub fn hello(){ + +bar::hello(); + println!("hello foo"); + }
\ No newline at end of file diff --git a/test/dynamic/main.rs b/test/dynamic/main.rs new file mode 100644 index 0000000..6da0e2e --- /dev/null +++ b/test/dynamic/main.rs @@ -0,0 +1,6 @@ +extern crate foo; + +fn main() { + +foo::hello(); +} diff --git a/test/rust-from-c/TARGETS b/test/rust-from-c/TARGETS new file mode 100644 index 0000000..1cb8019 --- /dev/null +++ b/test/rust-from-c/TARGETS @@ -0,0 +1,23 @@ +{ "main": + { "type": ["@", "rules-cc", "CC", "binary"] + , "pure C": ["true"] + , "name": ["main"] + , "srcs": ["main.c"] + , "private-deps": [["./", "foo", "foo"]] + } +, "test_foo": + { "type": ["rules/rust", "test"] + , "name": ["test_foo"] + , "crate_root": ["foo/foo_test.rs"] + , "stage": ["test_foo"] + , "deps": [["./", "foo", "foo"]] + } +, "check_ints": + { "type": ["@", "rules-cc", "shell/test", "script"] + , "name": ["check_ints"] + , "test": ["check_ints.sh"] + , "deps": ["main"] + } +, "TESTS": + {"type": "install", "deps": ["check_ints", "test_foo"], "tainted": ["test"]} +} diff --git a/test/rust-from-c/check_ints.sh b/test/rust-from-c/check_ints.sh new file mode 100644 index 0000000..00780c3 --- /dev/null +++ b/test/rust-from-c/check_ints.sh @@ -0,0 +1,5 @@ +set -e + +for i in `seq 1 42`; do + ./main -$i | grep " -$i is $i" +done diff --git a/test/rust-from-c/foo/TARGETS b/test/rust-from-c/foo/TARGETS new file mode 100644 index 0000000..17c66ba --- /dev/null +++ b/test/rust-from-c/foo/TARGETS @@ -0,0 +1,15 @@ +{ "foo": + { "type": ["rules/rust", "library"] + , "name": ["foo"] + , "crate_root": ["foo.rs"] + , "c_hdrs": ["foo.h"] + , "stage": ["foo"] + , "deps": ["bar"] + } +, "bar": + { "type": ["rules/rust", "library"] + , "name": ["bar"] + , "crate_root": ["bar.rs"] + , "stage": ["bar"] + } +} diff --git a/test/rust-from-c/foo/bar.rs b/test/rust-from-c/foo/bar.rs new file mode 100644 index 0000000..61e68f4 --- /dev/null +++ b/test/rust-from-c/foo/bar.rs @@ -0,0 +1,3 @@ +pub fn bar(x: i32) -> i32 { + return x.abs(); +}
\ No newline at end of file diff --git a/test/rust-from-c/foo/foo.h b/test/rust-from-c/foo/foo.h new file mode 100644 index 0000000..88deb2e --- /dev/null +++ b/test/rust-from-c/foo/foo.h @@ -0,0 +1,2 @@ +#pragma once +int foo(int); diff --git a/test/rust-from-c/foo/foo.rs b/test/rust-from-c/foo/foo.rs new file mode 100644 index 0000000..8735b67 --- /dev/null +++ b/test/rust-from-c/foo/foo.rs @@ -0,0 +1,6 @@ +extern crate bar; + +#[no_mangle] +pub extern "C" fn foo(x: i32) -> i32 { + return bar::bar(x); +} diff --git a/test/rust-from-c/foo/foo_test.rs b/test/rust-from-c/foo/foo_test.rs new file mode 100644 index 0000000..8b5de77 --- /dev/null +++ b/test/rust-from-c/foo/foo_test.rs @@ -0,0 +1,11 @@ +extern crate foo; + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_foo(){ + assert_eq!(foo::foo(-7),7); + } +}
\ No newline at end of file diff --git a/test/rust-from-c/main.c b/test/rust-from-c/main.c new file mode 100644 index 0000000..0f69281 --- /dev/null +++ b/test/rust-from-c/main.c @@ -0,0 +1,14 @@ +#include <stdio.h> +#include <stdlib.h> + +int foo(int); + +int main(int argc, char **argv) { + if (argc < 2) { + fprintf(stderr, "Please provide one number as argument\n"); + exit(1); + } + int x = atoi(argv[1]); + printf("absolute value of %d is %d\n", x, foo(x)); + return 0; +} diff --git a/test/static-native/TARGETS b/test/static-native/TARGETS new file mode 100644 index 0000000..2b26236 --- /dev/null +++ b/test/static-native/TARGETS @@ -0,0 +1,54 @@ +{ "baz-lib": + { "type": ["@", "rules", "rust", "library"] + , "name": ["baz"] + , "native": ["true"] + , "stage": ["baz"] + , "crate_root": ["baz.rs"] + , "edition": ["2021"] + , "version": ["1", "2", "3", "rc-1"] + } +, "bar-lib": + { "type": ["@", "rules", "rust", "library"] + , "name": ["bar"] + , "stage": ["bar"] + , "crate_root": ["bar.rs"] + , "edition": ["2021"] + , "deps": ["baz-lib"] + } +, "bar-missing-baz": + { "type": ["@", "rules", "rust", "library"] + , "name": ["bar"] + , "stage": ["bar"] + , "crate_root": ["bar.rs"] + , "edition": ["2021"] + } +, "foo-lib": + { "type": ["@", "rules", "rust", "library"] + , "name": ["foo"] + , "native": ["true"] + , "stage": ["foo"] + , "crate_root": ["foo.rs"] + , "edition": ["2021"] + , "deps": ["bar-lib"] + } +, "main": + { "type": ["@", "rules", "rust", "binary"] + , "name": ["main"] + , "stage": ["bin"] + , "crate_root": ["main.rs"] + , "deps": ["foo-lib"] + } +, "main-wrong-dep": + { "type": ["@", "rules", "rust", "binary"] + , "name": ["main"] + , "stage": ["bin"] + , "crate_root": ["main.rs"] + , "deps": ["bar-lib"] + } +, "main-missing-dep": + { "type": ["@", "rules", "rust", "binary"] + , "name": ["main"] + , "stage": ["bin"] + , "crate_root": ["main.rs"] + } +} diff --git a/test/static-native/bar.rs b/test/static-native/bar.rs new file mode 100644 index 0000000..6a0afce --- /dev/null +++ b/test/static-native/bar.rs @@ -0,0 +1,11 @@ + +extern crate baz; +pub fn hello(){ + baz::hello(); + println!("hello bar"); +} + +pub fn add(a: i32, b: i32) -> i32 { + a + b +} + diff --git a/test/static-native/baz.rs b/test/static-native/baz.rs new file mode 100644 index 0000000..4222589 --- /dev/null +++ b/test/static-native/baz.rs @@ -0,0 +1,5 @@ + +pub fn hello(){ + +println!("hello baz"); + }
\ No newline at end of file diff --git a/test/static-native/foo.rs b/test/static-native/foo.rs new file mode 100644 index 0000000..c2dca08 --- /dev/null +++ b/test/static-native/foo.rs @@ -0,0 +1,6 @@ +extern crate bar; +pub fn hello(){ + +bar::hello(); + println!("hello foo"); + }
\ No newline at end of file diff --git a/test/static-native/main.rs b/test/static-native/main.rs new file mode 100644 index 0000000..6da0e2e --- /dev/null +++ b/test/static-native/main.rs @@ -0,0 +1,6 @@ +extern crate foo; + +fn main() { + +foo::hello(); +} diff --git a/test/static/TARGETS b/test/static/TARGETS new file mode 100644 index 0000000..9337fc9 --- /dev/null +++ b/test/static/TARGETS @@ -0,0 +1,60 @@ +{ "baz-lib": + { "type": ["@", "rules", "rust", "library"] + , "name": ["baz"] + , "stage": ["baz"] + , "crate_root": ["baz.rs"] + , "deps": ["build_script"] + , "edition": ["2021"] + , "version": ["1", "2", "3", "rc-1"] + } +, "build_script": + { "type": ["@", "rules", "cargo", "build_script"] + , "name": ["build_script"] + , "crate_root": ["build.rs"] + , "edition": ["2018"] + , "stage": ["baz"] + } +, "bar-lib": + { "type": ["@", "rules", "rust", "library"] + , "name": ["bar"] + , "stage": ["bar"] + , "crate_root": ["bar.rs"] + , "edition": ["2021"] + , "deps": ["baz-lib"] + } +, "bar-missing-baz": + { "type": ["@", "rules", "rust", "library"] + , "name": ["bar"] + , "stage": ["bar"] + , "crate_root": ["bar.rs"] + , "edition": ["2021"] + } +, "foo-lib": + { "type": ["@", "rules", "rust", "library"] + , "name": ["foo"] + , "stage": ["foo"] + , "crate_root": ["foo.rs"] + , "edition": ["2021"] + , "deps": ["bar-lib"] + } +, "main": + { "type": ["@", "rules", "rust", "binary"] + , "name": ["main"] + , "stage": ["bin"] + , "crate_root": ["main.rs"] + , "deps": ["foo-lib"] + } +, "main-wrong-dep": + { "type": ["@", "rules", "rust", "binary"] + , "name": ["main"] + , "stage": ["bin"] + , "crate_root": ["main.rs"] + , "deps": ["bar-lib"] + } +, "main-missing-dep": + { "type": ["@", "rules", "rust", "binary"] + , "name": ["main"] + , "stage": ["bin"] + , "crate_root": ["main.rs"] + } +} diff --git a/test/static/bar.rs b/test/static/bar.rs new file mode 100644 index 0000000..6a0afce --- /dev/null +++ b/test/static/bar.rs @@ -0,0 +1,11 @@ + +extern crate baz; +pub fn hello(){ + baz::hello(); + println!("hello bar"); +} + +pub fn add(a: i32, b: i32) -> i32 { + a + b +} + diff --git a/test/static/baz.rs b/test/static/baz.rs new file mode 100644 index 0000000..4222589 --- /dev/null +++ b/test/static/baz.rs @@ -0,0 +1,5 @@ + +pub fn hello(){ + +println!("hello baz"); + }
\ No newline at end of file diff --git a/test/static/build.rs b/test/static/build.rs new file mode 100644 index 0000000..c2537fa --- /dev/null +++ b/test/static/build.rs @@ -0,0 +1,7 @@ + + +fn main() { + +println!("cargo:rustc-cfg=feature=\"config_transitionnnnnnnnnnnnnnnnnnnnnnnn\""); + +} diff --git a/test/static/foo.rs b/test/static/foo.rs new file mode 100644 index 0000000..c2dca08 --- /dev/null +++ b/test/static/foo.rs @@ -0,0 +1,6 @@ +extern crate bar; +pub fn hello(){ + +bar::hello(); + println!("hello foo"); + }
\ No newline at end of file diff --git a/test/static/main.rs b/test/static/main.rs new file mode 100644 index 0000000..6da0e2e --- /dev/null +++ b/test/static/main.rs @@ -0,0 +1,6 @@ +extern crate foo; + +fn main() { + +foo::hello(); +} |