Skip to content

Commit c16968e

Browse files
committed
[Bazel] Add support for Bzlmod
The workspace build is now gated behind `--config=deprecated_workspace`. See `utils/bazel/examples` for the new setup instructions. While not necessarily the most intuitive implementation, this seems to be the only way retain the flexibility of all potential usecases as of Bazel 8. The module build supports: - The in-tree build from within the `utils/bazel` directory. - The llvm-project cloned into an arbitrary directory (e.g. for local development, submodule setups and and Nix users). - The llvm-project fetched from github via an archive. Since module overrides are invisible to third-party dependents, every project that has the llvm project "somewhere" in its dependency tree needs to create an explicit override in their root module. It's possible to avoid this inconvenience by creating custom bazel registries, but only makes sense to do for the next stable tag that contains this commit. Notes for zlib users -------------------- The configuration options for zlib-ng and zstd have been moved to accomodate both the workspace and the module build: ``` // Old --@llvm-project-overlay//:llvm_enable_zstd --@llvm-project-overlay//:llvm_enable_zlib // New --@llvm-project//llvm:enable_zstd --@llvm-project//llvm:enable_zlib ``` This also fixes a subtle issue where the way that we used `zlib` and `zstd` was not idiomatic. Our existing implementation relied on custom defines exposed by build files. This bled llvm-specific configuration into what were supposed to be independent third-party dependencies. If you need to link against nonhermetic system variants of these libraries use custom overrides, for instance like so: ```python '''MODULE.bazel''' new_local_repository = use_repo_rule( "@bazel_tools//tools/build_defs/repo:local.bzl", "new_local_repository", ) new_local_repository( name = "zlib-ng", path = "xxxx", build_file_content = "xxxx", ) override_repo(llvm_project_overlay, "zlib-ng") ```
1 parent a3799f2 commit c16968e

File tree

17 files changed

+1241
-151
lines changed

17 files changed

+1241
-151
lines changed

utils/bazel/.bazelrc

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99

1010
# Flip off to disable MODULE.bazel until we're ready.
1111
# https://github.com/llvm/llvm-project/issues/55924
12-
common --enable_bzlmod=false --enable_workspace
12+
#
13+
# WARNING: This option will be removed soon. Please migrate to bzlmod.
14+
common:deprecated_workspace --enable_bzlmod=false --enable_workspace
1315

1416
# TODO: Remove lit test reliance on this
1517
common --legacy_external_runfiles
@@ -58,14 +60,6 @@ build --experimental_cc_shared_library
5860
# https://github.com/bazelbuild/bazel/commit/03246077f948f2790a83520e7dccc2625650e6df
5961
build --build_runfile_links=false
6062

61-
###############################################################################
62-
# Options to select different strategies for linking potential dependent
63-
# libraries. The default leaves it disabled.
64-
###############################################################################
65-
66-
build:zlib_external --repo_env=BAZEL_LLVM_ZLIB_STRATEGY=external
67-
build:zlib_system --repo_env=BAZEL_LLVM_ZLIB_STRATEGY=system
68-
6963
###############################################################################
7064
# Options for "generic_clang" builds: these options should generally apply to
7165
# builds using a Clang-based compiler, and default to the `clang` executable on

utils/bazel/.bazelversion

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
8.0.0
1+
8.0.1

utils/bazel/MODULE.bazel

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# This file is licensed under the Apache License v2.0 with LLVM Exceptions.
2+
# See https://llvm.org/LICENSE.txt for license information.
3+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4+
5+
module(
6+
name = "llvm-project-overlay",
7+
version = "main",
8+
compatibility_level = 0,
9+
)
10+
11+
bazel_dep(name = "bazel_skylib", version = "1.7.1")
12+
bazel_dep(name = "platforms", version = "0.0.11")
13+
bazel_dep(name = "rules_cc", version = "0.0.17")
14+
bazel_dep(name = "rules_python", version = "1.1.0")
15+
bazel_dep(name = "apple_support", version = "1.17.1")
16+
bazel_dep(name = "rules_foreign_cc", version = "0.13.0")
17+
bazel_dep(name = "robin-map", version = "1.3.0")
18+
bazel_dep(name = "zlib-ng", version = "2.0.7")
19+
bazel_dep(name = "zstd", version = "1.5.6")
20+
21+
llvm_project_overlay = use_extension(
22+
"//:extensions.bzl",
23+
"llvm_project_overlay",
24+
)
25+
26+
# Don't add targets here. An empty list resolves to "all targets" and allows
27+
# downstream repos to configure subsets.
28+
llvm_project_overlay.configure()
29+
30+
use_repo(
31+
llvm_project_overlay,
32+
"llvm-project",
33+
"llvm-raw",
34+
35+
# Vendored.
36+
"vulkan_headers",
37+
"vulkan_sdk",
38+
"gmp",
39+
"mpfr",
40+
"pfm",
41+
"pybind11",
42+
"nanobind",
43+
)

utils/bazel/MODULE.bazel.lock

Lines changed: 766 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

utils/bazel/WORKSPACE

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ maybe(
4343

4444
maybe(
4545
http_archive,
46-
name = "llvm_zlib",
46+
name = "zlib-ng",
4747
build_file = "@llvm-raw//utils/bazel/third_party_build:zlib-ng.BUILD",
4848
sha256 = "e36bb346c00472a1f9ff2a0a4643e590a254be6379da7cddd9daeb9a7f296731",
4949
strip_prefix = "zlib-ng-2.0.7",
@@ -71,13 +71,13 @@ maybe(
7171
)
7272

7373
http_archive(
74-
name = "build_bazel_apple_support",
74+
name = "apple_support",
7575
sha256 = "c4bb2b7367c484382300aee75be598b92f847896fb31bbd22f3a2346adf66a80",
7676
url = "https://github.com/bazelbuild/apple_support/releases/download/1.15.1/apple_support.1.15.1.tar.gz",
7777
)
7878

7979
load(
80-
"@build_bazel_apple_support//lib:repositories.bzl",
80+
"@apple_support//lib:repositories.bzl",
8181
"apple_support_dependencies",
8282
)
8383

@@ -137,7 +137,7 @@ maybe(
137137

138138
maybe(
139139
http_archive,
140-
name = "llvm_zstd",
140+
name = "zstd",
141141
build_file = "@llvm-raw//utils/bazel/third_party_build:zstd.BUILD",
142142
sha256 = "7c42d56fac126929a6a85dbc73ff1db2411d04f104fae9bdea51305663a83fd0",
143143
strip_prefix = "zstd-1.5.2",
@@ -157,7 +157,7 @@ maybe(
157157

158158
maybe(
159159
http_archive,
160-
name = "robin_map",
160+
name = "robin-map",
161161
build_file = "@llvm-raw//utils/bazel/third_party_build:robin_map.BUILD",
162162
sha256 = "a8424ad3b0affd4c57ed26f0f3d8a29604f0e1f2ef2089f497f614b1c94c7236",
163163
strip_prefix = "robin-map-1.3.0",

utils/bazel/configure.bzl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ DEFAULT_TARGETS = [
3131
]
3232

3333
def _overlay_directories(repository_ctx):
34-
src_path = repository_ctx.path(Label("@llvm-raw//:WORKSPACE")).dirname
35-
bazel_path = src_path.get_child("utils").get_child("bazel")
36-
overlay_path = bazel_path.get_child("llvm-project-overlay")
37-
script_path = bazel_path.get_child("overlay_directories.py")
34+
workspace_path = repository_ctx.path(Label("@llvm-raw//utils/bazel:WORKSPACE")).dirname
35+
src_path = workspace_path.get_child("../..")
36+
overlay_path = workspace_path.get_child("llvm-project-overlay")
37+
script_path = workspace_path.get_child("overlay_directories.py")
3838

3939
python_bin = repository_ctx.which("python3")
4040
if not python_bin:
@@ -81,7 +81,7 @@ def _extract_cmake_settings(repository_ctx, llvm_cmake):
8181

8282
# It would be easier to use external commands like sed(1) and python.
8383
# For portability, the parser should run on Starlark.
84-
llvm_cmake_path = repository_ctx.path(Label("//:" + llvm_cmake))
84+
llvm_cmake_path = repository_ctx.path(Label("@llvm-raw//:" + llvm_cmake))
8585
for line in repository_ctx.read(llvm_cmake_path).splitlines():
8686
# Extract "set ( FOO bar ... "
8787
setfoo = line.partition("(")
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
module(
2+
name = "bzlmod-example",
3+
version = "0.0.0",
4+
compatibility_level = 0,
5+
)
6+
7+
bazel_dep(name = "llvm-raw", version = "main")
8+
9+
LLVM_COMMIT="0000000000000000000000000000000000000000"
10+
11+
# Add the dependencies from "utils/bazel/MODULE.bazel" but name the module
12+
# "llvm-raw". This way you don't need to fetch the llvm sources twice and retain
13+
# compatibility for third-party dependts as module overrides are ignored in
14+
# non-root modules.
15+
archive_override(
16+
module_name = "llvm-raw",
17+
strip_prefix = "llvm-project-{}".format(LLVM_COMMIT),
18+
patch_cmds = [
19+
'''printf 'module(name=\"llvm-raw\")
20+
bazel_dep(name = "apple_support", version = "1.17.1")
21+
bazel_dep(name = "bazel_skylib", version = "1.7.1")
22+
bazel_dep(name = "platforms", version = "0.0.11")
23+
bazel_dep(name = "robin-map", version = "1.3.0")
24+
bazel_dep(name = "rules_cc", version = "0.0.17")
25+
bazel_dep(name = "rules_foreign_cc", version = "0.13.0")
26+
bazel_dep(name = "rules_python", version = "1.1.0")
27+
bazel_dep(name = "zlib-ng", version = "2.0.7")
28+
bazel_dep(name = "zstd", version = "1.5.6")' > MODULE.bazel'''
29+
],
30+
build_file_content = "# Empty.",
31+
integrity = "sha256-0000000000000000000000000000000000000000000=",
32+
urls = [
33+
"https://github.com/llvm/llvm-project/archive/{}.zip".format(
34+
LLVM_COMMIT,
35+
),
36+
],
37+
)
38+
39+
llvm_project_overlay = use_extension(
40+
"@llvm-raw//utils/bazel:extensions.bzl",
41+
"llvm_project_overlay",
42+
)
43+
44+
llvm_project_overlay.configure()
45+
46+
use_repo(
47+
llvm_project_overlay,
48+
"llvm-project",
49+
50+
# Vendored.
51+
"vulkan_headers",
52+
"vulkan_sdk",
53+
"gmp",
54+
"mpfr",
55+
"pfm",
56+
"pybind11",
57+
"nanobind",
58+
)
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# This file is licensed under the Apache License v2.0 with LLVM Exceptions.
2+
# See https://llvm.org/LICENSE.txt for license information.
3+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4+
5+
# Since the llvm project doesn't have `MODULE.bazel` and `BUILD.bazel` files in
6+
# its root directory you need to create an override for the `llvm-raw` sources
7+
# and then inject it into the `llvm-project-overlay` module extension.
8+
9+
module(
10+
name = "bzlmod-example",
11+
version = "0.0.0",
12+
compatibility_level = 0,
13+
)
14+
15+
new_local_repository = use_repo_rule(
16+
"@bazel_tools//tools/build_defs/repo:local.bzl",
17+
"new_local_repository",
18+
)
19+
20+
# WARNING: This is not a module override. If a third party depends on your
21+
# repository the repository will get lifted to the root module and
22+
# treated as if it was in the third party module.
23+
#
24+
# This means that if your repo is the top level module this behaves as
25+
# you'd expect, but third parties need to create another
26+
# repository in conjunction with a `repo_override`.
27+
#
28+
# See: https://bazel.build/rules/lib/repo/local#new_local_repository
29+
# https://bazel.build/rules/lib/repo/http#http_archive
30+
# https://bazel.build/rules/lib/globals/module#override_repo
31+
new_local_repository(
32+
name = "llvm-raw",
33+
path = "third_party/llvm-project",
34+
build_file_content = "# Empty.",
35+
)
36+
37+
bazel_dep(name = "llvm-project-overlay", version = "main")
38+
39+
# WARNING: Sice this is a module override it'll be ignored if a third party
40+
# depends on your project.
41+
#
42+
# This means that if your repo is the top level module this behaves as
43+
# you'd expect, but third parties need to create a new module override
44+
# as described in https://bazel.build/rules/lib/globals/module.
45+
local_path_override(
46+
module_name = "llvm-project-overlay",
47+
path = "third_party/llvm-project/utils/bazel",
48+
)
49+
50+
llvm_project_overlay = use_extension(
51+
"@llvm-project-overlay//:extensions.bzl",
52+
"llvm_project_overlay",
53+
)
54+
55+
inject_repo(
56+
llvm_project_overlay,
57+
"llvm-raw",
58+
)
59+
60+
llvm_project_overlay.configure()
61+
62+
use_repo(
63+
llvm_project_overlay,
64+
"llvm-project",
65+
66+
# Vendored.
67+
"vulkan_headers",
68+
"vulkan_sdk",
69+
"gmp",
70+
"mpfr",
71+
"pfm",
72+
"pybind11",
73+
"nanobind",
74+
)

