From 9da9c62225b256a6aa39d247bd8416a5a5e6803a Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Sat, 16 Jan 2021 16:08:51 -0800 Subject: [PATCH] Port Bazel toolchain and code to macOS (x86). (#238) This updates the Bazel toolchain logic to work on macOS. Much like on Linux, I'm not testing this against a *released* LLVM, but against a from-source build. You can build and install LLVM from top-of-tree locally with CMake, or on macOS maybe use Homebrew like: ``` brew install llvm --HEAD ``` You then need to point Bazel to the installed `clang` executable if it is not placed onto your PATH (Homebrew doesn't): ``` bazel test --repo_env=CC=$HOME/homebrew/opt/llvm/bin/clang //parser:all ``` This builds and passes tests for me at least. The fuzzer feature may not work (yet) with this setup, but that can be improved incrementally as we proceed. --- .../clang_cc_toolchain_config.bzl | 103 +++++++++++------- bazel/cc_toolchains/clang_toolchain.BUILD | 42 ++++--- source/source_buffer.cpp | 7 +- 3 files changed, 93 insertions(+), 59 deletions(-) diff --git a/bazel/cc_toolchains/clang_cc_toolchain_config.bzl b/bazel/cc_toolchains/clang_cc_toolchain_config.bzl index 191f50f7d8a0..8329918dd9b6 100644 --- a/bazel/cc_toolchains/clang_cc_toolchain_config.bzl +++ b/bazel/cc_toolchains/clang_cc_toolchain_config.bzl @@ -323,6 +323,36 @@ def _impl(ctx): ], ) + linux_link_flags_feature = feature( + name = "linux_link_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = ([ + flag_group( + flags = [ + "-fuse-ld=lld", + "-Wl,-no-as-needed", + # Force the C++ standard library to be statically + # linked. This works even with libc++ despite the + # name, however we have to manually link the ABI + # library and libunwind. + "-static-libstdc++", + # Link with libc++. + "-stdlib=libc++", + # Force static linking with libc++abi as well. + "-l:libc++abi.a", + # Link with Clang's runtime library. This is always + # linked statically. + #"-rtlib=compiler-rt", + ], + ), + ]), + ), + ], + ) + default_link_flags_feature = feature( name = "default_link_flags", enabled = True, @@ -364,29 +394,6 @@ def _impl(ctx): ), ], ), - flag_set( - actions = all_link_actions, - flag_groups = ([ - flag_group( - flags = [ - "-fuse-ld=lld", - "-Wl,-no-as-needed", - # Force the C++ standard library to be statically - # linked. This works even with libc++ despite the - # name, however we have to manually link the ABI - # library and libunwind. - "-static-libstdc++", - # Link with libc++. - "-stdlib=libc++", - # Force static linking with libc++abi as well. - "-l:libc++abi.a", - # Link with Clang's runtime library. This is always - # linked statically. - #"-rtlib=compiler-rt", - ], - ), - ]), - ), flag_set( actions = all_link_actions, flag_groups = [ @@ -675,22 +682,12 @@ def _impl(ctx): ], ) - features = [ - feature( - name = "no_legacy_features", - ), - feature( - name = "supports_pic", - enabled = True, - ), - feature( - name = "supports_start_end_lib", - enabled = True, - ), + common_features = [ + feature(name = "no_legacy_features"), + feature(name = "supports_pic", enabled = True), default_compile_flags_feature, default_archiver_flags_feature, default_link_flags_feature, - feature(name = "supports_dynamic_linker", enabled = True), feature(name = "dbg"), feature(name = "opt"), sysroot_feature, @@ -700,6 +697,21 @@ def _impl(ctx): use_module_maps, ] + # Select the features based on the target platform. Currently, this is + # configured with the "cpu" attribute for legacy reasons. Further, for + # legacy reasons the default is a Linux OS target and the x88-64 CPU name + # is "k8". + if (ctx.attr.target_cpu == "k8"): + features = common_features + [ + linux_link_flags_feature, + feature(name = "supports_start_end_lib", enabled = True), + feature(name = "supports_dynamic_linker", enabled = True), + ] + elif (ctx.attr.target_cpu == "darwin"): + features = common_features + else: + fail("Unsupported target platform!") + return cc_common.create_cc_toolchain_config_info( ctx = ctx, features = features, @@ -708,18 +720,29 @@ def _impl(ctx): # Append the share directory for sanitizer data files. clang_resource_dir + "/share", ], - toolchain_identifier = "local", - host_system_name = "local", - target_system_name = "local", - target_cpu = "k8", + + # This configuration only supports local non-cross builds so derive + # everything from the target CPU selected. + toolchain_identifier = "local-" + ctx.attr.target_cpu, + host_system_name = "local-" + ctx.attr.target_cpu, + target_system_name = "local-" + ctx.attr.target_cpu, + target_cpu = ctx.attr.target_cpu, + + # These attributes aren't meaningful at all so just use placeholder + # values. target_libc = "local", compiler = "local", abi_version = "local", abi_libc_version = "local", + + # We do have to pass in our tool paths. tool_paths = tool_paths, ) cc_toolchain_config = rule( implementation = _impl, + attrs = { + "target_cpu": attr.string(mandatory = True), + }, provides = [CcToolchainConfigInfo], ) diff --git a/bazel/cc_toolchains/clang_toolchain.BUILD b/bazel/cc_toolchains/clang_toolchain.BUILD index c3d6fd82db32..9e27b3832e2f 100644 --- a/bazel/cc_toolchains/clang_toolchain.BUILD +++ b/bazel/cc_toolchains/clang_toolchain.BUILD @@ -25,21 +25,6 @@ cc_toolchain_suite( }, ) -cc_toolchain( - name = "cc-compiler-darwin", - all_files = ":empty", - ar_files = ":empty", - as_files = ":empty", - compiler_files = ":empty", - dwp_files = ":empty", - linker_files = ":empty", - objcopy_files = ":empty", - strip_files = ":empty", - supports_param_files = 1, - toolchain_config = ":local", - toolchain_identifier = "local", -) - cc_toolchain( name = "cc-compiler-k8", all_files = ":empty", @@ -51,10 +36,31 @@ cc_toolchain( objcopy_files = ":empty", strip_files = ":empty", supports_param_files = 1, - toolchain_config = ":local", - toolchain_identifier = "local", + toolchain_config = ":local-k8", + toolchain_identifier = "local-k8", ) cc_toolchain_config( - name = "local", + name = "local-k8", + target_cpu = "k8", +) + +cc_toolchain( + name = "cc-compiler-darwin", + all_files = ":empty", + ar_files = ":empty", + as_files = ":empty", + compiler_files = ":empty", + dwp_files = ":empty", + linker_files = ":empty", + objcopy_files = ":empty", + strip_files = ":empty", + supports_param_files = 1, + toolchain_config = ":local-darwin", + toolchain_identifier = "local-darwin", +) + +cc_toolchain_config( + name = "local-darwin", + target_cpu = "darwin", ) diff --git a/source/source_buffer.cpp b/source/source_buffer.cpp index eaff55633d89..0464ba918034 100644 --- a/source/source_buffer.cpp +++ b/source/source_buffer.cpp @@ -54,7 +54,12 @@ auto SourceBuffer::CreateFromFile(llvm::StringRef filename) } errno = 0; - void* mapped_text = mmap(nullptr, size, PROT_READ, MAP_PRIVATE | MAP_POPULATE, + void* mapped_text = mmap(nullptr, size, PROT_READ, +#ifdef __APPLE__ + MAP_PRIVATE, +#else + MAP_PRIVATE | MAP_POPULATE, +#endif file_descriptor, /*offset=*/0); if (mapped_text == MAP_FAILED) { return ErrnoToError(errno);