• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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