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