mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	
		
			
	
	
		
			122 lines
		
	
	
	
		
			5.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			122 lines
		
	
	
	
		
			5.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
|   | """Class representing C/C++ extension modules.""" | ||
|  | 
 | ||
|  | from packaging import logger | ||
|  | 
 | ||
|  | # This class is really only used by the "build_ext" command, so it might | ||
|  | # make sense to put it in distutils.command.build_ext.  However, that | ||
|  | # module is already big enough, and I want to make this class a bit more | ||
|  | # complex to simplify some common cases ("foo" module in "foo.c") and do | ||
|  | # better error-checking ("foo.c" actually exists). | ||
|  | # | ||
|  | # Also, putting this in build_ext.py means every setup script would have to | ||
|  | # import that large-ish module (indirectly, through distutils.core) in | ||
|  | # order to do anything. | ||
|  | 
 | ||
|  | 
 | ||
|  | class Extension: | ||
|  |     """Just a collection of attributes that describes an extension
 | ||
|  |     module and everything needed to build it (hopefully in a portable | ||
|  |     way, but there are hooks that let you be as unportable as you need). | ||
|  | 
 | ||
|  |     Instance attributes: | ||
|  |       name : string | ||
|  |         the full name of the extension, including any packages -- ie. | ||
|  |         *not* a filename or pathname, but Python dotted name | ||
|  |       sources : [string] | ||
|  |         list of source filenames, relative to the distribution root | ||
|  |         (where the setup script lives), in Unix form (slash-separated) | ||
|  |         for portability.  Source files may be C, C++, SWIG (.i), | ||
|  |         platform-specific resource files, or whatever else is recognized | ||
|  |         by the "build_ext" command as source for a Python extension. | ||
|  |       include_dirs : [string] | ||
|  |         list of directories to search for C/C++ header files (in Unix | ||
|  |         form for portability) | ||
|  |       define_macros : [(name : string, value : string|None)] | ||
|  |         list of macros to define; each macro is defined using a 2-tuple, | ||
|  |         where 'value' is either the string to define it to or None to | ||
|  |         define it without a particular value (equivalent of "#define | ||
|  |         FOO" in source or -DFOO on Unix C compiler command line) | ||
|  |       undef_macros : [string] | ||
|  |         list of macros to undefine explicitly | ||
|  |       library_dirs : [string] | ||
|  |         list of directories to search for C/C++ libraries at link time | ||
|  |       libraries : [string] | ||
|  |         list of library names (not filenames or paths) to link against | ||
|  |       runtime_library_dirs : [string] | ||
|  |         list of directories to search for C/C++ libraries at run time | ||
|  |         (for shared extensions, this is when the extension is loaded) | ||
|  |       extra_objects : [string] | ||
|  |         list of extra files to link with (eg. object files not implied | ||
|  |         by 'sources', static library that must be explicitly specified, | ||
|  |         binary resource files, etc.) | ||
|  |       extra_compile_args : [string] | ||
|  |         any extra platform- and compiler-specific information to use | ||
|  |         when compiling the source files in 'sources'.  For platforms and | ||
|  |         compilers where "command line" makes sense, this is typically a | ||
|  |         list of command-line arguments, but for other platforms it could | ||
|  |         be anything. | ||
|  |       extra_link_args : [string] | ||
|  |         any extra platform- and compiler-specific information to use | ||
|  |         when linking object files together to create the extension (or | ||
|  |         to create a new static Python interpreter).  Similar | ||
|  |         interpretation as for 'extra_compile_args'. | ||
|  |       export_symbols : [string] | ||
|  |         list of symbols to be exported from a shared extension.  Not | ||
|  |         used on all platforms, and not generally necessary for Python | ||
|  |         extensions, which typically export exactly one symbol: "init" + | ||
|  |         extension_name. | ||
|  |       swig_opts : [string] | ||
|  |         any extra options to pass to SWIG if a source file has the .i | ||
|  |         extension. | ||
|  |       depends : [string] | ||
|  |         list of files that the extension depends on | ||
|  |       language : string | ||
|  |         extension language (i.e. "c", "c++", "objc"). Will be detected | ||
|  |         from the source extensions if not provided. | ||
|  |       optional : boolean | ||
|  |         specifies that a build failure in the extension should not abort the | ||
|  |         build process, but simply not install the failing extension. | ||
|  |     """
 | ||
|  | 
 | ||
|  |     # **kwargs are allowed so that a warning is emitted instead of an | ||
|  |     # exception | ||
|  |     def __init__(self, name, sources, include_dirs=None, define_macros=None, | ||
|  |                  undef_macros=None, library_dirs=None, libraries=None, | ||
|  |                  runtime_library_dirs=None, extra_objects=None, | ||
|  |                  extra_compile_args=None, extra_link_args=None, | ||
|  |                  export_symbols=None, swig_opts=None, depends=None, | ||
|  |                  language=None, optional=None, **kw): | ||
|  |         if not isinstance(name, str): | ||
|  |             raise AssertionError("'name' must be a string") | ||
|  | 
 | ||
|  |         if not isinstance(sources, list): | ||
|  |             raise AssertionError("'sources' must be a list of strings") | ||
|  | 
 | ||
|  |         for v in sources: | ||
|  |             if not isinstance(v, str): | ||
|  |                 raise AssertionError("'sources' must be a list of strings") | ||
|  | 
 | ||
|  |         self.name = name | ||
|  |         self.sources = sources | ||
|  |         self.include_dirs = include_dirs or [] | ||
|  |         self.define_macros = define_macros or [] | ||
|  |         self.undef_macros = undef_macros or [] | ||
|  |         self.library_dirs = library_dirs or [] | ||
|  |         self.libraries = libraries or [] | ||
|  |         self.runtime_library_dirs = runtime_library_dirs or [] | ||
|  |         self.extra_objects = extra_objects or [] | ||
|  |         self.extra_compile_args = extra_compile_args or [] | ||
|  |         self.extra_link_args = extra_link_args or [] | ||
|  |         self.export_symbols = export_symbols or [] | ||
|  |         self.swig_opts = swig_opts or [] | ||
|  |         self.depends = depends or [] | ||
|  |         self.language = language | ||
|  |         self.optional = optional | ||
|  | 
 | ||
|  |         # If there are unknown keyword options, warn about them | ||
|  |         if len(kw) > 0: | ||
|  |             options = [repr(option) for option in kw] | ||
|  |             options = ', '.join(sorted(options)) | ||
|  |             logger.warning( | ||
|  |                 'unknown arguments given to Extension: %s', options) |