Skip to content

Commit ede1bd2

Browse files
Fix for issue #7724: ensure that distutils and python's own setup.py
honor the MacOSX SDK when one is specified. This is needed to be able to build using the 10.4u SDK while running on OSX 10.6. This is a fixed version of the patch in r80963, I've tested this patch on OSX and Linux.
1 parent ea62b28 commit ede1bd2

2 files changed

Lines changed: 133 additions & 22 deletions

File tree

Lib/distutils/unixccompiler.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
__revision__ = "$Id$"
1717

18-
import os, sys
18+
import os, sys, re
1919
from types import StringType, NoneType
2020

2121
from distutils import sysconfig
@@ -305,10 +305,30 @@ def find_library_file(self, dirs, lib, debug=0):
305305
dylib_f = self.library_filename(lib, lib_type='dylib')
306306
static_f = self.library_filename(lib, lib_type='static')
307307

308+
if sys.platform == 'darwin':
309+
# On OSX users can specify an alternate SDK using
310+
# '-isysroot', calculate the SDK root if it is specified
311+
# (and use it further on)
312+
cflags = sysconfig.get_config_var('CFLAGS')
313+
m = re.search(r'-isysroot\s+(\S+)', cflags)
314+
if m is None:
315+
sysroot = '/'
316+
else:
317+
sysroot = m.group(1)
318+
319+
320+
308321
for dir in dirs:
309322
shared = os.path.join(dir, shared_f)
310323
dylib = os.path.join(dir, dylib_f)
311324
static = os.path.join(dir, static_f)
325+
326+
if sys.platform == 'darwin' and (
327+
dir.startswith('/System/') or dir.startswith('/usr/')):
328+
shared = os.path.join(sysroot, dir[1:], shared_f)
329+
dylib = os.path.join(sysroot, dir[1:], dylib_f)
330+
static = os.path.join(sysroot, dir[1:], static_f)
331+
312332
# We're second-guessing the linker here, with not much hard
313333
# data to go on: GCC seems to prefer the shared library, so I'm
314334
# assuming that *all* Unix C compilers do. And of course I'm

setup.py

Lines changed: 112 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,25 @@ def add_dir_to_list(dirlist, dir):
2929
if dir is not None and os.path.isdir(dir) and dir not in dirlist:
3030
dirlist.insert(0, dir)
3131

32+
def macosx_sdk_root():
33+
"""
34+
Return the directory of the current OSX SDK,
35+
or '/' if no SDK was specified.
36+
"""
37+
cflags = sysconfig.get_config_var('CFLAGS')
38+
m = re.search(r'-isysroot\s+(\S+)', cflags)
39+
if m is None:
40+
sysroot = '/'
41+
else:
42+
sysroot = m.group(1)
43+
return sysroot
44+
45+
def is_macosx_sdk_path(path):
46+
"""
47+
Returns True if 'path' can be located in an OSX SDK
48+
"""
49+
return path.startswith('/usr/') or path.startswith('/System/')
50+
3251
def find_file(filename, std_dirs, paths):
3352
"""Searches for the directory where a given file is located,
3453
and returns a possibly-empty list of additional directories, or None
@@ -40,15 +59,28 @@ def find_file(filename, std_dirs, paths):
4059
'paths' is a list of additional locations to check; if the file is
4160
found in one of them, the resulting list will contain the directory.
4261
"""
62+
if sys.platform == 'darwin':
63+
# Honor the MacOSX SDK setting when one was specified.
64+
# An SDK is a directory with the same structure as a real
65+
# system, but with only header files and libraries.
66+
sysroot = macosx_sdk_root()
4367

4468
# Check the standard locations
4569
for dir in std_dirs:
4670
f = os.path.join(dir, filename)
71+
72+
if sys.platform == 'darwin' and is_macosx_sdk_path(dir):
73+
f = os.path.join(sysroot, dir[1:], filename)
74+
4775
if os.path.exists(f): return []
4876

4977
# Check the additional directories
5078
for dir in paths:
5179
f = os.path.join(dir, filename)
80+
81+
if sys.platform == 'darwin' and is_macosx_sdk_path(dir):
82+
f = os.path.join(sysroot, dir[1:], filename)
83+
5284
if os.path.exists(f):
5385
return [dir]
5486

