7.6 KiB
Bazel zig cc toolchain
This is a C/C++ toolchain that can (cross-)compile C/C++ programs. It contains clang-13, musl, glibc (versions 2-2.34, selectable), all in a ~40MB package. Read here about zig-cc; the rest of the README will present how to use this toolchain from Bazel.
Usage
Add this to your WORKSPACE
:
BAZEL_ZIG_CC_VERSION = "v0.4.0"
http_archive(
name = "bazel-zig-cc",
sha256 = "e8caba26519a2d9c71ef34ce4237d9973bd42dfd454b77f4175eb304c57852a4",
strip_prefix = "bazel-zig-cc-{}".format(BAZEL_ZIG_CC_VERSION),
urls = ["https://git.sr.ht/~motiejus/bazel-zig-cc/archive/{}.tar.gz".format(BAZEL_ZIG_CC_VERSION)],
)
load("@bazel-zig-cc//toolchain:defs.bzl", zig_register_toolchains = "register_toolchains")
zig_register_toolchains(register = [
"x86_64-linux-gnu.2.28",
"x86_64-macos-gnu",
])
The snippet above will download the zig toolchain and register it for the following platforms:
x86_64-linux-gnu.2.28
for["@platforms//os:linux", "@platforms//cpu:x86_64"]
.x86_64-macos-gnu
for["@platforms//os:macos", "@platforms//cpu:x86_64"]
.
Note that both Go and Bazel naming schemes are accepted. For convenience with Go, the following Go-style toolchain aliases are created:
Bazel (zig) name | Go name |
---|---|
x86_64 |
amd64 |
aarch64 |
arm64 |
macos |
darwin |
For example, the toolchain linux_amd64_gnu.2.28
is aliased to
x86_64-linux-gnu.2.28
. To find out which toolchains can be registered or
used, run:
$ bazel query @zig_sdk//... | sed -En '/.*_toolchain$/ s/.*:(.*)_toolchain$/\1/p'
Known Issues In bazel-zig-cc
These are the things you may stumble into when using bazel-zig-cc. I am unlikely to implement them, but patches implementing those will be accepted. See Questions & Contributions on how to contribute.
OSX: sysroot
For non-trivial programs (and for all darwin/arm64 cgo programs) MacOS SDK may be necessary. Read Jakub's comment about it. Support for OSX sysroot is currently not implemented.
OSX: different OS targets (Catalina -- Monterey)
Zig 0.9.0 may target macos.10 (Catalina), macos.11 (Big Sur) or macos.12 (Monterey). It currently targets the lowest version, without ability to change it.
Zig cache
Currently zig cache is in $HOME
, so bazel clean --expunge
does not clear
the zig cache. Zig's cache should be stored somewhere in the project's path.
Alternative download URLs
Currently zig is downloaded from dl.jakstys.lt/zig, which is nuts. One should provide a way to specify alternative URLs for the zig toolchain.
Bazel toolchain target locations
The path to Bazel toolchains is @zig_sdk//:<toolchain>_toolchain
. It should
be moved to @zig_sdk//toolchain:<toolchain>
or similar; so the user-facing
targets are in their own namespace.
Known Issues In Upstream
This section lists issues that I've stumbled into when using zig cc
, and is
outside of bazel-zig-cc's control.
using glibc 2.27 or older
Severity: Low
Task: ziglang/zig #9485 glibc 2.27 or older: fcntl64 not found, but zig's glibc headers refer it
Background: when glibc 2.27 or older is selected, it may miss fcntl64
. A
workaround is applied for x86_64
, but not for aarch64. The same workaround
may apply to aarch64, but the author didn't find a need to test it (yet).
Closed Upstream Issues
- ziglang/zig misplaced relocated glibc stubs (pthread_sigmask) #7667 (CLOSED, thanks mjonaitis and andrewrk)
- ziglang/zig macho: fail if requested -framework is not found #10312 (CLOSED, thanks kubkon)
- ziglang/zig [darwin aarch64 cgo] regression #10299 (CLOSED, thanks kubkon)
- ziglang/zig [darwin x86_64 cgo] regression #10297 (CLOSED, thanks kubkon)
- ziglang/zig #9431 FileNotFound when compiling macos (CLOSED, thanks andrewrk)
- rules/go #2894 Per-arch_target linker flags (CLOSED, thanks mjonaitis)
- ziglang/zig #7915 ar-compatible command for zig cc (CLOSED, thanks andrewrk)
- ziglang/zig #7917 [meta] better c/c++ toolchain compatibility (CLOSED, thanks andrewrk)
- ziglang/zig #9050 golang linker segfault (CLOSED, thanks kubkon)
- golang/go #46644 cmd/link: with CC=zig: SIGSERV when cross-compiling to darwin/amd64 (CLOSED, thanks kubkon)
- ziglang/zig #9139 zig c++ hanging when compiling in parallel (CLOSED, thanks andrewrk)
Testing
linux cgo + glibc 2.28
$ bazel build --platforms @io_bazel_rules_go//go/toolchain:linux_amd64_cgo //test:hello
$ file bazel-out/k8-fastbuild-ST-d17813c235ce/bin/test/hello_/hello
bazel-out/k8-fastbuild-ST-d17813c235ce/bin/test/hello_/hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.0.0, Go BuildID=redacted, with debug_info, not stripped
linux cgo + musl
$ bazel build \
--platforms @io_bazel_rules_go//go/toolchain:linux_amd64_cgo \
--extra_toolchains @zig_sdk//:linux_amd64_musl_toolchain //test:hello
...
$ file ../bazel-out/k8-fastbuild-ST-d17813c235ce/bin/test/hello_/hello
../bazel-out/k8-fastbuild-ST-d17813c235ce/bin/test/hello_/hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=redacted, with debug_info, not stripped
$ ../bazel-out/k8-fastbuild-ST-d17813c235ce/bin/test/hello_/hello
hello, world
macos cgo
$ bazel build --platforms @io_bazel_rules_go//go/toolchain:darwin_amd64_cgo //test:hello
...
$ file bazel-bin/test/hello_/hello
bazel-bin/test/hello_/hello: Mach-O 64-bit x86_64 executable, flags:<NOUNDEFS|DYLDLINK|TWOLEVEL|PIE>
Transient docker environment
$ docker run -e CC=/usr/bin/false -ti --rm -v $(pwd):/x -w /x debian:bullseye-slim
# apt update && apt install direnv git -y
# . .envrc
And run the bazel build
commands above. Take a look at .build.yml
and see
how CI does it.
Questions & Contributions
Project's mailing list is ~motiejus/bazel-zig-cc. The mailing list is used for:
- announcements (I am aiming to send an email with every release).
- user discussions.
- raising issues.
- contributions.
I will generally respond to emails about issues. I may even be able to fix them. However, no promises: you are much more likely (and welcome!) to get it fixed by submitting a patch.
To contribute, send your patches to the mailing list, as described in git-send-email.io or via Sourcehut web UI.
Copyright is retained by the contributors.
Thanks
Many thanks to Adam Bouhenguel and his bazel-zig-cc, the parent of this repository. Also, the Zig team for making this all possible and handling the issues promptly.