1*cda5da8dSAndroid Build Coastguard Worker"""distutils.unixccompiler 2*cda5da8dSAndroid Build Coastguard Worker 3*cda5da8dSAndroid Build Coastguard WorkerContains the UnixCCompiler class, a subclass of CCompiler that handles 4*cda5da8dSAndroid Build Coastguard Workerthe "typical" Unix-style command-line C compiler: 5*cda5da8dSAndroid Build Coastguard Worker * macros defined with -Dname[=value] 6*cda5da8dSAndroid Build Coastguard Worker * macros undefined with -Uname 7*cda5da8dSAndroid Build Coastguard Worker * include search directories specified with -Idir 8*cda5da8dSAndroid Build Coastguard Worker * libraries specified with -lllib 9*cda5da8dSAndroid Build Coastguard Worker * library search directories specified with -Ldir 10*cda5da8dSAndroid Build Coastguard Worker * compile handled by 'cc' (or similar) executable with -c option: 11*cda5da8dSAndroid Build Coastguard Worker compiles .c to .o 12*cda5da8dSAndroid Build Coastguard Worker * link static library handled by 'ar' command (possibly with 'ranlib') 13*cda5da8dSAndroid Build Coastguard Worker * link shared library handled by 'cc -shared' 14*cda5da8dSAndroid Build Coastguard Worker""" 15*cda5da8dSAndroid Build Coastguard Worker 16*cda5da8dSAndroid Build Coastguard Workerimport os, sys, re 17*cda5da8dSAndroid Build Coastguard Worker 18*cda5da8dSAndroid Build Coastguard Workerfrom distutils import sysconfig 19*cda5da8dSAndroid Build Coastguard Workerfrom distutils.dep_util import newer 20*cda5da8dSAndroid Build Coastguard Workerfrom distutils.ccompiler import \ 21*cda5da8dSAndroid Build Coastguard Worker CCompiler, gen_preprocess_options, gen_lib_options 22*cda5da8dSAndroid Build Coastguard Workerfrom distutils.errors import \ 23*cda5da8dSAndroid Build Coastguard Worker DistutilsExecError, CompileError, LibError, LinkError 24*cda5da8dSAndroid Build Coastguard Workerfrom distutils import log 25*cda5da8dSAndroid Build Coastguard Worker 26*cda5da8dSAndroid Build Coastguard Workerif sys.platform == 'darwin': 27*cda5da8dSAndroid Build Coastguard Worker import _osx_support 28*cda5da8dSAndroid Build Coastguard Worker 29*cda5da8dSAndroid Build Coastguard Worker# XXX Things not currently handled: 30*cda5da8dSAndroid Build Coastguard Worker# * optimization/debug/warning flags; we just use whatever's in Python's 31*cda5da8dSAndroid Build Coastguard Worker# Makefile and live with it. Is this adequate? If not, we might 32*cda5da8dSAndroid Build Coastguard Worker# have to have a bunch of subclasses GNUCCompiler, SGICCompiler, 33*cda5da8dSAndroid Build Coastguard Worker# SunCCompiler, and I suspect down that road lies madness. 34*cda5da8dSAndroid Build Coastguard Worker# * even if we don't know a warning flag from an optimization flag, 35*cda5da8dSAndroid Build Coastguard Worker# we need some way for outsiders to feed preprocessor/compiler/linker 36*cda5da8dSAndroid Build Coastguard Worker# flags in to us -- eg. a sysadmin might want to mandate certain flags 37*cda5da8dSAndroid Build Coastguard Worker# via a site config file, or a user might want to set something for 38*cda5da8dSAndroid Build Coastguard Worker# compiling this module distribution only via the setup.py command 39*cda5da8dSAndroid Build Coastguard Worker# line, whatever. As long as these options come from something on the 40*cda5da8dSAndroid Build Coastguard Worker# current system, they can be as system-dependent as they like, and we 41*cda5da8dSAndroid Build Coastguard Worker# should just happily stuff them into the preprocessor/compiler/linker 42*cda5da8dSAndroid Build Coastguard Worker# options and carry on. 43*cda5da8dSAndroid Build Coastguard Worker 44*cda5da8dSAndroid Build Coastguard Worker 45*cda5da8dSAndroid Build Coastguard Workerclass UnixCCompiler(CCompiler): 46*cda5da8dSAndroid Build Coastguard Worker 47*cda5da8dSAndroid Build Coastguard Worker compiler_type = 'unix' 48*cda5da8dSAndroid Build Coastguard Worker 49*cda5da8dSAndroid Build Coastguard Worker # These are used by CCompiler in two places: the constructor sets 50*cda5da8dSAndroid Build Coastguard Worker # instance attributes 'preprocessor', 'compiler', etc. from them, and 51*cda5da8dSAndroid Build Coastguard Worker # 'set_executable()' allows any of these to be set. The defaults here 52*cda5da8dSAndroid Build Coastguard Worker # are pretty generic; they will probably have to be set by an outsider 53*cda5da8dSAndroid Build Coastguard Worker # (eg. using information discovered by the sysconfig about building 54*cda5da8dSAndroid Build Coastguard Worker # Python extensions). 55*cda5da8dSAndroid Build Coastguard Worker executables = {'preprocessor' : None, 56*cda5da8dSAndroid Build Coastguard Worker 'compiler' : ["cc"], 57*cda5da8dSAndroid Build Coastguard Worker 'compiler_so' : ["cc"], 58*cda5da8dSAndroid Build Coastguard Worker 'compiler_cxx' : ["cc"], 59*cda5da8dSAndroid Build Coastguard Worker 'linker_so' : ["cc", "-shared"], 60*cda5da8dSAndroid Build Coastguard Worker 'linker_exe' : ["cc"], 61*cda5da8dSAndroid Build Coastguard Worker 'archiver' : ["ar", "-cr"], 62*cda5da8dSAndroid Build Coastguard Worker 'ranlib' : None, 63*cda5da8dSAndroid Build Coastguard Worker } 64*cda5da8dSAndroid Build Coastguard Worker 65*cda5da8dSAndroid Build Coastguard Worker if sys.platform[:6] == "darwin": 66*cda5da8dSAndroid Build Coastguard Worker executables['ranlib'] = ["ranlib"] 67*cda5da8dSAndroid Build Coastguard Worker 68*cda5da8dSAndroid Build Coastguard Worker # Needed for the filename generation methods provided by the base 69*cda5da8dSAndroid Build Coastguard Worker # class, CCompiler. NB. whoever instantiates/uses a particular 70*cda5da8dSAndroid Build Coastguard Worker # UnixCCompiler instance should set 'shared_lib_ext' -- we set a 71*cda5da8dSAndroid Build Coastguard Worker # reasonable common default here, but it's not necessarily used on all 72*cda5da8dSAndroid Build Coastguard Worker # Unices! 73*cda5da8dSAndroid Build Coastguard Worker 74*cda5da8dSAndroid Build Coastguard Worker src_extensions = [".c",".C",".cc",".cxx",".cpp",".m"] 75*cda5da8dSAndroid Build Coastguard Worker obj_extension = ".o" 76*cda5da8dSAndroid Build Coastguard Worker static_lib_extension = ".a" 77*cda5da8dSAndroid Build Coastguard Worker shared_lib_extension = ".so" 78*cda5da8dSAndroid Build Coastguard Worker dylib_lib_extension = ".dylib" 79*cda5da8dSAndroid Build Coastguard Worker xcode_stub_lib_extension = ".tbd" 80*cda5da8dSAndroid Build Coastguard Worker static_lib_format = shared_lib_format = dylib_lib_format = "lib%s%s" 81*cda5da8dSAndroid Build Coastguard Worker xcode_stub_lib_format = dylib_lib_format 82*cda5da8dSAndroid Build Coastguard Worker if sys.platform == "cygwin": 83*cda5da8dSAndroid Build Coastguard Worker exe_extension = ".exe" 84*cda5da8dSAndroid Build Coastguard Worker 85*cda5da8dSAndroid Build Coastguard Worker def preprocess(self, source, output_file=None, macros=None, 86*cda5da8dSAndroid Build Coastguard Worker include_dirs=None, extra_preargs=None, extra_postargs=None): 87*cda5da8dSAndroid Build Coastguard Worker fixed_args = self._fix_compile_args(None, macros, include_dirs) 88*cda5da8dSAndroid Build Coastguard Worker ignore, macros, include_dirs = fixed_args 89*cda5da8dSAndroid Build Coastguard Worker pp_opts = gen_preprocess_options(macros, include_dirs) 90*cda5da8dSAndroid Build Coastguard Worker pp_args = self.preprocessor + pp_opts 91*cda5da8dSAndroid Build Coastguard Worker if output_file: 92*cda5da8dSAndroid Build Coastguard Worker pp_args.extend(['-o', output_file]) 93*cda5da8dSAndroid Build Coastguard Worker if extra_preargs: 94*cda5da8dSAndroid Build Coastguard Worker pp_args[:0] = extra_preargs 95*cda5da8dSAndroid Build Coastguard Worker if extra_postargs: 96*cda5da8dSAndroid Build Coastguard Worker pp_args.extend(extra_postargs) 97*cda5da8dSAndroid Build Coastguard Worker pp_args.append(source) 98*cda5da8dSAndroid Build Coastguard Worker 99*cda5da8dSAndroid Build Coastguard Worker # We need to preprocess: either we're being forced to, or we're 100*cda5da8dSAndroid Build Coastguard Worker # generating output to stdout, or there's a target output file and 101*cda5da8dSAndroid Build Coastguard Worker # the source file is newer than the target (or the target doesn't 102*cda5da8dSAndroid Build Coastguard Worker # exist). 103*cda5da8dSAndroid Build Coastguard Worker if self.force or output_file is None or newer(source, output_file): 104*cda5da8dSAndroid Build Coastguard Worker if output_file: 105*cda5da8dSAndroid Build Coastguard Worker self.mkpath(os.path.dirname(output_file)) 106*cda5da8dSAndroid Build Coastguard Worker try: 107*cda5da8dSAndroid Build Coastguard Worker self.spawn(pp_args) 108*cda5da8dSAndroid Build Coastguard Worker except DistutilsExecError as msg: 109*cda5da8dSAndroid Build Coastguard Worker raise CompileError(msg) 110*cda5da8dSAndroid Build Coastguard Worker 111*cda5da8dSAndroid Build Coastguard Worker def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): 112*cda5da8dSAndroid Build Coastguard Worker compiler_so = self.compiler_so 113*cda5da8dSAndroid Build Coastguard Worker if sys.platform == 'darwin': 114*cda5da8dSAndroid Build Coastguard Worker compiler_so = _osx_support.compiler_fixup(compiler_so, 115*cda5da8dSAndroid Build Coastguard Worker cc_args + extra_postargs) 116*cda5da8dSAndroid Build Coastguard Worker try: 117*cda5da8dSAndroid Build Coastguard Worker self.spawn(compiler_so + cc_args + [src, '-o', obj] + 118*cda5da8dSAndroid Build Coastguard Worker extra_postargs) 119*cda5da8dSAndroid Build Coastguard Worker except DistutilsExecError as msg: 120*cda5da8dSAndroid Build Coastguard Worker raise CompileError(msg) 121*cda5da8dSAndroid Build Coastguard Worker 122*cda5da8dSAndroid Build Coastguard Worker def create_static_lib(self, objects, output_libname, 123*cda5da8dSAndroid Build Coastguard Worker output_dir=None, debug=0, target_lang=None): 124*cda5da8dSAndroid Build Coastguard Worker objects, output_dir = self._fix_object_args(objects, output_dir) 125*cda5da8dSAndroid Build Coastguard Worker 126*cda5da8dSAndroid Build Coastguard Worker output_filename = \ 127*cda5da8dSAndroid Build Coastguard Worker self.library_filename(output_libname, output_dir=output_dir) 128*cda5da8dSAndroid Build Coastguard Worker 129*cda5da8dSAndroid Build Coastguard Worker if self._need_link(objects, output_filename): 130*cda5da8dSAndroid Build Coastguard Worker self.mkpath(os.path.dirname(output_filename)) 131*cda5da8dSAndroid Build Coastguard Worker self.spawn(self.archiver + 132*cda5da8dSAndroid Build Coastguard Worker [output_filename] + 133*cda5da8dSAndroid Build Coastguard Worker objects + self.objects) 134*cda5da8dSAndroid Build Coastguard Worker 135*cda5da8dSAndroid Build Coastguard Worker # Not many Unices required ranlib anymore -- SunOS 4.x is, I 136*cda5da8dSAndroid Build Coastguard Worker # think the only major Unix that does. Maybe we need some 137*cda5da8dSAndroid Build Coastguard Worker # platform intelligence here to skip ranlib if it's not 138*cda5da8dSAndroid Build Coastguard Worker # needed -- or maybe Python's configure script took care of 139*cda5da8dSAndroid Build Coastguard Worker # it for us, hence the check for leading colon. 140*cda5da8dSAndroid Build Coastguard Worker if self.ranlib: 141*cda5da8dSAndroid Build Coastguard Worker try: 142*cda5da8dSAndroid Build Coastguard Worker self.spawn(self.ranlib + [output_filename]) 143*cda5da8dSAndroid Build Coastguard Worker except DistutilsExecError as msg: 144*cda5da8dSAndroid Build Coastguard Worker raise LibError(msg) 145*cda5da8dSAndroid Build Coastguard Worker else: 146*cda5da8dSAndroid Build Coastguard Worker log.debug("skipping %s (up-to-date)", output_filename) 147*cda5da8dSAndroid Build Coastguard Worker 148*cda5da8dSAndroid Build Coastguard Worker def link(self, target_desc, objects, 149*cda5da8dSAndroid Build Coastguard Worker output_filename, output_dir=None, libraries=None, 150*cda5da8dSAndroid Build Coastguard Worker library_dirs=None, runtime_library_dirs=None, 151*cda5da8dSAndroid Build Coastguard Worker export_symbols=None, debug=0, extra_preargs=None, 152*cda5da8dSAndroid Build Coastguard Worker extra_postargs=None, build_temp=None, target_lang=None): 153*cda5da8dSAndroid Build Coastguard Worker objects, output_dir = self._fix_object_args(objects, output_dir) 154*cda5da8dSAndroid Build Coastguard Worker fixed_args = self._fix_lib_args(libraries, library_dirs, 155*cda5da8dSAndroid Build Coastguard Worker runtime_library_dirs) 156*cda5da8dSAndroid Build Coastguard Worker libraries, library_dirs, runtime_library_dirs = fixed_args 157*cda5da8dSAndroid Build Coastguard Worker 158*cda5da8dSAndroid Build Coastguard Worker lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, 159*cda5da8dSAndroid Build Coastguard Worker libraries) 160*cda5da8dSAndroid Build Coastguard Worker if not isinstance(output_dir, (str, type(None))): 161*cda5da8dSAndroid Build Coastguard Worker raise TypeError("'output_dir' must be a string or None") 162*cda5da8dSAndroid Build Coastguard Worker if output_dir is not None: 163*cda5da8dSAndroid Build Coastguard Worker output_filename = os.path.join(output_dir, output_filename) 164*cda5da8dSAndroid Build Coastguard Worker 165*cda5da8dSAndroid Build Coastguard Worker if self._need_link(objects, output_filename): 166*cda5da8dSAndroid Build Coastguard Worker ld_args = (objects + self.objects + 167*cda5da8dSAndroid Build Coastguard Worker lib_opts + ['-o', output_filename]) 168*cda5da8dSAndroid Build Coastguard Worker if debug: 169*cda5da8dSAndroid Build Coastguard Worker ld_args[:0] = ['-g'] 170*cda5da8dSAndroid Build Coastguard Worker if extra_preargs: 171*cda5da8dSAndroid Build Coastguard Worker ld_args[:0] = extra_preargs 172*cda5da8dSAndroid Build Coastguard Worker if extra_postargs: 173*cda5da8dSAndroid Build Coastguard Worker ld_args.extend(extra_postargs) 174*cda5da8dSAndroid Build Coastguard Worker self.mkpath(os.path.dirname(output_filename)) 175*cda5da8dSAndroid Build Coastguard Worker try: 176*cda5da8dSAndroid Build Coastguard Worker if target_desc == CCompiler.EXECUTABLE: 177*cda5da8dSAndroid Build Coastguard Worker linker = self.linker_exe[:] 178*cda5da8dSAndroid Build Coastguard Worker else: 179*cda5da8dSAndroid Build Coastguard Worker linker = self.linker_so[:] 180*cda5da8dSAndroid Build Coastguard Worker if target_lang == "c++" and self.compiler_cxx: 181*cda5da8dSAndroid Build Coastguard Worker # skip over environment variable settings if /usr/bin/env 182*cda5da8dSAndroid Build Coastguard Worker # is used to set up the linker's environment. 183*cda5da8dSAndroid Build Coastguard Worker # This is needed on OSX. Note: this assumes that the 184*cda5da8dSAndroid Build Coastguard Worker # normal and C++ compiler have the same environment 185*cda5da8dSAndroid Build Coastguard Worker # settings. 186*cda5da8dSAndroid Build Coastguard Worker i = 0 187*cda5da8dSAndroid Build Coastguard Worker if os.path.basename(linker[0]) == "env": 188*cda5da8dSAndroid Build Coastguard Worker i = 1 189*cda5da8dSAndroid Build Coastguard Worker while '=' in linker[i]: 190*cda5da8dSAndroid Build Coastguard Worker i += 1 191*cda5da8dSAndroid Build Coastguard Worker 192*cda5da8dSAndroid Build Coastguard Worker if os.path.basename(linker[i]) == 'ld_so_aix': 193*cda5da8dSAndroid Build Coastguard Worker # AIX platforms prefix the compiler with the ld_so_aix 194*cda5da8dSAndroid Build Coastguard Worker # script, so we need to adjust our linker index 195*cda5da8dSAndroid Build Coastguard Worker offset = 1 196*cda5da8dSAndroid Build Coastguard Worker else: 197*cda5da8dSAndroid Build Coastguard Worker offset = 0 198*cda5da8dSAndroid Build Coastguard Worker 199*cda5da8dSAndroid Build Coastguard Worker linker[i+offset] = self.compiler_cxx[i] 200*cda5da8dSAndroid Build Coastguard Worker 201*cda5da8dSAndroid Build Coastguard Worker if sys.platform == 'darwin': 202*cda5da8dSAndroid Build Coastguard Worker linker = _osx_support.compiler_fixup(linker, ld_args) 203*cda5da8dSAndroid Build Coastguard Worker 204*cda5da8dSAndroid Build Coastguard Worker self.spawn(linker + ld_args) 205*cda5da8dSAndroid Build Coastguard Worker except DistutilsExecError as msg: 206*cda5da8dSAndroid Build Coastguard Worker raise LinkError(msg) 207*cda5da8dSAndroid Build Coastguard Worker else: 208*cda5da8dSAndroid Build Coastguard Worker log.debug("skipping %s (up-to-date)", output_filename) 209*cda5da8dSAndroid Build Coastguard Worker 210*cda5da8dSAndroid Build Coastguard Worker # -- Miscellaneous methods ----------------------------------------- 211*cda5da8dSAndroid Build Coastguard Worker # These are all used by the 'gen_lib_options() function, in 212*cda5da8dSAndroid Build Coastguard Worker # ccompiler.py. 213*cda5da8dSAndroid Build Coastguard Worker 214*cda5da8dSAndroid Build Coastguard Worker def library_dir_option(self, dir): 215*cda5da8dSAndroid Build Coastguard Worker return "-L" + dir 216*cda5da8dSAndroid Build Coastguard Worker 217*cda5da8dSAndroid Build Coastguard Worker def _is_gcc(self, compiler_name): 218*cda5da8dSAndroid Build Coastguard Worker # clang uses same syntax for rpath as gcc 219*cda5da8dSAndroid Build Coastguard Worker return any(name in compiler_name for name in ("gcc", "g++", "clang")) 220*cda5da8dSAndroid Build Coastguard Worker 221*cda5da8dSAndroid Build Coastguard Worker def runtime_library_dir_option(self, dir): 222*cda5da8dSAndroid Build Coastguard Worker # XXX Hackish, at the very least. See Python bug #445902: 223*cda5da8dSAndroid Build Coastguard Worker # http://sourceforge.net/tracker/index.php 224*cda5da8dSAndroid Build Coastguard Worker # ?func=detail&aid=445902&group_id=5470&atid=105470 225*cda5da8dSAndroid Build Coastguard Worker # Linkers on different platforms need different options to 226*cda5da8dSAndroid Build Coastguard Worker # specify that directories need to be added to the list of 227*cda5da8dSAndroid Build Coastguard Worker # directories searched for dependencies when a dynamic library 228*cda5da8dSAndroid Build Coastguard Worker # is sought. GCC on GNU systems (Linux, FreeBSD, ...) has to 229*cda5da8dSAndroid Build Coastguard Worker # be told to pass the -R option through to the linker, whereas 230*cda5da8dSAndroid Build Coastguard Worker # other compilers and gcc on other systems just know this. 231*cda5da8dSAndroid Build Coastguard Worker # Other compilers may need something slightly different. At 232*cda5da8dSAndroid Build Coastguard Worker # this time, there's no way to determine this information from 233*cda5da8dSAndroid Build Coastguard Worker # the configuration data stored in the Python installation, so 234*cda5da8dSAndroid Build Coastguard Worker # we use this hack. 235*cda5da8dSAndroid Build Coastguard Worker compiler = os.path.basename(sysconfig.get_config_var("CC")) 236*cda5da8dSAndroid Build Coastguard Worker if sys.platform[:6] == "darwin": 237*cda5da8dSAndroid Build Coastguard Worker # MacOSX's linker doesn't understand the -R flag at all 238*cda5da8dSAndroid Build Coastguard Worker return "-L" + dir 239*cda5da8dSAndroid Build Coastguard Worker elif sys.platform[:7] == "freebsd": 240*cda5da8dSAndroid Build Coastguard Worker return "-Wl,-rpath=" + dir 241*cda5da8dSAndroid Build Coastguard Worker elif sys.platform[:5] == "hp-ux": 242*cda5da8dSAndroid Build Coastguard Worker if self._is_gcc(compiler): 243*cda5da8dSAndroid Build Coastguard Worker return ["-Wl,+s", "-L" + dir] 244*cda5da8dSAndroid Build Coastguard Worker return ["+s", "-L" + dir] 245*cda5da8dSAndroid Build Coastguard Worker else: 246*cda5da8dSAndroid Build Coastguard Worker if self._is_gcc(compiler): 247*cda5da8dSAndroid Build Coastguard Worker # gcc on non-GNU systems does not need -Wl, but can 248*cda5da8dSAndroid Build Coastguard Worker # use it anyway. Since distutils has always passed in 249*cda5da8dSAndroid Build Coastguard Worker # -Wl whenever gcc was used in the past it is probably 250*cda5da8dSAndroid Build Coastguard Worker # safest to keep doing so. 251*cda5da8dSAndroid Build Coastguard Worker if sysconfig.get_config_var("GNULD") == "yes": 252*cda5da8dSAndroid Build Coastguard Worker # GNU ld needs an extra option to get a RUNPATH 253*cda5da8dSAndroid Build Coastguard Worker # instead of just an RPATH. 254*cda5da8dSAndroid Build Coastguard Worker return "-Wl,--enable-new-dtags,-R" + dir 255*cda5da8dSAndroid Build Coastguard Worker else: 256*cda5da8dSAndroid Build Coastguard Worker return "-Wl,-R" + dir 257*cda5da8dSAndroid Build Coastguard Worker else: 258*cda5da8dSAndroid Build Coastguard Worker # No idea how --enable-new-dtags would be passed on to 259*cda5da8dSAndroid Build Coastguard Worker # ld if this system was using GNU ld. Don't know if a 260*cda5da8dSAndroid Build Coastguard Worker # system like this even exists. 261*cda5da8dSAndroid Build Coastguard Worker return "-R" + dir 262*cda5da8dSAndroid Build Coastguard Worker 263*cda5da8dSAndroid Build Coastguard Worker def library_option(self, lib): 264*cda5da8dSAndroid Build Coastguard Worker return "-l" + lib 265*cda5da8dSAndroid Build Coastguard Worker 266*cda5da8dSAndroid Build Coastguard Worker def find_library_file(self, dirs, lib, debug=0): 267*cda5da8dSAndroid Build Coastguard Worker shared_f = self.library_filename(lib, lib_type='shared') 268*cda5da8dSAndroid Build Coastguard Worker dylib_f = self.library_filename(lib, lib_type='dylib') 269*cda5da8dSAndroid Build Coastguard Worker xcode_stub_f = self.library_filename(lib, lib_type='xcode_stub') 270*cda5da8dSAndroid Build Coastguard Worker static_f = self.library_filename(lib, lib_type='static') 271*cda5da8dSAndroid Build Coastguard Worker 272*cda5da8dSAndroid Build Coastguard Worker if sys.platform == 'darwin': 273*cda5da8dSAndroid Build Coastguard Worker # On OSX users can specify an alternate SDK using 274*cda5da8dSAndroid Build Coastguard Worker # '-isysroot', calculate the SDK root if it is specified 275*cda5da8dSAndroid Build Coastguard Worker # (and use it further on) 276*cda5da8dSAndroid Build Coastguard Worker # 277*cda5da8dSAndroid Build Coastguard Worker # Note that, as of Xcode 7, Apple SDKs may contain textual stub 278*cda5da8dSAndroid Build Coastguard Worker # libraries with .tbd extensions rather than the normal .dylib 279*cda5da8dSAndroid Build Coastguard Worker # shared libraries installed in /. The Apple compiler tool 280*cda5da8dSAndroid Build Coastguard Worker # chain handles this transparently but it can cause problems 281*cda5da8dSAndroid Build Coastguard Worker # for programs that are being built with an SDK and searching 282*cda5da8dSAndroid Build Coastguard Worker # for specific libraries. Callers of find_library_file need to 283*cda5da8dSAndroid Build Coastguard Worker # keep in mind that the base filename of the returned SDK library 284*cda5da8dSAndroid Build Coastguard Worker # file might have a different extension from that of the library 285*cda5da8dSAndroid Build Coastguard Worker # file installed on the running system, for example: 286*cda5da8dSAndroid Build Coastguard Worker # /Applications/Xcode.app/Contents/Developer/Platforms/ 287*cda5da8dSAndroid Build Coastguard Worker # MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/ 288*cda5da8dSAndroid Build Coastguard Worker # usr/lib/libedit.tbd 289*cda5da8dSAndroid Build Coastguard Worker # vs 290*cda5da8dSAndroid Build Coastguard Worker # /usr/lib/libedit.dylib 291*cda5da8dSAndroid Build Coastguard Worker cflags = sysconfig.get_config_var('CFLAGS') 292*cda5da8dSAndroid Build Coastguard Worker m = re.search(r'-isysroot\s*(\S+)', cflags) 293*cda5da8dSAndroid Build Coastguard Worker if m is None: 294*cda5da8dSAndroid Build Coastguard Worker sysroot = _osx_support._default_sysroot(sysconfig.get_config_var('CC')) 295*cda5da8dSAndroid Build Coastguard Worker else: 296*cda5da8dSAndroid Build Coastguard Worker sysroot = m.group(1) 297*cda5da8dSAndroid Build Coastguard Worker 298*cda5da8dSAndroid Build Coastguard Worker 299*cda5da8dSAndroid Build Coastguard Worker 300*cda5da8dSAndroid Build Coastguard Worker for dir in dirs: 301*cda5da8dSAndroid Build Coastguard Worker shared = os.path.join(dir, shared_f) 302*cda5da8dSAndroid Build Coastguard Worker dylib = os.path.join(dir, dylib_f) 303*cda5da8dSAndroid Build Coastguard Worker static = os.path.join(dir, static_f) 304*cda5da8dSAndroid Build Coastguard Worker xcode_stub = os.path.join(dir, xcode_stub_f) 305*cda5da8dSAndroid Build Coastguard Worker 306*cda5da8dSAndroid Build Coastguard Worker if sys.platform == 'darwin' and ( 307*cda5da8dSAndroid Build Coastguard Worker dir.startswith('/System/') or ( 308*cda5da8dSAndroid Build Coastguard Worker dir.startswith('/usr/') and not dir.startswith('/usr/local/'))): 309*cda5da8dSAndroid Build Coastguard Worker 310*cda5da8dSAndroid Build Coastguard Worker shared = os.path.join(sysroot, dir[1:], shared_f) 311*cda5da8dSAndroid Build Coastguard Worker dylib = os.path.join(sysroot, dir[1:], dylib_f) 312*cda5da8dSAndroid Build Coastguard Worker static = os.path.join(sysroot, dir[1:], static_f) 313*cda5da8dSAndroid Build Coastguard Worker xcode_stub = os.path.join(sysroot, dir[1:], xcode_stub_f) 314*cda5da8dSAndroid Build Coastguard Worker 315*cda5da8dSAndroid Build Coastguard Worker # We're second-guessing the linker here, with not much hard 316*cda5da8dSAndroid Build Coastguard Worker # data to go on: GCC seems to prefer the shared library, so I'm 317*cda5da8dSAndroid Build Coastguard Worker # assuming that *all* Unix C compilers do. And of course I'm 318*cda5da8dSAndroid Build Coastguard Worker # ignoring even GCC's "-static" option. So sue me. 319*cda5da8dSAndroid Build Coastguard Worker if os.path.exists(dylib): 320*cda5da8dSAndroid Build Coastguard Worker return dylib 321*cda5da8dSAndroid Build Coastguard Worker elif os.path.exists(xcode_stub): 322*cda5da8dSAndroid Build Coastguard Worker return xcode_stub 323*cda5da8dSAndroid Build Coastguard Worker elif os.path.exists(shared): 324*cda5da8dSAndroid Build Coastguard Worker return shared 325*cda5da8dSAndroid Build Coastguard Worker elif os.path.exists(static): 326*cda5da8dSAndroid Build Coastguard Worker return static 327*cda5da8dSAndroid Build Coastguard Worker 328*cda5da8dSAndroid Build Coastguard Worker # Oops, didn't find it in *any* of 'dirs' 329*cda5da8dSAndroid Build Coastguard Worker return None 330