diff --git a/.build.yml b/.build.yml index 4408cf4..df729c5 100644 --- a/.build.yml +++ b/.build.yml @@ -9,6 +9,9 @@ environment: tasks: - setup: | sudo apt-get purge gcc -y && sudo apt-get autoremove -y + - test_list_toolchains: | + cd bazel-zig-cc; . .envrc; echo "Available toolchains:" + bazel query @zig_sdk//... | sed -En '/.*_toolchain$/ s/.*:(.*)_toolchain$/\1/p' - test_default: | cd bazel-zig-cc; . .envrc; ./build-and-file \ //test:hello | \ diff --git a/README.md b/README.md index c2b2ce7..e3c3b6d 100644 --- a/README.md +++ b/README.md @@ -2,17 +2,12 @@ # Bazel zig cc toolchain -This is an early stage zig-cc toolchain that can cross-compile C/C++ programs -(including cgo) to these os/archs: - -- amd64-linux-gnu.2.19 -- amd64-linux-musl -- arm64-linux-gnu.2.28 -- arm64-linux-musl -- amd64-macos -- arm64-macos - -... and more. +This is a C/C++ toolchain that can (cross-)compile C/C++ programs. It contains +clang-12, musl, glibc (versions 2-2.33, selectable), all in a ~40MB package. +Read +[here](https://andrewkelley.me/post/zig-cc-powerful-drop-in-replacement-gcc-clang.html) +about zig-cc; the rest of the README will present how to use this toolchain +from Bazel. # Usage @@ -30,11 +25,34 @@ http_archive( load("@bazel-zig-cc//toolchain:defs.bzl", zig_register_toolchains = "register_toolchains") -zig_register_toolchains() +zig_register_toolchains(["x86_64-linux-gnu.2.28", "x86_64-macos-gnu"]) ``` -This will register the "default" toolchains. Look into `register_toolchains` on -which parameters it accepts. +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 is aliased to +`x86_64-linux-gnu.2.28`. .2.28`. + +To find out which toolchains can be registered or used, run this: + +``` +$ bazel query @zig_sdk//... | sed -En '/.*_toolchain$/ s/.*:(.*)_toolchain$/\1/p' +``` + +This is still work in progress; please read [#Known Issues] before using. # Testing @@ -81,11 +99,46 @@ how CI does it. # Known Issues -- [ziglang/zig #9485 glibc 2.27 or older: fcntl64 not found, but zig's glibc headers refer it](https://github.com/ziglang/zig/issues/9485) -- [ziglang/zig #9431 FileNotFound when compiling macos](https://github.com/ziglang/zig/issues/9431) -- [rules/go #2894 Per-arch_target linker flags](https://github.com/bazelbuild/rules_go/issues/2894) +## Parallel `zig c++` invocations may fail -Closed issues: +Task: [ziglang/zig #9431 FileNotFound when compiling macos](https://github.com/ziglang/zig/issues/9431) + +Background: there is a race when calling `zig c++`, which Bazel does a lot. +This may fail compilation. Yours truly only reproduced it on macos with a cold +cache. Based on that, a workaround in the toolchain exists, named +`speed_first_safety_later`. The possible values are `auto` (default), `yes`, +`no`. + +## glibc 2.27 or older + +Task: [ziglang/zig #9485 glibc 2.27 or older: fcntl64 not found, but zig's glibc headers refer it](https://github.com/ziglang/zig/issues/9485) + +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 or ensure it +(yet). + +## cgo for darwin (macos) + +Task: [rules/go #2894 Per-arch_target linker flags](https://github.com/bazelbuild/rules_go/issues/2894) + +Background: this toolchain needs an extra step to be used for Darwin (macos) +targets. Specifically, one needs to add `gc_linkopts` for every `go_binary`: + +``` +go_binary( + <...> + gc_linkopts = select({ + "@platforms//os:macos": ["-s", "-w", "-buildmode=pie"], + "//conditions:default": [], + }), +) +``` + +Until the linked task is resolved, this needs to be done for every `go_binary` +that is meant to be compiled to Darwin. + +# Closed issues - [ziglang/zig #9139 zig c++ hanging when compiling in parallel](https://github.com/ziglang/zig/issues/9139) (CLOSED) - [golang/go #46644 cmd/link: with CC=zig: SIGSERV when cross-compiling to darwin/amd64](https://github.com/golang/go/issues/46644) (CLOSED) diff --git a/WORKSPACE b/WORKSPACE index 9ecb804..21a979c 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -53,4 +53,11 @@ load( zig_register_toolchains = "register_toolchains", ) -zig_register_toolchains(speed_first_safety_later="auto") +_REGISTER_TOOLCHAINS = [ + "linux_arm64_gnu.2.28", + "linux_amd64_gnu.2.19", + "darwin_amd64", + "darwin_arm64", +] + +zig_register_toolchains(register = _REGISTER_TOOLCHAINS) diff --git a/toolchain/defs.bzl b/toolchain/defs.bzl index 5f800f4..fe396d9 100644 --- a/toolchain/defs.bzl +++ b/toolchain/defs.bzl @@ -56,13 +56,6 @@ _GLIBCS = [ "2.33", ] -DEFAULT_TOOLCHAINS = [ - "linux_arm64_gnu.2.28", # There is a problem with fcntl on arm64, this is WIP - "linux_amd64_gnu.2.19", # Debian Jessie amd64 - "darwin_amd64", - "darwin_arm64", -] - def _target_darwin(gocpu, zigcpu): return struct( gotarget = "darwin_{}".format(gocpu), @@ -146,8 +139,16 @@ def _target_linux_musl(gocpu, zigcpu): ) def register_toolchains( - register = DEFAULT_TOOLCHAINS, + register = [], speed_first_safety_later = "auto"): + """ + Download zig toolchain and register some. + @param register registers the given toolchains to the system using + native.register_toolchains(). See README for possible choices. + @param speed_first_safety_later is a workaround for + https://github.com/ziglang/zig/issues/9431 + """ + zig_repository( name = "zig_sdk", # Pre-release: @@ -311,10 +312,6 @@ def zig_build_macro(absolute_path, zig_include_root): for target_config in _target_structs(): gotarget = target_config.gotarget zigtarget = target_config.zigtarget - native.platform( - name = gotarget, - constraint_values = target_config.constraint_values, - ) cxx_builtin_include_directories = [] for d in DEFAULT_INCLUDE_DIRECTORIES + target_config.includes: @@ -341,7 +338,7 @@ def zig_build_macro(absolute_path, zig_include_root): copts = copts + ["-include", absolute_path + "/" + incl] zig_cc_toolchain_config( - name = zigtarget + "_cc_toolchain_config", + name = zigtarget + "_toolchain_cc_config", target = zigtarget, tool_paths = absolute_tool_paths, cxx_builtin_include_directories = cxx_builtin_include_directories, @@ -356,9 +353,9 @@ def zig_build_macro(absolute_path, zig_include_root): ) native.cc_toolchain( - name = zigtarget + "_cc_toolchain", + name = zigtarget + "_toolchain_cc", toolchain_identifier = zigtarget + "-toolchain", - toolchain_config = ":%s_cc_toolchain_config" % zigtarget, + toolchain_config = ":%s_toolchain_cc_config" % zigtarget, all_files = ":zig", ar_files = ":zig", compiler_files = ":zig", @@ -375,7 +372,7 @@ def zig_build_macro(absolute_path, zig_include_root): name = gotarget + "_toolchain", exec_compatible_with = None, target_compatible_with = target_config.constraint_values, - toolchain = ":%s_cc_toolchain" % zigtarget, + toolchain = ":%s_toolchain_cc" % zigtarget, toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", ) @@ -384,6 +381,6 @@ def zig_build_macro(absolute_path, zig_include_root): name = zigtarget + "_toolchain", exec_compatible_with = None, target_compatible_with = target_config.constraint_values, - toolchain = ":%s_cc_toolchain" % zigtarget, + toolchain = ":%s_toolchain_cc" % zigtarget, toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", )