Skip to content
This repository was archived by the owner on Apr 21, 2025. It is now read-only.

Commit 137ddfc

Browse files
authored
Make symlinks so that RBE will work for Xcode toolchains (#417)
1 parent f72c5c1 commit 137ddfc

File tree

8 files changed

+164
-55
lines changed

8 files changed

+164
-55
lines changed

build/config/ios/ios_sdk.gni

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
# Use of this source code is governed by a BSD-style license that can be
33
# found in the LICENSE file.
44

5+
import("//build/toolchain/goma.gni")
6+
57
declare_args() {
68
# SDK path to use. When empty this will use the default SDK based on the
79
# value of use_ios_simulator.
@@ -27,15 +29,29 @@ declare_args() {
2729
}
2830

2931
if (ios_sdk_path == "") {
32+
ios_sdk_args = []
33+
if (use_goma) {
34+
ios_sdk_args += [
35+
"--symlink",
36+
rebase_path(root_gen_dir),
37+
]
38+
}
3039
if (!use_ios_simulator && ios_device_sdk_path == "") {
40+
ios_sdk_args += [
41+
"--sdk",
42+
"iphoneos",
43+
]
3144
_ios_device_sdk_result =
32-
exec_script("ios_sdk.py", [ "iphoneos" ], "list lines")
45+
exec_script("ios_sdk.py", ios_sdk_args, "list lines")
3346
ios_device_sdk_path = _ios_device_sdk_result[0]
3447
}
3548

3649
if (use_ios_simulator && ios_simulator_sdk_path == "") {
37-
_ios_sim_sdk_result =
38-
exec_script("ios_sdk.py", [ "iphonesimulator" ], "list lines")
50+
ios_sdk_args += [
51+
"--sdk",
52+
"iphonesimulator",
53+
]
54+
_ios_sim_sdk_result = exec_script("ios_sdk.py", ios_sdk_args, "list lines")
3955
ios_simulator_sdk_path = _ios_sim_sdk_result[0]
4056
}
4157

build/config/ios/ios_sdk.py

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,45 @@
22
# Use of this source code is governed by a BSD-style license that can be
33
# found in the LICENSE file.
44

5+
import argparse
6+
import errno
7+
import os
58
import subprocess
69
import sys
710

11+
sys.path.insert(1, '../../build')
12+
from pyutil.file_util import symlink
13+
814
# This script returns the path to the SDK of the given type. Pass the type of
9-
# SDK you want, which is typically "iphone" or "iphonesimulator".
15+
# SDK you want, which is typically 'iphone' or 'iphonesimulator'.
16+
17+
def main(argv):
18+
parser = argparse.ArgumentParser()
19+
parser.add_argument('--symlink',
20+
help='Whether to create a symlink in the buildroot to the SDK.')
21+
parser.add_argument('--sdk',
22+
choices=['iphone', 'iphonesimulator'],
23+
help='Which SDK to find.')
24+
args = parser.parse_args()
25+
26+
command = [
27+
'xcodebuild',
28+
'-version',
29+
'-sdk',
30+
args.sdk,
31+
'Path'
32+
]
1033

11-
if len(sys.argv) != 2:
12-
print "Takes one arg (SDK to find)"
13-
sys.exit(1)
34+
sdk_output = subprocess.check_output(command).strip()
35+
if args.symlink:
36+
symlink_target = os.path.join(args.symlink, os.path.basename(sdk_output))
37+
symlink(sdk_output, symlink_target)
38+
sdk_output = symlink_target
1439

15-
command = [
16-
'xcodebuild',
17-
'-version',
18-
'-sdk',
19-
sys.argv[1],
20-
'Path'
21-
]
40+
print(sdk_output)
41+
return 0
2242

23-
print subprocess.check_output(command).strip()
43+
if __name__ == '__main__':
44+
if sys.platform != 'darwin':
45+
raise Exception('This script only runs on Mac')
46+
sys.exit(main(sys.argv))

build/config/mac/mac_sdk.gni

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
# Use of this source code is governed by a BSD-style license that can be
33
# found in the LICENSE file.
44

5+
import("//build/toolchain/goma.gni")
6+
57
declare_args() {
68
# Minimum supported version of the Mac SDK.
79
mac_sdk_min = "10.12"
@@ -16,24 +18,24 @@ declare_args() {
1618
mac_sdk_path = ""
1719
}
1820

19-
find_sdk_args = [
20-
"--print_sdk_path",
21-
mac_sdk_min,
22-
]
23-
24-
# The tool will print the SDK path on the first line, and the version on the
25-
# second line.
26-
find_sdk_lines =
27-
exec_script("//build/mac/find_sdk.py", find_sdk_args, "list lines")
21+
if (mac_sdk_path == "") {
22+
find_sdk_args = []
23+
if (use_goma) {
24+
# RBE has a restriction that paths cannot come from outside the build root.
25+
find_sdk_args += [
26+
"--symlink",
27+
rebase_path(root_gen_dir),
28+
]
29+
}
30+
find_sdk_args += [
31+
"--print_sdk_path",
32+
mac_sdk_min,
33+
]
2834

29-
mac_sdk_version = find_sdk_lines[1]
35+
# The tool will print the SDK path on the first line, and the version on the
36+
# second line.
37+
find_sdk_lines =
38+
exec_script("//build/mac/find_sdk.py", find_sdk_args, "list lines")
3039

31-
if (mac_sdk_path == "") {
32-
# TODO(brettw) http://crbug.com/335325 when everybody moves to XCode 5 we
33-
# can remove the --print_sdk_path argument to find_sdk and instead just use
34-
# the following two lines to get the path. Although it looks longer here, it
35-
# saves forking a process in find_sdk.py so will be faster.
36-
#mac_sdk_root = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX"
37-
#mac_sdk_path = mac_sdk_root + mac_sdk_version + ".sdk"
3840
mac_sdk_path = find_sdk_lines[0]
3941
}

build/config/mac/xcode_toolchain.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,31 @@
33
# Use of this source code is governed by a BSD-style license that can be
44
# found in the LICENSE file.
55

6+
import argparse
67
import sys
78
import os
89
import subprocess
910

10-
def Main():
11-
path = subprocess.check_output(['/usr/bin/env', 'xcode-select', '-p']).strip();
11+
sys.path.insert(1, '../../build')
12+
from pyutil.file_util import symlink
13+
14+
15+
def main(argv):
16+
parser = argparse.ArgumentParser()
17+
parser.add_argument('--symlink',
18+
help='Whether to create a symlink in the buildroot to the SDK.')
19+
args = parser.parse_args()
20+
21+
path = subprocess.check_output(['/usr/bin/env', 'xcode-select', '-p']).strip()
1222
path = os.path.join(path, "Toolchains", "XcodeDefault.xctoolchain")
1323
assert os.path.exists(path)
14-
print path
24+
25+
if args.symlink:
26+
symlink_target = os.path.join(args.symlink, os.path.basename(path))
27+
symlink(path, symlink_target)
28+
path = symlink_target
29+
30+
print(path)
1531

1632
if __name__ == '__main__':
17-
sys.exit(Main())
33+
sys.exit(main(sys.argv))

build/config/sysroot.gni

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
# This header file defines the "sysroot" variable which is the absolute path
66
# of the sysroot. If no sysroot applies, the variable will be an empty string.
77

8+
import("//build/toolchain/goma.gni")
9+
810
declare_args() {
911
# The absolute path of the sysroot that is applied when compiling using
1012
# the target toolchain.
@@ -50,8 +52,15 @@ if (current_toolchain == default_toolchain && target_sysroot != "") {
5052
}
5153

5254
if ((is_mac || is_ios) && xcode_toolchain == "") {
55+
xcode_toolchain_args = []
56+
if (use_goma) {
57+
xcode_toolchain_args += [
58+
"--symlink",
59+
rebase_path(root_gen_dir),
60+
]
61+
}
5362
xcode_toolchain = exec_script("//build/config/mac/xcode_toolchain.py",
54-
[],
63+
xcode_toolchain_args,
5564
"trim string",
5665
[])
5766
}

build/mac/find_sdk.py

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@
1515
import subprocess
1616
import sys
1717

18-
1918
from optparse import OptionParser
2019

20+
sys.path.insert(1, '../../build')
21+
from pyutil.file_util import symlink
22+
2123

2224
def parse_version(version_str):
2325
"""'10.6' => [10, 6]"""
@@ -35,6 +37,9 @@ def main():
3537
parser.add_option("--print_sdk_path",
3638
action="store_true", dest="print_sdk_path", default=False,
3739
help="Additionaly print the path the SDK (appears first).")
40+
parser.add_option("--symlink",
41+
action="store", type="string", dest="symlink", default="",
42+
help="Whether to create a symlink in the buildroot to the SDK.")
3843
(options, args) = parser.parse_args()
3944
min_sdk_version = args[0]
4045

@@ -43,8 +48,7 @@ def main():
4348
stderr=subprocess.STDOUT)
4449
out, err = job.communicate()
4550
if job.returncode != 0:
46-
print >> sys.stderr, out
47-
print >> sys.stderr, err
51+
sys.stderr.writelines([out, err])
4852
raise Exception(('Error %d running xcode-select, you might have to run '
4953
'|sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer| '
5054
'if you are using Xcode 4.') % job.returncode)
@@ -64,27 +68,33 @@ def main():
6468
best_sdk = sorted(sdks, key=parse_version)[0]
6569

6670
if options.verify and best_sdk != min_sdk_version and not options.sdk_path:
67-
print >> sys.stderr, ''
68-
print >> sys.stderr, ' vvvvvvv'
69-
print >> sys.stderr, ''
70-
print >> sys.stderr, \
71-
'This build requires the %s SDK, but it was not found on your system.' \
72-
% min_sdk_version
73-
print >> sys.stderr, \
74-
'Either install it, or explicitly set mac_sdk in your GYP_DEFINES.'
75-
print >> sys.stderr, ''
76-
print >> sys.stderr, ' ^^^^^^^'
77-
print >> sys.stderr, ''
71+
sys.stderr.writelines([
72+
'',
73+
' vvvvvvv',
74+
'',
75+
'This build requires the %s SDK, but it was not found on your system.' \
76+
% min_sdk_version,
77+
'Either install it, or explicitly set mac_sdk in your gn args.',
78+
'',
79+
' ^^^^^^^',
80+
''])
7881
return min_sdk_version
7982

80-
if options.print_sdk_path:
81-
print subprocess.check_output(['xcodebuild', '-version', '-sdk',
82-
'macosx' + best_sdk, 'Path']).strip()
83+
if options.symlink or options.print_sdk_path:
84+
sdk_output = subprocess.check_output(['xcodebuild', '-version', '-sdk',
85+
'macosx' + best_sdk, 'Path']).strip()
86+
if options.symlink:
87+
symlink_target = os.path.join(options.symlink, os.path.basename(sdk_output))
88+
symlink(sdk_output, symlink_target)
89+
sdk_output = symlink_target
90+
91+
if options.print_sdk_path:
92+
print(sdk_output)
8393

8494
return best_sdk
8595

8696

8797
if __name__ == '__main__':
8898
if sys.platform != 'darwin':
8999
raise Exception("This script only runs on Mac")
90-
print main()
100+
print(main())

build/pyutil/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
2+
# Use of this source code is governed by a BSD-style license that can be
3+
# found in the LICENSE file.

build/pyutil/file_util.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
2+
# Use of this source code is governed by a BSD-style license that can be
3+
# found in the LICENSE file.
4+
5+
import errno
6+
import os
7+
8+
"""Creates a directory and its parents (i.e. `mkdir -p`).
9+
10+
If the directory already exists, does nothing."""
11+
def mkdir_p(path):
12+
try:
13+
os.makedirs(path)
14+
except OSError as exc:
15+
if exc.errno == errno.EEXIST and os.path.isdir(path):
16+
pass
17+
else:
18+
raise
19+
20+
21+
"""Creates or ovewrites a symlink from `link` to `target`."""
22+
def symlink(target, link):
23+
mkdir_p(os.path.dirname(link))
24+
tmp_link = link + '.tmp'
25+
try:
26+
os.remove(tmp_link)
27+
except OSError:
28+
pass
29+
os.symlink(target, tmp_link)
30+
os.rename(tmp_link, link)

0 commit comments

Comments
 (0)