+++ /dev/null
-"""distutils.extension\r
-\r
-Provides the Extension class, used to describe C/C++ extension\r
-modules in setup scripts."""\r
-\r
-__revision__ = "$Id$"\r
-\r
-import os, string, sys\r
-from types import *\r
-\r
-try:\r
- import warnings\r
-except ImportError:\r
- warnings = None\r
-\r
-# This class is really only used by the "build_ext" command, so it might\r
-# make sense to put it in distutils.command.build_ext. However, that\r
-# module is already big enough, and I want to make this class a bit more\r
-# complex to simplify some common cases ("foo" module in "foo.c") and do\r
-# better error-checking ("foo.c" actually exists).\r
-#\r
-# Also, putting this in build_ext.py means every setup script would have to\r
-# import that large-ish module (indirectly, through distutils.core) in\r
-# order to do anything.\r
-\r
-class Extension:\r
- """Just a collection of attributes that describes an extension\r
- module and everything needed to build it (hopefully in a portable\r
- way, but there are hooks that let you be as unportable as you need).\r
-\r
- Instance attributes:\r
- name : string\r
- the full name of the extension, including any packages -- ie.\r
- *not* a filename or pathname, but Python dotted name\r
- sources : [string]\r
- list of source filenames, relative to the distribution root\r
- (where the setup script lives), in Unix form (slash-separated)\r
- for portability. Source files may be C, C++, SWIG (.i),\r
- platform-specific resource files, or whatever else is recognized\r
- by the "build_ext" command as source for a Python extension.\r
- include_dirs : [string]\r
- list of directories to search for C/C++ header files (in Unix\r
- form for portability)\r
- define_macros : [(name : string, value : string|None)]\r
- list of macros to define; each macro is defined using a 2-tuple,\r
- where 'value' is either the string to define it to or None to\r
- define it without a particular value (equivalent of "#define\r
- FOO" in source or -DFOO on Unix C compiler command line)\r
- undef_macros : [string]\r
- list of macros to undefine explicitly\r
- library_dirs : [string]\r
- list of directories to search for C/C++ libraries at link time\r
- libraries : [string]\r
- list of library names (not filenames or paths) to link against\r
- runtime_library_dirs : [string]\r
- list of directories to search for C/C++ libraries at run time\r
- (for shared extensions, this is when the extension is loaded)\r
- extra_objects : [string]\r
- list of extra files to link with (eg. object files not implied\r
- by 'sources', static library that must be explicitly specified,\r
- binary resource files, etc.)\r
- extra_compile_args : [string]\r
- any extra platform- and compiler-specific information to use\r
- when compiling the source files in 'sources'. For platforms and\r
- compilers where "command line" makes sense, this is typically a\r
- list of command-line arguments, but for other platforms it could\r
- be anything.\r
- extra_link_args : [string]\r
- any extra platform- and compiler-specific information to use\r
- when linking object files together to create the extension (or\r
- to create a new static Python interpreter). Similar\r
- interpretation as for 'extra_compile_args'.\r
- export_symbols : [string]\r
- list of symbols to be exported from a shared extension. Not\r
- used on all platforms, and not generally necessary for Python\r
- extensions, which typically export exactly one symbol: "init" +\r
- extension_name.\r
- swig_opts : [string]\r
- any extra options to pass to SWIG if a source file has the .i\r
- extension.\r
- depends : [string]\r
- list of files that the extension depends on\r
- language : string\r
- extension language (i.e. "c", "c++", "objc"). Will be detected\r
- from the source extensions if not provided.\r
- """\r
-\r
- # When adding arguments to this constructor, be sure to update\r
- # setup_keywords in core.py.\r
- def __init__ (self, name, sources,\r
- include_dirs=None,\r
- define_macros=None,\r
- undef_macros=None,\r
- library_dirs=None,\r
- libraries=None,\r
- runtime_library_dirs=None,\r
- extra_objects=None,\r
- extra_compile_args=None,\r
- extra_link_args=None,\r
- export_symbols=None,\r
- swig_opts = None,\r
- depends=None,\r
- language=None,\r
- **kw # To catch unknown keywords\r
- ):\r
- assert type(name) is StringType, "'name' must be a string"\r
- assert (type(sources) is ListType and\r
- map(type, sources) == [StringType]*len(sources)), \\r
- "'sources' must be a list of strings"\r
-\r
- self.name = name\r
- self.sources = sources\r
- self.include_dirs = include_dirs or []\r
- self.define_macros = define_macros or []\r
- self.undef_macros = undef_macros or []\r
- self.library_dirs = library_dirs or []\r
- self.libraries = libraries or []\r
- self.runtime_library_dirs = runtime_library_dirs or []\r
- self.extra_objects = extra_objects or []\r
- self.extra_compile_args = extra_compile_args or []\r
- self.extra_link_args = extra_link_args or []\r
- self.export_symbols = export_symbols or []\r
- self.swig_opts = swig_opts or []\r
- self.depends = depends or []\r
- self.language = language\r
-\r
- # If there are unknown keyword options, warn about them\r
- if len(kw):\r
- L = kw.keys() ; L.sort()\r
- L = map(repr, L)\r
- msg = "Unknown Extension options: " + string.join(L, ', ')\r
- if warnings is not None:\r
- warnings.warn(msg)\r
- else:\r
- sys.stderr.write(msg + '\n')\r
-# class Extension\r
-\r
-\r
-def read_setup_file (filename):\r
- from distutils.sysconfig import \\r
- parse_makefile, expand_makefile_vars, _variable_rx\r
- from distutils.text_file import TextFile\r
- from distutils.util import split_quoted\r
-\r
- # First pass over the file to gather "VAR = VALUE" assignments.\r
- vars = parse_makefile(filename)\r
-\r
- # Second pass to gobble up the real content: lines of the form\r
- # <module> ... [<sourcefile> ...] [<cpparg> ...] [<library> ...]\r
- file = TextFile(filename,\r
- strip_comments=1, skip_blanks=1, join_lines=1,\r
- lstrip_ws=1, rstrip_ws=1)\r
- try:\r
- extensions = []\r
-\r
- while 1:\r
- line = file.readline()\r
- if line is None: # eof\r
- break\r
- if _variable_rx.match(line): # VAR=VALUE, handled in first pass\r
- continue\r
-\r
- if line[0] == line[-1] == "*":\r
- file.warn("'%s' lines not handled yet" % line)\r
- continue\r
-\r
- #print "original line: " + line\r
- line = expand_makefile_vars(line, vars)\r
- words = split_quoted(line)\r
- #print "expanded line: " + line\r
-\r
- # NB. this parses a slightly different syntax than the old\r
- # makesetup script: here, there must be exactly one extension per\r
- # line, and it must be the first word of the line. I have no idea\r
- # why the old syntax supported multiple extensions per line, as\r
- # they all wind up being the same.\r
-\r
- module = words[0]\r
- ext = Extension(module, [])\r
- append_next_word = None\r
-\r
- for word in words[1:]:\r
- if append_next_word is not None:\r
- append_next_word.append(word)\r
- append_next_word = None\r
- continue\r
-\r
- suffix = os.path.splitext(word)[1]\r
- switch = word[0:2] ; value = word[2:]\r
-\r
- if suffix in (".c", ".cc", ".cpp", ".cxx", ".c++", ".m", ".mm"):\r
- # hmm, should we do something about C vs. C++ sources?\r
- # or leave it up to the CCompiler implementation to\r
- # worry about?\r
- ext.sources.append(word)\r
- elif switch == "-I":\r
- ext.include_dirs.append(value)\r
- elif switch == "-D":\r
- equals = string.find(value, "=")\r
- if equals == -1: # bare "-DFOO" -- no value\r
- ext.define_macros.append((value, None))\r
- else: # "-DFOO=blah"\r
- ext.define_macros.append((value[0:equals],\r
- value[equals+2:]))\r
- elif switch == "-U":\r
- ext.undef_macros.append(value)\r
- elif switch == "-C": # only here 'cause makesetup has it!\r
- ext.extra_compile_args.append(word)\r
- elif switch == "-l":\r
- ext.libraries.append(value)\r
- elif switch == "-L":\r
- ext.library_dirs.append(value)\r
- elif switch == "-R":\r
- ext.runtime_library_dirs.append(value)\r
- elif word == "-rpath":\r
- append_next_word = ext.runtime_library_dirs\r
- elif word == "-Xlinker":\r
- append_next_word = ext.extra_link_args\r
- elif word == "-Xcompiler":\r
- append_next_word = ext.extra_compile_args\r
- elif switch == "-u":\r
- ext.extra_link_args.append(word)\r
- if not value:\r
- append_next_word = ext.extra_link_args\r
- elif word == "-Xcompiler":\r
- append_next_word = ext.extra_compile_args\r
- elif switch == "-u":\r
- ext.extra_link_args.append(word)\r
- if not value:\r
- append_next_word = ext.extra_link_args\r
- elif suffix in (".a", ".so", ".sl", ".o", ".dylib"):\r
- # NB. a really faithful emulation of makesetup would\r
- # append a .o file to extra_objects only if it\r
- # had a slash in it; otherwise, it would s/.o/.c/\r
- # and append it to sources. Hmmmm.\r
- ext.extra_objects.append(word)\r
- else:\r
- file.warn("unrecognized argument '%s'" % word)\r
-\r
- extensions.append(ext)\r
- finally:\r
- file.close()\r
-\r
- #print "module:", module\r
- #print "source files:", source_files\r
- #print "cpp args:", cpp_args\r
- #print "lib args:", library_args\r
-\r
- #extensions[module] = { 'sources': source_files,\r
- # 'cpp_args': cpp_args,\r
- # 'lib_args': library_args }\r
-\r
- return extensions\r
-\r
-# read_setup_file ()\r