1""" 2This file assembles a toolchain for a Mac host (either M1 or Intel) using the Clang Compiler 3and a locally-installed XCode. 4 5It downloads the necessary executables and creates symlinks in the external subfolder of the Bazel 6cache (the same place third party deps are downloaded with http_archive or similar functions in 7WORKSPACE.bazel). These will be able to be used via our 8custom c++ toolchain configuration (see //toolchain/mac_toolchain_config.bzl) 9 10The destination folder for these files and symlinks are: 11 [outputRoot (aka Bazel cache)]/[outputUserRoot]/[outputBase]/external/clang_mac 12 (See https://bazel.build/docs/output_directories#layout-diagram) 13""" 14 15load(":clang_layering_check.bzl", "generate_system_module_map") 16load(":utils.bzl", "gcs_mirror_url") 17 18# From https://github.com/llvm/llvm-project/releases/tag/llvmorg-15.0.1 19# When updating this, don't forget to use //bazel/gcs_mirror to upload a new version. 20# go run bazel/gcs_mirror/gcs_mirror.go --url [clang_url] --sha256 [clang_sha256] 21clang_prefix_arm64 = "clang+llvm-15.0.1-arm64-apple-darwin21.0" 22clang_sha256_arm64 = "858f86d96b5e4880f69f7a583daddbf97ee94e7cffce0d53aa05cba6967f13b8" 23clang_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" 24 25clang_prefix_amd64 = "clang+llvm-15.0.1-x86_64-apple-darwin" 26clang_sha256_amd64 = "0b2f1a811e68d011344103274733b7670c15bbe08b2a3a5140ccad8e19d9311e" 27clang_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" 28 29def _get_system_xcode_path(ctx): 30 # https://developer.apple.com/library/archive/technotes/tn2339/_index.html 31 res = ctx.execute(["xcode-select", "--print-path"]) 32 if res.return_code != 0: 33 fail("Error Getting XCode path: " + res.stderr) 34 return res.stdout.rstrip() 35 36def _delete_macos_sdk_symlinks(ctx): 37 ctx.delete("./symlinks/xcode/MacSDK/usr") 38 ctx.delete("./symlinks/xcode/MacSDK/System/Library/Frameworks") 39 40def _create_macos_sdk_symlinks(ctx): 41 system_xcode_path = _get_system_xcode_path(ctx) 42 43 # https://bazel.build/rules/lib/actions#symlink 44 ctx.symlink( 45 # from = 46 system_xcode_path + "/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr", 47 # to = 48 "./symlinks/xcode/MacSDK/usr", 49 ) 50 51 # It is very important to symlink the frameworks directory to [sysroot]/System/Library/Frameworks 52 # because some Frameworks "re-export" other frameworks. These framework paths are relative to 53 # the sysroot (which on a typical machine is /), and it is difficult to change these paths. 54 # By making the symlinks emulate the original path structure, we can keep those re-exports 55 # from breaking. 56 ctx.symlink( 57 # from = 58 system_xcode_path + "/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks", 59 # to = 60 "./symlinks/xcode/MacSDK/System/Library/Frameworks", 61 ) 62 63def _download_mac_toolchain_impl(ctx): 64 # https://bazel.build/rules/lib/repository_ctx#os 65 # https://bazel.build/rules/lib/repository_os 66 if ctx.os.arch == "aarch64": 67 clang_url = clang_url_arm64 68 clang_sha256 = clang_sha256_arm64 69 clang_prefix = clang_prefix_arm64 70 else: 71 clang_url = clang_url_amd64 72 clang_sha256 = clang_sha256_amd64 73 clang_prefix = clang_prefix_amd64 74 75 # Download the clang toolchain (the extraction can take a while) 76 # https://bazel.build/rules/lib/repository_ctx#download_and_extract 77 ctx.download_and_extract( 78 url = gcs_mirror_url(clang_url, clang_sha256), 79 output = "", 80 stripPrefix = clang_prefix, 81 sha256 = clang_sha256, 82 ) 83 84 # Some std library headers use #include_next to include system specific headers, and 85 # some skia source files require Xcode headers when compiling, (see SkTypes.h and look 86 # for TargetedConditionals.h)) All of these are located in Xcode, stopping the Mac 87 # builds from being purely hermetic. 88 # For now, we can grab the user's Xcode path by calling xcode-select and create a symlink in 89 # our toolchain directory to refer to during compilation. 90 91 _delete_macos_sdk_symlinks(ctx) 92 _create_macos_sdk_symlinks(ctx) 93 94 # This list of files lines up with _make_default_flags() in mac_toolchain_config.bzl 95 # It is all locations that our toolchain could find a system header. 96 builtin_include_directories = [ 97 "include/c++/v1", 98 "lib/clang/15.0.1/include", 99 "symlinks/xcode/MacSDK/System/Library/Frameworks", 100 "symlinks/xcode/MacSDK/usr/include", 101 ] 102 103 generate_system_module_map( 104 ctx, 105 module_file = "toolchain_system_headers.modulemap", 106 folders = builtin_include_directories, 107 ) 108 109 # Create a BUILD.bazel file that makes the files necessary for compiling, 110 # linking and creating archive files visible to Bazel. 111 # The smaller the globs are, the more performant the sandboxed builds will be. 112 # Additionally, globs that are too wide can pick up infinite symlink loops, 113 # and be difficult to quash: https://github.com/bazelbuild/bazel/issues/13950 114 # https://bazel.build/rules/lib/repository_ctx#file 115 ctx.file( 116 "BUILD.bazel", 117 content = """ 118# DO NOT EDIT THIS BAZEL FILE DIRECTLY 119# Generated from ctx.file action in download_mac_toolchain.bzl 120filegroup( 121 name = "generated_module_map", 122 srcs = ["toolchain_system_headers.modulemap"], 123 visibility = ["//visibility:public"], 124) 125 126filegroup( 127 name = "archive_files", 128 srcs = [ 129 "bin/llvm-ar", 130 ], 131 visibility = ["//visibility:public"], 132) 133 134# Any framework that Skia depends on directly or indirectly needs to be listed here. 135FRAMEWORK_GLOB = [ 136 "symlinks/xcode/MacSDK/System/Library/Frameworks/AppKit.Framework/**", 137 "symlinks/xcode/MacSDK/System/Library/Frameworks/ApplicationServices.Framework/**", 138 "symlinks/xcode/MacSDK/System/Library/Frameworks/Carbon.Framework/**", 139 "symlinks/xcode/MacSDK/System/Library/Frameworks/CFNetwork.Framework/**", 140 "symlinks/xcode/MacSDK/System/Library/Frameworks/CloudKit.Framework/**", 141 "symlinks/xcode/MacSDK/System/Library/Frameworks/Cocoa.Framework/**", 142 "symlinks/xcode/MacSDK/System/Library/Frameworks/ColorSync.Framework/**", 143 "symlinks/xcode/MacSDK/System/Library/Frameworks/CoreData.Framework/**", 144 "symlinks/xcode/MacSDK/System/Library/Frameworks/CoreFoundation.Framework/**", 145 "symlinks/xcode/MacSDK/System/Library/Frameworks/CoreGraphics.Framework/**", 146 "symlinks/xcode/MacSDK/System/Library/Frameworks/CoreImage.Framework/**", 147 "symlinks/xcode/MacSDK/System/Library/Frameworks/CoreLocation.Framework/**", 148 "symlinks/xcode/MacSDK/System/Library/Frameworks/CoreServices.Framework/**", 149 "symlinks/xcode/MacSDK/System/Library/Frameworks/CoreText.Framework/**", 150 "symlinks/xcode/MacSDK/System/Library/Frameworks/CoreVideo.Framework/**", 151 "symlinks/xcode/MacSDK/System/Library/Frameworks/DiskArbitration.Framework/**", 152 "symlinks/xcode/MacSDK/System/Library/Frameworks/Foundation.Framework/**", 153 "symlinks/xcode/MacSDK/System/Library/Frameworks/ImageIO.Framework/**", 154 "symlinks/xcode/MacSDK/System/Library/Frameworks/IOKit.Framework/**", 155 "symlinks/xcode/MacSDK/System/Library/Frameworks/IOSurface.Framework/**", 156 "symlinks/xcode/MacSDK/System/Library/Frameworks/Metal.Framework/**", 157 "symlinks/xcode/MacSDK/System/Library/Frameworks/MetalKit.Framework/**", 158 "symlinks/xcode/MacSDK/System/Library/Frameworks/OpenGL.Framework/**", 159 "symlinks/xcode/MacSDK/System/Library/Frameworks/QuartzCore.Framework/**", 160 "symlinks/xcode/MacSDK/System/Library/Frameworks/Security.Framework/**", 161] 162 163filegroup( 164 name = "compile_files", 165 srcs = [ 166 "bin/clang", 167 ] + glob( 168 include = [ 169 "include/c++/v1/**", 170 "lib/clang/15.0.1/include/**", 171 "symlinks/xcode/MacSDK/usr/include/**", 172 ] + FRAMEWORK_GLOB, 173 allow_empty = False, 174 ), 175 visibility = ["//visibility:public"], 176) 177 178filegroup( 179 name = "link_files", 180 srcs = [ 181 "bin/clang", 182 "bin/ld.lld", 183 "bin/lld", 184 "lib/libc++.a", 185 "lib/libc++abi.a", 186 "lib/libunwind.a", 187 ] + glob( 188 include = [ 189 # libc++.tbd and libSystem.tbd live here. 190 "symlinks/xcode/MacSDK/usr/lib/*", 191 ] + FRAMEWORK_GLOB, 192 allow_empty = False, 193 ), 194 visibility = ["//visibility:public"], 195) 196""", 197 executable = False, 198 ) 199 200# https://bazel.build/rules/repository_rules 201download_mac_toolchain = repository_rule( 202 implementation = _download_mac_toolchain_impl, 203 attrs = {}, 204 doc = "Downloads clang to build Skia with." + 205 "Assumes you have xcode located on your device and have" + 206 "xcode-select in your $PATH.", 207) 208