Skip to content

Commit c730211

Browse files
authored
bpo-36231: Support building on macOS without /usr/include (GH-13773) (GH-14208)
1 parent 452b417 commit c730211

File tree

2 files changed

+49
-7
lines changed

2 files changed

+49
-7
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Support building Python on macOS without /usr/include installed. As of macOS
2+
10.14, system header files are only available within an SDK provided by
3+
either the Command Line Tools or the Xcode app.

setup.py

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,18 +90,57 @@ def sysroot_paths(make_vars, subdirs):
9090
break
9191
return dirs
9292

93+
MACOS_SDK_ROOT = None
94+
9395
def macosx_sdk_root():
96+
"""Return the directory of the current macOS SDK.
97+
98+
If no SDK was explicitly configured, call the compiler to find which
99+
include files paths are being searched by default. Use '/' if the
100+
compiler is searching /usr/include (meaning system header files are
101+
installed) or use the root of an SDK if that is being searched.
102+
(The SDK may be supplied via Xcode or via the Command Line Tools).
103+
The SDK paths used by Apple-supplied tool chains depend on the
104+
setting of various variables; see the xcrun man page for more info.
94105
"""
95-
Return the directory of the current OSX SDK,
96-
or '/' if no SDK was specified.
97-
"""
106+
global MACOS_SDK_ROOT
107+
108+
# If already called, return cached result.
109+
if MACOS_SDK_ROOT:
110+
return MACOS_SDK_ROOT
111+
98112
cflags = sysconfig.get_config_var('CFLAGS')
99113
m = re.search(r'-isysroot\s+(\S+)', cflags)
100-
if m is None:
101-
sysroot = '/'
114+
if m is not None:
115+
MACOS_SDK_ROOT = m.group(1)
102116
else:
103-
sysroot = m.group(1)
104-
return sysroot
117+
MACOS_SDK_ROOT = '/'
118+
cc = sysconfig.get_config_var('CC')
119+
tmpfile = '/tmp/setup_sdk_root.%d' % os.getpid()
120+
try:
121+
os.unlink(tmpfile)
122+
except:
123+
pass
124+
ret = os.system('%s -E -v - </dev/null 2>%s 1>/dev/null' % (cc, tmpfile))
125+
in_incdirs = False
126+
try:
127+
if ret >> 8 == 0:
128+
with open(tmpfile) as fp:
129+
for line in fp.readlines():
130+
if line.startswith("#include <...>"):
131+
in_incdirs = True
132+
elif line.startswith("End of search list"):
133+
in_incdirs = False
134+
elif in_incdirs:
135+
line = line.strip()
136+
if line == '/usr/include':
137+
MACOS_SDK_ROOT = '/'
138+
elif line.endswith(".sdk/usr/include"):
139+
MACOS_SDK_ROOT = line[:-12]
140+
finally:
141+
os.unlink(tmpfile)
142+
143+
return MACOS_SDK_ROOT
105144

106145
def is_macosx_sdk_path(path):
107146
"""

0 commit comments

Comments
 (0)