From 579774a6c9917e0432fd86d696b4da44b0e37e0d Mon Sep 17 00:00:00 2001 From: Thulio Ferraz Assis <3149049+f0rmiga@users.noreply.github.com> Date: Fri, 18 Mar 2022 12:36:47 -0700 Subject: [PATCH] feat: gcc toolchain (#1) * feat: gcc toolchain Signed-off-by: Thulio Ferraz Assis <3149049+f0rmiga@users.noreply.github.com> * fix: generated header * fix: set -lstdc++ by default Many libraries under Bazel rely on this behaviour by default. Signed-off-by: Thulio Ferraz Assis <3149049+f0rmiga@users.noreply.github.com> * fix: set -I and -isystem flags Signed-off-by: Thulio Ferraz Assis <3149049+f0rmiga@users.noreply.github.com> * feat: switch to use bootlin pre-compiled tools Signed-off-by: Thulio Ferraz Assis <3149049+f0rmiga@users.noreply.github.com> * feat: explicit search dirs Signed-off-by: Thulio Ferraz Assis <3149049+f0rmiga@users.noreply.github.com> * refactor: reduce hops and expose more attrs Signed-off-by: Thulio Ferraz Assis <3149049+f0rmiga@users.noreply.github.com> * fix: use header substitution Signed-off-by: Thulio Ferraz Assis <3149049+f0rmiga@users.noreply.github.com> --- .bazelrc | 6 + .gitignore | 1 + BUILD.bazel | 0 WORKSPACE | 32 ++ examples/hello_world_c/BUILD.bazel | 4 + examples/hello_world_c/main.c | 7 + examples/hello_world_cpp/BUILD.bazel | 5 + examples/hello_world_cpp/main.cpp | 7 + toolchain/BUILD.bazel | 0 toolchain/config.bzl.tpl | 422 +++++++++++++++++++++++++++ toolchain/defs.bzl | 140 +++++++++ toolchain/toolchain.BUILD.bazel.tpl | 181 ++++++++++++ 12 files changed, 805 insertions(+) create mode 100644 .bazelrc create mode 100644 .gitignore create mode 100644 BUILD.bazel create mode 100644 WORKSPACE create mode 100644 examples/hello_world_c/BUILD.bazel create mode 100644 examples/hello_world_c/main.c create mode 100644 examples/hello_world_cpp/BUILD.bazel create mode 100644 examples/hello_world_cpp/main.cpp create mode 100644 toolchain/BUILD.bazel create mode 100644 toolchain/config.bzl.tpl create mode 100644 toolchain/defs.bzl create mode 100644 toolchain/toolchain.BUILD.bazel.tpl diff --git a/.bazelrc b/.bazelrc new file mode 100644 index 0000000..04f380e --- /dev/null +++ b/.bazelrc @@ -0,0 +1,6 @@ +build --extra_toolchains=@gcc_toolchain//:toolchain --incompatible_enable_cc_toolchain_resolution + +test --sandbox_default_allow_network=false +test --test_output=errors + +build:debug --verbose_failures --sandbox_debug --toolchain_resolution_debug diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ac51a05 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +bazel-* diff --git a/BUILD.bazel b/BUILD.bazel new file mode 100644 index 0000000..e69de29 diff --git a/WORKSPACE b/WORKSPACE new file mode 100644 index 0000000..975bbaa --- /dev/null +++ b/WORKSPACE @@ -0,0 +1,32 @@ +workspace(name = "bazel_gcc_toolchain") + +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + +http_archive( + name = "bazel_skylib", + urls = [ + "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.2.1/bazel-skylib-1.2.1.tar.gz", + "https://github.com/bazelbuild/bazel-skylib/releases/download/1.2.1/bazel-skylib-1.2.1.tar.gz", + ], + sha256 = "f7be3474d42aae265405a592bb7da8e171919d74c16f082a5457840f06054728", +) + +load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") + +bazel_skylib_workspace() + +http_archive( + name = "rules_cc", + urls = ["https://github.com/bazelbuild/rules_cc/releases/download/0.0.1/rules_cc-0.0.1.tar.gz"], + sha256 = "4dccbfd22c0def164c8f47458bd50e0c7148f3d92002cdb459c2a96a68498241", +) + +load("//toolchain:defs.bzl", "gcc_register_toolchain") + +gcc_register_toolchain( + name = "gcc_toolchain", + url = "https://toolchains.bootlin.com/downloads/releases/toolchains/x86-64/tarballs/x86-64--glibc--stable-2021.11-5.tar.bz2", + sha256 = "6fe812add925493ea0841365f1fb7ca17fd9224bab61a731063f7f12f3a621b0", + strip_prefix = "x86-64--glibc--stable-2021.11-5", + target_arch = "x86_64", +) diff --git a/examples/hello_world_c/BUILD.bazel b/examples/hello_world_c/BUILD.bazel new file mode 100644 index 0000000..5b7fd79 --- /dev/null +++ b/examples/hello_world_c/BUILD.bazel @@ -0,0 +1,4 @@ +cc_binary( + name = "hello_world_c", + srcs = ["main.c"], +) diff --git a/examples/hello_world_c/main.c b/examples/hello_world_c/main.c new file mode 100644 index 0000000..059c5a0 --- /dev/null +++ b/examples/hello_world_c/main.c @@ -0,0 +1,7 @@ +#include + +int main() +{ + printf("Hello World!\n"); + return 0; +} diff --git a/examples/hello_world_cpp/BUILD.bazel b/examples/hello_world_cpp/BUILD.bazel new file mode 100644 index 0000000..2b869bf --- /dev/null +++ b/examples/hello_world_cpp/BUILD.bazel @@ -0,0 +1,5 @@ +cc_binary( + name = "hello_world_cpp", + srcs = ["main.cpp"], + linkopts = ["-lstdc++"], +) diff --git a/examples/hello_world_cpp/main.cpp b/examples/hello_world_cpp/main.cpp new file mode 100644 index 0000000..8e31396 --- /dev/null +++ b/examples/hello_world_cpp/main.cpp @@ -0,0 +1,7 @@ +#include + +int main() +{ + std::cout << "Hello World!" << std::endl; + return 0; +} diff --git a/toolchain/BUILD.bazel b/toolchain/BUILD.bazel new file mode 100644 index 0000000..e69de29 diff --git a/toolchain/config.bzl.tpl b/toolchain/config.bzl.tpl new file mode 100644 index 0000000..c084c9a --- /dev/null +++ b/toolchain/config.bzl.tpl @@ -0,0 +1,422 @@ +"""%generated_header% +""" + +load( + "@bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl", + "action_config", + "feature", + "flag_group", + "flag_set", + "tool", + "tool_path", + "with_feature_set", +) +load( + "@bazel_tools//tools/build_defs/cc:action_names.bzl", + _ASSEMBLE_ACTION_NAME = "ASSEMBLE_ACTION_NAME", + _CLIF_MATCH_ACTION_NAME = "CLIF_MATCH_ACTION_NAME", + _CPP_COMPILE_ACTION_NAME = "CPP_COMPILE_ACTION_NAME", + _CPP_HEADER_PARSING_ACTION_NAME = "CPP_HEADER_PARSING_ACTION_NAME", + _CPP_LINK_DYNAMIC_LIBRARY_ACTION_NAME = "CPP_LINK_DYNAMIC_LIBRARY_ACTION_NAME", + _CPP_LINK_EXECUTABLE_ACTION_NAME = "CPP_LINK_EXECUTABLE_ACTION_NAME", + _CPP_LINK_NODEPS_DYNAMIC_LIBRARY_ACTION_NAME = "CPP_LINK_NODEPS_DYNAMIC_LIBRARY_ACTION_NAME", + _CPP_MODULE_CODEGEN_ACTION_NAME = "CPP_MODULE_CODEGEN_ACTION_NAME", + _CPP_MODULE_COMPILE_ACTION_NAME = "CPP_MODULE_COMPILE_ACTION_NAME", + _C_COMPILE_ACTION_NAME = "C_COMPILE_ACTION_NAME", + _LINKSTAMP_COMPILE_ACTION_NAME = "LINKSTAMP_COMPILE_ACTION_NAME", + _LTO_BACKEND_ACTION_NAME = "LTO_BACKEND_ACTION_NAME", + _PREPROCESS_ASSEMBLE_ACTION_NAME = "PREPROCESS_ASSEMBLE_ACTION_NAME", +) + +all_compile_actions = [ + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _ASSEMBLE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, +] + +all_cpp_compile_actions = [ + _CPP_COMPILE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, +] + +preprocessor_compile_actions = [ + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, +] + +codegen_compile_actions = [ + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _ASSEMBLE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, +] + +all_link_actions = [ + _CPP_LINK_EXECUTABLE_ACTION_NAME, + _CPP_LINK_DYNAMIC_LIBRARY_ACTION_NAME, + _CPP_LINK_NODEPS_DYNAMIC_LIBRARY_ACTION_NAME, +] + +def _impl(ctx): + hermetic_include_directories = %hermetic_include_directories% + hermetic_library_directories = %hermetic_library_directories% + use_builtin_sysroot = %use_builtin_sysroot% + builtin_sysroot = "%builtin_sysroot%" + tool_paths = %tool_paths% + + objcopy_tool = tool_paths.get("objcopy") + objcopy_embed_data_action = action_config( + action_name = "objcopy_embed_data", + enabled = True, + tools = [tool(path = objcopy_tool)], + ) + + hermetic_library_directories_feature = feature( + name = "hermetic_library_directories", + enabled = not use_builtin_sysroot, + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = [ + "-L{}".format(d) + for d in hermetic_library_directories + ], + ), + ], + ), + ], + ) + + default_link_flags_feature = feature( + name = "default_link_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = [\ + "-Wl,-z,relro,-z,now", + "-no-canonical-prefixes", + "-pass-exit-codes", + "-lstdc++", + ], + ), + ], + ), + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["-Wl,--gc-sections"])], + with_features = [with_feature_set(features = ["opt"])], + ), + ], + ) + + unfiltered_compile_flags_feature = feature( + name = "unfiltered_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + _ASSEMBLE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + ], + flag_groups = [ + flag_group( + flags = [ + "-no-canonical-prefixes", + "-fno-canonical-system-headers", + "-Wno-builtin-macro-redefined", + "-D__DATE__=\"redacted\"", + "-D__TIMESTAMP__=\"redacted\"", + "-D__TIME__=\"redacted\"", + ], + ), + ], + ), + ], + ) + + supports_pic_feature = feature( + name = "supports_pic", + enabled = True, + ) + + default_compile_flags_feature = feature( + name = "default_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + _ASSEMBLE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + ], + flag_groups = [ + flag_group( + flags = [ + "-fstack-protector", + "-Wall", + "-Wunused-but-set-parameter", + "-Wno-free-nonheap-object", + "-fno-omit-frame-pointer", + ], + ), + ], + ), + flag_set( + actions = [ + _ASSEMBLE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + ], + flag_groups = [ + flag_group( + flags = [ + "-U_FORTIFY_SOURCE", + "-D_FORTIFY_SOURCE=1", + ], + ), + ], + with_features = [with_feature_set(features = ["opt"])], + ), + flag_set( + actions = [ + _ASSEMBLE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + ], + flag_groups = [flag_group(flags = ["-g"])], + with_features = [with_feature_set(features = ["dbg"])], + ), + flag_set( + actions = [ + _ASSEMBLE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + ], + flag_groups = [ + flag_group( + flags = [ + "-g0", + "-O2", + "-DNDEBUG", + "-ffunction-sections", + "-fdata-sections", + ], + ), + ], + with_features = [with_feature_set(features = ["opt"])], + ), + flag_set( + actions = [ + _LINKSTAMP_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + ], + flag_groups = [flag_group(flags = ["-std=c++0x"])], + ), + flag_set( + actions = [ + _LINKSTAMP_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + ], + flag_groups = [ + flag_group( + flags = [ + "-I{}".format(d) + for d in hermetic_include_directories + ], + ), + ], + ), + ], + ) + + include_directories = hermetic_include_directories + + opt_feature = feature(name = "opt") + + supports_dynamic_linker_feature = feature( + name = "supports_dynamic_linker", + enabled = True, + ) + + objcopy_embed_flags_feature = feature( + name = "objcopy_embed_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = ["objcopy_embed_data"], + flag_groups = [flag_group(flags = ["-I", "binary"])], + ), + ], + ) + + dbg_feature = feature(name = "dbg") + + user_compile_flags_feature = feature( + name = "user_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + _ASSEMBLE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + ], + flag_groups = [ + flag_group( + flags = ["%{user_compile_flags}"], + iterate_over = "user_compile_flags", + expand_if_available = "user_compile_flags", + ), + ], + ), + ], + ) + + sysroot_feature = feature( + name = "sysroot", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + _CPP_LINK_EXECUTABLE_ACTION_NAME, + _CPP_LINK_DYNAMIC_LIBRARY_ACTION_NAME, + _CPP_LINK_NODEPS_DYNAMIC_LIBRARY_ACTION_NAME, + ], + flag_groups = [ + flag_group( + flags = ["--sysroot=%{sysroot}"], + expand_if_available = "sysroot", + ), + ], + ), + ], + ) + + features = [ + default_compile_flags_feature, + default_link_flags_feature, + supports_dynamic_linker_feature, + supports_pic_feature, + objcopy_embed_flags_feature, + opt_feature, + dbg_feature, + user_compile_flags_feature, + sysroot_feature, + unfiltered_compile_flags_feature, + ] + + return [ + cc_common.create_cc_toolchain_config_info( + ctx = ctx, + features = features, + action_configs = [objcopy_embed_data_action], + artifact_name_patterns = [], + cxx_builtin_include_directories = include_directories, + toolchain_identifier = "local_linux", + host_system_name = "local", + target_system_name = "local", + target_cpu = "local", + target_libc = "local", + compiler = "gcc", + abi_version = "local", + abi_libc_version = "local", + tool_paths = [ + tool_path(name = name, path = path) + for name, path in tool_paths.items() + ], + make_variables = [], + builtin_sysroot = builtin_sysroot if use_builtin_sysroot else None, + cc_target_os = None, + ), + ] + +cc_toolchain_config = rule( + implementation = _impl, + provides = [CcToolchainConfigInfo], +) diff --git a/toolchain/defs.bzl b/toolchain/defs.bzl new file mode 100644 index 0000000..be6f4d8 --- /dev/null +++ b/toolchain/defs.bzl @@ -0,0 +1,140 @@ +"""This module provides the definitions for registering a GCC toolchain for C and C++. +""" + +load("@bazel_skylib//lib:dicts.bzl", "dicts") +load("@bazel_skylib//lib:paths.bzl", "paths") + +def _gcc_toolchain_impl(rctx): + pwd = paths.dirname(str(rctx.path("WORKSPACE"))) + + rctx.download_and_extract( + sha256 = rctx.attr.sha256, + stripPrefix = rctx.attr.strip_prefix, + url = rctx.attr.url, + ) + + target_arch = rctx.attr.target_arch + + ar = str(rctx.path("bin/{}-linux-ar".format(target_arch))) + cpp = str(rctx.path("bin/{}-linux-cpp".format(target_arch))) + gcc = str(rctx.path("bin/{}-linux-gcc".format(target_arch))) + gcov = str(rctx.path("bin/{}-linux-gcov".format(target_arch))) + ld = str(rctx.path("bin/{}-linux-ld".format(target_arch))) + nm = str(rctx.path("bin/{}-linux-nm".format(target_arch))) + objcopy = str(rctx.path("bin/{}-linux-objcopy".format(target_arch))) + objdump = str(rctx.path("bin/{}-linux-objdump".format(target_arch))) + strip = str(rctx.path("bin/{}-linux-strip".format(target_arch))) + + res = rctx.execute([gcc, "-Wp,-v", "-xc++", "/dev/null", "-fsyntax-only"]) + hermetic_include_directories = [ + paths.normalize(line.strip()) + for line in res.stderr.split("\n") if line.strip().startswith(pwd) + ] + + res = rctx.execute([gcc, "-print-search-dirs"]) + libraries = None + for line in res.stdout.split("\n"): + if line.startswith("libraries:"): + libraries = line.split(":") + break + if not libraries: + fail("failed to find libraries directories") + hermetic_library_directories = [ + paths.normalize(library.strip().replace("=", "")) + for library in libraries + ] + + generated_header = "GENERATED - This file was generated by the repository target @{}.".format(rctx.name) + + substitutions = { + "%generated_header%": generated_header, + "%workspace_name%": rctx.name, + "%target_arch%": target_arch, + } + rctx.template("BUILD.bazel", rctx.attr._toolchain_build_template, substitutions = substitutions) + + use_builtin_sysroot = rctx.attr.use_builtin_sysroot + builtin_sysroot = str(rctx.path("{}-buildroot-linux-gnu/sysroot".format(target_arch))) if use_builtin_sysroot else "" + + substitutions = { + "%generated_header%": generated_header, + + # Sysroot + "%use_builtin_sysroot%": str(use_builtin_sysroot), + "%builtin_sysroot%": builtin_sysroot, + + # Includes + "%hermetic_include_directories%": str(hermetic_include_directories), + + # Libs + "%hermetic_library_directories%": str(hermetic_library_directories), + + # Tool paths + "%tool_paths%": str({ + "ar": ar, + "cpp": cpp, + "gcc": gcc, + "gcov": gcov, + "ld": ld, + "nm": nm, + "objcopy": objcopy, + "objdump": objdump, + "strip": strip, + }), + } + rctx.template("config.bzl", rctx.attr._config_template, substitutions = substitutions) + +_DOWNLOAD_TOOLCHAIN_ATTRS = { + "sha256": attr.string( + doc = "The SHA256 integrity hash for the interpreter tarball.", + mandatory = True, + ), + "strip_prefix": attr.string( + doc = "The prefix to strip from the extracted tarball.", + mandatory = True, + ), + "url": attr.string( + doc = "The URL of the interpreter tarball.", + mandatory = True, + ), +} + +_FEATURE_ATTRS = { + "target_arch": attr.string( + doc = "The target architecture this toolchain produces. E.g. x86_64.", + mandatory = True, + ), + "use_builtin_sysroot": attr.bool( + default = True, + doc = "Whether the builtin sysroot is used or not.", + ), +} + +_PRIVATE_ATTRS = { + "_build_bootlin_template": attr.label( + default = Label("//toolchain:BUILD.bootlin.tpl"), + ), + "_config_template": attr.label( + default = Label("//toolchain:config.bzl.tpl"), + ), + "_toolchain_build_template": attr.label( + default = Label("//toolchain:toolchain.BUILD.bazel.tpl"), + ), +} + +_gcc_toolchain = repository_rule( + _gcc_toolchain_impl, + attrs = dicts.add( + _DOWNLOAD_TOOLCHAIN_ATTRS, + _FEATURE_ATTRS, + _PRIVATE_ATTRS, + ), +) + +def gcc_register_toolchain(name, **kwargs): + _gcc_toolchain( + name = name, + **kwargs + ) + + native.register_toolchains("@{}//:toolchain".format(name)) diff --git a/toolchain/toolchain.BUILD.bazel.tpl b/toolchain/toolchain.BUILD.bazel.tpl new file mode 100644 index 0000000..0655ff1 --- /dev/null +++ b/toolchain/toolchain.BUILD.bazel.tpl @@ -0,0 +1,181 @@ +"""%generated_header% +""" + +load("@rules_cc//cc:defs.bzl", "cc_toolchain") +load("@%workspace_name%//:config.bzl", "cc_toolchain_config") + +toolchain( + name = "toolchain", + target_compatible_with = [ + "@platforms//os:linux", + "@platforms//cpu:%target_arch%", + ], + toolchain = ":cc_toolchain", + toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", +) + +cc_toolchain( + name = "cc_toolchain", + all_files = ":all_files", + ar_files = ":ar_files", + as_files = ":as_files", + compiler_files = ":compiler_files", + dwp_files = ":dwp_files", + linker_files = ":linker_files", + objcopy_files = ":objcopy_files", + strip_files = ":strip_files", + supports_param_files = 0, + toolchain_config = ":cc_toolchain_config", + toolchain_identifier = "gcc-toolchain", +) + +cc_toolchain_config( + name = "cc_toolchain_config", +) + +filegroup( + name = "all_files", + srcs = [ + ":ar_files", + ":as_files", + ":compiler_files", + ":dwp_files", + ":linker_files", + ":objcopy_files", + ":strip_files", + ], +) + +# GCC + +filegroup( + name = "compiler_files", + srcs = [ + ":gcc", + ":include", + ], +) + +filegroup( + name = "linker_files", + srcs = [ + ":gcc", + ":lib", + ":linker_files_binutils", + ], +) + +filegroup( + name = "include", + srcs = glob([ + "include/**", + "%target_arch%-buildroot-linux-gnu/include/**", + ]), +) + +filegroup( + name = "lib", + srcs = glob([ + "lib/**", + "lib64/**", + "%target_arch%-buildroot-linux-gnu/lib/**", + "%target_arch%-buildroot-linux-gnu/lib64/**", + ]), +) + +filegroup( + name = "gcc", + srcs = [ + ":gpp", + "bin/%target_arch%-linux-cpp", + "bin/%target_arch%-linux-gcc", + ], +) + +filegroup( + name = "gpp", + srcs = ["bin/%target_arch%-linux-g++"], +) + +# Binutils + +filegroup( + name = "ar_files", + srcs = [":ar"], +) + +filegroup( + name = "as_files", + srcs = [":as"], +) + +filegroup( + name = "dwp_files", + srcs = [], +) + +filegroup( + name = "linker_files_binutils", + srcs = [ + ":ar", + ":ld", + ], +) + +filegroup( + name = "objcopy_files", + srcs = [":objcopy"], +) + +filegroup( + name = "strip_files", + srcs = [":strip"], +) + +filegroup( + name = "ld", + srcs = [ + "bin/%target_arch%-linux-ld", + "bin/%target_arch%-linux-ld.bfd", + ], +) + +filegroup( + name = "ar", + srcs = ["bin/%target_arch%-linux-ar"], +) + +filegroup( + name = "as", + srcs = ["bin/%target_arch%-linux-as"], +) + +filegroup( + name = "nm", + srcs = ["bin/%target_arch%-linux-nm"], +) + +filegroup( + name = "objcopy", + srcs = ["bin/%target_arch%-linux-objcopy"], +) + +filegroup( + name = "objdump", + srcs = ["bin/%target_arch%-linux-objdump"], +) + +filegroup( + name = "ranlib", + srcs = ["bin/%target_arch%-linux-ranlib"], +) + +filegroup( + name = "readelf", + srcs = ["bin/%target_arch%-linux-readelf"], +) + +filegroup( + name = "strip", + srcs = ["bin/%target_arch%-linux-strip"], +)