1

Add libc constraint and libc aware toolchains

- Also get rid of @bazel_skylib dependency
This commit is contained in:
laurynasl 2022-04-13 14:52:25 +00:00
parent 7a81e2a129
commit 4d65b80903
20 changed files with 400 additions and 123 deletions

View File

@ -6,7 +6,4 @@ build --worker_sandboxing
build --compilation_mode=opt build --compilation_mode=opt
build --incompatible_enable_cc_toolchain_resolution build --incompatible_enable_cc_toolchain_resolution
build --extra_toolchains @zig_sdk//toolchain:linux_amd64_gnu.2.19 build --action_env BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1
build --extra_toolchains @zig_sdk//toolchain:linux_arm64_gnu.2.28
build --extra_toolchains @zig_sdk//toolchain:darwin_amd64
build --extra_toolchains @zig_sdk//toolchain:darwin_arm64

View File

@ -20,10 +20,7 @@ tasks:
sudo apt-get install libc6:arm64 -y sudo apt-get install libc6:arm64 -y
- list_toolchains_platforms: | - list_toolchains_platforms: |
cd bazel-zig-cc; . .envrc cd bazel-zig-cc; . .envrc
echo "Available toolchains:" ./ci/list_toolchains_platforms
bazel query @zig_sdk//toolchain:*
echo "Available platforms:"
bazel query @zig_sdk//platform:*
- test: | - test: |
cd bazel-zig-cc; . .envrc cd bazel-zig-cc; . .envrc
./ci/test --color=yes --curses=yes ./ci/test --color=yes --curses=yes

182
README.md
View File

