Search code examples
c++ubuntubazelmingw-w64

Mingw-w64 toolchain for Bazel (Ubuntu 20.04.1 )


I am trying to create my toolchain for mingw-w64 on Ubuntu with Bazel. I am following this tutorial: https://docs.bazel.build/versions/master/tutorial/cc-toolchain-config.html. However, when I try to adapt the compiler's paths to the paths of my mingw64 installation I get the following error:

bazel build --config=mingw_config -s //main:hello-world --verbose_failures
Starting local Bazel server and connecting to it...
INFO: Analyzed target //main:hello-world (16 packages loaded, 46 targets configured).
INFO: Found 1 target...
SUBCOMMAND: # //main:hello-world [action 'Compiling main/hello-world.cc', configuration: a79594d39f0782b210e102e89b8a67dda26e295f95805aa9c0140f6281fdd3f5, execution platform: @local_config_platform//:host]
(cd /home/federica/.cache/bazel/_bazel_federica/fb36143429cca4c38e61a5e83150e333/execroot/__main__ && \
  exec env - \
    PATH=/home/federica/.cache/bazelisk/downloads/bazelbuild/bazel-3.5.0-linux-x86_64/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin \
    PWD=/proc/self/cwd \
  /usr/bin/x86_64-w64-mingw32-gcc -MD -MF bazel-out/k8-fastbuild/bin/main/_objs/hello-world/hello-world.d '-frandom-seed=bazel-out/k8-fastbuild/bin/main/_objs/hello-world/hello-world.o' -iquote . -iquote bazel-out/k8-fastbuild/bin -iquote external/bazel_tools -iquote bazel-out/k8-fastbuild/bin/external/bazel_tools -c main/hello-world.cc -o bazel-out/k8-fastbuild/bin/main/_objs/hello-world/hello-world.o)
SUBCOMMAND: # //main:hello-world [action 'Linking main/hello-world', configuration: a79594d39f0782b210e102e89b8a67dda26e295f95805aa9c0140f6281fdd3f5, execution platform: @local_config_platform//:host]
(cd /home/federica/.cache/bazel/_bazel_federica/fb36143429cca4c38e61a5e83150e333/execroot/__main__ && \
  exec env - \
    PATH=/home/federica/.cache/bazelisk/downloads/bazelbuild/bazel-3.5.0-linux-x86_64/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin \
    PWD=/proc/self/cwd \
  /usr/bin/x86_64-w64-mingw32-gcc -o bazel-out/k8-fastbuild/bin/main/hello-world bazel-out/k8-fastbuild/bin/main/_objs/hello-world/hello-world.o -Wl,-S -lstdc++)
ERROR: /home/federica/examples/cpp_mingw_toolchain/stage1/main/BUILD:3:10: output 'main/hello-world' was not created
ERROR: /home/federica/examples/cpp_mingw_toolchain/stage1/main/BUILD:3:10: not all outputs were created or valid
Target //main:hello-world failed to build
INFO: Elapsed time: 9.390s, Critical Path: 0.58s
INFO: 2 processes: 2 linux-sandbox.
FAILED: Build did NOT complete successfully

and if I look inside bazel-out/k8-fastbuild/bin/main/hello-worldthe executable is not created. However, if I try to run in the bash the single command indicated from the verbose_failures:

cd /home/federica/.cache/bazel/_bazel_federica/fb36143429cca4c38e61a5e83150e333/execroot/__main__ && \
  exec env - \
    PATH=/home/federica/.cache/bazelisk/downloads/bazelbuild/bazel-3.5.0-linux-x86_64/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin \
    PWD=/proc/self/cwd \
  /usr/bin/x86_64-w64-mingw32-gcc -o bazel-out/k8-fastbuild/bin/main/hello-world bazel-out/k8-fastbuild/bin/main/_objs/hello-world/hello-world.o -Wl,-S -lstdc++

the executable 'Hello-world.exe' is created succesfully.

Any suggestion on what is going wrong?

Below, my toolchain BUILD file

package(default_visibility = ["//visibility:public"])

cc_toolchain_suite(
    name = "mingw_suite",
    toolchains = {
        "k8": ":k8_toolchain",
    },
)



filegroup(name = "empty")

cc_toolchain(
    name = "k8_toolchain",
    toolchain_identifier = "k8-toolchain",
    toolchain_config = ":k8_toolchain_config",
    all_files = ":empty",
    compiler_files = ":empty",
    dwp_files = ":empty",
    linker_files = ":empty",
    objcopy_files = ":empty",
    strip_files = ":empty",
    supports_param_files = 0,
)

load(":cc_toolchain_config.bzl", "cc_toolchain_config")
cc_toolchain_config(name = "k8_toolchain_config")

and the cc_toolchain_config.bzl:

load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES")
   # NEW
load(
    "@bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl",
    "feature",
    "flag_group",
    "flag_set",
    "tool_path",
)

all_link_actions = [ # NEW
    ACTION_NAMES.cpp_link_executable,
    ACTION_NAMES.cpp_link_dynamic_library,
    ACTION_NAMES.cpp_link_nodeps_dynamic_library,
]


def _impl(ctx):
    tool_paths = [ # NEW
        tool_path(
            name = "gcc",
            path = "/usr/bin/x86_64-w64-mingw32-gcc",
        ),
        tool_path(
            name = "ld",
            path = "/usr/bin/x86_64-w64-mingw32-ld",
        ),
        tool_path(
            name = "ar",
            path = "/usr/bin/x86_64-w64-mingw32-ld",
        ),
        tool_path(
            name = "cpp",
            path = "/bin/false",
        ),
        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 = [ # NEW
        feature(
            name = "default_linker_flags",
            enabled = True,
            flag_sets = [
                flag_set(
                    actions = all_link_actions,
                    flag_groups = ([
                        flag_group(
                            flags = [
                                "-lstdc++",
                            ],
                        ),
                    ]),
                ),
            ],
        ),
    ]
    return cc_common.create_cc_toolchain_config_info(
        ctx = ctx,
        features = features, # NEW
        cxx_builtin_include_directories = [ # NEW
        "/usr/x86_64-w64-mingw32/include",
        "/usr/lib/gcc/x86_64-w64-mingw32/9.3-win32/include/c++",
        "/usr/share/mingw-w64/include",
        "/usr/lib/gcc/x86_64-w64-mingw32/9.3-win32/include",
        "/usr/lib/gcc/x86_64-w64-mingw32/9.3-win32/include-fixed",
        "/usr/include",
        ],        
        toolchain_identifier = "k8-toolchain",
        host_system_name = "local",
        target_system_name = "local",
        target_cpu = "k8",
        target_libc = "unknown",
        compiler = "i686-w64-mingw32-gcc",
        abi_version = "unknown",
        abi_libc_version = "unknown",
        tool_paths = tool_paths,
    )

cc_toolchain_config = rule(
    implementation = _impl,
    attrs = {},
    provides = [CcToolchainConfigInfo],
)


Many thanks for any help!


Solution

  • The problem is relatively easy to miss, but actually already included in your question, the error says hello-world has not been created, while hello-world.exe has apparently been produced just fine. That is, we've actually built a file with the .exe suffix, but did not tell bazel through it's toolchain config that is the case and it failed expecting output without it.

    To address that, you can also load: artifact_name_pattern from @bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl with the other symbols and then set artifact_name_patterns attribute of cc_common.create_cc_toolchain_config_info():

    artifact_name_patterns = [
        artifact_name_pattern(
            category_name = "executable",
            prefix = "",
            extension = ".exe",
        ),
    ]