This sysroot provides ARM64-specific LLVM tools for Bazel builds. It is part of a larger system of sysroots that work together to provide a complete build environment.
The bazel_sysroot_llvm_arm64 sysroot is responsible for providing ARM64-specific LLVM tools that are required for building applications on ARM64 architectures. It works in conjunction with:
bazel_sysroot_library- Provides common headers and system librariesbazel_sysroot_lib_arm64- Provides ARM64-specific shared libraries
This sysroot must provide all tools required by both rules_cc and toolchain_llvm:
ar(aliased fromllvm-ar)as(aliased fromllvm-as)ld(aliased fromld.lld)llvm-covllvm-profdatacpp(aliased fromclang-cpp)gcc(aliased fromclang)dwp(aliased fromllvm-dwp)gcovnm(aliased fromllvm-nm)objcopy(aliased fromllvm-objcopy)objdump(aliased fromllvm-objdump)strip(aliased fromllvm-strip)c++filt(aliased fromllvm-c++filt)
clang-cpp(from clang package)clang-format(from clang-tools package)clang-tidy(from clang-tools package)clangd(from clang-tools package)ld.lld(from lld package)llvm-ar(from llvm package)llvm-dwp(from llvm package)llvm-profdata(from llvm package)llvm-cov(from llvm package)llvm-nm(from llvm package)llvm-objcopy(from llvm package)llvm-objdump(from llvm package)llvm-strip(from llvm package)
This sysroot implements a dual aliasing strategy to ensure compatibility with both Bazel's expectations and direct tool usage:
-
Filesystem-level aliases: During the build process, GNU tool symlinks are created in the
bin/directory:ln -sf clang gcc ln -sf clang cc ln -sf clang++ c++ ln -sf clang-cpp cpp ln -sf llvm-ar ar ln -sf llvm-ar ranlib ln -sf llvm-as as ln -sf ld.lld ld ln -sf llvm-nm nm ln -sf llvm-objcopy objcopy ln -sf llvm-objdump objdump ln -sf llvm-strip strip ln -sf llvm-dwp dwp ln -sf llvm-c++filt c++filt ln -sf llvm-cov gcov
-
Bazel-level aliases: The
BUILD.bazelfile defines filegroups that map GNU tool names to their LLVM equivalents:filegroup( name = "gcc", srcs = [":clang"], visibility = ["//visibility:public"], ) # ... other aliases ...
This dual approach ensures compatibility at both the filesystem level (for direct tool usage) and the Bazel level (for build system integration). While either approach alone might be sufficient, using both provides maximum compatibility and flexibility.
sysroot/
└── bin/ # ARM64-specific LLVM tools
├── clang* # Clang compiler tools
├── lld* # LLVM linker tools
├── llvm-* # Other LLVM tools
└── llvm-dwp # DWARF packaging tool
The BUILD.bazel file defines the following targets:
package(default_visibility = ["//visibility:public"])
# Main sysroot filegroup
filegroup(
name = "sysroot",
srcs = glob(["bin/**"]),
visibility = ["//visibility:public"],
)
# Individual tool targets
filegroup(
name = "clang",
srcs = glob(["bin/clang*"]),
visibility = ["//visibility:public"],
)
filegroup(
name = "lld",
srcs = glob(["bin/lld*"]),
visibility = ["//visibility:public"],
)
filegroup(
name = "llvm-ar",
srcs = ["bin/llvm-ar"],
visibility = ["//visibility:public"],
)
filegroup(
name = "llvm-as",
srcs = ["bin/llvm-as"],
visibility = ["//visibility:public"],
)
filegroup(
name = "llvm-nm",
srcs = ["bin/llvm-nm"],
visibility = ["//visibility:public"],
)
filegroup(
name = "llvm-objcopy",
srcs = ["bin/llvm-objcopy"],
visibility = ["//visibility:public"],
)
filegroup(
name = "llvm-objdump",
srcs = ["bin/llvm-objdump"],
visibility = ["//visibility:public"],
)
filegroup(
name = "llvm-readelf",
srcs = ["bin/llvm-readelf"],
visibility = ["//visibility:public"],
)
filegroup(
name = "llvm-strip",
srcs = ["bin/llvm-strip"],
visibility = ["//visibility:public"],
)
filegroup(
name = "llvm-dwp",
srcs = ["bin/llvm-dwp"],
visibility = ["//visibility:public"],
)
# Tool aliases
filegroup(
name = "gcc",
srcs = [":clang"],
visibility = ["//visibility:public"],
)
filegroup(
name = "cpp",
srcs = [":clang"],
visibility = ["//visibility:public"],
)
filegroup(
name = "ar",
srcs = [":llvm-ar"],
visibility = ["//visibility:public"],
)
filegroup(
name = "as",
srcs = [":llvm-as"],
visibility = ["//visibility:public"],
)
filegroup(
name = "ld",
srcs = [":lld"],
visibility = ["//visibility:public"],
)
filegroup(
name = "nm",
srcs = [":llvm-nm"],
visibility = ["//visibility:public"],
)
filegroup(
name = "objcopy",
srcs = [":llvm-objcopy"],
visibility = ["//visibility:public"],
)
filegroup(
name = "objdump",
srcs = [":llvm-objdump"],
visibility = ["//visibility:public"],
)
filegroup(
name = "strip",
srcs = [":llvm-strip"],
visibility = ["//visibility:public"],
)
filegroup(
name = "dwp",
srcs = [":llvm-dwp"],
visibility = ["//visibility:public"],
)This sysroot is used as part of the LLVM toolchain configuration in your MODULE.bazel:
llvm.toolchain(
name = "llvm_arm64",
llvm_version = "20.1.2",
stdlib = {
"linux-aarch64": "stdc++",
},
)
llvm.sysroot(
name = "llvm_arm64",
targets = ["linux-aarch64"],
# Main sysroot containing the LLVM tools
label = "@bazel_sysroot_llvm_arm64//:sysroot",
# Additional sysroots for headers and libraries
include_prefix = "@bazel_sysroot_library//:include",
lib_prefix = "@bazel_sysroot_lib_arm64//:lib",
# System libraries from both common and architecture-specific sysroots
system_libs = [
"@bazel_sysroot_library//:system_deps",
"@bazel_sysroot_library//:system_deps_static",
"@bazel_sysroot_lib_arm64//:system_libs",
],
)To build this sysroot:
nix-build default.nixThe resulting sysroot will be available in the result/sysroot directory.
The sysroot follows a specific structure to ensure compatibility with Bazel's LLVM toolchain. For details, see SYSROOT_STRUCTURE.md.
To build the sysroot:
nix buildThe sysroot can be used in Bazel projects by adding it as a dependency in your MODULE.bazel file:
http_archive(
name = "bazel_sysroot_tarball_arm64",
urls = ["https://github.com/yourusername/bazel_sysroot_llvm_arm64/archive/refs/heads/main.tar.gz"],
strip_prefix = "bazel_sysroot_llvm_arm64-main",
)- All binaries are placed in the
bin/directory - The sysroot is designed to work in conjunction with:
bazel_sysroot_libraryfor common headers and system librariesbazel_sysroot_lib_arm64for ARM64-specific shared libraries
- The BUILD file provides granular access to individual tools through filegroups
- Each tool is exposed with public visibility for use in Bazel builds
- GNU tool symlinks are created to ensure compatibility with Bazel's expectations
- Excluding llvm-exegesis as it's a large benchmarking tool (75MB) not needed for compilation See https://llvm.org/docs/CommandGuide/llvm-exegesis.html for details
- The
compiler-rtpackage is included to provide runtime libraries for LLVM sanitizers (ASan, MSan, etc.) and other runtime features. These are useful for debug builds and development, but not typically needed for production builds. See https://compiler-rt.llvm.org/ for more details.
make help- Show available targets and their descriptionsmake update-flake- Update flake.lock with latest dependenciesmake build- Build the ARM64 LLVM toolchain using nix buildmake tarball- Create a .tar.gz archive of the ARM64 LLVM toolchainmake nix-tarball- Create a .tar.gz archive using nix buildmake copy- Copy files from Nix store to sysroot directorymake push- Push changes to GitHub with dated commitmake update-all- Update flake, build, copy, and pushmake clean- Clean up build artifacts
.
├── default.nix # Nix package definition
├── flake.nix # Nix flake configuration
├── Makefile # Build and maintenance targets
├── sysroot/ # Sysroot files (generated)
│ ├── include/ # Header files
│ ├── lib/ # Library files
│ └── bin/ # Binary files (LLVM tools and coreutils)
└── .gitignore # Git ignore rules
- Nix package manager
- rsync (for copying files)
- git (for version control)