@ -23,67 +23,168 @@ http_archive(
urls = ["https://git.sr.ht/~motiejus/bazel-zig-cc/archive/{}.tar.gz".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") load("@bazel-zig-cc//toolchain:defs.bzl", zig_toolchains = "toolchains")
zig_register_toolchains() zig_toolchains()
# Or, if you are using this in production, you probably want more control:
zig_register_toolchains(
version = "<...>",
url_formats = [
"https://example.internal/zig/zig-{host_platform}-{version}.tar.xz",
],
host_platform_sha256 = { ... },
)
``` ```
> ### zig sdk download control
>
> If you are using this in production, you probably want more control over
> where the zig sdk is downloaded from:
> ```
> zig_register_toolchains(
> version = "<...>",
> url_formats = [
> "https://example.internal/zig/zig-{host_platform}-{version}.tar.xz",
> ],
> host_platform_sha256 = { ... },
> )
> ```
And this to `.bazelrc`: And this to `.bazelrc`:
``` ```
build --incompatible_enable_cc_toolchain_resolution build --incompatible_enable_cc_toolchain_resolution
build --extra_toolchains @zig_sdk//toolchain:linux_amd64_gnu.2.19 ```
build --extra_toolchains @zig_sdk//toolchain:linux_arm64_gnu.2.28
build --extra_toolchains @zig_sdk//toolchain:darwin_amd64 The snippets above will download the zig toolchain and make the bazel
build --extra_toolchains @zig_sdk//toolchain:darwin_arm64 toolchains available for registration and usage.
The next steps depend on your use case.
## I want to manually build a single target with a specific zig cc toolchain
You may explicitly request Bazel to use a specific toolchain (compatible with
the specified platform). For example, if you wish to compile a specific binary
(or run tests) on linux/amd64/musl, you may specify:
```
bazel build \
--platforms @zig_sdk//platform:linux_arm64 \
--extra_toolchains @zig_sdk//toolchain:linux_arm64_musl \
//test/go:go
```
This registers the toolchain `@zig_sdk//toolchain:linux_arm64_musl` for linux
arm64 targets. This toolchains links code statically with musl. We also specify
that we want to build //test/go:go for linux arm64.
## I want to use zig cc as the default compiler
Replace the call to `zig_register_toolchains` with
```
register_toolchains(
"@zig_sdk//toolchain:linux_amd64_gnu.2.19",
"@zig_sdk//toolchain:linux_arm64_gnu.2.28",
"@zig_sdk//toolchain:darwin_amd64",
"@zig_sdk//toolchain:darwin_arm64",
)
``` ```
The snippets above will download the zig toolchain and register it for the The snippets above will download the zig toolchain and register it for the
following platforms: following configurations:
- `x86_64-linux-gnu.2.19` for `["@platforms//os:linux", "@platforms//cpu:x86_64"]`. - `toolchain:linux_amd64_gnu.2.19` for `["@platforms//os:linux", "@platforms//cpu:x86_64", "@zig_sdk//libc:unconstrained"]`.
- `x86_64-linux-gnu.2.28` for `["@platforms//os:linux", "@platforms//cpu:aarch64"]`. - `toolchain:linux_arm64_gnu.2.28` for `["@platforms//os:linux", "@platforms//cpu:aarch64", "@zig_sdk//libc:unconstrained"]`.
- `x86_64-macos-gnu` for `["@platforms//os:macos", "@platforms//cpu:x86_64"]`. - `toolchain:darwin_arm64` for `["@platforms//os:macos", "@platforms//cpu:x86_64"]`.
- `aarch64-macos-gnu` for `["@platforms//os:macos", "@platforms//cpu:aarch64"]`. - `toolchain:darwin_arm64` for `["@platforms//os:macos", "@platforms//cpu:aarch64"]`.
Note that both Go and Bazel naming schemes are accepted. For convenience with > ### Naming
Go, the following Go-style toolchain aliases are created: >
> 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//toolchain/...
> ```
|Bazel (zig) name | Go name | > ### Disabling the default bazel cc toolchain
|---------------- | -------- | >
|`x86_64` | `amd64` | > It may be useful to disable the default toolchain that bazel configures for
|`aarch64` | `arm64` | > you, so that configuration issues can be caught early on:
|`macos` | `darwin` | >
> .bazelrc
> ```
> build:zig_cc --action_env BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1
> ```
>
> This is not documented in bazel, so use at your own peril.
For example, the toolchain `linux_amd64_gnu.2.28` is aliased to ## I want to start using the zig cc toolchain gradually
`x86_64-linux-gnu.2.28`. To find out which toolchains can be registered or
used, run:
You can register your zig cc toolchains under a config in your .bazelrc
``` ```
$ bazel query @zig_sdk//toolchain/... build:zig_cc --extra_toolchains @zig_sdk//toolchain:linux_amd64_gnu.2.19
build:zig_cc --extra_toolchains @zig_sdk//toolchain:linux_arm64_gnu.2.28
build:zig_cc --extra_toolchains @zig_sdk//toolchain:darwin_amd64
build:zig_cc --extra_toolchains @zig_sdk//toolchain:darwin_arm64
``` ```
## Specifying non-default toolchains Then for your builds/tests you need to specify that the `zig_cc` config
should be used:
You may explicitly request Bazel to use a specific toolchain, even though a
different one is registered using `--extra_toolchains <toolchain>` in
`.bazelrc`. For example, if you wish to compile a specific binary (or run
tests) on linux/amd64/musl, you may specify:
``` ```
--extra_toolchains @zig_sdk//toolchain:linux_amd64_musl bazel build --config zig_cc //test/go:go
``` ```
## UBSAN and "SIGILL: Illegal Instruction" You can build a target for a different platform like so:
```
bazel build --config zig_cc \
--platforms @zig_sdk//platform:linux_arm64 \
//test/go:go
```
## I want to use zig to build targets for multiple libc variants
If you have targets that need to be build with different glibc versions or with
musl, you can register a linux toolchain declared under `libc_aware/toolchains`.
It will only be selected when building for a specific libc version. For example
- `libc_aware/toolchain:linux_amd64_gnu.2.19` for `["@platforms//os:linux", "@platforms//cpu:x86_64", "@zig_sdk//libc:gnu.2.19"]`.
- `libc_aware/toolchain:linux_amd64_gnu.2.28` for `["@platforms//os:linux", "@platforms//cpu:x86_64", "@zig_sdk//libc:gnu.2.28"]`.
- `libc_aware/toolchain:x86_64-linux-musl` for `["@platforms//os:linux", "@platforms//cpu:x86_64", "@zig_sdk//libc:musl"]`.
With these toolchains registered, you can build a project for a specific libc
aware platform:
```
$ bazel build --platforms @zig_sdk//libc_aware/platform:linux_amd64_gnu.2.19 //test/go:go
$ bazel build --platforms @zig_sdk//libc_aware/platform:linux_amd64_gnu.2.28 //test/go:go
$ bazel build --platforms @zig_sdk//libc_aware/platform:linux_amd64_musl //test/go:go
```
You can see the list of libc aware toolchains and platforms by running:
```
$ bazel query @zig_sdk//libc_aware/toolchain/...
$ bazel query @zig_sdk//libc_aware/platform/...
```
This is especially useful if you are relying on [transitions][transitions], as
transitioning `extra_platforms` will cause your host tools to be rebuilt with
the specific libc version, which takes time, and your host may not be able to
run them.
The `@zig_sdk//libc:variant` constraint is used to select a matching toolchain.
If you are using your own platform definitions, add a `@zig_sdk//libc:variant`
constraint to them. See the list of available values:
```
$ bazel query "attr(constraint_setting, @zig_sdk//libc:variant, @zig_sdk//...)"
```
`@zig_sdk//libc:unconstrained` is a special value that indicates that no value
for the constraint is specified. The non libc aware linux toolchains are only
compatible with this value to prevent accidental silent fallthrough to them.
# UBSAN and "SIGILL: Illegal Instruction"
`zig cc` differs from "mainstream" compilers by [enabling UBSAN by `zig cc` differs from "mainstream" compilers by [enabling UBSAN by
default][ubsan1]. Which means your program may compile successfully and crash default][ubsan1]. Which means your program may compile successfully and crash
@ -200,3 +301,4 @@ the issues promptly.
[sysroot]: https://github.com/ziglang/zig/issues/10299#issuecomment-989153750 [sysroot]: https://github.com/ziglang/zig/issues/10299#issuecomment-989153750
[ubsan1]: https://github.com/ziglang/zig/issues/4830#issuecomment-605491606 [ubsan1]: https://github.com/ziglang/zig/issues/4830#issuecomment-605491606
[ubsan2]: https://github.com/ziglang/zig/issues/5163 [ubsan2]: https://github.com/ziglang/zig/issues/5163
[transitions]: https://docs.bazel.build/versions/main/skylark/config.html#user-defined-transitions

View File

@ -44,7 +44,14 @@ gazelle_dependencies(go_repository_default_config = "@//:WORKSPACE")
load( load(
"//toolchain:defs.bzl", "//toolchain:defs.bzl",
zig_register_toolchains = "register_toolchains", zig_toolchains = "toolchains",
) )
zig_register_toolchains() zig_toolchains()
register_toolchains(
"@zig_sdk//toolchain:linux_amd64_gnu.2.19",
"@zig_sdk//toolchain:linux_arm64_gnu.2.28",
"@zig_sdk//toolchain:darwin_amd64",
"@zig_sdk//toolchain:darwin_arm64",
)

15
ci/list_toolchains_platforms Executable file
View File

@ -0,0 +1,15 @@
#!/bin/bash
set -euo pipefail
indent() { sed 's/^/ /'; }
echo "Available toolchains:"
bazel query '@zig_sdk//toolchain:*' | indent
echo "Available platforms:"
bazel query '@zig_sdk//platform:*' | indent
echo "Available libc aware toolchains:"
bazel query '@zig_sdk//libc_aware/toolchain:*' | indent
echo "Available libc aware platforms:"
bazel query '@zig_sdk//libc_aware/platform:*' | indent
echo "Available libc variants:"
bazel query "attr(constraint_setting, @zig_sdk//libc:variant, @zig_sdk//...)" | indent

View File

@ -1,8 +1,8 @@
def _platform_transition_impl(settings, attr): def _platform_transition_impl(settings, attr):
_ignore = settings _ignore = settings
return { return {
"//command_line_option:platforms": "@zig_sdk//platform:{}".format(attr.platform), "//command_line_option:platforms": "@zig_sdk{}".format(attr.platform),
"//command_line_option:extra_toolchains": ["@zig_sdk//toolchain:{}".format(tc) for tc in attr.extra_toolchains], "//command_line_option:extra_toolchains": ["@zig_sdk{}".format(tc) for tc in attr.extra_toolchains],
} }
_platform_transition = transition( _platform_transition = transition(

46
test/c/BUILD Normal file
View File

@ -0,0 +1,46 @@
load("@bazel-zig-cc//rules:platform.bzl", "platform_binary")
cc_binary(
name = "which_libc",
srcs = ["main.c"],
target_compatible_with = [
"@platforms//os:linux",
],
)
[
(
platform_binary(
name = "which_libc_{}".format(name),
src = "which_libc",
extra_toolchains = [
# toolchains for specific libc versions
"//libc_aware/toolchain:linux_amd64_gnu.2.19",
"//libc_aware/toolchain:linux_amd64_gnu.2.28",
"//libc_aware/toolchain:linux_amd64_gnu.2.31",
"//libc_aware/toolchain:linux_amd64_musl",
# fallback toolchains
"//toolchain:linux_amd64_gnu.2.19",
"//toolchain:linux_arm64_gnu.2.28",
],
platform = platform,
),
sh_test(
name = "test_libc_{}".format(name),
srcs = ["test.sh"],
data = ["which_libc_{}".format(name)],
env = {
"WANT": want,
"BINARY": "$(location which_libc_{})".format(name),
},
),
)
for name, platform, want in [
("linux_amd64_musl", "//libc_aware/platform:linux_amd64_musl", "non-glibc"),
("linux_amd64_gnu.2.19", "//libc_aware/platform:linux_amd64_gnu.2.19", "glibc_2.19"),
("linux_amd64_gnu.2.28", "//libc_aware/platform:linux_amd64_gnu.2.28", "glibc_2.28"),
("linux_amd64_gnu.2.31", "//libc_aware/platform:linux_amd64_gnu.2.31", "glibc_2.31"),
("linux_amd64", "//platform:linux_amd64", "glibc_2.19"),
("linux_arm64", "//platform:linux_arm64", "glibc_2.28"),
]
]

11
test/c/main.c Normal file
View File

@ -0,0 +1,11 @@
#include <stdio.h>
#include <features.h>
int main() {
#ifdef __GLIBC__
printf("glibc_%d.%d", __GLIBC__, __GLIBC_MINOR__);
#else
puts("non-glibc");
#endif
return 0;
}

16
test/c/test.sh Executable file
View File

@ -0,0 +1,16 @@
#/bin/bash
set -euo pipefail
want=$WANT
binary=$BINARY
got=$($binary)
if [[ "$got" != "$want" ]]; then
echo wanted:
echo \ \ "$want"
echo got:
echo \ \ "$got"
exit 1
fi

View File

@ -26,8 +26,8 @@ go_test(
platform_binary( platform_binary(
name = "go_{}".format(toolchain), name = "go_{}".format(toolchain),
src = "go", src = "go",
extra_toolchains = [toolchain], extra_toolchains = ["//toolchain:{}".format(toolchain)],
platform = platform, platform = "//platform:{}".format(platform),
) )
for platform, toolchain in [ for platform, toolchain in [
("linux_amd64", "linux_amd64_musl"), ("linux_amd64", "linux_amd64_musl"),
@ -42,8 +42,8 @@ go_test(
platform_test( platform_test(
name = "go_test_{}".format(toolchain), name = "go_test_{}".format(toolchain),
src = "go_test", src = "go_test",
extra_toolchains = [toolchain], extra_toolchains = ["//toolchain:{}".format(toolchain)],
platform = platform, platform = "//platform:{}".format(platform),
) )
for platform, toolchain in [ for platform, toolchain in [
("linux_amd64", "linux_amd64_musl"), ("linux_amd64", "linux_amd64_musl"),

View File

@ -4,6 +4,8 @@ package(
default_visibility = ["//visibility:public"], default_visibility = ["//visibility:public"],
) )
declare_files( declare_files(
zig_include_root = {zig_include_root}, zig_include_root = {zig_include_root},
) )

View File

@ -1,4 +1,3 @@
load("@bazel_skylib//lib:shell.bzl", "shell")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "read_user_netrc", "use_netrc") load("@bazel_tools//tools/build_defs/repo:utils.bzl", "read_user_netrc", "use_netrc")
load("@bazel-zig-cc//toolchain/private:defs.bzl", "DEFAULT_INCLUDE_DIRECTORIES", "ZIG_TOOL_PATH", "target_structs") load("@bazel-zig-cc//toolchain/private:defs.bzl", "DEFAULT_INCLUDE_DIRECTORIES", "ZIG_TOOL_PATH", "target_structs")
@ -42,15 +41,15 @@ _HOST_PLATFORM_SHA256 = {
"macos-x86_64": "78220a4460a7c0f563d7365313fcd3ea028ed38166ebac55ba22f17ab6404851", "macos-x86_64": "78220a4460a7c0f563d7365313fcd3ea028ed38166ebac55ba22f17ab6404851",
} }
def register_toolchains( def toolchains(
register = [],
version = _VERSION, version = _VERSION,
url_formats = [URL_FORMAT_JAKSTYS], url_formats = [URL_FORMAT_JAKSTYS],
host_platform_sha256 = _HOST_PLATFORM_SHA256): host_platform_sha256 = _HOST_PLATFORM_SHA256):
""" """
Download zig toolchain and register some. Download zig toolchain and declare bazel toolchains.
@param register registers the given toolchains to the system using The platforms are not registered automatically, that should be done by
native.register_toolchains(). See README for possible choices. the user with register_toolchains() in the WORKSPACE file. See README
for possible choices.
""" """
zig_repository( zig_repository(
name = "zig_sdk", name = "zig_sdk",
@ -65,9 +64,6 @@ def register_toolchains(
}, },
) )
toolchains = ["@zig_sdk//toolchain:%s" % t for t in register]
native.register_toolchains(*toolchains)
ZIG_TOOL_WRAPPER = """#!/bin/bash ZIG_TOOL_WRAPPER = """#!/bin/bash
set -e set -e
@ -95,6 +91,9 @@ _ZIG_TOOLS = [
"wasm-ld", # WebAssembly "wasm-ld", # WebAssembly
] ]
def _quote(s):
return "'" + s.replace("'", "'\\''") + "'"
def _zig_repository_impl(repository_ctx): def _zig_repository_impl(repository_ctx):
arch = repository_ctx.os.arch arch = repository_ctx.os.arch
if arch == "amd64": if arch == "amd64":
@ -139,34 +138,28 @@ def _zig_repository_impl(repository_ctx):
content = _fcntl_h, content = _fcntl_h,
) )
repository_ctx.symlink( for dest, src in {
Label("//toolchain/platform:BUILD"), "platform/BUILD": "//toolchain/platform:BUILD",
"platform/BUILD", "toolchain/BUILD": "//toolchain/toolchain:BUILD",
) "libc/BUILD": "//toolchain/libc:BUILD",
"libc_aware/platform/BUILD": "//toolchain/libc_aware/platform:BUILD",
"libc_aware/toolchain/BUILD": "//toolchain/libc_aware/toolchain:BUILD",
}.items():
repository_ctx.symlink(Label(src), dest)
repository_ctx.template( for dest, src in {
"BUILD", "BUILD": "//toolchain:BUILD.sdk.bazel",
Label("//toolchain:BUILD.sdk.bazel"), "private/BUILD": "//toolchain/private:BUILD.sdk.bazel",
executable = False, }.items():
substitutions = { repository_ctx.template(
"{zig_include_root}": shell.quote(zig_include_root), dest,
}, Label(src),
) executable = False,
substitutions = {
repository_ctx.symlink( "{absolute_path}": _quote(str(repository_ctx.path(""))),
Label("//toolchain/toolchain:BUILD"), "{zig_include_root}": _quote(zig_include_root),
"toolchain/BUILD", },
) )
repository_ctx.template(
"private/BUILD",
Label("//toolchain/private:BUILD.sdk.bazel"),
executable = False,
substitutions = {
"{absolute_path}": shell.quote(str(repository_ctx.path(""))),
"{zig_include_root}": shell.quote(zig_include_root),
},
)
zig_repository = repository_rule( zig_repository = repository_rule(
attrs = { attrs = {

17
toolchain/libc/BUILD Normal file
View File

@ -0,0 +1,17 @@
load("@bazel-zig-cc//toolchain/libc:defs.bzl", "declare_libcs")
package(
default_visibility = ["//visibility:public"],
)
constraint_setting(
name = "variant",
default_constraint_value = "unconstrained",
)
constraint_value(
name = "unconstrained",
constraint_setting = "variant",
)
declare_libcs()

8
toolchain/libc/defs.bzl Normal file
View File

@ -0,0 +1,8 @@
load("@bazel-zig-cc//toolchain/private:defs.bzl", "LIBCS")
def declare_libcs():
for libc in LIBCS:
native.constraint_value(
name = libc,
constraint_setting = "variant",
)

View File

@ -0,0 +1,7 @@
load("@bazel-zig-cc//toolchain/platform:defs.bzl", "declare_libc_aware_platforms")
package(
default_visibility = ["//visibility:public"],
)
declare_libc_aware_platforms()

View File

@ -0,0 +1,7 @@
load("@bazel-zig-cc//toolchain/toolchain:defs.bzl", "declare_libc_aware_toolchains")
package(
default_visibility = ["//visibility:public"],
)
declare_libc_aware_toolchains()

View File

@ -1,3 +1,7 @@
load("@bazel-zig-cc//toolchain/platform:defs.bzl", "declare_platforms") load("@bazel-zig-cc//toolchain/platform:defs.bzl", "declare_platforms")
package(
default_visibility = ["//visibility:public"],
)
declare_platforms() declare_platforms()

View File

@ -1,17 +1,40 @@
load("@bazel-zig-cc//toolchain/private:defs.bzl", "LIBCS")
_CPUS = (("x86_64", "amd64"), ("aarch64", "arm64"))
def declare_platforms(): def declare_platforms():
# create @zig_sdk//{os}_{arch}_platform entries with zig and go conventions # create @zig_sdk//{os}_{arch}_platform entries with zig and go conventions
for zigcpu, gocpu in (("x86_64", "amd64"), ("aarch64", "arm64")): for zigcpu, gocpu in _CPUS:
for bzlos, oss in {"linux": ["linux"], "macos": ["macos", "darwin"]}.items(): for bzlos, oss in {"linux": ["linux"], "macos": ["macos", "darwin"]}.items():
for os in oss: for os in oss:
constraint_values = [ declare_platform(gocpu, zigcpu, bzlos, os)
"@platforms//os:{}".format(bzlos),
"@platforms//cpu:{}".format(zigcpu), def declare_libc_aware_platforms():
] # create @zig_sdk//{os}_{arch}_platform entries with zig and go conventions
native.platform( # with libc specified
name = "{os}_{zigcpu}".format(os = os, zigcpu = zigcpu), for zigcpu, gocpu in _CPUS:
constraint_values = constraint_values, for libc in LIBCS:
) declare_platform(
native.platform( gocpu,
name = "{os}_{gocpu}".format(os = os, gocpu = gocpu), zigcpu,
constraint_values = constraint_values, "linux",
) "linux",
suffix = "_{}".format(libc),
extra_constraints = ["@zig_sdk//libc:{}".format(libc)],
)
def declare_platform(gocpu, zigcpu, bzlos, os, suffix = "", extra_constraints = []):
constraint_values = [
"@platforms//os:{}".format(bzlos),
"@platforms//cpu:{}".format(zigcpu),
] + extra_constraints
native.platform(
name = "{os}_{zigcpu}{suffix}".format(os = os, zigcpu = zigcpu, suffix = suffix),
constraint_values = constraint_values,
)
native.platform(
name = "{os}_{gocpu}{suffix}".format(os = os, gocpu = gocpu, suffix = suffix),
constraint_values = constraint_values,
)

View File

@ -28,6 +28,8 @@ _GLIBCS = [
"2.34", "2.34",
] ]
LIBCS = ["musl", "gnu"] + ["gnu.{}".format(glibc) for glibc in _GLIBCS]
def target_structs(): def target_structs():
ret = [] ret = []
for zigcpu, gocpu in (("x86_64", "amd64"), ("aarch64", "arm64")): for zigcpu, gocpu in (("x86_64", "amd64"), ("aarch64", "arm64")):
@ -100,6 +102,7 @@ def _target_linux_gnu(gocpu, zigcpu, glibc_version = ""):
"@platforms//os:linux", "@platforms//os:linux",
"@platforms//cpu:{}".format(zigcpu), "@platforms//cpu:{}".format(zigcpu),
], ],
libc_constraint = "@zig_sdk//libc:{}".format(glibc_suffix),
tool_paths = {"ld": "ld.lld"}, tool_paths = {"ld": "ld.lld"},
) )
@ -120,5 +123,6 @@ def _target_linux_musl(gocpu, zigcpu):
"@platforms//os:linux", "@platforms//os:linux",
"@platforms//cpu:{}".format(zigcpu), "@platforms//cpu:{}".format(zigcpu),
], ],
libc_constraint = "@zig_sdk//libc:musl",
tool_paths = {"ld": "ld.lld"}, tool_paths = {"ld": "ld.lld"},
) )