@@ -60,11 +92,19 @@ def find_library_file(compiler, libname, std_dirs, paths):
6092
if result is None:
6193
return None
6294

95+
if sys.platform == 'darwin':
96+
sysroot = macosx_sdk_root()
97+
6398
# Check whether the found file is in one of the standard directories
6499
dirname = os.path.dirname(result)
65100
for p in std_dirs:
66101
# Ensure path doesn't end with path separator
67102
p = p.rstrip(os.sep)
103+
104+
if sys.platform == 'darwin' and is_macosx_sdk_path(p):
105+
if os.path.join(sysroot, p[1:]) == dirname:
106+
return [ ]
107+
68108
if p == dirname:
69109
return [ ]
70110

@@ -73,6 +113,11 @@ def find_library_file(compiler, libname, std_dirs, paths):
73113
for p in paths:
74114
# Ensure path doesn't end with path separator
75115
p = p.rstrip(os.sep)
116+
117+
if sys.platform == 'darwin' and is_macosx_sdk_path(p):
118+
if os.path.join(sysroot, p[1:]) == dirname:
119+
return [ p ]
120+
76121
if p == dirname:
77122
return [p]
78123
else:
@@ -560,7 +605,7 @@ def detect_modules(self):
560605
# library and then a static library, instead of first looking
561606
# for dynamic libraries on the entiry path.
562607
# This way a staticly linked custom readline gets picked up
563-
# before the (broken) dynamic library in /usr/lib.
608+
# before the (possibly broken) dynamic library in /usr/lib.
564609
readline_extra_link_args = ('-Wl,-search_paths_first',)
565610
else:
566611
readline_extra_link_args = ()
@@ -631,24 +676,24 @@ def detect_modules(self):
631676
openssl_ver = 0
632677
openssl_ver_re = re.compile(
633678
'^\s*#\s*define\s+OPENSSL_VERSION_NUMBER\s+(0x[0-9a-fA-F]+)' )
634-
for ssl_inc_dir in inc_dirs + search_for_ssl_incs_in:
635-
name = os.path.join(ssl_inc_dir, 'openssl', 'opensslv.h')
636-
if os.path.isfile(name):
637-
try:
638-
incfile = open(name, 'r')
639-
for line in incfile:
640-
m = openssl_ver_re.match(line)
641-
if m:
642-
openssl_ver = eval(m.group(1))
643-
break
644-
except IOError:
645-
pass
646679

647-
# first version found is what we'll use (as the compiler should)
648-
if openssl_ver:
649-
break
680+
# look for the openssl version header on the compiler search path.
681+
opensslv_h = find_file('openssl/opensslv.h', [],
682+
inc_dirs + search_for_ssl_incs_in)
683+
if opensslv_h:
684+
name = os.path.join(opensslv_h[0], 'openssl/opensslv.h')
685+
if sys.platform == 'darwin' and is_macosx_sdk_path(name):
686+
name = os.path.join(macosx_sdk_root(), name[1:])
687+
try:
688+
incfile = open(name, 'r')
689+
for line in incfile:
690+
m = openssl_ver_re.match(line)
691+
if m:
692+
openssl_ver = eval(m.group(1))
693+
except IOError, msg:
694+
print "IOError while reading opensshv.h:", msg
695+
pass
650696

651-
#print 'openssl_ver = 0x%08x' % openssl_ver
652697
min_openssl_ver = 0x00907000
653698
have_any_openssl = ssl_incs is not None and ssl_libs is not None
654699
have_usable_openssl = (have_any_openssl and
@@ -781,12 +826,19 @@ def gen_db_minor_ver_nums(major):
781826

782827
db_ver_inc_map = {}
783828

829+
if sys.platform == 'darwin':
830+
sysroot = macosx_sdk_root()
831+
784832
class db_found(Exception): pass
785833
try:
786834
# See whether there is a Sleepycat header in the standard
787835
# search path.
788836
for d in inc_dirs + db_inc_paths:
789837
f = os.path.join(d, "db.h")
838+
839+
if sys.platform == 'darwin' and is_macosx_sdk_path(d):
840+
f = os.path.join(sysroot, d[1:], "db.h")
841+
790842
if db_setup_debug: print "db: looking for db.h in", f
791843
if os.path.exists(f):
792844
f = open(f).read()
@@ -833,7 +885,20 @@ class db_found(Exception): pass
833885
db_incdir.replace("include", 'lib64'),
834886
db_incdir.replace("include", 'lib'),
835887
]
836-
db_dirs_to_check = filter(os.path.isdir, db_dirs_to_check)
888+
889+
if sys.platform != 'darwin':
890+
db_dirs_to_check = filter(os.path.isdir, db_dirs_to_check)
891+
892+
else:
893+
# Same as other branch, but takes OSX SDK into account
894+
tmp = []
895+
for dn in db_dirs_to_check:
896+
if is_macosx_sdk_path(dn):
897+
if os.path.isdir(os.path.join(sysroot, dn[1:])):
898+
tmp.append(dn)
899+
else:
900+
if os.path.isdir(dn):
901+
tmp.append(dn)
837902

