diff --git a/toolchain/defs.bzl b/toolchain/defs.bzl index 61e099f..084af86 100644 --- a/toolchain/defs.bzl +++ b/toolchain/defs.bzl @@ -1,23 +1,7 @@ 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:utils.bzl", "read_user_netrc", "use_netrc") -load(":zig_toolchain.bzl", "zig_cc_toolchain_config") - -DEFAULT_TOOL_PATHS = { - "ar": "ar", - "gcc": "c++", # https://github.com/bazelbuild/bazel/issues/4644 - "cpp": "/usr/bin/false", - "gcov": "/usr/bin/false", - "nm": "/usr/bin/false", - "objdump": "/usr/bin/false", - "strip": "/usr/bin/false", -}.items() - -DEFAULT_INCLUDE_DIRECTORIES = [ - "include", - "libcxx/include", - "libcxxabi/include", -] +load("@bazel-zig-cc//toolchain/private:defs.bzl", "DEFAULT_INCLUDE_DIRECTORIES", "ZIG_TOOL_PATH", "target_structs") _fcntl_map = """ GLIBC_2.2.5 { @@ -32,114 +16,6 @@ __asm__(".symver fcntl64, fcntl@GLIBC_2.2.5"); #endif """ -# Zig supports even older glibcs than defined below, but we have tested only -# down to 2.17. -# $ zig targets | jq -r '.glibc[]' | sort -V -_GLIBCS = [ - "2.17", - "2.18", - "2.19", - "2.22", - "2.23", - "2.24", - "2.25", - "2.26", - "2.27", - "2.28", - "2.29", - "2.30", - "2.31", - "2.32", - "2.33", - "2.34", -] - -def _target_darwin(gocpu, zigcpu): - min_os = "10" - if zigcpu == "aarch64": - min_os = "11" - return struct( - gotarget = "darwin_{}".format(gocpu), - zigtarget = "{}-macos-gnu".format(zigcpu), - includes = [ - "libunwind/include", - # TODO: Define a toolchain for each minimum OS version - "libc/include/{}-macos.{}-gnu".format(zigcpu, min_os), - "libc/include/any-macos.{}-any".format(min_os), - "libc/include/any-macos-any", - ], - linkopts = [], - copts = [], - bazel_target_cpu = "darwin", - constraint_values = [ - "@platforms//os:macos", - "@platforms//cpu:{}".format(zigcpu), - ], - tool_paths = {"ld": "ld64.lld"}, - ) - -def _target_linux_gnu(gocpu, zigcpu, glibc_version = ""): - glibc_suffix = "gnu" - if glibc_version != "": - glibc_suffix = "gnu.{}".format(glibc_version) - - # https://github.com/ziglang/zig/issues/5882#issuecomment-888250676 - # fcntl_hack is only required for glibc 2.27 or less. We assume that - # glibc_version == "" (autodetect) is running a recent glibc version, thus - # adding this hack only when glibc is explicitly 2.27 or lower. - fcntl_hack = False - if glibc_version == "": - # zig doesn't reliably detect the glibc version, so - # often falls back to 2.17; the hack should be included. - # https://github.com/ziglang/zig/issues/6469 - fcntl_hack = True - else: - # hack is required for 2.27 or less. - fcntl_hack = glibc_version < "2.28" - - return struct( - gotarget = "linux_{}_{}".format(gocpu, glibc_suffix), - zigtarget = "{}-linux-{}".format(zigcpu, glibc_suffix), - includes = [ - "libunwind/include", - "libc/include/generic-glibc", - "libc/include/any-linux-any", - "libc/include/{}-linux-gnu".format(zigcpu), - "libc/include/{}-linux-any".format(zigcpu), - ] + (["libc/include/x86-linux-any"] if zigcpu == "x86_64" else []), - toplevel_include = ["glibc-hacks"] if fcntl_hack else [], - compiler_extra_includes = ["glibc-hacks/glibchack-fcntl.h"] if fcntl_hack else [], - linker_version_scripts = ["glibc-hacks/fcntl.map"] if fcntl_hack else [], - linkopts = ["-lc++", "-lc++abi"], - copts = [], - bazel_target_cpu = "k8", - constraint_values = [ - "@platforms//os:linux", - "@platforms//cpu:{}".format(zigcpu), - ], - tool_paths = {"ld": "ld.lld"}, - ) - -def _target_linux_musl(gocpu, zigcpu): - return struct( - gotarget = "linux_{}_musl".format(gocpu), - zigtarget = "{}-linux-musl".format(zigcpu), - includes = [ - "libc/include/generic-musl", - "libc/include/any-linux-any", - "libc/include/{}-linux-musl".format(zigcpu), - "libc/include/{}-linux-any".format(zigcpu), - ] + (["libc/include/x86-linux-any"] if zigcpu == "x86_64" else []), - linkopts = ["-s", "-w"], - copts = ["-D_LIBCPP_HAS_MUSL_LIBC", "-D_LIBCPP_HAS_THREAD_API_PTHREAD"], - bazel_target_cpu = "k8", - constraint_values = [ - "@platforms//os:linux", - "@platforms//cpu:{}".format(zigcpu), - ], - tool_paths = {"ld": "ld.lld"}, - ) - # Official recommended version. Should use this when we have a usable release. URL_FORMAT_RELEASE = "https://ziglang.org/download/{version}/zig-{host_platform}-{version}.tar.xz" @@ -192,7 +68,6 @@ def register_toolchains( toolchains = ["@zig_sdk//:toolchain:%s" % t for t in register] native.register_toolchains(*toolchains) -ZIG_TOOL_PATH = "tools/{zig_tool}" ZIG_TOOL_WRAPPER = """#!/bin/bash set -e @@ -297,14 +172,7 @@ zig_repository = repository_rule( implementation = _zig_repository_impl, ) -def _target_structs(): - ret = [] - for zigcpu, gocpu in (("x86_64", "amd64"), ("aarch64", "arm64")): - ret.append(_target_darwin(gocpu, zigcpu)) - ret.append(_target_linux_musl(gocpu, zigcpu)) - for glibc in [""] + _GLIBCS: - ret.append(_target_linux_gnu(gocpu, zigcpu, glibc)) - return ret + def filegroup(name, **kwargs): native.filegroup(name = name, **kwargs) @@ -317,84 +185,8 @@ def declare_files(zig_include_root): lazy_filegroups = {} - for target_config in _target_structs(): + for target_config in target_structs(): for d in DEFAULT_INCLUDE_DIRECTORIES + target_config.includes: d = zig_include_root + d if d not in lazy_filegroups: lazy_filegroups[d] = filegroup(name = d, srcs = native.glob([d + "/**"])) - - -def declare_toolchains(absolute_path, zig_include_root): - for target_config in _target_structs(): - gotarget = target_config.gotarget - zigtarget = target_config.zigtarget - - cxx_builtin_include_directories = [] - for d in DEFAULT_INCLUDE_DIRECTORIES + target_config.includes: - d = zig_include_root + d - cxx_builtin_include_directories.append(absolute_path + "/" + d) - for d in getattr(target_config, "toplevel_include", []): - cxx_builtin_include_directories.append(absolute_path + "/" + d) - - absolute_tool_paths = {} - for name, path in target_config.tool_paths.items() + DEFAULT_TOOL_PATHS: - if path[0] == "/": - absolute_tool_paths[name] = path - continue - tool_path = ZIG_TOOL_PATH.format(zig_tool = path) - absolute_tool_paths[name] = "%s/%s" % (absolute_path, tool_path) - - linkopts = target_config.linkopts - copts = target_config.copts - for s in getattr(target_config, "linker_version_scripts", []): - linkopts = linkopts + ["-Wl,--version-script,%s/%s" % (absolute_path, s)] - for incl in getattr(target_config, "compiler_extra_includes", []): - copts = copts + ["-include", absolute_path + "/" + incl] - - zig_cc_toolchain_config( - name = zigtarget + "_cc_config", - target = zigtarget, - tool_paths = absolute_tool_paths, - cxx_builtin_include_directories = cxx_builtin_include_directories, - copts = copts, - linkopts = linkopts, - target_cpu = target_config.bazel_target_cpu, - target_system_name = "unknown", - target_libc = "unknown", - compiler = "clang", - abi_version = "unknown", - abi_libc_version = "unknown", - ) - - native.cc_toolchain( - name = zigtarget + "_cc", - toolchain_identifier = zigtarget + "-toolchain", - toolchain_config = ":%s_cc_config" % zigtarget, - all_files = "@zig_sdk//:zig", - ar_files = "@zig_sdk//:zig", - compiler_files = "@zig_sdk//:zig", - linker_files = "@zig_sdk//:zig", - dwp_files = "@zig_sdk//:empty", - objcopy_files = "@zig_sdk//:empty", - strip_files = "@zig_sdk//:empty", - supports_param_files = 0, - ) - - # 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_config.constraint_values, - toolchain = ":%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_config.constraint_values, - toolchain = ":%s_cc" % zigtarget, - toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", - ) diff --git a/toolchain/private/BUILD b/toolchain/private/BUILD new file mode 100644 index 0000000..e69de29 diff --git a/toolchain/private/defs.bzl b/toolchain/private/defs.bzl new file mode 100644 index 0000000..8380071 --- /dev/null +++ b/toolchain/private/defs.bzl @@ -0,0 +1,124 @@ +DEFAULT_INCLUDE_DIRECTORIES = [ + "include", + "libcxx/include", + "libcxxabi/include", +] + +ZIG_TOOL_PATH = "tools/{zig_tool}" + +# Zig supports even older glibcs than defined below, but we have tested only +# down to 2.17. +# $ zig targets | jq -r '.glibc[]' | sort -V +_GLIBCS = [ + "2.17", + "2.18", + "2.19", + "2.22", + "2.23", + "2.24", + "2.25", + "2.26", + "2.27", + "2.28", + "2.29", + "2.30", + "2.31", + "2.32", + "2.33", + "2.34", +] + +def target_structs(): + ret = [] + for zigcpu, gocpu in (("x86_64", "amd64"), ("aarch64", "arm64")): + ret.append(_target_darwin(gocpu, zigcpu)) + ret.append(_target_linux_musl(gocpu, zigcpu)) + for glibc in [""] + _GLIBCS: + ret.append(_target_linux_gnu(gocpu, zigcpu, glibc)) + return ret + +def _target_darwin(gocpu, zigcpu): + min_os = "10" + if zigcpu == "aarch64": + min_os = "11" + return struct( + gotarget = "darwin_{}".format(gocpu), + zigtarget = "{}-macos-gnu".format(zigcpu), + includes = [ + "libunwind/include", + # TODO: Define a toolchain for each minimum OS version + "libc/include/{}-macos.{}-gnu".format(zigcpu, min_os), + "libc/include/any-macos.{}-any".format(min_os), + "libc/include/any-macos-any", + ], + linkopts = [], + copts = [], + bazel_target_cpu = "darwin", + constraint_values = [ + "@platforms//os:macos", + "@platforms//cpu:{}".format(zigcpu), + ], + tool_paths = {"ld": "ld64.lld"}, + ) + +def _target_linux_gnu(gocpu, zigcpu, glibc_version = ""): + glibc_suffix = "gnu" + if glibc_version != "": + glibc_suffix = "gnu.{}".format(glibc_version) + + # https://github.com/ziglang/zig/issues/5882#issuecomment-888250676 + # fcntl_hack is only required for glibc 2.27 or less. We assume that + # glibc_version == "" (autodetect) is running a recent glibc version, thus + # adding this hack only when glibc is explicitly 2.27 or lower. + fcntl_hack = False + if glibc_version == "": + # zig doesn't reliably detect the glibc version, so + # often falls back to 2.17; the hack should be included. + # https://github.com/ziglang/zig/issues/6469 + fcntl_hack = True + else: + # hack is required for 2.27 or less. + fcntl_hack = glibc_version < "2.28" + + return struct( + gotarget = "linux_{}_{}".format(gocpu, glibc_suffix), + zigtarget = "{}-linux-{}".format(zigcpu, glibc_suffix), + includes = [ + "libunwind/include", + "libc/include/generic-glibc", + "libc/include/any-linux-any", + "libc/include/{}-linux-gnu".format(zigcpu), + "libc/include/{}-linux-any".format(zigcpu), + ] + (["libc/include/x86-linux-any"] if zigcpu == "x86_64" else []), + toplevel_include = ["glibc-hacks"] if fcntl_hack else [], + compiler_extra_includes = ["glibc-hacks/glibchack-fcntl.h"] if fcntl_hack else [], + linker_version_scripts = ["glibc-hacks/fcntl.map"] if fcntl_hack else [], + linkopts = ["-lc++", "-lc++abi"], + copts = [], + bazel_target_cpu = "k8", + constraint_values = [ + "@platforms//os:linux", + "@platforms//cpu:{}".format(zigcpu), + ], + tool_paths = {"ld": "ld.lld"}, + ) + +def _target_linux_musl(gocpu, zigcpu): + return struct( + gotarget = "linux_{}_musl".format(gocpu), + zigtarget = "{}-linux-musl".format(zigcpu), + includes = [ + "libc/include/generic-musl", + "libc/include/any-linux-any", + "libc/include/{}-linux-musl".format(zigcpu), + "libc/include/{}-linux-any".format(zigcpu), + ] + (["libc/include/x86-linux-any"] if zigcpu == "x86_64" else []), + linkopts = ["-s", "-w"], + copts = ["-D_LIBCPP_HAS_MUSL_LIBC", "-D_LIBCPP_HAS_THREAD_API_PTHREAD"], + bazel_target_cpu = "k8", + constraint_values = [ + "@platforms//os:linux", + "@platforms//cpu:{}".format(zigcpu), + ], + tool_paths = {"ld": "ld.lld"}, + ) diff --git a/toolchain/toolchain/BUILD.sdk.bazel b/toolchain/toolchain/BUILD.sdk.bazel index 4b505dc..7cbca73 100644 --- a/toolchain/toolchain/BUILD.sdk.bazel +++ b/toolchain/toolchain/BUILD.sdk.bazel @@ -1,4 +1,4 @@ -load("@bazel-zig-cc//toolchain:defs.bzl", "declare_toolchains") +load("@bazel-zig-cc//toolchain/toolchain:defs.bzl", "declare_toolchains") package( default_visibility = ["//visibility:public"], diff --git a/toolchain/toolchain/defs.bzl b/toolchain/toolchain/defs.bzl new file mode 100644 index 0000000..1b0c087 --- /dev/null +++ b/toolchain/toolchain/defs.bzl @@ -0,0 +1,87 @@ +load("@bazel-zig-cc//toolchain:zig_toolchain.bzl", "zig_cc_toolchain_config") +load("@bazel-zig-cc//toolchain/private:defs.bzl", "DEFAULT_INCLUDE_DIRECTORIES", "ZIG_TOOL_PATH", "target_structs") + +DEFAULT_TOOL_PATHS = { + "ar": "ar", + "gcc": "c++", # https://github.com/bazelbuild/bazel/issues/4644 + "cpp": "/usr/bin/false", + "gcov": "/usr/bin/false", + "nm": "/usr/bin/false", + "objdump": "/usr/bin/false", + "strip": "/usr/bin/false", +}.items() + +def declare_toolchains(absolute_path, zig_include_root): + for target_config in target_structs(): + gotarget = target_config.gotarget + zigtarget = target_config.zigtarget + + cxx_builtin_include_directories = [] + for d in DEFAULT_INCLUDE_DIRECTORIES + target_config.includes: + d = zig_include_root + d + cxx_builtin_include_directories.append(absolute_path + "/" + d) + for d in getattr(target_config, "toplevel_include", []): + cxx_builtin_include_directories.append(absolute_path + "/" + d) + + absolute_tool_paths = {} + for name, path in target_config.tool_paths.items() + DEFAULT_TOOL_PATHS: + if path[0] == "/": + absolute_tool_paths[name] = path + continue + tool_path = ZIG_TOOL_PATH.format(zig_tool = path) + absolute_tool_paths[name] = "%s/%s" % (absolute_path, tool_path) + + linkopts = target_config.linkopts + copts = target_config.copts + for s in getattr(target_config, "linker_version_scripts", []): + linkopts = linkopts + ["-Wl,--version-script,%s/%s" % (absolute_path, s)] + for incl in getattr(target_config, "compiler_extra_includes", []): + copts = copts + ["-include", absolute_path + "/" + incl] + + zig_cc_toolchain_config( + name = zigtarget + "_cc_config", + target = zigtarget, + tool_paths = absolute_tool_paths, + cxx_builtin_include_directories = cxx_builtin_include_directories, + copts = copts, + linkopts = linkopts, + target_cpu = target_config.bazel_target_cpu, + target_system_name = "unknown", + target_libc = "unknown", + compiler = "clang", + abi_version = "unknown", + abi_libc_version = "unknown", + ) + + native.cc_toolchain( + name = zigtarget + "_cc", + toolchain_identifier = zigtarget + "-toolchain", + toolchain_config = ":%s_cc_config" % zigtarget, + all_files = "@zig_sdk//:zig", + ar_files = "@zig_sdk//:zig", + compiler_files = "@zig_sdk//:zig", + linker_files = "@zig_sdk//:zig", + dwp_files = "@zig_sdk//:empty", + objcopy_files = "@zig_sdk//:empty", + strip_files = "@zig_sdk//:empty", + supports_param_files = 0, + ) + + # 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_config.constraint_values, + toolchain = ":%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_config.constraint_values, + toolchain = ":%s_cc" % zigtarget, + toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", + )