View File

@ -1,25 +1,46 @@
load("@bazel-zig-cc//toolchain/private:defs.bzl", "DEFAULT_INCLUDE_DIRECTORIES", "ZIG_TOOL_PATH", "target_structs") load("@bazel-zig-cc//toolchain/private:defs.bzl", "target_structs")
def declare_toolchains(): def declare_toolchains():
for target_config in target_structs(): for target_config in target_structs():
gotarget = target_config.gotarget gotarget = target_config.gotarget
zigtarget = target_config.zigtarget zigtarget = target_config.zigtarget
# register two kinds of toolchain targets: Go and Zig conventions. # if the toolchain is libc aware, create two variants for it: one that
# Go convention: amd64/arm64, linux/darwin # is only selected if libc is not expicitly set and another one that is
native.toolchain( # only selected if the specific libc variant is selected.
name = gotarget, extra_constraints = []
exec_compatible_with = None, if hasattr(target_config, "libc_constraint"):
target_compatible_with = target_config.constraint_values, extra_constraints = ["@zig_sdk//libc:unconstrained"]
toolchain = "@zig_sdk//private:%s_cc" % zigtarget,
toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
)
# Zig convention: x86_64/aarch64, linux/macos _declare_toolchain(gotarget, zigtarget, target_config.constraint_values + extra_constraints)
native.toolchain(
name = zigtarget, def declare_libc_aware_toolchains():
exec_compatible_with = None, for target_config in target_structs():
target_compatible_with = target_config.constraint_values, gotarget = target_config.gotarget
toolchain = "@zig_sdk//private:%s_cc" % zigtarget, zigtarget = target_config.zigtarget
toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
) # if the toolchain is libc aware, create two variants for it: one that
# is only selected if libc is not expicitly set and another one that is
# only selected if the specific libc variant is selected.
if hasattr(target_config, "libc_constraint"):
_declare_toolchain(gotarget, zigtarget, target_config.constraint_values + [target_config.libc_constraint])
def _declare_toolchain(gotarget, zigtarget, target_compatible_with):
# register two kinds of toolchain targets: Go and Zig conventions.
# Go convention: amd64/arm64, linux/darwin
native.toolchain(
name = gotarget,
exec_compatible_with = None,
target_compatible_with = target_compatible_with,
toolchain = "@zig_sdk//private:%s_cc" % zigtarget,
toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
)
# Zig convention: x86_64/aarch64, linux/macos
native.toolchain(
name = zigtarget,
exec_compatible_with = None,
target_compatible_with = target_compatible_with,
toolchain = "@zig_sdk//private:%s_cc" % zigtarget,
toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
)