ยปCore Development>Code coverage>setup.py

Python code coverage for setup.py

#countcontent
1n/a# Autodetecting setup.py script for building the Python extensions
2n/a#
3n/a
4n/aimport sys, os, importlib.machinery, re, optparse
5n/afrom glob import glob
6n/aimport importlib._bootstrap
7n/aimport importlib.util
8n/aimport sysconfig
9n/a
10n/afrom distutils import log
11n/afrom distutils.errors import *
12n/afrom distutils.core import Extension, setup
13n/afrom distutils.command.build_ext import build_ext
14n/afrom distutils.command.install import install
15n/afrom distutils.command.install_lib import install_lib
16n/afrom distutils.command.build_scripts import build_scripts
17n/afrom distutils.spawn import find_executable
18n/a
19n/across_compiling = "_PYTHON_HOST_PLATFORM" in os.environ
20n/a
21n/a# Add special CFLAGS reserved for building the interpreter and the stdlib
22n/a# modules (Issue #21121).
23n/acflags = sysconfig.get_config_var('CFLAGS')
24n/apy_cflags_nodist = sysconfig.get_config_var('PY_CFLAGS_NODIST')
25n/asysconfig.get_config_vars()['CFLAGS'] = cflags + ' ' + py_cflags_nodist
26n/a
27n/aclass Dummy:
28n/a """Hack for parallel build"""
29n/a ProcessPoolExecutor = None
30n/asys.modules['concurrent.futures.process'] = Dummy
31n/a
32n/adef get_platform():
33n/a # cross build
34n/a if "_PYTHON_HOST_PLATFORM" in os.environ:
35n/a return os.environ["_PYTHON_HOST_PLATFORM"]
36n/a # Get value of sys.platform
37n/a if sys.platform.startswith('osf1'):
38n/a return 'osf1'
39n/a return sys.platform
40n/ahost_platform = get_platform()
41n/a
42n/a# Were we compiled --with-pydebug or with #define Py_DEBUG?
43n/aCOMPILED_WITH_PYDEBUG = ('--with-pydebug' in sysconfig.get_config_var("CONFIG_ARGS"))
44n/a
45n/a# This global variable is used to hold the list of modules to be disabled.
46n/adisabled_module_list = []
47n/a
48n/adef add_dir_to_list(dirlist, dir):
49n/a """Add the directory 'dir' to the list 'dirlist' (after any relative
50n/a directories) if:
51n/a
52n/a 1) 'dir' is not already in 'dirlist'
53n/a 2) 'dir' actually exists, and is a directory.
54n/a """
55n/a if dir is None or not os.path.isdir(dir) or dir in dirlist:
56n/a return
57n/a for i, path in enumerate(dirlist):
58n/a if not os.path.isabs(path):
59n/a dirlist.insert(i + 1, dir)
60n/a return
61n/a dirlist.insert(0, dir)
62n/a
63n/adef macosx_sdk_root():
64n/a """
65n/a Return the directory of the current OSX SDK,
66n/a or '/' if no SDK was specified.
67n/a """
68n/a cflags = sysconfig.get_config_var('CFLAGS')
69n/a m = re.search(r'-isysroot\s+(\S+)', cflags)
70n/a if m is None:
71n/a sysroot = '/'
72n/a else:
73n/a sysroot = m.group(1)
74n/a return sysroot
75n/a
76n/adef is_macosx_sdk_path(path):
77n/a """
78n/a Returns True if 'path' can be located in an OSX SDK
79n/a """
80n/a return ( (path.startswith('/usr/') and not path.startswith('/usr/local'))
81n/a or path.startswith('/System/')
82n/a or path.startswith('/Library/') )
83n/a
84n/adef find_file(filename, std_dirs, paths):
85n/a """Searches for the directory where a given file is located,
86n/a and returns a possibly-empty list of additional directories, or None
87n/a if the file couldn't be found at all.
88n/a
89n/a 'filename' is the name of a file, such as readline.h or libcrypto.a.
90n/a 'std_dirs' is the list of standard system directories; if the
91n/a file is found in one of them, no additional directives are needed.
92n/a 'paths' is a list of additional locations to check; if the file is
93n/a found in one of them, the resulting list will contain the directory.
94n/a """
95n/a if host_platform == 'darwin':
96n/a # Honor the MacOSX SDK setting when one was specified.
97n/a # An SDK is a directory with the same structure as a real
98n/a # system, but with only header files and libraries.
99n/a sysroot = macosx_sdk_root()
100n/a
101n/a # Check the standard locations
102n/a for dir in std_dirs:
103n/a f = os.path.join(dir, filename)
104n/a
105n/a if host_platform == 'darwin' and is_macosx_sdk_path(dir):
106n/a f = os.path.join(sysroot, dir[1:], filename)
107n/a
108n/a if os.path.exists(f): return []
109n/a
110n/a # Check the additional directories
111n/a for dir in paths:
112n/a f = os.path.join(dir, filename)
113n/a
114n/a if host_platform == 'darwin' and is_macosx_sdk_path(dir):
115n/a f = os.path.join(sysroot, dir[1:], filename)
116n/a
117n/a if os.path.exists(f):
118n/a return [dir]
119n/a
120n/a # Not found anywhere
121n/a return None
122n/a
123n/adef find_library_file(compiler, libname, std_dirs, paths):
124n/a result = compiler.find_library_file(std_dirs + paths, libname)
125n/a if result is None:
126n/a return None
127n/a
128n/a if host_platform == 'darwin':
129n/a sysroot = macosx_sdk_root()
130n/a
131n/a # Check whether the found file is in one of the standard directories
132n/a dirname = os.path.dirname(result)
133n/a for p in std_dirs:
134n/a # Ensure path doesn't end with path separator
135n/a p = p.rstrip(os.sep)
136n/a
137n/a if host_platform == 'darwin' and is_macosx_sdk_path(p):
138n/a # Note that, as of Xcode 7, Apple SDKs may contain textual stub
139n/a # libraries with .tbd extensions rather than the normal .dylib
140n/a # shared libraries installed in /. The Apple compiler tool
141n/a # chain handles this transparently but it can cause problems
142n/a # for programs that are being built with an SDK and searching
143n/a # for specific libraries. Distutils find_library_file() now
144n/a # knows to also search for and return .tbd files. But callers
145n/a # of find_library_file need to keep in mind that the base filename
146n/a # of the returned SDK library file might have a different extension
147n/a # from that of the library file installed on the running system,
148n/a # for example:
149n/a # /Applications/Xcode.app/Contents/Developer/Platforms/
150n/a # MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/
151n/a # usr/lib/libedit.tbd
152n/a # vs
153n/a # /usr/lib/libedit.dylib
154n/a if os.path.join(sysroot, p[1:]) == dirname:
155n/a return [ ]
156n/a
157n/a if p == dirname:
158n/a return [ ]
159n/a
160n/a # Otherwise, it must have been in one of the additional directories,
161n/a # so we have to figure out which one.
162n/a for p in paths:
163n/a # Ensure path doesn't end with path separator
164n/a p = p.rstrip(os.sep)
165n/a
166n/a if host_platform == 'darwin' and is_macosx_sdk_path(p):
167n/a if os.path.join(sysroot, p[1:]) == dirname:
168n/a return [ p ]
169n/a
170n/a if p == dirname:
171n/a return [p]
172n/a else:
173n/a assert False, "Internal error: Path not found in std_dirs or paths"
174n/a
175n/adef module_enabled(extlist, modname):
176n/a """Returns whether the module 'modname' is present in the list
177n/a of extensions 'extlist'."""
178n/a extlist = [ext for ext in extlist if ext.name == modname]
179n/a return len(extlist)
180n/a
181n/adef find_module_file(module, dirlist):
182n/a """Find a module in a set of possible folders. If it is not found
183n/a return the unadorned filename"""
184n/a list = find_file(module, [], dirlist)
185n/a if not list:
186n/a return module
187n/a if len(list) > 1:
188n/a log.info("WARNING: multiple copies of %s found", module)
189n/a return os.path.join(list[0], module)
190n/a
191n/aclass PyBuildExt(build_ext):
192n/a
193n/a def __init__(self, dist):
194n/a build_ext.__init__(self, dist)
195n/a self.failed = []
196n/a self.failed_on_import = []
197n/a if '-j' in os.environ.get('MAKEFLAGS', ''):
198n/a self.parallel = True
199n/a
200n/a def build_extensions(self):
201n/a
202n/a # Detect which modules should be compiled
203n/a missing = self.detect_modules()
204n/a
205n/a # Remove modules that are present on the disabled list
206n/a extensions = [ext for ext in self.extensions
207n/a if ext.name not in disabled_module_list]
208n/a # move ctypes to the end, it depends on other modules
209n/a ext_map = dict((ext.name, i) for i, ext in enumerate(extensions))
210n/a if "_ctypes" in ext_map:
211n/a ctypes = extensions.pop(ext_map["_ctypes"])
212n/a extensions.append(ctypes)
213n/a self.extensions = extensions
214n/a
215n/a # Fix up the autodetected modules, prefixing all the source files
216n/a # with Modules/.
217n/a srcdir = sysconfig.get_config_var('srcdir')
218n/a if not srcdir:
219n/a # Maybe running on Windows but not using CYGWIN?
220n/a raise ValueError("No source directory; cannot proceed.")
221n/a srcdir = os.path.abspath(srcdir)
222n/a moddirlist = [os.path.join(srcdir, 'Modules')]
223n/a
224n/a # Fix up the paths for scripts, too
225n/a self.distribution.scripts = [os.path.join(srcdir, filename)
226n/a for filename in self.distribution.scripts]
227n/a
228n/a # Python header files
229n/a headers = [sysconfig.get_config_h_filename()]
230n/a headers += glob(os.path.join(sysconfig.get_path('include'), "*.h"))
231n/a
232n/a # The sysconfig variable built by makesetup, listing the already
233n/a # built modules as configured by the Setup files.
234n/a modnames = sysconfig.get_config_var('MODNAMES').split()
235n/a
236n/a removed_modules = []
237n/a for ext in self.extensions:
238n/a ext.sources = [ find_module_file(filename, moddirlist)
239n/a for filename in ext.sources ]
240n/a if ext.depends is not None:
241n/a ext.depends = [find_module_file(filename, moddirlist)
242n/a for filename in ext.depends]
243n/a else:
244n/a ext.depends = []
245n/a # re-compile extensions if a header file has been changed
246n/a ext.depends.extend(headers)
247n/a
248n/a # If a module has already been built by the Makefile,
249n/a # don't build it here.
250n/a if ext.name in modnames:
251n/a removed_modules.append(ext)
252n/a
253n/a if removed_modules:
254n/a self.extensions = [x for x in self.extensions if x not in
255n/a removed_modules]
256n/a
257n/a # When you run "make CC=altcc" or something similar, you really want
258n/a # those environment variables passed into the setup.py phase. Here's
259n/a # a small set of useful ones.
260n/a compiler = os.environ.get('CC')
261n/a args = {}
262n/a # unfortunately, distutils doesn't let us provide separate C and C++
263n/a # compilers
264n/a if compiler is not None:
265n/a (ccshared,cflags) = sysconfig.get_config_vars('CCSHARED','CFLAGS')
266n/a args['compiler_so'] = compiler + ' ' + ccshared + ' ' + cflags
267n/a self.compiler.set_executables(**args)
268n/a
269n/a build_ext.build_extensions(self)
270n/a
271n/a for ext in self.extensions:
272n/a self.check_extension_import(ext)
273n/a
274n/a longest = max([len(e.name) for e in self.extensions], default=0)
275n/a if self.failed or self.failed_on_import:
276n/a all_failed = self.failed + self.failed_on_import
277n/a longest = max(longest, max([len(name) for name in all_failed]))
278n/a
279n/a def print_three_column(lst):
280n/a lst.sort(key=str.lower)
281n/a # guarantee zip() doesn't drop anything
282n/a while len(lst) % 3:
283n/a lst.append("")
284n/a for e, f, g in zip(lst[::3], lst[1::3], lst[2::3]):
285n/a print("%-*s %-*s %-*s" % (longest, e, longest, f,
286n/a longest, g))
287n/a
288n/a if missing:
289n/a print()
290n/a print("Python build finished successfully!")
291n/a print("The necessary bits to build these optional modules were not "
292n/a "found:")
293n/a print_three_column(missing)
294n/a print("To find the necessary bits, look in setup.py in"
295n/a " detect_modules() for the module's name.")
296n/a print()
297n/a
298n/a if removed_modules:
299n/a print("The following modules found by detect_modules() in"
300n/a " setup.py, have been")
301n/a print("built by the Makefile instead, as configured by the"
302n/a " Setup files:")
303n/a print_three_column([ext.name for ext in removed_modules])
304n/a
305n/a if self.failed:
306n/a failed = self.failed[:]
307n/a print()
308n/a print("Failed to build these modules:")
309n/a print_three_column(failed)
310n/a print()
311n/a
312n/a if self.failed_on_import:
313n/a failed = self.failed_on_import[:]
314n/a print()
315n/a print("Following modules built successfully"
316n/a " but were removed because they could not be imported:")
317n/a print_three_column(failed)
318n/a print()
319n/a
320n/a def build_extension(self, ext):
321n/a
322n/a if ext.name == '_ctypes':
323n/a if not self.configure_ctypes(ext):
324n/a self.failed.append(ext.name)
325n/a return
326n/a
327n/a try:
328n/a build_ext.build_extension(self, ext)
329n/a except (CCompilerError, DistutilsError) as why:
330n/a self.announce('WARNING: building of extension "%s" failed: %s' %
331n/a (ext.name, sys.exc_info()[1]))
332n/a self.failed.append(ext.name)
333n/a return
334n/a
335n/a def check_extension_import(self, ext):
336n/a # Don't try to import an extension that has failed to compile
337n/a if ext.name in self.failed:
338n/a self.announce(
339n/a 'WARNING: skipping import check for failed build "%s"' %
340n/a ext.name, level=1)
341n/a return
342n/a
343n/a # Workaround for Mac OS X: The Carbon-based modules cannot be
344n/a # reliably imported into a command-line Python
345n/a if 'Carbon' in ext.extra_link_args:
346n/a self.announce(
347n/a 'WARNING: skipping import check for Carbon-based "%s"' %
348n/a ext.name)
349n/a return
350n/a
351n/a if host_platform == 'darwin' and (
352n/a sys.maxsize > 2**32 and '-arch' in ext.extra_link_args):
353n/a # Don't bother doing an import check when an extension was
354n/a # build with an explicit '-arch' flag on OSX. That's currently
355n/a # only used to build 32-bit only extensions in a 4-way
356n/a # universal build and loading 32-bit code into a 64-bit
357n/a # process will fail.
358n/a self.announce(
359n/a 'WARNING: skipping import check for "%s"' %
360n/a ext.name)
361n/a return
362n/a
363n/a # Workaround for Cygwin: Cygwin currently has fork issues when many
364n/a # modules have been imported
365n/a if host_platform == 'cygwin':
366n/a self.announce('WARNING: skipping import check for Cygwin-based "%s"'
367n/a % ext.name)
368n/a return
369n/a ext_filename = os.path.join(
370n/a self.build_lib,
371n/a self.get_ext_filename(self.get_ext_fullname(ext.name)))
372n/a
373n/a # If the build directory didn't exist when setup.py was
374n/a # started, sys.path_importer_cache has a negative result
375n/a # cached. Clear that cache before trying to import.
376n/a sys.path_importer_cache.clear()
377n/a
378n/a # Don't try to load extensions for cross builds
379n/a if cross_compiling:
380n/a return
381n/a
382n/a loader = importlib.machinery.ExtensionFileLoader(ext.name, ext_filename)
383n/a spec = importlib.util.spec_from_file_location(ext.name, ext_filename,
384n/a loader=loader)
385n/a try:
386n/a importlib._bootstrap._load(spec)
387n/a except ImportError as why:
388n/a self.failed_on_import.append(ext.name)
389n/a self.announce('*** WARNING: renaming "%s" since importing it'
390n/a ' failed: %s' % (ext.name, why), level=3)
391n/a assert not self.inplace
392n/a basename, tail = os.path.splitext(ext_filename)
393n/a newname = basename + "_failed" + tail
394n/a if os.path.exists(newname):
395n/a os.remove(newname)
396n/a os.rename(ext_filename, newname)
397n/a
398n/a except:
399n/a exc_type, why, tb = sys.exc_info()
400n/a self.announce('*** WARNING: importing extension "%s" '
401n/a 'failed with %s: %s' % (ext.name, exc_type, why),
402n/a level=3)
403n/a self.failed.append(ext.name)
404n/a
405n/a def add_multiarch_paths(self):
406n/a # Debian/Ubuntu multiarch support.
407n/a # https://wiki.ubuntu.com/MultiarchSpec
408n/a cc = sysconfig.get_config_var('CC')
409n/a tmpfile = os.path.join(self.build_temp, 'multiarch')
410n/a if not os.path.exists(self.build_temp):
411n/a os.makedirs(self.build_temp)
412n/a ret = os.system(
413n/a '%s -print-multiarch > %s 2> /dev/null' % (cc, tmpfile))
414n/a multiarch_path_component = ''
415n/a try:
416n/a if ret >> 8 == 0:
417n/a with open(tmpfile) as fp:
418n/a multiarch_path_component = fp.readline().strip()
419n/a finally:
420n/a os.unlink(tmpfile)
421n/a
422n/a if multiarch_path_component != '':
423n/a add_dir_to_list(self.compiler.library_dirs,
424n/a '/usr/lib/' + multiarch_path_component)
425n/a add_dir_to_list(self.compiler.include_dirs,
426n/a '/usr/include/' + multiarch_path_component)
427n/a return
428n/a
429n/a if not find_executable('dpkg-architecture'):
430n/a return
431n/a opt = ''
432n/a if cross_compiling:
433n/a opt = '-t' + sysconfig.get_config_var('HOST_GNU_TYPE')
434n/a tmpfile = os.path.join(self.build_temp, 'multiarch')
435n/a if not os.path.exists(self.build_temp):
436n/a os.makedirs(self.build_temp)
437n/a ret = os.system(
438n/a 'dpkg-architecture %s -qDEB_HOST_MULTIARCH > %s 2> /dev/null' %
439n/a (opt, tmpfile))
440n/a try:
441n/a if ret >> 8 == 0:
442n/a with open(tmpfile) as fp:
443n/a multiarch_path_component = fp.readline().strip()
444n/a add_dir_to_list(self.compiler.library_dirs,
445n/a '/usr/lib/' + multiarch_path_component)
446n/a add_dir_to_list(self.compiler.include_dirs,
447n/a '/usr/include/' + multiarch_path_component)
448n/a finally:
449n/a os.unlink(tmpfile)
450n/a
451n/a def add_gcc_paths(self):
452n/a gcc = sysconfig.get_config_var('CC')
453n/a tmpfile = os.path.join(self.build_temp, 'gccpaths')
454n/a if not os.path.exists(self.build_temp):
455n/a os.makedirs(self.build_temp)
456n/a ret = os.system('%s -E -v - </dev/null 2>%s 1>/dev/null' % (gcc, tmpfile))
457n/a is_gcc = False
458n/a in_incdirs = False
459n/a inc_dirs = []
460n/a lib_dirs = []
461n/a try:
462n/a if ret >> 8 == 0:
463n/a with open(tmpfile) as fp:
464n/a for line in fp.readlines():
465n/a if line.startswith("gcc version"):
466n/a is_gcc = True
467n/a elif line.startswith("#include <...>"):
468n/a in_incdirs = True
469n/a elif line.startswith("End of search list"):
470n/a in_incdirs = False
471n/a elif is_gcc and line.startswith("LIBRARY_PATH"):
472n/a for d in line.strip().split("=")[1].split(":"):
473n/a d = os.path.normpath(d)
474n/a if '/gcc/' not in d:
475n/a add_dir_to_list(self.compiler.library_dirs,
476n/a d)
477n/a elif is_gcc and in_incdirs and '/gcc/' not in line:
478n/a add_dir_to_list(self.compiler.include_dirs,
479n/a line.strip())
480n/a finally:
481n/a os.unlink(tmpfile)
482n/a
483n/a def detect_math_libs(self):
484n/a # Check for MacOS X, which doesn't need libm.a at all
485n/a if host_platform == 'darwin':
486n/a return []
487n/a else:
488n/a return ['m']
489n/a
490n/a def detect_modules(self):
491n/a # Ensure that /usr/local is always used, but the local build
492n/a # directories (i.e. '.' and 'Include') must be first. See issue
493n/a # 10520.
494n/a if not cross_compiling:
495n/a add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib')
496n/a add_dir_to_list(self.compiler.include_dirs, '/usr/local/include')
497n/a # only change this for cross builds for 3.3, issues on Mageia
498n/a if cross_compiling:
499n/a self.add_gcc_paths()
500n/a self.add_multiarch_paths()
501n/a
502n/a # Add paths specified in the environment variables LDFLAGS and
503n/a # CPPFLAGS for header and library files.
504n/a # We must get the values from the Makefile and not the environment
505n/a # directly since an inconsistently reproducible issue comes up where
506n/a # the environment variable is not set even though the value were passed
507n/a # into configure and stored in the Makefile (issue found on OS X 10.3).
508n/a for env_var, arg_name, dir_list in (
509n/a ('LDFLAGS', '-R', self.compiler.runtime_library_dirs),
510n/a ('LDFLAGS', '-L', self.compiler.library_dirs),
511n/a ('CPPFLAGS', '-I', self.compiler.include_dirs)):
512n/a env_val = sysconfig.get_config_var(env_var)
513n/a if env_val:
514n/a # To prevent optparse from raising an exception about any
515n/a # options in env_val that it doesn't know about we strip out
516n/a # all double dashes and any dashes followed by a character
517n/a # that is not for the option we are dealing with.
518n/a #
519n/a # Please note that order of the regex is important! We must
520n/a # strip out double-dashes first so that we don't end up with
521n/a # substituting "--Long" to "-Long" and thus lead to "ong" being
522n/a # used for a library directory.
523n/a env_val = re.sub(r'(^|\s+)-(-|(?!%s))' % arg_name[1],
524n/a ' ', env_val)
525n/a parser = optparse.OptionParser()
526n/a # Make sure that allowing args interspersed with options is
527n/a # allowed
528n/a parser.allow_interspersed_args = True
529n/a parser.error = lambda msg: None
530n/a parser.add_option(arg_name, dest="dirs", action="append")
531n/a options = parser.parse_args(env_val.split())[0]
532n/a if options.dirs:
533n/a for directory in reversed(options.dirs):
534n/a add_dir_to_list(dir_list, directory)
535n/a
536n/a if (not cross_compiling and
537n/a os.path.normpath(sys.base_prefix) != '/usr' and
538n/a not sysconfig.get_config_var('PYTHONFRAMEWORK')):
539n/a # OSX note: Don't add LIBDIR and INCLUDEDIR to building a framework
540n/a # (PYTHONFRAMEWORK is set) to avoid # linking problems when
541n/a # building a framework with different architectures than
542n/a # the one that is currently installed (issue #7473)
543n/a add_dir_to_list(self.compiler.library_dirs,
544n/a sysconfig.get_config_var("LIBDIR"))
545n/a add_dir_to_list(self.compiler.include_dirs,
546n/a sysconfig.get_config_var("INCLUDEDIR"))
547n/a
548n/a # lib_dirs and inc_dirs are used to search for files;
549n/a # if a file is found in one of those directories, it can
550n/a # be assumed that no additional -I,-L directives are needed.
551n/a if not cross_compiling:
552n/a lib_dirs = self.compiler.library_dirs + [
553n/a '/lib64', '/usr/lib64',
554n/a '/lib', '/usr/lib',
555n/a ]
556n/a inc_dirs = self.compiler.include_dirs + ['/usr/include']
557n/a else:
558n/a lib_dirs = self.compiler.library_dirs[:]
559n/a inc_dirs = self.compiler.include_dirs[:]
560n/a exts = []
561n/a missing = []
562n/a
563n/a config_h = sysconfig.get_config_h_filename()
564n/a with open(config_h) as file:
565n/a config_h_vars = sysconfig.parse_config_h(file)
566n/a
567n/a srcdir = sysconfig.get_config_var('srcdir')
568n/a
569n/a # OSF/1 and Unixware have some stuff in /usr/ccs/lib (like -ldb)
570n/a if host_platform in ['osf1', 'unixware7', 'openunix8']:
571n/a lib_dirs += ['/usr/ccs/lib']
572n/a
573n/a # HP-UX11iv3 keeps files in lib/hpux folders.
574n/a if host_platform == 'hp-ux11':
575n/a lib_dirs += ['/usr/lib/hpux64', '/usr/lib/hpux32']
576n/a
577n/a if host_platform == 'darwin':
578n/a # This should work on any unixy platform ;-)
579n/a # If the user has bothered specifying additional -I and -L flags
580n/a # in OPT and LDFLAGS we might as well use them here.
581n/a #
582n/a # NOTE: using shlex.split would technically be more correct, but
583n/a # also gives a bootstrap problem. Let's hope nobody uses
584n/a # directories with whitespace in the name to store libraries.
585n/a cflags, ldflags = sysconfig.get_config_vars(
586n/a 'CFLAGS', 'LDFLAGS')
587n/a for item in cflags.split():
588n/a if item.startswith('-I'):
589n/a inc_dirs.append(item[2:])
590n/a
591n/a for item in ldflags.split():
592n/a if item.startswith('-L'):
593n/a lib_dirs.append(item[2:])
594n/a
595n/a math_libs = self.detect_math_libs()
596n/a
597n/a # XXX Omitted modules: gl, pure, dl, SGI-specific modules
598n/a
599n/a #
600n/a # The following modules are all pretty straightforward, and compile
601n/a # on pretty much any POSIXish platform.
602n/a #
603n/a
604n/a # array objects
605n/a exts.append( Extension('array', ['arraymodule.c']) )
606n/a
607n/a shared_math = 'Modules/_math.o'
608n/a # complex math library functions
609n/a exts.append( Extension('cmath', ['cmathmodule.c'],
610n/a extra_objects=[shared_math],
611n/a depends=['_math.h', shared_math],
612n/a libraries=math_libs) )
613n/a # math library functions, e.g. sin()
614n/a exts.append( Extension('math', ['mathmodule.c'],
615n/a extra_objects=[shared_math],
616n/a depends=['_math.h', shared_math],
617n/a libraries=math_libs) )
618n/a
619n/a # time libraries: librt may be needed for clock_gettime()
620n/a time_libs = []
621n/a lib = sysconfig.get_config_var('TIMEMODULE_LIB')
622n/a if lib:
623n/a time_libs.append(lib)
624n/a
625n/a # time operations and variables
626n/a exts.append( Extension('time', ['timemodule.c'],
627n/a libraries=time_libs) )
628n/a # math_libs is needed by delta_new() that uses round() and by accum()
629n/a # that uses modf().
630n/a exts.append( Extension('_datetime', ['_datetimemodule.c'],
631n/a libraries=math_libs) )
632n/a # random number generator implemented in C
633n/a exts.append( Extension("_random", ["_randommodule.c"]) )
634n/a # bisect
635n/a exts.append( Extension("_bisect", ["_bisectmodule.c"]) )
636n/a # heapq
637n/a exts.append( Extension("_heapq", ["_heapqmodule.c"]) )
638n/a # C-optimized pickle replacement
639n/a exts.append( Extension("_pickle", ["_pickle.c"]) )
640n/a # atexit
641n/a exts.append( Extension("atexit", ["atexitmodule.c"]) )
642n/a # _json speedups
643n/a exts.append( Extension("_json", ["_json.c"]) )
644n/a # Python C API test module
645n/a exts.append( Extension('_testcapi', ['_testcapimodule.c'],
646n/a depends=['testcapi_long.h']) )
647n/a # Python PEP-3118 (buffer protocol) test module
648n/a exts.append( Extension('_testbuffer', ['_testbuffer.c']) )
649n/a # Test loading multiple modules from one compiled file (http://bugs.python.org/issue16421)
650n/a exts.append( Extension('_testimportmultiple', ['_testimportmultiple.c']) )
651n/a # Test multi-phase extension module init (PEP 489)
652n/a exts.append( Extension('_testmultiphase', ['_testmultiphase.c']) )
653n/a # profiler (_lsprof is for cProfile.py)
654n/a exts.append( Extension('_lsprof', ['_lsprof.c', 'rotatingtree.c']) )
655n/a # static Unicode character database
656n/a exts.append( Extension('unicodedata', ['unicodedata.c'],
657n/a depends=['unicodedata_db.h', 'unicodename_db.h']) )
658n/a # _opcode module
659n/a exts.append( Extension('_opcode', ['_opcode.c']) )
660n/a # asyncio speedups
661n/a exts.append( Extension("_asyncio", ["_asynciomodule.c"]) )
662n/a
663n/a # Modules with some UNIX dependencies -- on by default:
664n/a # (If you have a really backward UNIX, select and socket may not be
665n/a # supported...)
666n/a
667n/a # fcntl(2) and ioctl(2)
668n/a libs = []
669n/a if (config_h_vars.get('FLOCK_NEEDS_LIBBSD', False)):
670n/a # May be necessary on AIX for flock function
671n/a libs = ['bsd']
672n/a exts.append( Extension('fcntl', ['fcntlmodule.c'], libraries=libs) )
673n/a # pwd(3)
674n/a exts.append( Extension('pwd', ['pwdmodule.c']) )
675n/a # grp(3)
676n/a exts.append( Extension('grp', ['grpmodule.c']) )
677n/a # spwd, shadow passwords
678n/a if (config_h_vars.get('HAVE_GETSPNAM', False) or
679n/a config_h_vars.get('HAVE_GETSPENT', False)):
680n/a exts.append( Extension('spwd', ['spwdmodule.c']) )
681n/a else:
682n/a missing.append('spwd')
683n/a
684n/a # select(2); not on ancient System V
685n/a exts.append( Extension('select', ['selectmodule.c']) )
686n/a
687n/a # Fred Drake's interface to the Python parser
688n/a exts.append( Extension('parser', ['parsermodule.c']) )
689n/a
690n/a # Memory-mapped files (also works on Win32).
691n/a exts.append( Extension('mmap', ['mmapmodule.c']) )
692n/a
693n/a # Lance Ellinghaus's syslog module
694n/a # syslog daemon interface
695n/a exts.append( Extension('syslog', ['syslogmodule.c']) )
696n/a
697n/a #
698n/a # Here ends the simple stuff. From here on, modules need certain
699n/a # libraries, are platform-specific, or present other surprises.
700n/a #
701n/a
702n/a # Multimedia modules
703n/a # These don't work for 64-bit platforms!!!
704n/a # These represent audio samples or images as strings:
705n/a #
706n/a # Operations on audio samples
707n/a # According to #993173, this one should actually work fine on
708n/a # 64-bit platforms.
709n/a #
710n/a # audioop needs math_libs for floor() in multiple functions.
711n/a exts.append( Extension('audioop', ['audioop.c'],
712n/a libraries=math_libs) )
713n/a
714n/a # readline
715n/a do_readline = self.compiler.find_library_file(lib_dirs, 'readline')
716n/a readline_termcap_library = ""
717n/a curses_library = ""
718n/a # Cannot use os.popen here in py3k.
719n/a tmpfile = os.path.join(self.build_temp, 'readline_termcap_lib')
720n/a if not os.path.exists(self.build_temp):
721n/a os.makedirs(self.build_temp)
722n/a # Determine if readline is already linked against curses or tinfo.
723n/a if do_readline:
724n/a if cross_compiling:
725n/a ret = os.system("%s -d %s | grep '(NEEDED)' > %s" \
726n/a % (sysconfig.get_config_var('READELF'),
727n/a do_readline, tmpfile))
728n/a elif find_executable('ldd'):
729n/a ret = os.system("ldd %s > %s" % (do_readline, tmpfile))
730n/a else:
731n/a ret = 256
732n/a if ret >> 8 == 0:
733n/a with open(tmpfile) as fp:
734n/a for ln in fp:
735n/a if 'curses' in ln:
736n/a readline_termcap_library = re.sub(
737n/a r'.*lib(n?cursesw?)\.so.*', r'\1', ln
738n/a ).rstrip()
739n/a break
740n/a # termcap interface split out from ncurses
741n/a if 'tinfo' in ln:
742n/a readline_termcap_library = 'tinfo'
743n/a break
744n/a if os.path.exists(tmpfile):
745n/a os.unlink(tmpfile)
746n/a # Issue 7384: If readline is already linked against curses,
747n/a # use the same library for the readline and curses modules.
748n/a if 'curses' in readline_termcap_library:
749n/a curses_library = readline_termcap_library
750n/a elif self.compiler.find_library_file(lib_dirs, 'ncursesw'):
751n/a curses_library = 'ncursesw'
752n/a elif self.compiler.find_library_file(lib_dirs, 'ncurses'):
753n/a curses_library = 'ncurses'
754n/a elif self.compiler.find_library_file(lib_dirs, 'curses'):
755n/a curses_library = 'curses'
756n/a
757n/a if host_platform == 'darwin':
758n/a os_release = int(os.uname()[2].split('.')[0])
759n/a dep_target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET')
760n/a if (dep_target and
761n/a (tuple(int(n) for n in dep_target.split('.')[0:2])
762n/a < (10, 5) ) ):
763n/a os_release = 8
764n/a if os_release < 9:
765n/a # MacOSX 10.4 has a broken readline. Don't try to build
766n/a # the readline module unless the user has installed a fixed
767n/a # readline package
768n/a if find_file('readline/rlconf.h', inc_dirs, []) is None:
769n/a do_readline = False
770n/a if do_readline:
771n/a if host_platform == 'darwin' and os_release < 9:
772n/a # In every directory on the search path search for a dynamic
773n/a # library and then a static library, instead of first looking
774n/a # for dynamic libraries on the entire path.
775n/a # This way a statically linked custom readline gets picked up
776n/a # before the (possibly broken) dynamic library in /usr/lib.
777n/a readline_extra_link_args = ('-Wl,-search_paths_first',)
778n/a else:
779n/a readline_extra_link_args = ()
780n/a
781n/a readline_libs = ['readline']
782n/a if readline_termcap_library:
783n/a pass # Issue 7384: Already linked against curses or tinfo.
784n/a elif curses_library:
785n/a readline_libs.append(curses_library)
786n/a elif self.compiler.find_library_file(lib_dirs +
787n/a ['/usr/lib/termcap'],
788n/a 'termcap'):
789n/a readline_libs.append('termcap')
790n/a exts.append( Extension('readline', ['readline.c'],
791n/a library_dirs=['/usr/lib/termcap'],
792n/a extra_link_args=readline_extra_link_args,
793n/a libraries=readline_libs) )
794n/a else:
795n/a missing.append('readline')
796n/a
797n/a # crypt module.
798n/a
799n/a if self.compiler.find_library_file(lib_dirs, 'crypt'):
800n/a libs = ['crypt']
801n/a else:
802n/a libs = []
803n/a exts.append( Extension('_crypt', ['_cryptmodule.c'], libraries=libs) )
804n/a
805n/a # CSV files
806n/a exts.append( Extension('_csv', ['_csv.c']) )
807n/a
808n/a # POSIX subprocess module helper.
809n/a exts.append( Extension('_posixsubprocess', ['_posixsubprocess.c']) )
810n/a
811n/a # socket(2)
812n/a exts.append( Extension('_socket', ['socketmodule.c'],
813n/a depends = ['socketmodule.h']) )
814n/a # Detect SSL support for the socket module (via _ssl)
815n/a search_for_ssl_incs_in = [
816n/a '/usr/local/ssl/include',
817n/a '/usr/contrib/ssl/include/'
818n/a ]
819n/a ssl_incs = find_file('openssl/ssl.h', inc_dirs,
820n/a search_for_ssl_incs_in
821n/a )
822n/a if ssl_incs is not None:
823n/a krb5_h = find_file('krb5.h', inc_dirs,
824n/a ['/usr/kerberos/include'])
825n/a if krb5_h:
826n/a ssl_incs += krb5_h
827n/a ssl_libs = find_library_file(self.compiler, 'ssl',lib_dirs,
828n/a ['/usr/local/ssl/lib',
829n/a '/usr/contrib/ssl/lib/'
830n/a ] )
831n/a
832n/a if (ssl_incs is not None and
833n/a ssl_libs is not None):
834n/a exts.append( Extension('_ssl', ['_ssl.c'],
835n/a include_dirs = ssl_incs,
836n/a library_dirs = ssl_libs,
837n/a libraries = ['ssl', 'crypto'],
838n/a depends = ['socketmodule.h']), )
839n/a else:
840n/a missing.append('_ssl')
841n/a
842n/a # find out which version of OpenSSL we have
843n/a openssl_ver = 0
844n/a openssl_ver_re = re.compile(
845n/a r'^\s*#\s*define\s+OPENSSL_VERSION_NUMBER\s+(0x[0-9a-fA-F]+)' )
846n/a
847n/a # look for the openssl version header on the compiler search path.
848n/a opensslv_h = find_file('openssl/opensslv.h', [],
849n/a inc_dirs + search_for_ssl_incs_in)
850n/a if opensslv_h:
851n/a name = os.path.join(opensslv_h[0], 'openssl/opensslv.h')
852n/a if host_platform == 'darwin' and is_macosx_sdk_path(name):
853n/a name = os.path.join(macosx_sdk_root(), name[1:])
854n/a try:
855n/a with open(name, 'r') as incfile:
856n/a for line in incfile:
857n/a m = openssl_ver_re.match(line)
858n/a if m:
859n/a openssl_ver = int(m.group(1), 16)
860n/a break
861n/a except IOError as msg:
862n/a print("IOError while reading opensshv.h:", msg)
863n/a
864n/a #print('openssl_ver = 0x%08x' % openssl_ver)
865n/a min_openssl_ver = 0x00907000
866n/a have_any_openssl = ssl_incs is not None and ssl_libs is not None
867n/a have_usable_openssl = (have_any_openssl and
868n/a openssl_ver >= min_openssl_ver)
869n/a
870n/a if have_any_openssl:
871n/a if have_usable_openssl:
872n/a # The _hashlib module wraps optimized implementations
873n/a # of hash functions from the OpenSSL library.
874n/a exts.append( Extension('_hashlib', ['_hashopenssl.c'],
875n/a depends = ['hashlib.h'],
876n/a include_dirs = ssl_incs,
877n/a library_dirs = ssl_libs,
878n/a libraries = ['ssl', 'crypto']) )
879n/a else:
880n/a print("warning: openssl 0x%08x is too old for _hashlib" %
881n/a openssl_ver)
882n/a missing.append('_hashlib')
883n/a
884n/a # We always compile these even when OpenSSL is available (issue #14693).
885n/a # It's harmless and the object code is tiny (40-50 KB per module,
886n/a # only loaded when actually used).
887n/a exts.append( Extension('_sha256', ['sha256module.c'],
888n/a depends=['hashlib.h']) )
889n/a exts.append( Extension('_sha512', ['sha512module.c'],
890n/a depends=['hashlib.h']) )
891n/a exts.append( Extension('_md5', ['md5module.c'],
892n/a depends=['hashlib.h']) )
893n/a exts.append( Extension('_sha1', ['sha1module.c'],
894n/a depends=['hashlib.h']) )
895n/a
896n/a blake2_deps = glob(os.path.join(os.getcwd(), srcdir,
897n/a 'Modules/_blake2/impl/*'))
898n/a blake2_deps.append('hashlib.h')
899n/a
900n/a blake2_macros = []
901n/a if not cross_compiling and os.uname().machine == "x86_64":
902n/a # Every x86_64 machine has at least SSE2.
903n/a blake2_macros.append(('BLAKE2_USE_SSE', '1'))
904n/a
905n/a exts.append( Extension('_blake2',
906n/a ['_blake2/blake2module.c',
907n/a '_blake2/blake2b_impl.c',
908n/a '_blake2/blake2s_impl.c'],
909n/a define_macros=blake2_macros,
910n/a depends=blake2_deps) )
911n/a
912n/a sha3_deps = glob(os.path.join(os.getcwd(), srcdir,
913n/a 'Modules/_sha3/kcp/*'))
914n/a sha3_deps.append('hashlib.h')
915n/a exts.append( Extension('_sha3',
916n/a ['_sha3/sha3module.c'],
917n/a depends=sha3_deps))
918n/a
919n/a # Modules that provide persistent dictionary-like semantics. You will
920n/a # probably want to arrange for at least one of them to be available on
921n/a # your machine, though none are defined by default because of library
922n/a # dependencies. The Python module dbm/__init__.py provides an
923n/a # implementation independent wrapper for these; dbm/dumb.py provides
924n/a # similar functionality (but slower of course) implemented in Python.
925n/a
926n/a # Sleepycat^WOracle Berkeley DB interface.
927n/a # http://www.oracle.com/database/berkeley-db/db/index.html
928n/a #
929n/a # This requires the Sleepycat^WOracle DB code. The supported versions
930n/a # are set below. Visit the URL above to download
931n/a # a release. Most open source OSes come with one or more
932n/a # versions of BerkeleyDB already installed.
933n/a
934n/a max_db_ver = (5, 3)
935n/a min_db_ver = (3, 3)
936n/a db_setup_debug = False # verbose debug prints from this script?
937n/a
938n/a def allow_db_ver(db_ver):
939n/a """Returns a boolean if the given BerkeleyDB version is acceptable.
940n/a
941n/a Args:
942n/a db_ver: A tuple of the version to verify.
943n/a """
944n/a if not (min_db_ver <= db_ver <= max_db_ver):
945n/a return False
946n/a return True
947n/a
948n/a def gen_db_minor_ver_nums(major):
949n/a if major == 4:
950n/a for x in range(max_db_ver[1]+1):
951n/a if allow_db_ver((4, x)):
952n/a yield x
953n/a elif major == 3:
954n/a for x in (3,):
955n/a if allow_db_ver((3, x)):
956n/a yield x
957n/a else:
958n/a raise ValueError("unknown major BerkeleyDB version", major)
959n/a
960n/a # construct a list of paths to look for the header file in on
961n/a # top of the normal inc_dirs.
962n/a db_inc_paths = [
963n/a '/usr/include/db4',
964n/a '/usr/local/include/db4',
965n/a '/opt/sfw/include/db4',
966n/a '/usr/include/db3',
967n/a '/usr/local/include/db3',
968n/a '/opt/sfw/include/db3',
969n/a # Fink defaults (http://fink.sourceforge.net/)
970n/a '/sw/include/db4',
971n/a '/sw/include/db3',
972n/a ]
973n/a # 4.x minor number specific paths
974n/a for x in gen_db_minor_ver_nums(4):
975n/a db_inc_paths.append('/usr/include/db4%d' % x)
976n/a db_inc_paths.append('/usr/include/db4.%d' % x)
977n/a db_inc_paths.append('/usr/local/BerkeleyDB.4.%d/include' % x)
978n/a db_inc_paths.append('/usr/local/include/db4%d' % x)
979n/a db_inc_paths.append('/pkg/db-4.%d/include' % x)
980n/a db_inc_paths.append('/opt/db-4.%d/include' % x)
981n/a # MacPorts default (http://www.macports.org/)
982n/a db_inc_paths.append('/opt/local/include/db4%d' % x)
983n/a # 3.x minor number specific paths
984n/a for x in gen_db_minor_ver_nums(3):
985n/a db_inc_paths.append('/usr/include/db3%d' % x)
986n/a db_inc_paths.append('/usr/local/BerkeleyDB.3.%d/include' % x)
987n/a db_inc_paths.append('/usr/local/include/db3%d' % x)
988n/a db_inc_paths.append('/pkg/db-3.%d/include' % x)
989n/a db_inc_paths.append('/opt/db-3.%d/include' % x)
990n/a
991n/a if cross_compiling:
992n/a db_inc_paths = []
993n/a
994n/a # Add some common subdirectories for Sleepycat DB to the list,
995n/a # based on the standard include directories. This way DB3/4 gets
996n/a # picked up when it is installed in a non-standard prefix and
997n/a # the user has added that prefix into inc_dirs.
998n/a std_variants = []
999n/a for dn in inc_dirs:
1000n/a std_variants.append(os.path.join(dn, 'db3'))
1001n/a std_variants.append(os.path.join(dn, 'db4'))
1002n/a for x in gen_db_minor_ver_nums(4):
1003n/a std_variants.append(os.path.join(dn, "db4%d"%x))
1004n/a std_variants.append(os.path.join(dn, "db4.%d"%x))
1005n/a for x in gen_db_minor_ver_nums(3):
1006n/a std_variants.append(os.path.join(dn, "db3%d"%x))
1007n/a std_variants.append(os.path.join(dn, "db3.%d"%x))
1008n/a
1009n/a db_inc_paths = std_variants + db_inc_paths
1010n/a db_inc_paths = [p for p in db_inc_paths if os.path.exists(p)]
1011n/a
1012n/a db_ver_inc_map = {}
1013n/a
1014n/a if host_platform == 'darwin':
1015n/a sysroot = macosx_sdk_root()
1016n/a
1017n/a class db_found(Exception): pass
1018n/a try:
1019n/a # See whether there is a Sleepycat header in the standard
1020n/a # search path.
1021n/a for d in inc_dirs + db_inc_paths:
1022n/a f = os.path.join(d, "db.h")
1023n/a if host_platform == 'darwin' and is_macosx_sdk_path(d):
1024n/a f = os.path.join(sysroot, d[1:], "db.h")
1025n/a
1026n/a if db_setup_debug: print("db: looking for db.h in", f)
1027n/a if os.path.exists(f):
1028n/a with open(f, 'rb') as file:
1029n/a f = file.read()
1030n/a m = re.search(br"#define\WDB_VERSION_MAJOR\W(\d+)", f)
1031n/a if m:
1032n/a db_major = int(m.group(1))
1033n/a m = re.search(br"#define\WDB_VERSION_MINOR\W(\d+)", f)
1034n/a db_minor = int(m.group(1))
1035n/a db_ver = (db_major, db_minor)
1036n/a
1037n/a # Avoid 4.6 prior to 4.6.21 due to a BerkeleyDB bug
1038n/a if db_ver == (4, 6):
1039n/a m = re.search(br"#define\WDB_VERSION_PATCH\W(\d+)", f)
1040n/a db_patch = int(m.group(1))
1041n/a if db_patch < 21:
1042n/a print("db.h:", db_ver, "patch", db_patch,
1043n/a "being ignored (4.6.x must be >= 4.6.21)")
1044n/a continue
1045n/a
1046n/a if ( (db_ver not in db_ver_inc_map) and
1047n/a allow_db_ver(db_ver) ):
1048n/a # save the include directory with the db.h version
1049n/a # (first occurrence only)
1050n/a db_ver_inc_map[db_ver] = d
1051n/a if db_setup_debug:
1052n/a print("db.h: found", db_ver, "in", d)
1053n/a else:
1054n/a # we already found a header for this library version
1055n/a if db_setup_debug: print("db.h: ignoring", d)
1056n/a else:
1057n/a # ignore this header, it didn't contain a version number
1058n/a if db_setup_debug:
1059n/a print("db.h: no version number version in", d)
1060n/a
1061n/a db_found_vers = list(db_ver_inc_map.keys())
1062n/a db_found_vers.sort()
1063n/a
1064n/a while db_found_vers:
1065n/a db_ver = db_found_vers.pop()
1066n/a db_incdir = db_ver_inc_map[db_ver]
1067n/a
1068n/a # check lib directories parallel to the location of the header
1069n/a db_dirs_to_check = [
1070n/a db_incdir.replace("include", 'lib64'),
1071n/a db_incdir.replace("include", 'lib'),
1072n/a ]
1073n/a
1074n/a if host_platform != 'darwin':
1075n/a db_dirs_to_check = list(filter(os.path.isdir, db_dirs_to_check))
1076n/a
1077n/a else:
1078n/a # Same as other branch, but takes OSX SDK into account
1079n/a tmp = []
1080n/a for dn in db_dirs_to_check:
1081n/a if is_macosx_sdk_path(dn):
1082n/a if os.path.isdir(os.path.join(sysroot, dn[1:])):
1083n/a tmp.append(dn)
1084n/a else:
1085n/a if os.path.isdir(dn):
1086n/a tmp.append(dn)
1087n/a db_dirs_to_check = tmp
1088n/a
1089n/a db_dirs_to_check = tmp
1090n/a
1091n/a # Look for a version specific db-X.Y before an ambiguous dbX
1092n/a # XXX should we -ever- look for a dbX name? Do any
1093n/a # systems really not name their library by version and
1094n/a # symlink to more general names?
1095n/a for dblib in (('db-%d.%d' % db_ver),
1096n/a ('db%d%d' % db_ver),
1097n/a ('db%d' % db_ver[0])):
1098n/a dblib_file = self.compiler.find_library_file(
1099n/a db_dirs_to_check + lib_dirs, dblib )
1100n/a if dblib_file:
1101n/a dblib_dir = [ os.path.abspath(os.path.dirname(dblib_file)) ]
1102n/a raise db_found
1103n/a else:
1104n/a if db_setup_debug: print("db lib: ", dblib, "not found")
1105n/a
1106n/a except db_found:
1107n/a if db_setup_debug:
1108n/a print("bsddb using BerkeleyDB lib:", db_ver, dblib)
1109n/a print("bsddb lib dir:", dblib_dir, " inc dir:", db_incdir)
1110n/a dblibs = [dblib]
1111n/a # Only add the found library and include directories if they aren't
1112n/a # already being searched. This avoids an explicit runtime library
1113n/a # dependency.
1114n/a if db_incdir in inc_dirs:
1115n/a db_incs = None
1116n/a else:
1117n/a db_incs = [db_incdir]
1118n/a if dblib_dir[0] in lib_dirs:
1119n/a dblib_dir = None
1120n/a else:
1121n/a if db_setup_debug: print("db: no appropriate library found")
1122n/a db_incs = None
1123n/a dblibs = []
1124n/a dblib_dir = None
1125n/a
1126n/a # The sqlite interface
1127n/a sqlite_setup_debug = False # verbose debug prints from this script?
1128n/a
1129n/a # We hunt for #define SQLITE_VERSION "n.n.n"
1130n/a # We need to find >= sqlite version 3.0.8
1131n/a sqlite_incdir = sqlite_libdir = None
1132n/a sqlite_inc_paths = [ '/usr/include',
1133n/a '/usr/include/sqlite',
1134n/a '/usr/include/sqlite3',
1135n/a '/usr/local/include',
1136n/a '/usr/local/include/sqlite',
1137n/a '/usr/local/include/sqlite3',
1138n/a ]
1139n/a if cross_compiling:
1140n/a sqlite_inc_paths = []
1141n/a MIN_SQLITE_VERSION_NUMBER = (3, 0, 8)
1142n/a MIN_SQLITE_VERSION = ".".join([str(x)
1143n/a for x in MIN_SQLITE_VERSION_NUMBER])
1144n/a
1145n/a # Scan the default include directories before the SQLite specific
1146n/a # ones. This allows one to override the copy of sqlite on OSX,
1147n/a # where /usr/include contains an old version of sqlite.
1148n/a if host_platform == 'darwin':
1149n/a sysroot = macosx_sdk_root()
1150n/a
1151n/a for d_ in inc_dirs + sqlite_inc_paths:
1152n/a d = d_
1153n/a if host_platform == 'darwin' and is_macosx_sdk_path(d):
1154n/a d = os.path.join(sysroot, d[1:])
1155n/a
1156n/a f = os.path.join(d, "sqlite3.h")
1157n/a if os.path.exists(f):
1158n/a if sqlite_setup_debug: print("sqlite: found %s"%f)
1159n/a with open(f) as file:
1160n/a incf = file.read()
1161n/a m = re.search(
1162n/a r'\s*.*#\s*.*define\s.*SQLITE_VERSION\W*"([\d\.]*)"', incf)
1163n/a if m:
1164n/a sqlite_version = m.group(1)
1165n/a sqlite_version_tuple = tuple([int(x)
1166n/a for x in sqlite_version.split(".")])
1167n/a if sqlite_version_tuple >= MIN_SQLITE_VERSION_NUMBER:
1168n/a # we win!
1169n/a if sqlite_setup_debug:
1170n/a print("%s/sqlite3.h: version %s"%(d, sqlite_version))
1171n/a sqlite_incdir = d
1172n/a break
1173n/a else:
1174n/a if sqlite_setup_debug:
1175n/a print("%s: version %d is too old, need >= %s"%(d,
1176n/a sqlite_version, MIN_SQLITE_VERSION))
1177n/a elif sqlite_setup_debug:
1178n/a print("sqlite: %s had no SQLITE_VERSION"%(f,))
1179n/a
1180n/a if sqlite_incdir:
1181n/a sqlite_dirs_to_check = [
1182n/a os.path.join(sqlite_incdir, '..', 'lib64'),
1183n/a os.path.join(sqlite_incdir, '..', 'lib'),
1184n/a os.path.join(sqlite_incdir, '..', '..', 'lib64'),
1185n/a os.path.join(sqlite_incdir, '..', '..', 'lib'),
1186n/a ]
1187n/a sqlite_libfile = self.compiler.find_library_file(
1188n/a sqlite_dirs_to_check + lib_dirs, 'sqlite3')
1189n/a if sqlite_libfile:
1190n/a sqlite_libdir = [os.path.abspath(os.path.dirname(sqlite_libfile))]
1191n/a
1192n/a if sqlite_incdir and sqlite_libdir:
1193n/a sqlite_srcs = ['_sqlite/cache.c',
1194n/a '_sqlite/connection.c',
1195n/a '_sqlite/cursor.c',
1196n/a '_sqlite/microprotocols.c',
1197n/a '_sqlite/module.c',
1198n/a '_sqlite/prepare_protocol.c',
1199n/a '_sqlite/row.c',
1200n/a '_sqlite/statement.c',
1201n/a '_sqlite/util.c', ]
1202n/a
1203n/a sqlite_defines = []
1204n/a if host_platform != "win32":
1205n/a sqlite_defines.append(('MODULE_NAME', '"sqlite3"'))
1206n/a else:
1207n/a sqlite_defines.append(('MODULE_NAME', '\\"sqlite3\\"'))
1208n/a
1209n/a # Enable support for loadable extensions in the sqlite3 module
1210n/a # if --enable-loadable-sqlite-extensions configure option is used.
1211n/a if '--enable-loadable-sqlite-extensions' not in sysconfig.get_config_var("CONFIG_ARGS"):
1212n/a sqlite_defines.append(("SQLITE_OMIT_LOAD_EXTENSION", "1"))
1213n/a
1214n/a if host_platform == 'darwin':
1215n/a # In every directory on the search path search for a dynamic
1216n/a # library and then a static library, instead of first looking
1217n/a # for dynamic libraries on the entire path.
1218n/a # This way a statically linked custom sqlite gets picked up
1219n/a # before the dynamic library in /usr/lib.
1220n/a sqlite_extra_link_args = ('-Wl,-search_paths_first',)
1221n/a else:
1222n/a sqlite_extra_link_args = ()
1223n/a
1224n/a include_dirs = ["Modules/_sqlite"]
1225n/a # Only include the directory where sqlite was found if it does
1226n/a # not already exist in set include directories, otherwise you
1227n/a # can end up with a bad search path order.
1228n/a if sqlite_incdir not in self.compiler.include_dirs:
1229n/a include_dirs.append(sqlite_incdir)
1230n/a # avoid a runtime library path for a system library dir
1231n/a if sqlite_libdir and sqlite_libdir[0] in lib_dirs:
1232n/a sqlite_libdir = None
1233n/a exts.append(Extension('_sqlite3', sqlite_srcs,
1234n/a define_macros=sqlite_defines,
1235n/a include_dirs=include_dirs,
1236n/a library_dirs=sqlite_libdir,
1237n/a extra_link_args=sqlite_extra_link_args,
1238n/a libraries=["sqlite3",]))
1239n/a else:
1240n/a missing.append('_sqlite3')
1241n/a
1242n/a dbm_setup_debug = False # verbose debug prints from this script?
1243n/a dbm_order = ['gdbm']
1244n/a # The standard Unix dbm module:
1245n/a if host_platform not in ['cygwin']:
1246n/a config_args = [arg.strip("'")
1247n/a for arg in sysconfig.get_config_var("CONFIG_ARGS").split()]
1248n/a dbm_args = [arg for arg in config_args
1249n/a if arg.startswith('--with-dbmliborder=')]
1250n/a if dbm_args:
1251n/a dbm_order = [arg.split('=')[-1] for arg in dbm_args][-1].split(":")
1252n/a else:
1253n/a dbm_order = "ndbm:gdbm:bdb".split(":")
1254n/a dbmext = None
1255n/a for cand in dbm_order:
1256n/a if cand == "ndbm":
1257n/a if find_file("ndbm.h", inc_dirs, []) is not None:
1258n/a # Some systems have -lndbm, others have -lgdbm_compat,
1259n/a # others don't have either
1260n/a if self.compiler.find_library_file(lib_dirs,
1261n/a 'ndbm'):
1262n/a ndbm_libs = ['ndbm']
1263n/a elif self.compiler.find_library_file(lib_dirs,
1264n/a 'gdbm_compat'):
1265n/a ndbm_libs = ['gdbm_compat']
1266n/a else:
1267n/a ndbm_libs = []
1268n/a if dbm_setup_debug: print("building dbm using ndbm")
1269n/a dbmext = Extension('_dbm', ['_dbmmodule.c'],
1270n/a define_macros=[
1271n/a ('HAVE_NDBM_H',None),
1272n/a ],
1273n/a libraries=ndbm_libs)
1274n/a break
1275n/a
1276n/a elif cand == "gdbm":
1277n/a if self.compiler.find_library_file(lib_dirs, 'gdbm'):
1278n/a gdbm_libs = ['gdbm']
1279n/a if self.compiler.find_library_file(lib_dirs,
1280n/a 'gdbm_compat'):
1281n/a gdbm_libs.append('gdbm_compat')
1282n/a if find_file("gdbm/ndbm.h", inc_dirs, []) is not None:
1283n/a if dbm_setup_debug: print("building dbm using gdbm")
1284n/a dbmext = Extension(
1285n/a '_dbm', ['_dbmmodule.c'],
1286n/a define_macros=[
1287n/a ('HAVE_GDBM_NDBM_H', None),
1288n/a ],
1289n/a libraries = gdbm_libs)
1290n/a break
1291n/a if find_file("gdbm-ndbm.h", inc_dirs, []) is not None:
1292n/a if dbm_setup_debug: print("building dbm using gdbm")
1293n/a dbmext = Extension(
1294n/a '_dbm', ['_dbmmodule.c'],
1295n/a define_macros=[
1296n/a ('HAVE_GDBM_DASH_NDBM_H', None),
1297n/a ],
1298n/a libraries = gdbm_libs)
1299n/a break
1300n/a elif cand == "bdb":
1301n/a if dblibs:
1302n/a if dbm_setup_debug: print("building dbm using bdb")
1303n/a dbmext = Extension('_dbm', ['_dbmmodule.c'],
1304n/a library_dirs=dblib_dir,
1305n/a runtime_library_dirs=dblib_dir,
1306n/a include_dirs=db_incs,
1307n/a define_macros=[
1308n/a ('HAVE_BERKDB_H', None),
1309n/a ('DB_DBM_HSEARCH', None),
1310n/a ],
1311n/a libraries=dblibs)
1312n/a break
1313n/a if dbmext is not None:
1314n/a exts.append(dbmext)
1315n/a else:
1316n/a missing.append('_dbm')
1317n/a
1318n/a # Anthony Baxter's gdbm module. GNU dbm(3) will require -lgdbm:
1319n/a if ('gdbm' in dbm_order and
1320n/a self.compiler.find_library_file(lib_dirs, 'gdbm')):
1321n/a exts.append( Extension('_gdbm', ['_gdbmmodule.c'],
1322n/a libraries = ['gdbm'] ) )
1323n/a else:
1324n/a missing.append('_gdbm')
1325n/a
1326n/a # Unix-only modules
1327n/a if host_platform != 'win32':
1328n/a # Steen Lumholt's termios module
1329n/a exts.append( Extension('termios', ['termios.c']) )
1330n/a # Jeremy Hylton's rlimit interface
1331n/a exts.append( Extension('resource', ['resource.c']) )
1332n/a
1333n/a # Sun yellow pages. Some systems have the functions in libc.
1334n/a if (host_platform not in ['cygwin', 'qnx6'] and
1335n/a find_file('rpcsvc/yp_prot.h', inc_dirs, []) is not None):
1336n/a if (self.compiler.find_library_file(lib_dirs, 'nsl')):
1337n/a libs = ['nsl']
1338n/a else:
1339n/a libs = []
1340n/a exts.append( Extension('nis', ['nismodule.c'],
1341n/a libraries = libs) )
1342n/a else:
1343n/a missing.append('nis')
1344n/a else:
1345n/a missing.extend(['nis', 'resource', 'termios'])
1346n/a
1347n/a # Curses support, requiring the System V version of curses, often
1348n/a # provided by the ncurses library.
1349n/a curses_defines = []
1350n/a curses_includes = []
1351n/a panel_library = 'panel'
1352n/a if curses_library == 'ncursesw':
1353n/a curses_defines.append(('HAVE_NCURSESW', '1'))
1354n/a if not cross_compiling:
1355n/a curses_includes.append('/usr/include/ncursesw')
1356n/a # Bug 1464056: If _curses.so links with ncursesw,
1357n/a # _curses_panel.so must link with panelw.
1358n/a panel_library = 'panelw'
1359n/a if host_platform == 'darwin':
1360n/a # On OS X, there is no separate /usr/lib/libncursesw nor
1361n/a # libpanelw. If we are here, we found a locally-supplied
1362n/a # version of libncursesw. There should be also be a
1363n/a # libpanelw. _XOPEN_SOURCE defines are usually excluded
1364n/a # for OS X but we need _XOPEN_SOURCE_EXTENDED here for
1365n/a # ncurses wide char support
1366n/a curses_defines.append(('_XOPEN_SOURCE_EXTENDED', '1'))
1367n/a elif host_platform == 'darwin' and curses_library == 'ncurses':
1368n/a # Building with the system-suppied combined libncurses/libpanel
1369n/a curses_defines.append(('HAVE_NCURSESW', '1'))
1370n/a curses_defines.append(('_XOPEN_SOURCE_EXTENDED', '1'))
1371n/a
1372n/a if curses_library.startswith('ncurses'):
1373n/a curses_libs = [curses_library]
1374n/a exts.append( Extension('_curses', ['_cursesmodule.c'],
1375n/a include_dirs=curses_includes,
1376n/a define_macros=curses_defines,
1377n/a libraries = curses_libs) )
1378n/a elif curses_library == 'curses' and host_platform != 'darwin':
1379n/a # OSX has an old Berkeley curses, not good enough for
1380n/a # the _curses module.
1381n/a if (self.compiler.find_library_file(lib_dirs, 'terminfo')):
1382n/a curses_libs = ['curses', 'terminfo']
1383n/a elif (self.compiler.find_library_file(lib_dirs, 'termcap')):
1384n/a curses_libs = ['curses', 'termcap']
1385n/a else:
1386n/a curses_libs = ['curses']
1387n/a
1388n/a exts.append( Extension('_curses', ['_cursesmodule.c'],
1389n/a define_macros=curses_defines,
1390n/a libraries = curses_libs) )
1391n/a else:
1392n/a missing.append('_curses')
1393n/a
1394n/a # If the curses module is enabled, check for the panel module
1395n/a if (module_enabled(exts, '_curses') and
1396n/a self.compiler.find_library_file(lib_dirs, panel_library)):
1397n/a exts.append( Extension('_curses_panel', ['_curses_panel.c'],
1398n/a include_dirs=curses_includes,
1399n/a define_macros=curses_defines,
1400n/a libraries = [panel_library] + curses_libs) )
1401n/a else:
1402n/a missing.append('_curses_panel')
1403n/a
1404n/a # Andrew Kuchling's zlib module. Note that some versions of zlib
1405n/a # 1.1.3 have security problems. See CERT Advisory CA-2002-07:
1406n/a # http://www.cert.org/advisories/CA-2002-07.html
1407n/a #
1408n/a # zlib 1.1.4 is fixed, but at least one vendor (RedHat) has decided to
1409n/a # patch its zlib 1.1.3 package instead of upgrading to 1.1.4. For
1410n/a # now, we still accept 1.1.3, because we think it's difficult to
1411n/a # exploit this in Python, and we'd rather make it RedHat's problem
1412n/a # than our problem <wink>.
1413n/a #
1414n/a # You can upgrade zlib to version 1.1.4 yourself by going to
1415n/a # http://www.gzip.org/zlib/
1416n/a zlib_inc = find_file('zlib.h', [], inc_dirs)
1417n/a have_zlib = False
1418n/a if zlib_inc is not None:
1419n/a zlib_h = zlib_inc[0] + '/zlib.h'
1420n/a version = '"0.0.0"'
1421n/a version_req = '"1.1.3"'
1422n/a if host_platform == 'darwin' and is_macosx_sdk_path(zlib_h):
1423n/a zlib_h = os.path.join(macosx_sdk_root(), zlib_h[1:])
1424n/a with open(zlib_h) as fp:
1425n/a while 1:
1426n/a line = fp.readline()
1427n/a if not line:
1428n/a break
1429n/a if line.startswith('#define ZLIB_VERSION'):
1430n/a version = line.split()[2]
1431n/a break
1432n/a if version >= version_req:
1433n/a if (self.compiler.find_library_file(lib_dirs, 'z')):
1434n/a if host_platform == "darwin":
1435n/a zlib_extra_link_args = ('-Wl,-search_paths_first',)
1436n/a else:
1437n/a zlib_extra_link_args = ()
1438n/a exts.append( Extension('zlib', ['zlibmodule.c'],
1439n/a libraries = ['z'],
1440n/a extra_link_args = zlib_extra_link_args))
1441n/a have_zlib = True
1442n/a else:
1443n/a missing.append('zlib')
1444n/a else:
1445n/a missing.append('zlib')
1446n/a else:
1447n/a missing.append('zlib')
1448n/a
1449n/a # Helper module for various ascii-encoders. Uses zlib for an optimized
1450n/a # crc32 if we have it. Otherwise binascii uses its own.
1451n/a if have_zlib:
1452n/a extra_compile_args = ['-DUSE_ZLIB_CRC32']
1453n/a libraries = ['z']
1454n/a extra_link_args = zlib_extra_link_args
1455n/a else:
1456n/a extra_compile_args = []
1457n/a libraries = []
1458n/a extra_link_args = []
1459n/a exts.append( Extension('binascii', ['binascii.c'],
1460n/a extra_compile_args = extra_compile_args,
1461n/a libraries = libraries,
1462n/a extra_link_args = extra_link_args) )
1463n/a
1464n/a # Gustavo Niemeyer's bz2 module.
1465n/a if (self.compiler.find_library_file(lib_dirs, 'bz2')):
1466n/a if host_platform == "darwin":
1467n/a bz2_extra_link_args = ('-Wl,-search_paths_first',)
1468n/a else:
1469n/a bz2_extra_link_args = ()
1470n/a exts.append( Extension('_bz2', ['_bz2module.c'],
1471n/a libraries = ['bz2'],
1472n/a extra_link_args = bz2_extra_link_args) )
1473n/a else:
1474n/a missing.append('_bz2')
1475n/a
1476n/a # LZMA compression support.
1477n/a if self.compiler.find_library_file(lib_dirs, 'lzma'):
1478n/a exts.append( Extension('_lzma', ['_lzmamodule.c'],
1479n/a libraries = ['lzma']) )
1480n/a else:
1481n/a missing.append('_lzma')
1482n/a
1483n/a # Interface to the Expat XML parser
1484n/a #
1485n/a # Expat was written by James Clark and is now maintained by a group of
1486n/a # developers on SourceForge; see www.libexpat.org for more information.
1487n/a # The pyexpat module was written by Paul Prescod after a prototype by
1488n/a # Jack Jansen. The Expat source is included in Modules/expat/. Usage
1489n/a # of a system shared libexpat.so is possible with --with-system-expat
1490n/a # configure option.
1491n/a #
1492n/a # More information on Expat can be found at www.libexpat.org.
1493n/a #
1494n/a if '--with-system-expat' in sysconfig.get_config_var("CONFIG_ARGS"):
1495n/a expat_inc = []
1496n/a define_macros = []
1497n/a expat_lib = ['expat']
1498n/a expat_sources = []
1499n/a expat_depends = []
1500n/a else:
1501n/a expat_inc = [os.path.join(os.getcwd(), srcdir, 'Modules', 'expat')]
1502n/a define_macros = [
1503n/a ('HAVE_EXPAT_CONFIG_H', '1'),
1504n/a ]
1505n/a expat_lib = []
1506n/a expat_sources = ['expat/xmlparse.c',
1507n/a 'expat/xmlrole.c',
1508n/a 'expat/xmltok.c']
1509n/a expat_depends = ['expat/ascii.h',
1510n/a 'expat/asciitab.h',
1511n/a 'expat/expat.h',
1512n/a 'expat/expat_config.h',
1513n/a 'expat/expat_external.h',
1514n/a 'expat/internal.h',
1515n/a 'expat/latin1tab.h',
1516n/a 'expat/utf8tab.h',
1517n/a 'expat/xmlrole.h',
1518n/a 'expat/xmltok.h',
1519n/a 'expat/xmltok_impl.h'
1520n/a ]
1521n/a
1522n/a exts.append(Extension('pyexpat',
1523n/a define_macros = define_macros,
1524n/a include_dirs = expat_inc,
1525n/a libraries = expat_lib,
1526n/a sources = ['pyexpat.c'] + expat_sources,
1527n/a depends = expat_depends,
1528n/a ))
1529n/a
1530n/a # Fredrik Lundh's cElementTree module. Note that this also
1531n/a # uses expat (via the CAPI hook in pyexpat).
1532n/a
1533n/a if os.path.isfile(os.path.join(srcdir, 'Modules', '_elementtree.c')):
1534n/a define_macros.append(('USE_PYEXPAT_CAPI', None))
1535n/a exts.append(Extension('_elementtree',
1536n/a define_macros = define_macros,
1537n/a include_dirs = expat_inc,
1538n/a libraries = expat_lib,
1539n/a sources = ['_elementtree.c'],
1540n/a depends = ['pyexpat.c'] + expat_sources +
1541n/a expat_depends,
1542n/a ))
1543n/a else:
1544n/a missing.append('_elementtree')
1545n/a
1546n/a # Hye-Shik Chang's CJKCodecs modules.
1547n/a exts.append(Extension('_multibytecodec',
1548n/a ['cjkcodecs/multibytecodec.c']))
1549n/a for loc in ('kr', 'jp', 'cn', 'tw', 'hk', 'iso2022'):
1550n/a exts.append(Extension('_codecs_%s' % loc,
1551n/a ['cjkcodecs/_codecs_%s.c' % loc]))
1552n/a
1553n/a # Stefan Krah's _decimal module
1554n/a exts.append(self._decimal_ext())
1555n/a
1556n/a # Thomas Heller's _ctypes module
1557n/a self.detect_ctypes(inc_dirs, lib_dirs)
1558n/a
1559n/a # Richard Oudkerk's multiprocessing module
1560n/a if host_platform == 'win32': # Windows
1561n/a macros = dict()
1562n/a libraries = ['ws2_32']
1563n/a
1564n/a elif host_platform == 'darwin': # Mac OSX
1565n/a macros = dict()
1566n/a libraries = []
1567n/a
1568n/a elif host_platform == 'cygwin': # Cygwin
1569n/a macros = dict()
1570n/a libraries = []
1571n/a
1572n/a elif host_platform in ('freebsd4', 'freebsd5', 'freebsd6', 'freebsd7', 'freebsd8'):
1573n/a # FreeBSD's P1003.1b semaphore support is very experimental
1574n/a # and has many known problems. (as of June 2008)
1575n/a macros = dict()
1576n/a libraries = []
1577n/a
1578n/a elif host_platform.startswith('openbsd'):
1579n/a macros = dict()
1580n/a libraries = []
1581n/a
1582n/a elif host_platform.startswith('netbsd'):
1583n/a macros = dict()
1584n/a libraries = []
1585n/a
1586n/a else: # Linux and other unices
1587n/a macros = dict()
1588n/a libraries = ['rt']
1589n/a
1590n/a if host_platform == 'win32':
1591n/a multiprocessing_srcs = [ '_multiprocessing/multiprocessing.c',
1592n/a '_multiprocessing/semaphore.c',
1593n/a ]
1594n/a
1595n/a else:
1596n/a multiprocessing_srcs = [ '_multiprocessing/multiprocessing.c',
1597n/a ]
1598n/a if (sysconfig.get_config_var('HAVE_SEM_OPEN') and not
1599n/a sysconfig.get_config_var('POSIX_SEMAPHORES_NOT_ENABLED')):
1600n/a multiprocessing_srcs.append('_multiprocessing/semaphore.c')
1601n/a
1602n/a if sysconfig.get_config_var('WITH_THREAD'):
1603n/a exts.append ( Extension('_multiprocessing', multiprocessing_srcs,
1604n/a define_macros=list(macros.items()),
1605n/a include_dirs=["Modules/_multiprocessing"]))
1606n/a else:
1607n/a missing.append('_multiprocessing')
1608n/a # End multiprocessing
1609n/a
1610n/a # Platform-specific libraries
1611n/a if host_platform.startswith(('linux', 'freebsd', 'gnukfreebsd')):
1612n/a exts.append( Extension('ossaudiodev', ['ossaudiodev.c']) )
1613n/a else:
1614n/a missing.append('ossaudiodev')
1615n/a
1616n/a if host_platform == 'darwin':
1617n/a exts.append(
1618n/a Extension('_scproxy', ['_scproxy.c'],
1619n/a extra_link_args=[
1620n/a '-framework', 'SystemConfiguration',
1621n/a '-framework', 'CoreFoundation',
1622n/a ]))
1623n/a
1624n/a self.extensions.extend(exts)
1625n/a
1626n/a # Call the method for detecting whether _tkinter can be compiled
1627n/a self.detect_tkinter(inc_dirs, lib_dirs)
1628n/a
1629n/a if '_tkinter' not in [e.name for e in self.extensions]:
1630n/a missing.append('_tkinter')
1631n/a
1632n/a## # Uncomment these lines if you want to play with xxmodule.c
1633n/a## ext = Extension('xx', ['xxmodule.c'])
1634n/a## self.extensions.append(ext)
1635n/a
1636n/a if 'd' not in sysconfig.get_config_var('ABIFLAGS'):
1637n/a ext = Extension('xxlimited', ['xxlimited.c'],
1638n/a define_macros=[('Py_LIMITED_API', '0x03050000')])
1639n/a self.extensions.append(ext)
1640n/a
1641n/a return missing
1642n/a
1643n/a def detect_tkinter_explicitly(self):
1644n/a # Build _tkinter using explicit locations for Tcl/Tk.
1645n/a #
1646n/a # This is enabled when both arguments are given to ./configure:
1647n/a #
1648n/a # --with-tcltk-includes="-I/path/to/tclincludes \
1649n/a # -I/path/to/tkincludes"
1650n/a # --with-tcltk-libs="-L/path/to/tcllibs -ltclm.n \
1651n/a # -L/path/to/tklibs -ltkm.n"
1652n/a #
1653n/a # These values can also be specified or overridden via make:
1654n/a # make TCLTK_INCLUDES="..." TCLTK_LIBS="..."
1655n/a #
1656n/a # This can be useful for building and testing tkinter with multiple
1657n/a # versions of Tcl/Tk. Note that a build of Tk depends on a particular
1658n/a # build of Tcl so you need to specify both arguments and use care when
1659n/a # overriding.
1660n/a
1661n/a # The _TCLTK variables are created in the Makefile sharedmods target.
1662n/a tcltk_includes = os.environ.get('_TCLTK_INCLUDES')
1663n/a tcltk_libs = os.environ.get('_TCLTK_LIBS')
1664n/a if not (tcltk_includes and tcltk_libs):
1665n/a # Resume default configuration search.
1666n/a return 0
1667n/a
1668n/a extra_compile_args = tcltk_includes.split()
1669n/a extra_link_args = tcltk_libs.split()
1670n/a ext = Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'],
1671n/a define_macros=[('WITH_APPINIT', 1)],
1672n/a extra_compile_args = extra_compile_args,
1673n/a extra_link_args = extra_link_args,
1674n/a )
1675n/a self.extensions.append(ext)
1676n/a return 1
1677n/a
1678n/a def detect_tkinter_darwin(self, inc_dirs, lib_dirs):
1679n/a # The _tkinter module, using frameworks. Since frameworks are quite
1680n/a # different the UNIX search logic is not sharable.
1681n/a from os.path import join, exists
1682n/a framework_dirs = [
1683n/a '/Library/Frameworks',
1684n/a '/System/Library/Frameworks/',
1685n/a join(os.getenv('HOME'), '/Library/Frameworks')
1686n/a ]
1687n/a
1688n/a sysroot = macosx_sdk_root()
1689n/a
1690n/a # Find the directory that contains the Tcl.framework and Tk.framework
1691n/a # bundles.
1692n/a # XXX distutils should support -F!
1693n/a for F in framework_dirs:
1694n/a # both Tcl.framework and Tk.framework should be present
1695n/a
1696n/a
1697n/a for fw in 'Tcl', 'Tk':
1698n/a if is_macosx_sdk_path(F):
1699n/a if not exists(join(sysroot, F[1:], fw + '.framework')):
1700n/a break
1701n/a else:
1702n/a if not exists(join(F, fw + '.framework')):
1703n/a break
1704n/a else:
1705n/a # ok, F is now directory with both frameworks. Continure
1706n/a # building
1707n/a break
1708n/a else:
1709n/a # Tk and Tcl frameworks not found. Normal "unix" tkinter search
1710n/a # will now resume.
1711n/a return 0
1712n/a
1713n/a # For 8.4a2, we must add -I options that point inside the Tcl and Tk
1714n/a # frameworks. In later release we should hopefully be able to pass
1715n/a # the -F option to gcc, which specifies a framework lookup path.
1716n/a #
1717n/a include_dirs = [
1718n/a join(F, fw + '.framework', H)
1719n/a for fw in ('Tcl', 'Tk')
1720n/a for H in ('Headers', 'Versions/Current/PrivateHeaders')
1721n/a ]
1722n/a
1723n/a # For 8.4a2, the X11 headers are not included. Rather than include a
1724n/a # complicated search, this is a hard-coded path. It could bail out
1725n/a # if X11 libs are not found...
1726n/a include_dirs.append('/usr/X11R6/include')
1727n/a frameworks = ['-framework', 'Tcl', '-framework', 'Tk']
1728n/a
1729n/a # All existing framework builds of Tcl/Tk don't support 64-bit
1730n/a # architectures.
1731n/a cflags = sysconfig.get_config_vars('CFLAGS')[0]
1732n/a archs = re.findall(r'-arch\s+(\w+)', cflags)
1733n/a
1734n/a tmpfile = os.path.join(self.build_temp, 'tk.arch')
1735n/a if not os.path.exists(self.build_temp):
1736n/a os.makedirs(self.build_temp)
1737n/a
1738n/a # Note: cannot use os.popen or subprocess here, that
1739n/a # requires extensions that are not available here.
1740n/a if is_macosx_sdk_path(F):
1741n/a os.system("file %s/Tk.framework/Tk | grep 'for architecture' > %s"%(os.path.join(sysroot, F[1:]), tmpfile))
1742n/a else:
1743n/a os.system("file %s/Tk.framework/Tk | grep 'for architecture' > %s"%(F, tmpfile))
1744n/a
1745n/a with open(tmpfile) as fp:
1746n/a detected_archs = []
1747n/a for ln in fp:
1748n/a a = ln.split()[-1]
1749n/a if a in archs:
1750n/a detected_archs.append(ln.split()[-1])
1751n/a os.unlink(tmpfile)
1752n/a
1753n/a for a in detected_archs:
1754n/a frameworks.append('-arch')
1755n/a frameworks.append(a)
1756n/a
1757n/a ext = Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'],
1758n/a define_macros=[('WITH_APPINIT', 1)],
1759n/a include_dirs = include_dirs,
1760n/a libraries = [],
1761n/a extra_compile_args = frameworks[2:],
1762n/a extra_link_args = frameworks,
1763n/a )
1764n/a self.extensions.append(ext)
1765n/a return 1
1766n/a
1767n/a def detect_tkinter(self, inc_dirs, lib_dirs):
1768n/a # The _tkinter module.
1769n/a
1770n/a # Check whether --with-tcltk-includes and --with-tcltk-libs were
1771n/a # configured or passed into the make target. If so, use these values
1772n/a # to build tkinter and bypass the searches for Tcl and TK in standard
1773n/a # locations.
1774n/a if self.detect_tkinter_explicitly():
1775n/a return
1776n/a
1777n/a # Rather than complicate the code below, detecting and building
1778n/a # AquaTk is a separate method. Only one Tkinter will be built on
1779n/a # Darwin - either AquaTk, if it is found, or X11 based Tk.
1780n/a if (host_platform == 'darwin' and
1781n/a self.detect_tkinter_darwin(inc_dirs, lib_dirs)):
1782n/a return
1783n/a
1784n/a # Assume we haven't found any of the libraries or include files
1785n/a # The versions with dots are used on Unix, and the versions without
1786n/a # dots on Windows, for detection by cygwin.
1787n/a tcllib = tklib = tcl_includes = tk_includes = None
1788n/a for version in ['8.6', '86', '8.5', '85', '8.4', '84', '8.3', '83',
1789n/a '8.2', '82', '8.1', '81', '8.0', '80']:
1790n/a tklib = self.compiler.find_library_file(lib_dirs,
1791n/a 'tk' + version)
1792n/a tcllib = self.compiler.find_library_file(lib_dirs,
1793n/a 'tcl' + version)
1794n/a if tklib and tcllib:
1795n/a # Exit the loop when we've found the Tcl/Tk libraries
1796n/a break
1797n/a
1798n/a # Now check for the header files
1799n/a if tklib and tcllib:
1800n/a # Check for the include files on Debian and {Free,Open}BSD, where
1801n/a # they're put in /usr/include/{tcl,tk}X.Y
1802n/a dotversion = version
1803n/a if '.' not in dotversion and "bsd" in host_platform.lower():
1804n/a # OpenBSD and FreeBSD use Tcl/Tk library names like libtcl83.a,
1805n/a # but the include subdirs are named like .../include/tcl8.3.
1806n/a dotversion = dotversion[:-1] + '.' + dotversion[-1]
1807n/a tcl_include_sub = []
1808n/a tk_include_sub = []
1809n/a for dir in inc_dirs:
1810n/a tcl_include_sub += [dir + os.sep + "tcl" + dotversion]
1811n/a tk_include_sub += [dir + os.sep + "tk" + dotversion]
1812n/a tk_include_sub += tcl_include_sub
1813n/a tcl_includes = find_file('tcl.h', inc_dirs, tcl_include_sub)
1814n/a tk_includes = find_file('tk.h', inc_dirs, tk_include_sub)
1815n/a
1816n/a if (tcllib is None or tklib is None or
1817n/a tcl_includes is None or tk_includes is None):
1818n/a self.announce("INFO: Can't locate Tcl/Tk libs and/or headers", 2)
1819n/a return
1820n/a
1821n/a # OK... everything seems to be present for Tcl/Tk.
1822n/a
1823n/a include_dirs = [] ; libs = [] ; defs = [] ; added_lib_dirs = []
1824n/a for dir in tcl_includes + tk_includes:
1825n/a if dir not in include_dirs:
1826n/a include_dirs.append(dir)
1827n/a
1828n/a # Check for various platform-specific directories
1829n/a if host_platform == 'sunos5':
1830n/a include_dirs.append('/usr/openwin/include')
1831n/a added_lib_dirs.append('/usr/openwin/lib')
1832n/a elif os.path.exists('/usr/X11R6/include'):
1833n/a include_dirs.append('/usr/X11R6/include')
1834n/a added_lib_dirs.append('/usr/X11R6/lib64')
1835n/a added_lib_dirs.append('/usr/X11R6/lib')
1836n/a elif os.path.exists('/usr/X11R5/include'):
1837n/a include_dirs.append('/usr/X11R5/include')
1838n/a added_lib_dirs.append('/usr/X11R5/lib')
1839n/a else:
1840n/a # Assume default location for X11
1841n/a include_dirs.append('/usr/X11/include')
1842n/a added_lib_dirs.append('/usr/X11/lib')
1843n/a
1844n/a # If Cygwin, then verify that X is installed before proceeding
1845n/a if host_platform == 'cygwin':
1846n/a x11_inc = find_file('X11/Xlib.h', [], include_dirs)
1847n/a if x11_inc is None:
1848n/a return
1849n/a
1850n/a # Check for BLT extension
1851n/a if self.compiler.find_library_file(lib_dirs + added_lib_dirs,
1852n/a 'BLT8.0'):
1853n/a defs.append( ('WITH_BLT', 1) )
1854n/a libs.append('BLT8.0')
1855n/a elif self.compiler.find_library_file(lib_dirs + added_lib_dirs,
1856n/a 'BLT'):
1857n/a defs.append( ('WITH_BLT', 1) )
1858n/a libs.append('BLT')
1859n/a
1860n/a # Add the Tcl/Tk libraries
1861n/a libs.append('tk'+ version)
1862n/a libs.append('tcl'+ version)
1863n/a
1864n/a if host_platform in ['aix3', 'aix4']:
1865n/a libs.append('ld')
1866n/a
1867n/a # Finally, link with the X11 libraries (not appropriate on cygwin)
1868n/a if host_platform != "cygwin":
1869n/a libs.append('X11')
1870n/a
1871n/a ext = Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'],
1872n/a define_macros=[('WITH_APPINIT', 1)] + defs,
1873n/a include_dirs = include_dirs,
1874n/a libraries = libs,
1875n/a library_dirs = added_lib_dirs,
1876n/a )
1877n/a self.extensions.append(ext)
1878n/a
1879n/a # XXX handle these, but how to detect?
1880n/a # *** Uncomment and edit for PIL (TkImaging) extension only:
1881n/a # -DWITH_PIL -I../Extensions/Imaging/libImaging tkImaging.c \
1882n/a # *** Uncomment and edit for TOGL extension only:
1883n/a # -DWITH_TOGL togl.c \
1884n/a # *** Uncomment these for TOGL extension only:
1885n/a # -lGL -lGLU -lXext -lXmu \
1886n/a
1887n/a def configure_ctypes_darwin(self, ext):
1888n/a # Darwin (OS X) uses preconfigured files, in
1889n/a # the Modules/_ctypes/libffi_osx directory.
1890n/a srcdir = sysconfig.get_config_var('srcdir')
1891n/a ffi_srcdir = os.path.abspath(os.path.join(srcdir, 'Modules',
1892n/a '_ctypes', 'libffi_osx'))
1893n/a sources = [os.path.join(ffi_srcdir, p)
1894n/a for p in ['ffi.c',
1895n/a 'x86/darwin64.S',
1896n/a 'x86/x86-darwin.S',
1897n/a 'x86/x86-ffi_darwin.c',
1898n/a 'x86/x86-ffi64.c',
1899n/a 'powerpc/ppc-darwin.S',
1900n/a 'powerpc/ppc-darwin_closure.S',
1901n/a 'powerpc/ppc-ffi_darwin.c',
1902n/a 'powerpc/ppc64-darwin_closure.S',
1903n/a ]]
1904n/a
1905n/a # Add .S (preprocessed assembly) to C compiler source extensions.
1906n/a self.compiler.src_extensions.append('.S')
1907n/a
1908n/a include_dirs = [os.path.join(ffi_srcdir, 'include'),
1909n/a os.path.join(ffi_srcdir, 'powerpc')]
1910n/a ext.include_dirs.extend(include_dirs)
1911n/a ext.sources.extend(sources)
1912n/a return True
1913n/a
1914n/a def configure_ctypes(self, ext):
1915n/a if not self.use_system_libffi:
1916n/a if host_platform == 'darwin':
1917n/a return self.configure_ctypes_darwin(ext)
1918n/a print('INFO: Could not locate ffi libs and/or headers')
1919n/a return False
1920n/a return True
1921n/a
1922n/a def detect_ctypes(self, inc_dirs, lib_dirs):
1923n/a self.use_system_libffi = False
1924n/a include_dirs = []
1925n/a extra_compile_args = []
1926n/a extra_link_args = []
1927n/a sources = ['_ctypes/_ctypes.c',
1928n/a '_ctypes/callbacks.c',
1929n/a '_ctypes/callproc.c',
1930n/a '_ctypes/stgdict.c',
1931n/a '_ctypes/cfield.c']
1932n/a depends = ['_ctypes/ctypes.h']
1933n/a math_libs = self.detect_math_libs()
1934n/a
1935n/a if host_platform == 'darwin':
1936n/a sources.append('_ctypes/malloc_closure.c')
1937n/a sources.append('_ctypes/darwin/dlfcn_simple.c')
1938n/a extra_compile_args.append('-DMACOSX')
1939n/a include_dirs.append('_ctypes/darwin')
1940n/a# XXX Is this still needed?
1941n/a## extra_link_args.extend(['-read_only_relocs', 'warning'])
1942n/a
1943n/a elif host_platform == 'sunos5':
1944n/a # XXX This shouldn't be necessary; it appears that some
1945n/a # of the assembler code is non-PIC (i.e. it has relocations
1946n/a # when it shouldn't. The proper fix would be to rewrite
1947n/a # the assembler code to be PIC.
1948n/a # This only works with GCC; the Sun compiler likely refuses
1949n/a # this option. If you want to compile ctypes with the Sun
1950n/a # compiler, please research a proper solution, instead of
1951n/a # finding some -z option for the Sun compiler.
1952n/a extra_link_args.append('-mimpure-text')
1953n/a
1954n/a elif host_platform.startswith('hp-ux'):
1955n/a extra_link_args.append('-fPIC')
1956n/a
1957n/a ext = Extension('_ctypes',
1958n/a include_dirs=include_dirs,
1959n/a extra_compile_args=extra_compile_args,
1960n/a extra_link_args=extra_link_args,
1961n/a libraries=[],
1962n/a sources=sources,
1963n/a depends=depends)
1964n/a # function my_sqrt() needs math library for sqrt()
1965n/a ext_test = Extension('_ctypes_test',
1966n/a sources=['_ctypes/_ctypes_test.c'],
1967n/a libraries=math_libs)
1968n/a self.extensions.extend([ext, ext_test])
1969n/a
1970n/a if host_platform == 'darwin':
1971n/a if '--with-system-ffi' not in sysconfig.get_config_var("CONFIG_ARGS"):
1972n/a return
1973n/a # OS X 10.5 comes with libffi.dylib; the include files are
1974n/a # in /usr/include/ffi
1975n/a inc_dirs.append('/usr/include/ffi')
1976n/a
1977n/a ffi_inc = [sysconfig.get_config_var("LIBFFI_INCLUDEDIR")]
1978n/a if not ffi_inc or ffi_inc[0] == '':
1979n/a ffi_inc = find_file('ffi.h', [], inc_dirs)
1980n/a if ffi_inc is not None:
1981n/a ffi_h = ffi_inc[0] + '/ffi.h'
1982n/a with open(ffi_h) as f:
1983n/a for line in f:
1984n/a line = line.strip()
1985n/a if line.startswith(('#define LIBFFI_H',
1986n/a '#define ffi_wrapper_h')):
1987n/a break
1988n/a else:
1989n/a ffi_inc = None
1990n/a print('Header file {} does not define LIBFFI_H or '
1991n/a 'ffi_wrapper_h'.format(ffi_h))
1992n/a ffi_lib = None
1993n/a if ffi_inc is not None:
1994n/a for lib_name in ('ffi', 'ffi_pic'):
1995n/a if (self.compiler.find_library_file(lib_dirs, lib_name)):
1996n/a ffi_lib = lib_name
1997n/a break
1998n/a
1999n/a if ffi_inc and ffi_lib:
2000n/a ext.include_dirs.extend(ffi_inc)
2001n/a ext.libraries.append(ffi_lib)
2002n/a self.use_system_libffi = True
2003n/a
2004n/a def _decimal_ext(self):
2005n/a extra_compile_args = []
2006n/a undef_macros = []
2007n/a if '--with-system-libmpdec' in sysconfig.get_config_var("CONFIG_ARGS"):
2008n/a include_dirs = []
2009n/a libraries = [':libmpdec.so.2']
2010n/a sources = ['_decimal/_decimal.c']
2011n/a depends = ['_decimal/docstrings.h']
2012n/a else:
2013n/a srcdir = sysconfig.get_config_var('srcdir')
2014n/a include_dirs = [os.path.abspath(os.path.join(srcdir,
2015n/a 'Modules',
2016n/a '_decimal',
2017n/a 'libmpdec'))]
2018n/a libraries = self.detect_math_libs()
2019n/a sources = [
2020n/a '_decimal/_decimal.c',
2021n/a '_decimal/libmpdec/basearith.c',
2022n/a '_decimal/libmpdec/constants.c',
2023n/a '_decimal/libmpdec/context.c',
2024n/a '_decimal/libmpdec/convolute.c',
2025n/a '_decimal/libmpdec/crt.c',
2026n/a '_decimal/libmpdec/difradix2.c',
2027n/a '_decimal/libmpdec/fnt.c',
2028n/a '_decimal/libmpdec/fourstep.c',
2029n/a '_decimal/libmpdec/io.c',
2030n/a '_decimal/libmpdec/memory.c',
2031n/a '_decimal/libmpdec/mpdecimal.c',
2032n/a '_decimal/libmpdec/numbertheory.c',
2033n/a '_decimal/libmpdec/sixstep.c',
2034n/a '_decimal/libmpdec/transpose.c',
2035n/a ]
2036n/a depends = [
2037n/a '_decimal/docstrings.h',
2038n/a '_decimal/libmpdec/basearith.h',
2039n/a '_decimal/libmpdec/bits.h',
2040n/a '_decimal/libmpdec/constants.h',
2041n/a '_decimal/libmpdec/convolute.h',
2042n/a '_decimal/libmpdec/crt.h',
2043n/a '_decimal/libmpdec/difradix2.h',
2044n/a '_decimal/libmpdec/fnt.h',
2045n/a '_decimal/libmpdec/fourstep.h',
2046n/a '_decimal/libmpdec/io.h',
2047n/a '_decimal/libmpdec/mpalloc.h',
2048n/a '_decimal/libmpdec/mpdecimal.h',
2049n/a '_decimal/libmpdec/numbertheory.h',
2050n/a '_decimal/libmpdec/sixstep.h',
2051n/a '_decimal/libmpdec/transpose.h',
2052n/a '_decimal/libmpdec/typearith.h',
2053n/a '_decimal/libmpdec/umodarith.h',
2054n/a ]
2055n/a
2056n/a config = {
2057n/a 'x64': [('CONFIG_64','1'), ('ASM','1')],
2058n/a 'uint128': [('CONFIG_64','1'), ('ANSI','1'), ('HAVE_UINT128_T','1')],
2059n/a 'ansi64': [('CONFIG_64','1'), ('ANSI','1')],
2060n/a 'ppro': [('CONFIG_32','1'), ('PPRO','1'), ('ASM','1')],
2061n/a 'ansi32': [('CONFIG_32','1'), ('ANSI','1')],
2062n/a 'ansi-legacy': [('CONFIG_32','1'), ('ANSI','1'),
2063n/a ('LEGACY_COMPILER','1')],
2064n/a 'universal': [('UNIVERSAL','1')]
2065n/a }
2066n/a
2067n/a cc = sysconfig.get_config_var('CC')
2068n/a sizeof_size_t = sysconfig.get_config_var('SIZEOF_SIZE_T')
2069n/a machine = os.environ.get('PYTHON_DECIMAL_WITH_MACHINE')
2070n/a
2071n/a if machine:
2072n/a # Override automatic configuration to facilitate testing.
2073n/a define_macros = config[machine]
2074n/a elif host_platform == 'darwin':
2075n/a # Universal here means: build with the same options Python
2076n/a # was built with.
2077n/a define_macros = config['universal']
2078n/a elif sizeof_size_t == 8:
2079n/a if sysconfig.get_config_var('HAVE_GCC_ASM_FOR_X64'):
2080n/a define_macros = config['x64']
2081n/a elif sysconfig.get_config_var('HAVE_GCC_UINT128_T'):
2082n/a define_macros = config['uint128']
2083n/a else:
2084n/a define_macros = config['ansi64']
2085n/a elif sizeof_size_t == 4:
2086n/a ppro = sysconfig.get_config_var('HAVE_GCC_ASM_FOR_X87')
2087n/a if ppro and ('gcc' in cc or 'clang' in cc) and \
2088n/a not 'sunos' in host_platform:
2089n/a # solaris: problems with register allocation.
2090n/a # icc >= 11.0 works as well.
2091n/a define_macros = config['ppro']
2092n/a extra_compile_args.append('-Wno-unknown-pragmas')
2093n/a else:
2094n/a define_macros = config['ansi32']
2095n/a else:
2096n/a raise DistutilsError("_decimal: unsupported architecture")
2097n/a
2098n/a # Workarounds for toolchain bugs:
2099n/a if sysconfig.get_config_var('HAVE_IPA_PURE_CONST_BUG'):
2100n/a # Some versions of gcc miscompile inline asm:
2101n/a # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46491
2102n/a # http://gcc.gnu.org/ml/gcc/2010-11/msg00366.html
2103n/a extra_compile_args.append('-fno-ipa-pure-const')
2104n/a if sysconfig.get_config_var('HAVE_GLIBC_MEMMOVE_BUG'):
2105n/a # _FORTIFY_SOURCE wrappers for memmove and bcopy are incorrect:
2106n/a # http://sourceware.org/ml/libc-alpha/2010-12/msg00009.html
2107n/a undef_macros.append('_FORTIFY_SOURCE')
2108n/a
2109n/a # Faster version without thread local contexts:
2110n/a if not sysconfig.get_config_var('WITH_THREAD'):
2111n/a define_macros.append(('WITHOUT_THREADS', 1))
2112n/a
2113n/a # Uncomment for extra functionality:
2114n/a #define_macros.append(('EXTRA_FUNCTIONALITY', 1))
2115n/a ext = Extension (
2116n/a '_decimal',
2117n/a include_dirs=include_dirs,
2118n/a libraries=libraries,
2119n/a define_macros=define_macros,
2120n/a undef_macros=undef_macros,
2121n/a extra_compile_args=extra_compile_args,
2122n/a sources=sources,
2123n/a depends=depends
2124n/a )
2125n/a return ext
2126n/a
2127n/aclass PyBuildInstall(install):
2128n/a # Suppress the warning about installation into the lib_dynload
2129n/a # directory, which is not in sys.path when running Python during
2130n/a # installation:
2131n/a def initialize_options (self):
2132n/a install.initialize_options(self)
2133n/a self.warn_dir=0
2134n/a
2135n/a # Customize subcommands to not install an egg-info file for Python
2136n/a sub_commands = [('install_lib', install.has_lib),
2137n/a ('install_headers', install.has_headers),
2138n/a ('install_scripts', install.has_scripts),
2139n/a ('install_data', install.has_data)]
2140n/a
2141n/a
2142n/aclass PyBuildInstallLib(install_lib):
2143n/a # Do exactly what install_lib does but make sure correct access modes get
2144n/a # set on installed directories and files. All installed files with get
2145n/a # mode 644 unless they are a shared library in which case they will get
2146n/a # mode 755. All installed directories will get mode 755.
2147n/a
2148n/a # this is works for EXT_SUFFIX too, which ends with SHLIB_SUFFIX
2149n/a shlib_suffix = sysconfig.get_config_var("SHLIB_SUFFIX")
2150n/a
2151n/a def install(self):
2152n/a outfiles = install_lib.install(self)
2153n/a self.set_file_modes(outfiles, 0o644, 0o755)
2154n/a self.set_dir_modes(self.install_dir, 0o755)
2155n/a return outfiles
2156n/a
2157n/a def set_file_modes(self, files, defaultMode, sharedLibMode):
2158n/a if not self.is_chmod_supported(): return
2159n/a if not files: return
2160n/a
2161n/a for filename in files:
2162n/a if os.path.islink(filename): continue
2163n/a mode = defaultMode
2164n/a if filename.endswith(self.shlib_suffix): mode = sharedLibMode
2165n/a log.info("changing mode of %s to %o", filename, mode)
2166n/a if not self.dry_run: os.chmod(filename, mode)
2167n/a
2168n/a def set_dir_modes(self, dirname, mode):
2169n/a if not self.is_chmod_supported(): return
2170n/a for dirpath, dirnames, fnames in os.walk(dirname):
2171n/a if os.path.islink(dirpath):
2172n/a continue
2173n/a log.info("changing mode of %s to %o", dirpath, mode)
2174n/a if not self.dry_run: os.chmod(dirpath, mode)
2175n/a
2176n/a def is_chmod_supported(self):
2177n/a return hasattr(os, 'chmod')
2178n/a
2179n/aclass PyBuildScripts(build_scripts):
2180n/a def copy_scripts(self):
2181n/a outfiles, updated_files = build_scripts.copy_scripts(self)
2182n/a fullversion = '-{0[0]}.{0[1]}'.format(sys.version_info)
2183n/a minoronly = '.{0[1]}'.format(sys.version_info)
2184n/a newoutfiles = []
2185n/a newupdated_files = []
2186n/a for filename in outfiles:
2187n/a if filename.endswith(('2to3', 'pyvenv')):
2188n/a newfilename = filename + fullversion
2189n/a else:
2190n/a newfilename = filename + minoronly
2191n/a log.info('renaming %s to %s', filename, newfilename)
2192n/a os.rename(filename, newfilename)
2193n/a newoutfiles.append(newfilename)
2194n/a if filename in updated_files:
2195n/a newupdated_files.append(newfilename)
2196n/a return newoutfiles, newupdated_files
2197n/a
2198n/aSUMMARY = """
2199n/aPython is an interpreted, interactive, object-oriented programming
2200n/alanguage. It is often compared to Tcl, Perl, Scheme or Java.
2201n/a
2202n/aPython combines remarkable power with very clear syntax. It has
2203n/amodules, classes, exceptions, very high level dynamic data types, and
2204n/adynamic typing. There are interfaces to many system calls and
2205n/alibraries, as well as to various windowing systems (X11, Motif, Tk,
2206n/aMac, MFC). New built-in modules are easily written in C or C++. Python
2207n/ais also usable as an extension language for applications that need a
2208n/aprogrammable interface.
2209n/a
2210n/aThe Python implementation is portable: it runs on many brands of UNIX,
2211n/aon Windows, DOS, Mac, Amiga... If your favorite system isn't
2212n/alisted here, it may still be supported, if there's a C compiler for
2213n/ait. Ask around on comp.lang.python -- or just try compiling Python
2214n/ayourself.
2215n/a"""
2216n/a
2217n/aCLASSIFIERS = """
2218n/aDevelopment Status :: 6 - Mature
2219n/aLicense :: OSI Approved :: Python Software Foundation License
2220n/aNatural Language :: English
2221n/aProgramming Language :: C
2222n/aProgramming Language :: Python
2223n/aTopic :: Software Development
2224n/a"""
2225n/a
2226n/adef main():
2227n/a # turn off warnings when deprecated modules are imported
2228n/a import warnings
2229n/a warnings.filterwarnings("ignore",category=DeprecationWarning)
2230n/a setup(# PyPI Metadata (PEP 301)
2231n/a name = "Python",
2232n/a version = sys.version.split()[0],
2233n/a url = "http://www.python.org/%d.%d" % sys.version_info[:2],
2234n/a maintainer = "Guido van Rossum and the Python community",
2235n/a maintainer_email = "python-dev@python.org",
2236n/a description = "A high-level object-oriented programming language",
2237n/a long_description = SUMMARY.strip(),
2238n/a license = "PSF license",
2239n/a classifiers = [x for x in CLASSIFIERS.split("\n") if x],
2240n/a platforms = ["Many"],
2241n/a
2242n/a # Build info
2243n/a cmdclass = {'build_ext': PyBuildExt,
2244n/a 'build_scripts': PyBuildScripts,
2245n/a 'install': PyBuildInstall,
2246n/a 'install_lib': PyBuildInstallLib},
2247n/a # The struct module is defined here, because build_ext won't be
2248n/a # called unless there's at least one extension module defined.
2249n/a ext_modules=[Extension('_struct', ['_struct.c'])],
2250n/a
2251n/a # If you change the scripts installed here, you also need to
2252n/a # check the PyBuildScripts command above, and change the links
2253n/a # created by the bininstall target in Makefile.pre.in
2254n/a scripts = ["Tools/scripts/pydoc3", "Tools/scripts/idle3",
2255n/a "Tools/scripts/2to3", "Tools/scripts/pyvenv"]
2256n/a )
2257n/a
2258n/a# --install-platlib
2259n/aif __name__ == '__main__':
2260n/a main()