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 // Workaround differences in inttypes.h between host and target. 33 //See bug 12708004. 34 "-D__STDC_FORMAT_MACROS", 35 "-D__STDC_CONSTANT_MACROS", 36 37 "-isysroot ${macSdkRoot}", 38 "-mmacosx-version-min=${macMinVersion}", 39 "-DMACOSX_DEPLOYMENT_TARGET=${macMinVersion}", 40 41 "-m64", 42 43 "-integrated-as", 44 "-fstack-protector-strong", 45 } 46 47 darwinLdflags = []string{ 48 "-isysroot ${macSdkRoot}", 49 "-Wl,-syslibroot,${macSdkRoot}", 50 "-mmacosx-version-min=${macMinVersion}", 51 "-m64", 52 "-mlinker-version=305", 53 } 54 55 darwinSupportedSdkVersions = []string{ 56 "11", 57 "12", 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 pctx.VariableFunc("macSdkRoot", func(ctx android.PackageVarContext) string { 80 return getMacTools(ctx).sdkRoot 81 }) 82 pctx.StaticVariable("macMinVersion", "10.13") 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 106func MacStripPath(ctx android.PathContext) string { 107 return getMacTools(ctx).stripPath 108} 109 110type macPlatformTools struct { 111 once sync.Once 112 err error 113 114 sdkRoot string 115 arPath string 116 lipoPath string 117 stripPath string 118 toolPath string 119} 120 121var macTools = &macPlatformTools{} 122 123func getMacTools(ctx android.PathContext) *macPlatformTools { 124 macTools.once.Do(func() { 125 xcrunTool := "/usr/bin/xcrun" 126 127 xcrun := func(args ...string) string { 128 if macTools.err != nil { 129 return "" 130 } 131 132 bytes, err := exec.Command(xcrunTool, append([]string{"--sdk", "macosx"}, args...)...).Output() 133 if err != nil { 134 macTools.err = fmt.Errorf("xcrun %q failed with: %q", args, err) 135 return "" 136 } 137 138 return strings.TrimSpace(string(bytes)) 139 } 140 141 sdkVersion := xcrun("--show-sdk-version") 142 sdkVersionSupported := false 143 for _, version := range darwinSupportedSdkVersions { 144 if version == sdkVersion || strings.HasPrefix(sdkVersion, version+".") { 145 sdkVersionSupported = true 146 } 147 } 148 if !sdkVersionSupported { 149 macTools.err = fmt.Errorf("Unsupported macOS SDK version %q not in %v", sdkVersion, darwinSupportedSdkVersions) 150 return 151 } 152 153 macTools.sdkRoot = xcrun("--show-sdk-path") 154 155 macTools.arPath = xcrun("--find", "ar") 156 macTools.lipoPath = xcrun("--find", "lipo") 157 macTools.stripPath = xcrun("--find", "strip") 158 macTools.toolPath = filepath.Dir(xcrun("--find", "ld")) 159 }) 160 if macTools.err != nil { 161 android.ReportPathErrorf(ctx, "%q", macTools.err) 162 } 163 return macTools 164} 165 166type toolchainDarwin struct { 167 cFlags, ldFlags string 168 toolchain64Bit 169 toolchainNoCrt 170 toolchainBase 171} 172 173type toolchainDarwinX86 struct { 174 toolchainDarwin 175} 176 177type toolchainDarwinArm struct { 178 toolchainDarwin 179} 180 181func (t *toolchainDarwinArm) Name() string { 182 return "arm64" 183} 184 185func (t *toolchainDarwinX86) Name() string { 186 return "x86_64" 187} 188 189func (t *toolchainDarwin) IncludeFlags() string { 190 return "" 191} 192 193func (t *toolchainDarwinArm) ClangTriple() string { 194 return "aarch64-apple-darwin" 195} 196 197func (t *toolchainDarwinX86) ClangTriple() string { 198 return "x86_64-apple-darwin" 199} 200 201func (t *toolchainDarwin) Cflags() string { 202 return "${config.DarwinCflags}" 203} 204 205func (t *toolchainDarwin) Cppflags() string { 206 return "" 207} 208 209func (t *toolchainDarwin) Ldflags() string { 210 return "${config.DarwinLdflags}" 211} 212 213func (t *toolchainDarwin) Lldflags() string { 214 return "${config.DarwinLldflags}" 215} 216 217func (t *toolchainDarwin) YasmFlags() string { 218 return "${config.DarwinYasmFlags}" 219} 220 221func (t *toolchainDarwin) ShlibSuffix() string { 222 return ".dylib" 223} 224 225func (t *toolchainDarwin) ExecutableSuffix() string { 226 return "" 227} 228 229func (t *toolchainDarwin) AvailableLibraries() []string { 230 return darwinAvailableLibraries 231} 232 233func (t *toolchainDarwin) ToolchainCflags() string { 234 return "-B${config.MacToolPath}" 235} 236 237func (t *toolchainDarwin) ToolchainLdflags() string { 238 return "-B${config.MacToolPath}" 239} 240 241var toolchainDarwinArmSingleton Toolchain = &toolchainDarwinArm{} 242var toolchainDarwinX86Singleton Toolchain = &toolchainDarwinX86{} 243 244func darwinArmToolchainFactory(arch android.Arch) Toolchain { 245 return toolchainDarwinArmSingleton 246} 247 248func darwinX86ToolchainFactory(arch android.Arch) Toolchain { 249 return toolchainDarwinX86Singleton 250} 251 252func init() { 253 registerToolchainFactory(android.Darwin, android.Arm64, darwinArmToolchainFactory) 254 registerToolchainFactory(android.Darwin, android.X86_64, darwinX86ToolchainFactory) 255} 256