utils/bazel/extensions.bzl

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# This file is licensed under the Apache License v2.0 with LLVM Exceptions.
2+
# See https://llvm.org/LICENSE.txt for license information.
3+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4+
5+
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
6+
load("@bazel_tools//tools/build_defs/repo:local.bzl", "new_local_repository")
7+
load(":vulkan_sdk.bzl", "vulkan_sdk_setup")
8+
load(":configure.bzl", "llvm_configure", "DEFAULT_TARGETS")
9+
10+
def _llvm_configure_extension_impl(ctx):
11+
targets = []
12+
13+
# Aggregate targets across imports.
14+
targets.extend([
15+
target
16+
for module in ctx.modules
17+
for config in module.tags.configure
18+
for target in config.targets
19+
if target not in targets
20+
])
21+
22+
# Fall back to the default targets if all configurations of this extension
23+
# omit the `target` attribute.
24+
if targets == []:
25+
targets = DEFAULT_TARGETS
26+
27+
llvm_configure(name = "llvm-project", targets = targets)
28+
29+
# Deliberately omit the "llvm-raw" directory if we're not in the utils/bazel
30+
# directory.
31+
#
32+
# In downstream repos this intentionally causes the extension to immediately
33+
# error out if "llvm-raw" wasn't injected explicitly.
34+
#
35+
# We can't add this repo to the utils/bazel/MODULE.bazel as it would cause
36+
# submodule imports to resolve the new_local_repository at wrong paths.
37+
[
38+
new_local_repository(
39+
name = "llvm-raw",
40+
path = "../..",
41+
build_file_content = "# Empty."
42+
)
43+
for module in ctx.modules
44+
if module.name == "llvm-project-overlay" and module.is_root
45+
]
46+
47+
print(ctx.path(Label("@llvm-raw//:BUILD.bazel")))
48+
49+
http_archive(
50+
name = "vulkan_headers",
51+
build_file = "@llvm-raw//utils/bazel/third_party_build:vulkan_headers.BUILD",
52+
sha256 = "19f491784ef0bc73caff877d11c96a48b946b5a1c805079d9006e3fbaa5c1895",
53+
strip_prefix = "Vulkan-Headers-9bd3f561bcee3f01d22912de10bb07ce4e23d378",
54+
urls = [
55+
"https://github.com/KhronosGroup/Vulkan-Headers/archive/9bd3f561bcee3f01d22912de10bb07ce4e23d378.tar.gz",
56+
],
57+
)
58+
59+
vulkan_sdk_setup(name = "vulkan_sdk")
60+
61+
http_archive(
62+
name = "gmp",
63+
build_file = "@llvm-raw//utils/bazel/third_party_build:gmp.BUILD",
64+
sha256 = "fd4829912cddd12f84181c3451cc752be224643e87fac497b69edddadc49b4f2",
65+
strip_prefix = "gmp-6.2.1",
66+
urls = [
67+
"https://gmplib.org/download/gmp/gmp-6.2.1.tar.xz",
68+
"https://ftp.gnu.org/gnu/gmp/gmp-6.2.1.tar.xz",
69+
],
70+
)
71+
72+
# https://www.mpfr.org/mpfr-current/
73+
#
74+
# When updating to a newer version, don't use URLs with "mpfr-current" in them.
75+
# Instead, find a stable URL like the one used currently.
76+
http_archive(
77+
name = "mpfr",
78+
build_file = "@llvm-raw//utils/bazel/third_party_build:mpfr.BUILD",
79+
sha256 = "9cbed5d0af0d9ed5e9f8dd013e17838eb15e1db9a6ae0d371d55d35f93a782a7",
80+
strip_prefix = "mpfr-4.1.1",
81+
urls = ["https://www.mpfr.org/mpfr-4.1.1/mpfr-4.1.1.tar.gz"],
82+
)
83+
84+
http_archive(
85+
name = "pfm",
86+
build_file = "@llvm-raw//utils/bazel/third_party_build:pfm.BUILD",
87+
sha256 = "d18b97764c755528c1051d376e33545d0eb60c6ebf85680436813fa5b04cc3d1",
88+
strip_prefix = "libpfm-4.13.0",
89+
urls = ["https://versaweb.dl.sourceforge.net/project/perfmon2/libpfm4/libpfm-4.13.0.tar.gz"],
90+
)
91+
92+
http_archive(
93+
name = "pybind11",
94+
build_file = "@llvm-raw//utils/bazel/third_party_build:pybind.BUILD",
95+
sha256 = "201966a61dc826f1b1879a24a3317a1ec9214a918c8eb035be2f30c3e9cfbdcb",
96+
strip_prefix = "pybind11-2.10.3",
97+
url = "https://github.com/pybind/pybind11/archive/v2.10.3.zip",
98+
)
99+
100+
# TODO: Make `NB_BUILD=1` and `NB_SHARED=1` configurable in the BCR variant
101+
# and import this via `MODULE.bazel`.
102+
http_archive(
103+
name = "nanobind",
104+
build_file = "@llvm-raw//utils/bazel/third_party_build:nanobind.BUILD",
105+
sha256 = "bb35deaed7efac5029ed1e33880a415638352f757d49207a8e6013fefb6c49a7",
106+
strip_prefix = "nanobind-2.4.0",
107+
url = "https://github.com/wjakob/nanobind/archive/refs/tags/v2.4.0.tar.gz",
108+
)
109+
110+
111+
llvm_project_overlay = module_extension(
112+
doc = """Configure the llvm-project.
113+
114+
Tags:
115+
targets: List of targets which Clang should support.
116+
""",
117+
implementation = _llvm_configure_extension_impl,
118+
tag_classes = {
119+
"configure": tag_class(
120+
attrs = {
121+
"targets": attr.string_list(),
122+
},
123+
),
124+
},
125+
)

0 commit comments

Comments
 (0)