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 } 58 59 darwinAvailableLibraries = append( 60 addPrefix([]string{ 61 "c", 62 "dl", 63 "m", 64 "ncurses", 65 "objc", 66 "pthread", 67 }, "-l"), 68 "-framework AppKit", 69 "-framework CoreFoundation", 70 "-framework Foundation", 71 "-framework IOKit", 72 "-framework Security", 73 "-framework SystemConfiguration", 74 ) 75) 76 77func init() { 78 if runtime.GOOS == "darwin" { 79 pctx.VariableFunc("macSdkRoot", func(ctx android.PackageVarContext) string { 80 return getMacTools(ctx).sdkRoot 81 }) 82 pctx.StaticVariable("macMinVersion", "10.14") 83 pctx.VariableFunc("MacArPath", func(ctx android.PackageVarContext) string { 84 return getMacTools(ctx).arPath 85 }) 86 87 pctx.VariableFunc("MacLipoPath", func(ctx android.PackageVarContext) string { 88 return getMacTools(ctx).lipoPath 89 }) 90 91 pctx.VariableFunc("MacStripPath", func(ctx android.PackageVarContext) string { 92 return getMacTools(ctx).stripPath 93 }) 94 95 pctx.VariableFunc("MacToolPath", func(ctx android.PackageVarContext) string { 96 return getMacTools(ctx).toolPath 97 }) 98 99 pctx.StaticVariable("DarwinCflags", strings.Join(darwinCflags, " ")) 100 pctx.StaticVariable("DarwinLdflags", strings.Join(darwinLdflags, " ")) 101 pctx.StaticVariable("DarwinLldflags", strings.Join(darwinLdflags, " ")) 102 103 pctx.StaticVariable("DarwinYasmFlags", "-f macho -m amd64") 104 } 105} 106 107func MacStripPath(ctx android.PathContext) string { 108 return getMacTools(ctx).stripPath 109} 110 111type macPlatformTools struct { 112 once sync.Once 113 err error 114 115 sdkRoot string 116 arPath string 117 lipoPath string 118 stripPath string 119 toolPath string 120} 121 122var macTools = &macPlatformTools{} 123 124func getMacTools(ctx android.PathContext) *macPlatformTools { 125 macTools.once.Do(func() { 126 xcrunTool := "/usr/bin/xcrun" 127 128 xcrun := func(args ...string) string { 129 if macTools.err != nil { 130 return "" 131 } 132 133 bytes, err := exec.Command(xcrunTool, append([]string{"--sdk", "macosx"}, args...)...).Output() 134 if err != nil { 135 macTools.err = fmt.Errorf("xcrun %q failed with: %q", args, err) 136 return "" 137 } 138 139 return strings.TrimSpace(string(bytes)) 140 } 141 142 sdkVersion := xcrun("--show-sdk-version") 143 sdkVersionSupported := false 144 for _, version := range darwinSupportedSdkVersions { 145 if version == sdkVersion || strings.HasPrefix(sdkVersion, version+".") { 146 sdkVersionSupported = true 147 } 148 } 149 if !sdkVersionSupported { 150 macTools.err = fmt.Errorf("Unsupported macOS SDK version %q not in %v", sdkVersion, darwinSupportedSdkVersions) 151 return 152 } 153 154 macTools.sdkRoot = xcrun("--show-sdk-path") 155 156 macTools.arPath = xcrun("--find", "ar") 157 macTools.lipoPath = xcrun("--find", "lipo") 158 macTools.stripPath = xcrun("--find", "strip") 159 macTools.toolPath = filepath.Dir(xcrun("--find", "ld")) 160 }) 161 if macTools.err != nil { 162 android.ReportPathErrorf(ctx, "%q", macTools.err) 163 } 164 return macTools 165} 166 167type toolchainDarwin struct { 168 cFlags, ldFlags string 169 toolchain64Bit 170 toolchainNoCrt 171 toolchainBase 172} 173 174type toolchainDarwinX86 struct { 175 toolchainDarwin 176} 177 178type toolchainDarwinArm struct { 179 toolchainDarwin 180} 181 182func (t *toolchainDarwinArm) Name() string { 183 return "arm64" 184} 185 186func (t *toolchainDarwinX86) Name() string { 187 return "x86_64" 188} 189 190func (t *toolchainDarwin) IncludeFlags() string { 191 return "" 192} 193 194func (t *toolchainDarwinArm) ClangTriple() string { 195 return "aarch64-apple-darwin" 196} 197 198func (t *toolchainDarwinX86) ClangTriple() string { 199 return "x86_64-apple-darwin" 200} 201 202func (t *toolchainDarwin) Cflags() string { 203 return "${config.DarwinCflags}" 204} 205 206func (t *toolchainDarwin) Cppflags() string { 207 return "" 208} 209 210func (t *toolchainDarwin) Ldflags() string { 211 return "${config.DarwinLdflags}" 212} 213 214func (t *toolchainDarwin) Lldflags() string { 215 return "${config.DarwinLldflags}" 216} 217 218func (t *toolchainDarwin) YasmFlags() string { 219 return "${config.DarwinYasmFlags}" 220} 221 222func (t *toolchainDarwin) ShlibSuffix() string { 223 return ".dylib" 224} 225 226func (t *toolchainDarwin) ExecutableSuffix() string { 227 return "" 228} 229 230func (t *toolchainDarwin) AvailableLibraries() []string { 231 return darwinAvailableLibraries 232} 233 234func (t *toolchainDarwin) ToolchainCflags() string { 235 return "-B${config.MacToolPath}" 236} 237 238func (t *toolchainDarwin) ToolchainLdflags() string { 239 return "-B${config.MacToolPath}" 240} 241 242var toolchainDarwinArmSingleton Toolchain = &toolchainDarwinArm{} 243var toolchainDarwinX86Singleton Toolchain = &toolchainDarwinX86{} 244 245func darwinArmToolchainFactory(arch android.Arch) Toolchain { 246 return toolchainDarwinArmSingleton 247} 248 249func darwinX86ToolchainFactory(arch android.Arch) Toolchain { 250 return toolchainDarwinX86Singleton 251} 252 253func init() { 254 registerToolchainFactory(android.Darwin, android.Arm64, darwinArmToolchainFactory) 255 registerToolchainFactory(android.Darwin, android.X86_64, darwinX86ToolchainFactory) 256} 257