1// Copyright 2016 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package config 16 17import ( 18 "fmt" 19 "os/exec" 20 "path/filepath" 21 "runtime" 22 "strings" 23 "sync" 24 25 "android/soong/android" 26) 27 28var ( 29 darwinCflags = []string{ 30 "-fPIC", 31 "-funwind-tables", 32 "-fno-omit-frame-pointer", 33 34 "-isysroot ${macSdkRoot}", 35 "-mmacosx-version-min=${macMinVersion}", 36 "-DMACOSX_DEPLOYMENT_TARGET=${macMinVersion}", 37 38 "-m64", 39 40 "-integrated-as", 41 "-fstack-protector-strong", 42 } 43 44 darwinLdflags = []string{ 45 "-isysroot ${macSdkRoot}", 46 "-Wl,-syslibroot,${macSdkRoot}", 47 "-mmacosx-version-min=${macMinVersion}", 48 "-m64", 49 "-mlinker-version=305", 50 } 51 52 darwinSupportedSdkVersions = []string{ 53 "11", 54 "12", 55 "13", 56 "14", 57 "15", 58 } 59 60 darwinAvailableLibraries = append( 61 addPrefix([]string{ 62 "c", 63 "dl", 64 "m", 65 "ncurses", 66 "objc", 67 "pthread", 68 }, "-l"), 69 "-framework AppKit", 70 "-framework CoreFoundation", 71 "-framework Foundation", 72 "-framework IOKit", 73 "-framework Security", 74 "-framework SystemConfiguration", 75 ) 76) 77 78func init() { 79 if runtime.GOOS == "darwin" { 80 pctx.VariableFunc("macSdkRoot", func(ctx android.PackageVarContext) string { 81 return getMacTools(ctx).sdkRoot 82 }) 83 pctx.StaticVariable("macMinVersion", "10.14") 84 pctx.VariableFunc("MacArPath", func(ctx android.PackageVarContext) string { 85 return getMacTools(ctx).arPath 86 }) 87 88 pctx.VariableFunc("MacLipoPath", func(ctx android.PackageVarContext) string { 89 return getMacTools(ctx).lipoPath 90 }) 91 92 pctx.VariableFunc("MacStripPath", func(ctx android.PackageVarContext) string { 93 return getMacTools(ctx).stripPath 94 }) 95 96 pctx.VariableFunc("MacToolPath", func(ctx android.PackageVarContext) string { 97 return getMacTools(ctx).toolPath 98 }) 99 100 pctx.StaticVariable("DarwinCflags", strings.Join(darwinCflags, " ")) 101 pctx.StaticVariable("DarwinLdflags", strings.Join(darwinLdflags, " ")) 102 pctx.StaticVariable("DarwinLldflags", strings.Join(darwinLdflags, " ")) 103 104 pctx.StaticVariable("DarwinYasmFlags", "-f macho -m amd64") 105 } 106} 107 108func MacStripPath(ctx android.PathContext) string { 109 return getMacTools(ctx).stripPath 110} 111 112type macPlatformTools struct { 113 once sync.Once 114 err error 115 116 sdkRoot string 117 arPath string 118 lipoPath string 119 stripPath string 120 toolPath string 121} 122 123var macTools = &macPlatformTools{} 124 125func getMacTools(ctx android.PathContext) *macPlatformTools { 126 macTools.once.Do(func() { 127 xcrunTool := "/usr/bin/xcrun" 128 129 xcrun := func(args ...string) string { 130 if macTools.err != nil { 131 return "" 132 } 133 134 bytes, err := exec.Command(xcrunTool, append([]string{"--sdk", "macosx"}, args...)...).Output() 135 if err != nil { 136 macTools.err = fmt.Errorf("xcrun %q failed with: %q", args, err) 137 return "" 138 } 139 140 return strings.TrimSpace(string(bytes)) 141 } 142 143 sdkVersion := xcrun("--show-sdk-version") 144 sdkVersionSupported := false 145 for _, version := range darwinSupportedSdkVersions { 146 if version == sdkVersion || strings.HasPrefix(sdkVersion, version+".") { 147 sdkVersionSupported = true 148 } 149 } 150 if !sdkVersionSupported { 151 macTools.err = fmt.Errorf("Unsupported macOS SDK version %q not in %v", sdkVersion, darwinSupportedSdkVersions) 152 return 153 } 154 155 macTools.sdkRoot = xcrun("--show-sdk-path") 156 157 macTools.arPath = xcrun("--find", "ar") 158 macTools.lipoPath = xcrun("--find", "lipo") 159 macTools.stripPath = xcrun("--find", "strip") 160 macTools.toolPath = filepath.Dir(xcrun("--find", "ld")) 161 }) 162 if macTools.err != nil { 163 android.ReportPathErrorf(ctx, "%q", macTools.err) 164 } 165 return macTools 166} 167 168type toolchainDarwin struct { 169 cFlags, ldFlags string 170 toolchain64Bit 171 toolchainNoCrt 172 toolchainBase 173} 174 175type toolchainDarwinX86 struct { 176 toolchainDarwin 177} 178 179type toolchainDarwinArm struct { 180 toolchainDarwin 181} 182 183func (t *toolchainDarwinArm) Name() string { 184 return "arm64" 185} 186 187func (t *toolchainDarwinX86) Name() string { 188 return "x86_64" 189} 190 191func (t *toolchainDarwin) IncludeFlags() string { 192 return "" 193} 194 195func (t *toolchainDarwinArm) ClangTriple() string { 196 return "aarch64-apple-darwin" 197} 198 199func (t *toolchainDarwinX86) ClangTriple() string { 200 return "x86_64-apple-darwin" 201} 202 203func (t *toolchainDarwin) Cflags() string { 204 return "${config.DarwinCflags}" 205} 206 207func (t *toolchainDarwin) Cppflags() string { 208 return "" 209} 210 211func (t *toolchainDarwin) Ldflags() string { 212 return "${config.DarwinLdflags}" 213} 214 215func (t *toolchainDarwin) Lldflags() string { 216 return "${config.DarwinLldflags}" 217} 218 219func (t *toolchainDarwin) YasmFlags() string { 220 return "${config.DarwinYasmFlags}" 221} 222 223func (t *toolchainDarwin) ShlibSuffix() string { 224 return ".dylib" 225} 226 227func (t *toolchainDarwin) ExecutableSuffix() string { 228 return "" 229} 230 231func (t *toolchainDarwin) AvailableLibraries() []string { 232 return darwinAvailableLibraries 233} 234 235func (t *toolchainDarwin) ToolchainCflags() string { 236 return "-B${config.MacToolPath}" 237} 238 239func (t *toolchainDarwin) ToolchainLdflags() string { 240 return "-B${config.MacToolPath}" 241} 242 243var toolchainDarwinArmSingleton Toolchain = &toolchainDarwinArm{} 244var toolchainDarwinX86Singleton Toolchain = &toolchainDarwinX86{} 245 246func darwinArmToolchainFactory(arch android.Arch) Toolchain { 247 return toolchainDarwinArmSingleton 248} 249 250func darwinX86ToolchainFactory(arch android.Arch) Toolchain { 251 return toolchainDarwinX86Singleton 252} 253 254func init() { 255 registerToolchainFactory(android.Darwin, android.Arm64, darwinArmToolchainFactory) 256 registerToolchainFactory(android.Darwin, android.X86_64, darwinX86ToolchainFactory) 257} 258