Skip to content

Instantly share code, notes, and snippets.

@krestovolt
Last active January 14, 2023 00:04
Show Gist options
  • Save krestovolt/ba6f948f0418e8f44687e0a8c3a2e3f2 to your computer and use it in GitHub Desktop.
Save krestovolt/ba6f948f0418e8f44687e0a8c3a2e3f2 to your computer and use it in GitHub Desktop.
Bazel cross-toolchain for CGO on mac (M1 arm64) targeting x86_64

The original idea is taken from this comment

Note:

The configuration used to build a project which use CGO in some of its deps. Using @io_bazel_rules_go//go/toolchain:linux_amd64_cgo alone still got an error (no toolchain matched), the custom toolchain listed here is intended to be used inside docker container running an ubuntu on arm64 platform with build target x86_64.

Usage

On project's WORKSPACE:

register_toolchains(
    "//toolchain:cc-toolchain-linux-cross-64",
)

On project's root BUILD:

platform(
    name = "gcc_cross_64",
    constraint_values = [
        "@platforms//os:linux",
        "@platforms//cpu:x86_64",
    ],
    parents = [
        "@io_bazel_rules_go//go/toolchain:linux_amd64_cgo",
    ],
)

Add config (for shorter build syntax) .bazelrc:

build:go_linux_64 --host_crosstool_top=@bazel_tools//tools/cpp:toolchain
build:go_linux_64 --host_platform=@local_config_platform//:host
build:go_linux_64 --crosstool_top=//toolchain:cc_linux_cross_64_suite
build:go_linux_64 --cpu=x86_64
build:go_linux_64 --compiler=gcc-cross
build:go_linux_64 --platforms=:gcc_cross_64

Execute the build using bazel build <target> --config=go_linux_64

Disclaimer:

I never test this solution for different projects, this is more of a self-note.

# toolchain/BUILD.bazel
package(default_visibility = ["//visibility:public"])
cc_toolchain_suite(
name = "cc_linux_cross_64_suite",
toolchains = {
"x86_64": ":linux_cross_toolchain_64",
"x86_64|gcc-cross": ":linux_cross_toolchain_64",
},
)
filegroup(name = "empty")
cc_toolchain(
name = "linux_cross_toolchain_64",
all_files = ":empty",
compiler_files = ":empty",
dwp_files = ":empty",
linker_files = ":empty",
objcopy_files = ":empty",
strip_files = ":empty",
supports_param_files = 0,
toolchain_config = ":cfg_cc_linux_cross_toolchain_config_64",
toolchain_identifier = "cc-linux-cross-toolchain-64",
)
load(
":cc_toolchain_config.bzl",
"cc_linux_cross_toolchain_config_64",
)
cc_linux_cross_toolchain_config_64(name = "cfg_cc_linux_cross_toolchain_config_64")
toolchain(
name = "cc-toolchain-linux-cross-64",
exec_compatible_with = [
"@platforms//cpu:aarch64",
"@platforms//os:linux",
],
target_compatible_with = [
"@platforms//cpu:x86_64",
"@platforms//os:linux",
],
toolchain = ":linux_cross_toolchain_64",
toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
)
# toolchain/cc_toolchain_config.bzl
# The original idea is taken from this comment:
# https://github.com/bazelbuild/rules_go/issues/1642#issuecomment-747470624
load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES")
load(
"@bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl",
"feature",
"flag_group",
"flag_set",
"tool_path",
)
def _impl_64(ctx):
# TODO: make hermetic, currently relies on host-installed lib
tool_paths = [
tool_path(
name = "gcc",
path = "/usr/bin/x86_64-linux-gnu-gcc",
),
tool_path(
name = "ld",
path = "/usr/bin/x86_64-linux-gnu-ld",
),
tool_path(
name = "ar",
path = "/usr/bin/x86_64-linux-gnu-ar",
),
tool_path(
name = "cpp",
path = "/usr/bin/x86_64-linux-gnu-g++-10",
),
tool_path(
name = "gcov",
path = "/bin/false",
),
tool_path(
name = "nm",
path = "/bin/false",
),
tool_path(
name = "objdump",
path = "/bin/false",
),
tool_path(
name = "strip",
path = "/bin/false",
),
]
features = [
feature(
name = "default_linker_flags",
enabled = True,
flag_sets = [
flag_set(
actions = [
ACTION_NAMES.cpp_link_executable,
ACTION_NAMES.cpp_link_dynamic_library,
ACTION_NAMES.cpp_link_nodeps_dynamic_library,
],
flag_groups = ([
flag_group(
flags = [
"-lstdc++",
"-p",
],
),
]),
),
],
),
]
return cc_common.create_cc_toolchain_config_info(
ctx = ctx,
cxx_builtin_include_directories = [
"/usr/lib/gcc-cross/x86_64-linux-gnu/10/include",
],
features = features,
toolchain_identifier = "local",
host_system_name = "local",
target_system_name = "linux",
target_cpu = "@platforms//cpu:x86_64",
target_libc = "unknown",
compiler = "gcc-cross",
abi_version = "unknown",
abi_libc_version = "unknown",
tool_paths = tool_paths,
)
cc_linux_cross_toolchain_config_64 = rule(
implementation = _impl_64,
attrs = {},
provides = [CcToolchainConfigInfo],
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment