Jelajahi Sumber

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.
Chandler Carruth 5 tahun lalu
induk
melakukan
9da9c62225

+ 63 - 40
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(
     default_link_flags_feature = feature(
         name = "default_link_flags",
         name = "default_link_flags",
         enabled = True,
         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(
             flag_set(
                 actions = all_link_actions,
                 actions = all_link_actions,
                 flag_groups = [
                 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_compile_flags_feature,
         default_archiver_flags_feature,
         default_archiver_flags_feature,
         default_link_flags_feature,
         default_link_flags_feature,
-        feature(name = "supports_dynamic_linker", enabled = True),
         feature(name = "dbg"),
         feature(name = "dbg"),
         feature(name = "opt"),
         feature(name = "opt"),
         sysroot_feature,
         sysroot_feature,
@@ -700,6 +697,21 @@ def _impl(ctx):
         use_module_maps,
         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(
     return cc_common.create_cc_toolchain_config_info(
         ctx = ctx,
         ctx = ctx,
         features = features,
         features = features,
@@ -708,18 +720,29 @@ def _impl(ctx):
             # Append the share directory for sanitizer data files.
             # Append the share directory for sanitizer data files.
             clang_resource_dir + "/share",
             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",
         target_libc = "local",
         compiler = "local",
         compiler = "local",
         abi_version = "local",
         abi_version = "local",
         abi_libc_version = "local",
         abi_libc_version = "local",
+
+        # We do have to pass in our tool paths.
         tool_paths = tool_paths,
         tool_paths = tool_paths,
     )
     )
 
 
 cc_toolchain_config = rule(
 cc_toolchain_config = rule(
     implementation = _impl,
     implementation = _impl,
+    attrs = {
+        "target_cpu": attr.string(mandatory = True),
+    },
     provides = [CcToolchainConfigInfo],
     provides = [CcToolchainConfigInfo],
 )
 )

+ 13 - 7
bazel/cc_toolchains/clang_toolchain.BUILD

@@ -26,7 +26,7 @@ cc_toolchain_suite(
 )
 )
 
 
 cc_toolchain(
 cc_toolchain(
-    name = "cc-compiler-darwin",
+    name = "cc-compiler-k8",
     all_files = ":empty",
     all_files = ":empty",
     ar_files = ":empty",
     ar_files = ":empty",
     as_files = ":empty",
     as_files = ":empty",
@@ -36,12 +36,17 @@ cc_toolchain(
     objcopy_files = ":empty",
     objcopy_files = ":empty",
     strip_files = ":empty",
     strip_files = ":empty",
     supports_param_files = 1,
     supports_param_files = 1,
-    toolchain_config = ":local",
-    toolchain_identifier = "local",
+    toolchain_config = ":local-k8",
+    toolchain_identifier = "local-k8",
+)
+
+cc_toolchain_config(
+    name = "local-k8",
+    target_cpu = "k8",
 )
 )
 
 
 cc_toolchain(
 cc_toolchain(
-    name = "cc-compiler-k8",
+    name = "cc-compiler-darwin",
     all_files = ":empty",
     all_files = ":empty",
     ar_files = ":empty",
     ar_files = ":empty",
     as_files = ":empty",
     as_files = ":empty",
@@ -51,10 +56,11 @@ cc_toolchain(
     objcopy_files = ":empty",
     objcopy_files = ":empty",
     strip_files = ":empty",
     strip_files = ":empty",
     supports_param_files = 1,
     supports_param_files = 1,
-    toolchain_config = ":local",
-    toolchain_identifier = "local",
+    toolchain_config = ":local-darwin",
+    toolchain_identifier = "local-darwin",
 )
 )
 
 
 cc_toolchain_config(
 cc_toolchain_config(
-    name = "local",
+    name = "local-darwin",
+    target_cpu = "darwin",
 )
 )

+ 6 - 1
source/source_buffer.cpp

@@ -54,7 +54,12 @@ auto SourceBuffer::CreateFromFile(llvm::StringRef filename)
   }
   }
 
 
   errno = 0;
   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);
                            file_descriptor, /*offset=*/0);
   if (mapped_text == MAP_FAILED) {
   if (mapped_text == MAP_FAILED) {
     return ErrnoToError(errno);
     return ErrnoToError(errno);