| """ | 
 | This file assembles a toolchain for a Mac host (either M1 or Intel) using the Clang Compiler | 
 | and a locally-installed XCode. | 
 |  | 
 | It downloads the necessary executables and creates symlinks in the external subfolder of the Bazel | 
 | cache (the same place third party deps are downloaded with http_archive or similar functions in | 
 | WORKSPACE.bazel). These will be able to be used via our | 
 | custom c++ toolchain configuration (see //toolchain/mac_toolchain_config.bzl) | 
 |  | 
 | The destination folder for these files and symlinks are: | 
 |   [outputRoot (aka Bazel cache)]/[outputUserRoot]/[outputBase]/external/clang_mac | 
 |   (See https://bazel.build/docs/output_directories#layout-diagram) | 
 | """ | 
 |  | 
 | load(":clang_layering_check.bzl", "generate_system_module_map") | 
 | load(":utils.bzl", "gcs_mirror_url") | 
 |  | 
 | # From https://github.com/llvm/llvm-project/releases/tag/llvmorg-15.0.1 | 
 | # When updating this, don't forget to use //bazel/gcs_mirror to upload a new version. | 
 | # go run bazel/gcs_mirror/gcs_mirror.go --url [clang_url] --sha256 [clang_sha256] | 
 | clang_prefix_arm64 = "clang+llvm-15.0.1-arm64-apple-darwin21.0" | 
 | clang_sha256_arm64 = "858f86d96b5e4880f69f7a583daddbf97ee94e7cffce0d53aa05cba6967f13b8" | 
 | clang_url_arm64 = "https://github.com/llvm/llvm-project/releases/download/llvmorg-15.0.1/clang+llvm-15.0.1-arm64-apple-darwin21.0.tar.xz" | 
 |  | 
 | clang_prefix_amd64 = "clang+llvm-15.0.1-x86_64-apple-darwin" | 
 | clang_sha256_amd64 = "0b2f1a811e68d011344103274733b7670c15bbe08b2a3a5140ccad8e19d9311e" | 
 | clang_url_amd64 = "https://github.com/llvm/llvm-project/releases/download/llvmorg-15.0.1/clang+llvm-15.0.1-x86_64-apple-darwin.tar.xz" | 
 |  | 
 | def _get_system_xcode_path(ctx): | 
 |     # https://developer.apple.com/library/archive/technotes/tn2339/_index.html | 
 |     res = ctx.execute(["xcode-select", "-p"]) | 
 |     if res.return_code != 0: | 
 |         fail("Error Getting XCode path: " + res.stderr) | 
 |     return res.stdout.rstrip() | 
 |  | 
 | def _delete_macos_sdk_symlinks(ctx): | 
 |     ctx.delete("./symlinks/xcode/MacSDK/usr") | 
 |     ctx.delete("./symlinks/xcode/MacSDK/Frameworks") | 
 |  | 
 | def _create_macos_sdk_symlinks(ctx): | 
 |     system_xcode_path = _get_system_xcode_path(ctx) | 
 |  | 
 |     # https://bazel.build/rules/lib/actions#symlink | 
 |     ctx.symlink( | 
 |         # from = | 
 |         system_xcode_path + "/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr", | 
 |         # to = | 
 |         "./symlinks/xcode/MacSDK/usr", | 
 |     ) | 
 |     ctx.symlink( | 
 |         # from = | 
 |         system_xcode_path + "/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks", | 
 |         # to = | 
 |         "./symlinks/xcode/MacSDK/Frameworks", | 
 |     ) | 
 |  | 
 | def _download_mac_toolchain_impl(ctx): | 
 |     # https://bazel.build/rules/lib/repository_ctx#os | 
 |     # https://bazel.build/rules/lib/repository_os | 
 |     if ctx.os.arch == "aarch64": | 
 |         clang_url = clang_url_arm64 | 
 |         clang_sha256 = clang_sha256_arm64 | 
 |         clang_prefix = clang_prefix_arm64 | 
 |     else: | 
 |         clang_url = clang_url_amd64 | 
 |         clang_sha256 = clang_sha256_amd64 | 
 |         clang_prefix = clang_prefix_amd64 | 
 |  | 
 |     # Download the clang toolchain (the extraction can take a while) | 
 |     # https://bazel.build/rules/lib/repository_ctx#download_and_extract | 
 |     ctx.download_and_extract( | 
 |         url = gcs_mirror_url(clang_url, clang_sha256), | 
 |         output = "", | 
 |         stripPrefix = clang_prefix, | 
 |         sha256 = clang_sha256, | 
 |     ) | 
 |  | 
 |     # Some std library headers use #include_next to include system specific headers, and | 
 |     # some skia source files require Xcode headers when compiling, (see SkTypes.h and look | 
 |     # for TargetedConditionals.h)) All of these are located in Xcode, stopping the Mac | 
 |     # builds from being purely hermetic. | 
 |     # For now, we can grab the user's Xcode path by calling xcode-select and create a symlink in | 
 |     # our toolchain directory to refer to during compilation. | 
 |  | 
 |     _delete_macos_sdk_symlinks(ctx) | 
 |     _create_macos_sdk_symlinks(ctx) | 
 |  | 
 |     # This list of files lines up with _make_default_flags() in mac_toolchain_config.bzl | 
 |     # It is all locations that our toolchain could find a system header. | 
 |     builtin_include_directories = [ | 
 |         "include/c++/v1", | 
 |         "lib/clang/15.0.1/include", | 
 |         "symlinks/xcode/MacSDK/Frameworks", | 
 |         "symlinks/xcode/MacSDK/usr/include", | 
 |     ] | 
 |  | 
 |     generate_system_module_map( | 
 |         ctx, | 
 |         module_file = "toolchain_system_headers.modulemap", | 
 |         folders = builtin_include_directories, | 
 |     ) | 
 |  | 
 |     # Create a BUILD.bazel file that makes the files necessary for compiling, | 
 |     # linking and creating archive files visible to Bazel. | 
 |     # The smaller the globs are, the more performant the sandboxed builds will be. | 
 |     # Additionally, globs that are too wide can pick up infinite symlink loops, | 
 |     # and be difficult to quash: https://github.com/bazelbuild/bazel/issues/13950 | 
 |     # https://bazel.build/rules/lib/repository_ctx#file | 
 |     ctx.file( | 
 |         "BUILD.bazel", | 
 |         content = """ | 
 | # DO NOT EDIT THIS BAZEL FILE DIRECTLY | 
 | # Generated from ctx.file action in download_mac_toolchain.bzl | 
 | filegroup( | 
 |     name = "generated_module_map", | 
 |     srcs = ["toolchain_system_headers.modulemap"], | 
 |     visibility = ["//visibility:public"], | 
 | ) | 
 |  | 
 | filegroup( | 
 |     name = "archive_files", | 
 |     srcs = [ | 
 |         "bin/llvm-ar", | 
 |     ], | 
 |     visibility = ["//visibility:public"], | 
 | ) | 
 |  | 
 | filegroup( | 
 |     name = "compile_files", | 
 |     srcs = [ | 
 |         "bin/clang", | 
 |     ] + glob( | 
 |         include = [ | 
 |             "include/c++/v1/**", | 
 |             "lib/clang/15.0.1/include/**", | 
 |             "symlinks/xcode/MacSDK/Frameworks/AppKit.Framework/**", | 
 |             "symlinks/xcode/MacSDK/Frameworks/ApplicationServices.Framework/**", | 
 |             "symlinks/xcode/MacSDK/Frameworks/Carbon.Framework/**", | 
 |             "symlinks/xcode/MacSDK/Frameworks/CFNetwork.Framework/**", | 
 |             "symlinks/xcode/MacSDK/Frameworks/CloudKit.Framework/**", | 
 |             "symlinks/xcode/MacSDK/Frameworks/Cocoa.Framework/**", | 
 |             "symlinks/xcode/MacSDK/Frameworks/ColorSync.Framework/**", | 
 |             "symlinks/xcode/MacSDK/Frameworks/CoreData.Framework/**", | 
 |             "symlinks/xcode/MacSDK/Frameworks/CoreFoundation.Framework/**", | 
 |             "symlinks/xcode/MacSDK/Frameworks/CoreGraphics.Framework/**", | 
 |             "symlinks/xcode/MacSDK/Frameworks/CoreImage.Framework/**", | 
 |             "symlinks/xcode/MacSDK/Frameworks/CoreLocation.Framework/**", | 
 |             "symlinks/xcode/MacSDK/Frameworks/CoreServices.Framework/**", | 
 |             "symlinks/xcode/MacSDK/Frameworks/CoreText.Framework/**", | 
 |             "symlinks/xcode/MacSDK/Frameworks/CoreVideo.Framework/**", | 
 |             "symlinks/xcode/MacSDK/Frameworks/DiskArbitration.Framework/**", | 
 |             "symlinks/xcode/MacSDK/Frameworks/Foundation.Framework/**", | 
 |             "symlinks/xcode/MacSDK/Frameworks/ImageIO.Framework/**", | 
 |             "symlinks/xcode/MacSDK/Frameworks/IOKit.Framework/**", | 
 |             "symlinks/xcode/MacSDK/Frameworks/IOSurface.Framework/**", | 
 |             "symlinks/xcode/MacSDK/Frameworks/Metal.Framework/**", | 
 |             "symlinks/xcode/MacSDK/Frameworks/OpenGL.Framework/**", | 
 |             "symlinks/xcode/MacSDK/Frameworks/QuartzCore.Framework/**", | 
 |             "symlinks/xcode/MacSDK/Frameworks/Security.Framework/**", | 
 |             "symlinks/xcode/MacSDK/usr/include/**", | 
 |         ], | 
 |         allow_empty = False, | 
 |     ), | 
 |     visibility = ["//visibility:public"], | 
 | ) | 
 |  | 
 | filegroup( | 
 |     name = "link_files", | 
 |     srcs = [ | 
 |         "bin/clang", | 
 |         "bin/ld.lld", | 
 |         "bin/lld", | 
 |         "lib/libc++.a", | 
 |         "lib/libc++abi.a", | 
 |         "lib/libunwind.a", | 
 |     ] + glob( | 
 |         include = [ | 
 |             # libc++.tbd and libSystem.tbd live here. | 
 |             "symlinks/xcode/MacSDK/usr/lib/*", | 
 |         ], | 
 |         allow_empty = False, | 
 |     ), | 
 |     visibility = ["//visibility:public"], | 
 | ) | 
 | """, | 
 |         executable = False, | 
 |     ) | 
 |  | 
 | # https://bazel.build/rules/repository_rules | 
 | download_mac_toolchain = repository_rule( | 
 |     implementation = _download_mac_toolchain_impl, | 
 |     attrs = {}, | 
 |     doc = "Downloads clang to build Skia with." + | 
 |           "Assumes you have xcode located on your device and have" + | 
 |           "xcode-select in your $PATH.", | 
 | ) |