838903
# Look for a version specific db-X.Y before an ambiguoius dbX
839904
# XXX should we -ever- look for a dbX name? Do any
@@ -895,8 +960,15 @@ class db_found(Exception): pass
895960
# Scan the default include directories before the SQLite specific
896961
# ones. This allows one to override the copy of sqlite on OSX,
897962
# where /usr/include contains an old version of sqlite.
963+
if sys.platform == 'darwin':
964+
sysroot = macosx_sdk_root()
965+
898966
for d in inc_dirs + sqlite_inc_paths:
899967
f = os.path.join(d, "sqlite3.h")
968+
969+
if sys.platform == 'darwin' and is_macosx_sdk_path(d):
970+
f = os.path.join(sysroot, d[1:], "sqlite3.h")
971+
900972
if os.path.exists(f):
901973
if sqlite_setup_debug: print "sqlite: found %s"%f
902974
incf = open(f).read()
@@ -984,6 +1056,12 @@ class db_found(Exception): pass
9841056
# the more recent berkeleydb's db.h file first in the include path
9851057
# when attempting to compile and it will fail.
9861058
f = "/usr/include/db.h"
1059+
1060+
if sys.platform == 'darwin':
1061+
if is_macosx_sdk_path(f):
1062+
sysroot = macosx_sdk_root()
1063+
f = os.path.join(sysroot, f[1:])
1064+
9871065
if os.path.exists(f) and not db_incs:
9881066
data = open(f).read()
9891067
m = re.search(r"#s*define\s+HASHVERSION\s+2\s*", data)
@@ -1490,14 +1568,22 @@ def detect_tkinter_darwin(self, inc_dirs, lib_dirs):
14901568
join(os.getenv('HOME'), '/Library/Frameworks')
14911569
]
14921570

1571+
sysroot = macosx_sdk_root()
1572+
14931573
# Find the directory that contains the Tcl.framework and Tk.framework
14941574
# bundles.
14951575
# XXX distutils should support -F!
14961576
for F in framework_dirs:
14971577
# both Tcl.framework and Tk.framework should be present
1578+
1579+
14981580
for fw in 'Tcl', 'Tk':
1499-
if not exists(join(F, fw + '.framework')):
1500-
break
1581+
if is_macosx_sdk_path(F):
1582+
if not exists(join(sysroot, F[1:], fw + '.framework')):
1583+
break
1584+
else:
1585+
if not exists(join(F, fw + '.framework')):
1586+
break
15011587
else:
15021588
# ok, F is now directory with both frameworks. Continure
15031589
# building
@@ -1527,7 +1613,12 @@ def detect_tkinter_darwin(self, inc_dirs, lib_dirs):
15271613
# architectures.
15281614
cflags = sysconfig.get_config_vars('CFLAGS')[0]
15291615
archs = re.findall('-arch\s+(\w+)', cflags)
1530-
fp = os.popen("file %s/Tk.framework/Tk | grep 'for architecture'"%(F,))
1616+
1617+
if is_macosx_sdk_path(F):
1618+
fp = os.popen("file %s/Tk.framework/Tk | grep 'for architecture'"%(os.path.join(sysroot, F[1:]),))
1619+
else:
1620+
fp = os.popen("file %s/Tk.framework/Tk | grep 'for architecture'"%(F,))
1621+
15311622
detected_archs = []
15321623
for ln in fp:
15331624
a = ln.split()[-1]

0 commit comments

Comments
 (0)