project.py :  » Development » PyFort » Pyfort-8.5.3 » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Development » PyFort 
PyFort » Pyfort 8.5.3 » project.py
import sys, os, glob, string, types
import grammar, generator, fortran_compiler, configuration, version
from distutils.core import setup,Extension
default_makefile = """\
SOURCES=%(sources)s
lib%(name)s.a: $(SOURCES)
\t$(Pyfort_COMPILER) $(Pyfort_COMPILER_OPTIONS) -c $(SOURCES)
\tld -r -o lib%(name)s.a *.o
clean:
\t/bin/rm -f lib%(name)s.a *.o
"""
def execute (line):
    print line
    result = os.system(line)
    if result: 
        raise ValueError, 'Error executing '+line

class pyf:
    """pyf(filename, 
           sources=[], 
           libraries = '',
           library_directories = '',
           compiler_options = '',
           python_directory = '',
           generate_as = '',
           package_name = '',
           freeform = 0,
           use_c_compiler = 0,
       )
       Represents a Pyfort input file that depends on the given sources.
       The sources can be given as a list and will be used as input to 
       glob.glob.
   
       libraries is a list of library objects.
       
       python_directory = directory holding associated python modules, if any.
       freeform = 1 or 0, indicating whether format of file is freeform or 
          column 1 has special meaning
       package_name is an optional name for the module into which the 
          Python code if any and the generated Pyfort extension should be
          installed.
"""

    def __init__ (self, filename, **kw):
        if filename:
            head, tail = os.path.split(filename)
            self.name, junk = os.path.splitext (tail)
        else:
            self.name = ''
        self.filename = filename
        self.sources = kw.get('sources', [])
        self.libraries = kw.get('libraries', '')
        self.library_directories = kw.get('library_directories', '')
        self.compiler_options = kw.get('compiler_options', '')
        self.generate_as = kw.get('generate_as', '')
        self.use_c_compiler = kw.get('use_c_compiler',0)
        self.freeform = kw.get('freeform', 0)
        self.python_directory = kw.get('python_directory', '')
        self.package_name = kw.get('package_name', '')

    def __repr__ (self):
        result = "pyf('%s'" % self.filename
        if self.sources:
            result = result + ", \n    sources=" + repr(self.sources)
        if self.libraries:
            result = result + ", \n    libraries=" + repr(self.libraries)
        if self.library_directories:
            result = result + ", \n    library_directories=" + repr(self.library_directories)
        if self.compiler_options:
            result = result + ", \n    compiler_options=" + repr(self.compiler_options)
        if self.python_directory != '':
            result = result + ", \n    python_directory=" + \
                                 repr(self.python_directory) 
        if self.package_name != '':
            result = result + ", \n    package_name=" + \
                                 repr(self.package_name) 
        if self.generate_as != '':
            result = result + ", \n    generate_as=" + \
                                 repr(self.generate_as) 
        if self.use_c_compiler != 0:
            result = result + ", \n    use_c_compiler="+repr(self.use_c_compiler) 
        if self.freeform != 0:
            result = result + ", \n    freeform=" + repr(self.freeform)
        result = result + ")"
        return result

    def is_advanced (self):
        if self.libraries or self.library_directories or \
               self.compiler_options or self.python_directory or \
               self.package_name:
            return 1
        else:
            return 0

    def generated_module_name (self):
        if self.generate_as: return self.generate_as
        return self.name

    def validate (self):
        "Check the pyf. If not valid, return an error message."
        if not os.path.isfile(self.filename):
            return self.filename + "does not exist."
        if self.python_directory:
            if not os.path.isdir(self.python_directory):
                return "In %s, Python directory %s specified does not exist."\
                      % (self.filename, self.python_directory,)
            if os.path.isfile(os.path.join(self.python_directory, '__init__.py')):
                # Package case
                if not self.package_name:
                    return """In re %s, Python directory %s
contains an __init__.py file, so  you must specify a module name.
""" % (self.filename, self.python_directory)
        else:  # do not have Python
            if self.package_name: 
                return """%s specifies a package name without a Python directory""" % (self.filename,)
        for s in self.sources:
            g = glob.glob(s)
            if not g:
                return self.name + ' source ' + s + \
                       ' does not match any existing file.'
            for x in g:
                name, ext = os.path.splitext(x)
                if not ext:
                    return self.name + ' source ' + s + \
                       ' lacks an extension. Cannot tell if C or Fortran.'
                if ext.lower() == ".c" and not self.use_c_compiler:
                    return self.name + ' source ' + s + \
                       ' is C, but C option not selected.'
                if ext != ".c" and self.use_c_compiler:
                    return self.name + ' source ' + s + \
                       ' is not C, but C option is selected.'
        return ''

    def expanded_sources (self):
        """The expanded list of source files."""
        sources = []
        for x in self.sources:
            sources += [os.path.abspath(\
                        os.path.expanduser(y)) \
                        for y in glob.glob(x)
                       ]
        return sources
        
    def build (self, flags):
        """ build(flags); flags is a dictionary set up by the outer build.

There are three cases:
1. Python package, install everything in it.
2. Python supplied but it isn't a package 
    -- install it and the C at top level
3. No python -- just install C extension at top level
For cleanliness and uninstall, put everything in an "extra_path" area.
"""
        print "Building Pyfort module", self.name
