rust.bzl 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. # Copyright Materialize, Inc. and contributors. All rights reserved.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License in the LICENSE file at the
  6. # root of this repository, or online at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
  16. load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
  17. load("@rules_rust//rust:repositories.bzl", "DEFAULT_TOOLCHAIN_TRIPLES", "rust_repository_set")
  18. def rust_toolchains(versions, targets):
  19. """
  20. Macro that registers Rust toolchains for the provided targets.
  21. `rules_rust` provides a `rust_register_toolchains` macro but it fetches
  22. more Rust toolchains than we need, i.e. Linux, macOS, FreeBSD, and WASM.
  23. Instead the alternative of `rust_repostitory_set` is verbose enough that we
  24. abstract it away into this macro.
  25. """
  26. for version in versions:
  27. # Release channel for the current version.
  28. if version.startswith("nightly"):
  29. channel = "nightly"
  30. elif version.startswith("beta"):
  31. channel = "beta"
  32. else:
  33. channel = "stable"
  34. # Namespace for the GitHub release URLs.
  35. if channel == "stable":
  36. url_namespace = version
  37. else:
  38. url_namespace = channel
  39. for (target, versioned_components) in targets.items():
  40. # Support cross compiling to all other targets we specify.
  41. extra_targets = [t for t in targets.keys()]
  42. extra_targets.remove(target)
  43. # Get the hashes for the current version.
  44. components = versioned_components[channel]
  45. integrity = {}
  46. for (component, sha256) in components.items():
  47. key = _integrity_key(version, target, component)
  48. integrity[key] = sha256
  49. # These components are used when cross compiling and so we include
  50. # their hashes in the integrity for every target.
  51. CROSS_COMPILING_COMPONENTS = ["rust-std"]
  52. for extra_target in extra_targets:
  53. for component in CROSS_COMPILING_COMPONENTS:
  54. sha256 = targets[extra_target][channel].get(component)
  55. if not sha256:
  56. continue
  57. key = _integrity_key(version, extra_target, component)
  58. integrity[key] = sha256
  59. rust_repository_set(
  60. name = DEFAULT_TOOLCHAIN_TRIPLES[target],
  61. edition = "2024",
  62. exec_triple = target,
  63. extra_target_triples = extra_targets,
  64. versions = [version],
  65. sha256s = integrity,
  66. urls = [
  67. "https://github.com/MaterializeInc/toolchains/releases/download/rust-{NS}/{{}}.tar.zst".format(NS = url_namespace),
  68. ],
  69. )
  70. def _integrity_key(version, target, component):
  71. if version.startswith("nightly") or version.startswith("beta"):
  72. parts = version.split("/", 1)
  73. channel = parts[0]
  74. date = parts[1]
  75. return "{0}/{1}-{2}-{3}".format(date, component, channel, target)
  76. else:
  77. return "{0}-{1}-{2}".format(component, version, target)
  78. _BINDGEN_TOOLCHAIN_BUILD_FILE = """
  79. package(default_visibility = ["//visibility:public"])
  80. sh_binary(
  81. name = "clang",
  82. srcs = ["bin/clang"],
  83. )
  84. cc_import(
  85. name = "libclang",
  86. shared_library = "lib/libclang.{SHARED_EXTENSION}",
  87. )
  88. cc_import(
  89. name = "libc++",
  90. shared_library = "lib/{STDCXX}"
  91. )
  92. """
  93. def bindgen_toolchains(clang_release, targets):
  94. """
  95. Macro that registers [Rust bindgen] toolchains for the provided targets.
  96. [Rust bindgen](https://github.com/rust-lang/rust-bindgen)
  97. Args:
  98. clang_release (string): Name of the clang dependency we'll fetch.
  99. targets (dict[string, string]): Map of platform to the integrity for
  100. the libclang toolchain we fetch.
  101. """
  102. for (platform, integrity) in targets.items():
  103. if platform.startswith("darwin"):
  104. shared_extension = "dylib"
  105. stdcxx = "libc++.1.0.dylib"
  106. else:
  107. shared_extension = "so"
  108. stdcxx = "libc++.so.1.0"
  109. maybe(
  110. http_archive,
  111. name = "rust_bindgen__{0}".format(platform),
  112. build_file_content = _BINDGEN_TOOLCHAIN_BUILD_FILE.format(SHARED_EXTENSION = shared_extension, STDCXX = stdcxx),
  113. integrity = integrity,
  114. url = "https://github.com/MaterializeInc/toolchains/releases/download/clang-{0}/{1}_libclang.tar.zst".format(clang_release, platform),
  115. )
  116. native.register_toolchains("@//misc/bazel/toolchains:rust_bindgen_toolchain__{0}".format(platform))