# This validation removes such coding from build itself.
        msg = self.validate()
        if msg: 
            raise SystemExit, msg
        library_directory_list = self.library_directories.split()
        library_names = self.libraries.split()
        libname = 'pyfort_'+self.name
        dir = os.path.abspath(os.path.join('build',libname))
        outdir = flags.get('outdir','')
        if not outdir: 
            outdir = dir
            if not os.path.isdir(outdir):
                os.makedirs(dir)
        minusg = flags.get('minusg', '') 
        if self.sources:
            library_names.insert(0, libname)
            if dir not in library_directory_list:
                library_directory_list.append(dir)
            if not os.path.isdir(dir):
                os.makedirs(dir)
            makefile = os.path.join(dir, "Makefile")
            if os.path.isfile(makefile):
                os.remove(makefile)
            d = { 'name': libname, 
                  'sources': string.join(self.expanded_sources()),
                }
            print >> sys.stderr, "Creating a simple Makefile at ", \
                                  os.path.join(dir, makefile)
            f = open(makefile, 'w')
            print >> f, default_makefile % d
            f.close()
            here = os.getcwd()
            os.chdir(dir)
            if self.use_c_compiler:
                if os.environ.has_key('CC'):
                    c = os.environ['CC']
                else:
                    c = 'cc'
                os.environ['Pyfort_COMPILER'] = c
            else:
                compiler_id = flags.get('fortran_compiler_id', 'default')
                compiler_object = fortran_compiler.get_compiler(compiler_id)
                compiler_name = compiler_object.executable_name()
                os.environ['Pyfort_COMPILER'] = compiler_name
            os.environ['Pyfort_COMPILER_OPTIONS'] = self.compiler_options + " " + \
                                             minusg
            try:
                execute('make')
            except ValueError, msg:
                print '****** Error occurred; your extension was not built.'
                raise SystemExit, 1
            os.chdir(here)

        command = flags.get('command')
        if configuration.prefix:
            command = command.replace('install', 
                                   'install --prefix='+configuration.prefix)
        project_name = flags.get('project_name')+configuration.project_suffix
        fortran_compiler_id = flags.get('fortran_compiler_id')
        if self.use_c_compiler:
            compiler = fortran_compiler.get_compiler('cc')
        else:
            compiler = fortran_compiler.get_compiler(fortran_compiler_id)
        lversion = flags.get('version', version.version)
        sys.argv = ["PYFORT"]+command.split() # Distutils uses sys.argv, sick.
        gmn = self.generated_module_name()
        setupargs = {'name': gmn + "_extension",
                     'version': lversion,
                    }
        if not configuration.prefix:
            setupargs['extra_path'] =  project_name

        if self.python_directory:
            if os.path.isfile(os.path.join(self.python_directory, '__init__.py')):
                # Package case
                module_id = self.package_name + "." + gmn
                setupargs['packages'] = [self.package_name]
                setupargs['package_dir'] = {self.package_name:self.python_directory}
            else:
                # Have Python but not a package
                module_id = gmn
                setupargs['packages'] = ['']
                setupargs['package_dir'] = {'':self.python_directory}
        else:
            # No Python at all
            module_id = gmn
        dfile, cfile = process(gmn, self.filename, compiler, 
                               outdir, not self.freeform)
        print "Your extension has been generated in %s." %outdir
        if command:
            if cfile:
# Note we add in the Fortran runtime libraries here...
                extspec = { 
                'name': module_id,
                'library_dirs': library_directory_list + compiler.dirlist,
                'libraries': library_names + compiler.liblist, 
                'sources': [cfile],
                 }
                eobj = apply(Extension, [], extspec)
                setupargs['ext_modules'] = [eobj]
            print "Executing setup ", command, "using these arguments:"
            for key, value in setupargs.items():
                if key == 'ext_modules':
                    print "    ", "External module specified by:"
                    for k, v in extspec.items():
                        print "        ", k, "=", repr(v)
                else:
                    print "    ", key, "=", repr(value)
            print "---------------------------------"
            if command != "echo":
                apply (setup, [], setupargs)

def process(pyf_module_name, pathname, compiler, outdir, column1_comments):
    """Processes the input file pointed to by pathname to create desired module.
       Returns the names of the two files created.
    """
    tokens = grammar.scan(pathname, column1_comments)
    if not tokens:
        return '',''
    else:
        proclist = grammar.parse(tokens)
    print "Generating documentation file"
    d = generator.Document_Generator(pyf_module_name, ".", proclist, [])
    d.generate()
    print "Generating Pyfort interface in ", outdir
    w = generator.C_Module_Generator(compiler, pyf_module_name, outdir, proclist, [])
    w.generate()
    return (d.filename, w.filename)

class project:
    "A contributed project"
    def __init__ (self, filename):
        self.filename = filename
        dir, basename = os.path.split(filename)
        name, extension = os.path.splitext(basename)
        if not name:
            raise ValueError, 'Must supply a non-blank name for the project.'
        if extension != ".pfp":
            raise ValueError, 'Not a project file: '+ filename
        self.name = name
        self.pyfs = []
        print "Reading", self.filename
        if os.path.isfile(self.filename):
            self.read (self.filename)
        else:
            print "Note: ", self.filename, "does not exist."

    def read (self, filename):
        "Read a saved state from the file."
        d = {'pyf': self.add_pyf}
        execfile(filename, d)
       
    def save (self, filename=None):
        if filename is None:
            filename = self.filename
        f = open(filename, 'w')
        print >>f, str(self)
        f.close()
 
    def validate (self):
        "return a message if project not valid"
        for pyf in self.pyfs:
            msg = pyf.validate()
            if msg: return msg
        return ''

    def __str__ (self):
        result = ""
        for item in self.pyfs:
            result = result + repr(item) + '\n'
        return result

    def add_pyf (self, filename, **kw):
        self.pyfs.append(pyf(filename, **kw))

    def __repr__ (self):
        return "project(%s)" % self.filename

    def build (self, flags):
        flags['package'] = self.name
        for item in self.pyfs:
            item.build(flags)


def build(filename, flags):
    print "Building project", filename
    dir, base = os.path.split(filename)
    here = os.getcwd()
    if dir and dir != here: 
        print "Changing to directory", dir
        os.chdir(dir)
    for k in flags: print k, "=", flags[k]
    p = project(filename)
    p.build(flags)
    os.chdir(here)
    
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.