Example #1
0
 def run (self):
     # Build C file
     if os.path.exists ("src/compizconfig.pyx"):
         from Cython.Compiler.Main import compile as cython_compile
         cython_compile ("src/compizconfig.pyx")
     # Run regular sdist
     _sdist.run (self)
Example #2
0
    def run_cython(self, test_directory, module, targetdir, incdir, annotate,
                   extra_compile_options=None):
        include_dirs = INCLUDE_DIRS[:]
        if incdir:
            include_dirs.append(incdir)
        source = self.find_module_source_file(
            os.path.join(test_directory, module + '.pyx'))
        target = os.path.join(targetdir, self.build_target_filename(module))

        if extra_compile_options is None:
            extra_compile_options = {}

        try:
            CompilationOptions
        except NameError:
            from Cython.Compiler.Main import CompilationOptions
            from Cython.Compiler.Main import compile as cython_compile
            from Cython.Compiler.Main import default_options

        options = CompilationOptions(
            default_options,
            include_path = include_dirs,
            output_file = target,
            annotate = annotate,
            use_listing_file = False,
            cplus = self.language == 'cpp',
            language_level = self.language_level,
            generate_pxi = False,
            evaluate_tree_assertions = True,
            **extra_compile_options
            )
        cython_compile(source, options=options,
                       full_module_name=module)
Example #3
0
    def run(self):
        try:
            from Cython.Compiler.Main import compile as cython_compile
            from Cython.Compiler.Options import extra_warnings
        except ImportError:
            raise SystemExit('Cython needs to be installed for this command')
        
        directives = dict(extra_warnings)
        directives['embedsignature'] = True
        directives['language_level'] = 3
        
        # http://trac.cython.org/cython_trac/ticket/714
        directives['warn.maybe_uninitialized'] = False
        
        options = {'include_path': [ os.path.join(basedir, 'Include') ],
                   'recursive': False, 'verbose': True, 'timestamps': False,
                   'compiler_directives': directives, 'warning_errors': True,
                   'compile_time_env': {} }

        for sysname in ('linux', 'freebsd', 'darwin'):
            print('compiling capi.pyx to capi_%s.c...' % (sysname,))
            options['compile_time_env']['TARGET_PLATFORM'] = sysname
            options['output_file'] = os.path.join(basedir, 'src', 'llfuse',
                                                  'capi_%s.c' % (sysname,))
            res = cython_compile(os.path.join(basedir, 'src', 'llfuse', 'capi.pyx'),
                                 full_module_name='llfuse.capi', **options)
            if res.num_errors != 0:
                raise SystemExit('Cython encountered errors.')
Example #4
0
    def run(self):
        try:
            import Cython
            from Cython.Compiler.Main import compile as cython_compile
            from Cython.Compiler.Options import extra_warnings
        except ImportError:
            raise SystemExit('Cython needs to be installed for this command') from None

        if LooseVersion(Cython.__version__) < "0.17":
            raise SystemExit('Found Cython %s, but need 0.17 or newer'
                             % (Cython.__version__,))

        directives = dict(extra_warnings)
        directives['embedsignature'] = True
        directives['language_level'] = 3
        options = { 'recursive': False, 'verbose': True, 'timestamps': False,
                   'compiler_directives': directives, 'warning_errors': True }

        # http://trac.cython.org/cython_trac/ticket/714
        options['compiler_directives']['warn.maybe_uninitialized'] = False

        for extension in self.extensions:
            for file_ in extension.sources:
                (file_, ext) = os.path.splitext(file_)
                path = os.path.join(basedir, file_)
                if ext != '.c':
                    continue
                if os.path.exists(path + '.pyx'):
                    print('compiling %s to %s' % (file_ + '.pyx', file_ + ext))
                    res = cython_compile(path + '.pyx', full_module_name=extension.name,
                                         **options)
                    if res.num_errors != 0:
                        raise SystemExit('Cython encountered errors.')
                else:
                    print('%s is up to date' % (file_ + ext,))
Example #5
0
def run_cython(cython_file, c_file):
    assert have_cython
    msg('Cythonizing %s -> %s', cython_file, c_file)
    options = CythonCompilationOptions(cython_default_options)
    options.output_file = c_file
    try:
        result = cython_compile([cython_file], options)
    except (EnvironmentError, PyrexError), e:
        error_msg(str(e))
Example #6
0
def run_cython(cython_file, c_file):
    assert have_cython
    msg('Cythonizing %s -> %s', cython_file, c_file)
    options = CythonCompilationOptions(cython_default_options)
    options.output_file = c_file
    try:
        result = cython_compile([cython_file], options)
    except (EnvironmentError, PyrexError), e:
        error_msg(str(e))
Example #7
0
 def run_cython(self, test_directory, module, targetdir, incdir, annotate):
     include_dirs = INCLUDE_DIRS[:]
     if incdir:
         include_dirs.append(incdir)
     source = self.find_module_source_file(
         os.path.join(test_directory, module + '.pyx'))
     target = os.path.join(targetdir, self.build_target_filename(module))
     options = CompilationOptions(
         pyrex_default_options,
         include_path = include_dirs,
         output_file = target,
         annotate = annotate,
         use_listing_file = False,
         cplus = self.language == 'cpp',
         language_level = self.language_level,
         generate_pxi = False,
         evaluate_tree_assertions = True,
         )
     cython_compile(source, options=options,
                    full_module_name=module)
Example #8
0
def _compile(code):
    with NamedTemporaryFile(suffix='.py') as f:
        f.write(code.encode('utf8'))
        f.flush()

        try:
            from StringIO import StringIO
        except ImportError:
            from io import StringIO

        old_stderr = sys.stderr
        try:
            sys.stderr = StringIO()
            result = cython_compile(f.name, language_level=3)
        finally:
            sys.stderr = old_stderr
    return result
Example #9
0
    def run(self):
        try:
            import Cython
            from Cython.Compiler.Main import compile as cython_compile
            from Cython.Compiler.Options import extra_warnings
        except ImportError:
            raise SystemExit(
                'Cython needs to be installed for this command') from None

        cython_ver = [int(x) for x in Cython.__version__.split('.')]
        if cython_ver < [0, 17]:
            raise SystemExit('Found Cython %s, but need 0.17 or newer' %
                             (Cython.__version__, ))

        directives = dict(extra_warnings)
        directives['embedsignature'] = True
        directives['language_level'] = 3
        options = {
            'recursive': False,
            'verbose': True,
            'timestamps': False,
            'compiler_directives': directives,
            'warning_errors': True
        }

        # http://trac.cython.org/cython_trac/ticket/714
        options['compiler_directives']['warn.maybe_uninitialized'] = False

        for extension in self.extensions:
            for file_ in extension.sources:
                (file_, ext) = os.path.splitext(file_)
                path = os.path.join(basedir, file_)
                if ext != '.c':
                    continue
                if os.path.exists(path + '.pyx'):
                    print('compiling %s to %s' % (file_ + '.pyx', file_ + ext))
                    res = cython_compile(path + '.pyx',
                                         full_module_name=extension.name,
                                         **options)
                    if res.num_errors != 0:
                        raise SystemExit('Cython encountered errors.')
                else:
                    print('%s is up to date' % (file_ + ext, ))
Example #10
0
    def cython_sources(self, sources, extension):
        """
        Walk the list of source files in 'sources', looking for Cython
        source files (.pyx and .py).  Run Cython on all that are
        found, and return a modified 'sources' list with Cython source
        files replaced by the generated C (or C++) files.
        """

        if PyrexError == None:
            raise DistutilsPlatformError, \
                  ("Cython does not appear to be installed "
                   "on platform '%s'") % os.name

        new_sources = []
        pyrex_sources = []
        pyrex_targets = {}

        # Setup create_list and cplus from the extension options if
        # Cython.Distutils.extension.Extension is used, otherwise just
        # use what was parsed from the command-line or the configuration file.
        # cplus will also be set to true is extension.language is equal to
        # 'C++' or 'c++'.
        #try:
        #    create_listing = self.pyrex_create_listing or \
        #                        extension.pyrex_create_listing
        #    cplus = self.pyrex_cplus or \
        #                extension.pyrex_cplus or \
        #                (extension.language != None and \
        #                    extension.language.lower() == 'c++')
        #except AttributeError:
        #    create_listing = self.pyrex_create_listing
        #    cplus = self.pyrex_cplus or \
        #                (extension.language != None and \
        #                    extension.language.lower() == 'c++')

        create_listing = self.pyrex_create_listing or \
            getattr(extension, 'pyrex_create_listing', 0)
        cplus = self.pyrex_cplus or getattr(extension, 'pyrex_cplus', 0) or \
                (extension.language and extension.language.lower() == 'c++')
        pyrex_gen_pxi = self.pyrex_gen_pxi or getattr(extension,
                                                      'pyrex_gen_pxi', 0)

        # Set up the include_path for the Cython compiler:
        #    1.    Start with the command line option.
        #    2.    Add in any (unique) paths from the extension
        #        pyrex_include_dirs (if Cython.Distutils.extension is used).
        #    3.    Add in any (unique) paths from the extension include_dirs
        includes = self.pyrex_include_dirs
        try:
            for i in extension.pyrex_include_dirs:
                if not i in includes:
                    includes.append(i)
        except AttributeError:
            pass
        for i in extension.include_dirs:
            if not i in includes:
                includes.append(i)

        # Set the target_ext to '.c'.  Cython will change this to '.cpp' if
        # needed.
        if cplus:
            target_ext = '.cpp'
        else:
            target_ext = '.c'

        # Decide whether to drop the generated C files into the temp dir
        # or the source tree.

        if not self.inplace and (self.pyrex_c_in_temp
                                 or getattr(extension, 'pyrex_c_in_temp', 0)):
            target_dir = os.path.join(self.build_temp, "pyrex")
        else:
            target_dir = None

        newest_dependency = None
        for source in sources:
            (base, ext) = os.path.splitext(os.path.basename(source))
            if ext == ".py":
                # FIXME: we might want to special case this some more
                ext = '.pyx'
            if ext == ".pyx":  # Cython source file
                output_dir = target_dir or os.path.dirname(source)
                new_sources.append(os.path.join(output_dir, base + target_ext))
                pyrex_sources.append(source)
                pyrex_targets[source] = new_sources[-1]
            elif ext == '.pxi' or ext == '.pxd':
                if newest_dependency is None \
                        or newer(source, newest_dependency):
                    newest_dependency = source
            else:
                new_sources.append(source)

        if not pyrex_sources:
            return new_sources

        module_name = extension.name

        for source in pyrex_sources:
            target = pyrex_targets[source]
            rebuild = self.force or newer(source, target)
            if not rebuild and newest_dependency is not None:
                rebuild = newer(newest_dependency, target)
            if rebuild:
                log.info("cythoning %s to %s", source, target)
                self.mkpath(os.path.dirname(target))
                options = CompilationOptions(pyrex_default_options,
                                             use_listing_file=create_listing,
                                             include_path=includes,
                                             output_file=target,
                                             cplus=cplus,
                                             generate_pxi=pyrex_gen_pxi)
                result = cython_compile(source,
                                        options=options,
                                        full_module_name=module_name)

        return new_sources
Example #11
0
    def cython_sources(self, sources, extension):

        """
        Walk the list of source files in 'sources', looking for Cython
        source files (.pyx and .py).  Run Cython on all that are
        found, and return a modified 'sources' list with Cython source
        files replaced by the generated C (or C++) files.
        """

        if PyrexError == None:
            raise DistutilsPlatformError, \
                  ("Cython does not appear to be installed "
                   "on platform '%s'") % os.name

        new_sources = []
        pyrex_sources = []
        pyrex_targets = {}

        # Setup create_list and cplus from the extension options if
        # Cython.Distutils.extension.Extension is used, otherwise just
        # use what was parsed from the command-line or the configuration file.
        # cplus will also be set to true is extension.language is equal to
        # 'C++' or 'c++'.
        #try:
        #	create_listing = self.pyrex_create_listing or \
        #						extension.pyrex_create_listing
        #	cplus = self.pyrex_cplus or \
        #				extension.pyrex_cplus or \
        #				(extension.language != None and \
        #					extension.language.lower() == 'c++')
        #except AttributeError:
        #	create_listing = self.pyrex_create_listing
        #	cplus = self.pyrex_cplus or \
        #				(extension.language != None and \
        #					extension.language.lower() == 'c++')
        
        create_listing = self.pyrex_create_listing or \
            getattr(extension, 'pyrex_create_listing', 0)
        cplus = self.pyrex_cplus or getattr(extension, 'pyrex_cplus', 0) or \
                (extension.language and extension.language.lower() == 'c++')
        pyrex_gen_pxi = self.pyrex_gen_pxi or getattr(extension, 'pyrex_gen_pxi', 0)

        # Set up the include_path for the Cython compiler:
        #	1.	Start with the command line option.
        #	2.	Add in any (unique) paths from the extension
        #		pyrex_include_dirs (if Cython.Distutils.extension is used).
        #	3.	Add in any (unique) paths from the extension include_dirs
        includes = self.pyrex_include_dirs
        try:
            for i in extension.pyrex_include_dirs:
                if not i in includes:
                    includes.append(i)
        except AttributeError:
            pass
        for i in extension.include_dirs:
            if not i in includes:
                includes.append(i)

        # Set the target_ext to '.c'.  Cython will change this to '.cpp' if
        # needed.
        if cplus:
            target_ext = '.cpp'
        else:
            target_ext = '.c'

        # Decide whether to drop the generated C files into the temp dir
        # or the source tree.

        if not self.inplace and (self.pyrex_c_in_temp
                or getattr(extension, 'pyrex_c_in_temp', 0)):
            target_dir = os.path.join(self.build_temp, "pyrex")
        else:
            target_dir = None

        newest_dependency = None
        for source in sources:
            (base, ext) = os.path.splitext(os.path.basename(source))
            if ext == ".py":
                # FIXME: we might want to special case this some more
                ext = '.pyx'
            if ext == ".pyx":			  # Cython source file
                output_dir = target_dir or os.path.dirname(source)
                new_sources.append(os.path.join(output_dir, base + target_ext))
                pyrex_sources.append(source)
                pyrex_targets[source] = new_sources[-1]
            elif ext == '.pxi' or ext == '.pxd':
                if newest_dependency is None \
                        or newer(source, newest_dependency):
                    newest_dependency = source
            else:
                new_sources.append(source)

        if not pyrex_sources:
            return new_sources

        module_name = extension.name

        for source in pyrex_sources:
            target = pyrex_targets[source]
            rebuild = self.force or newer(source, target)
            if not rebuild and newest_dependency is not None:
                rebuild = newer(newest_dependency, target)
            if rebuild:
                log.info("cythoning %s to %s", source, target)
                self.mkpath(os.path.dirname(target))
                options = CompilationOptions(pyrex_default_options, 
                    use_listing_file = create_listing,
                    include_path = includes,
                    output_file = target,
                    cplus = cplus,
                    generate_pxi = pyrex_gen_pxi)
                result = cython_compile(source, options=options,
                                        full_module_name=module_name)

        return new_sources
Example #12
0
def cython_action(target, source, env):
    from Cython.Compiler.Main import compile as cython_compile
    res = cython_compile(str(source[0]))
Example #13
0
def cython_action(target, source, env):
    from Cython.Compiler.Main import compile as cython_compile
    res = cython_compile(str(source[0]))
Example #14
0
cython_sources = [
    fr0st_package_name  + '/_utils.pyx'
]

c_sources = [os.path.splitext(x)[0] + '.c' for x in cython_sources]

if not os.path.exists(c_sources[0]):
    # Need to cythonize the source files
    try:
        from Cython.Compiler.Main import compile as cython_compile
    except ImportError:
        raise RuntimeError("Error: Source needs to be cythonized but Cython is not installed")

    #TODO: This doesn't honor any of the cython compile options. Meh?
    for source_file in cython_sources:
        cython_compile(source_file)

###########################################################################
#  And some InnoSetup stuff

class InnoScript:
    def __init__(self, name, lib_dir, dist_dir, windows_exe_files = [], lib_files = [], version = "1.0"):
        self.lib_dir = lib_dir
        self.dist_dir = dist_dir
        if not self.dist_dir[-1] in "\\/":
            self.dist_dir += "\\"
        self.name = name
        self.version = version
        self.windows_exe_files = [self.chop(p) for p in windows_exe_files]
        self.lib_files = [self.chop(p) for p in lib_files]
Example #15
0
    def cython_sources(self, sources, extension):
        """
        Walk the list of source files in 'sources', looking for Cython
        source files (.pyx and .py).  Run Cython on all that are
        found, and return a modified 'sources' list with Cython source
        files replaced by the generated C (or C++) files.
        """
        try:
            from Cython.Compiler.Main \
                import CompilationOptions, \
                       default_options as cython_default_options, \
                       compile as cython_compile
            from Cython.Compiler.Errors import PyrexError
        except ImportError:
            e = sys.exc_info()[1]
            print("failed to import Cython: %s" % e)
            raise DistutilsPlatformError("Cython does not appear to be installed")

        new_sources = []
        cython_sources = []
        cython_targets = {}

        # Setup create_list and cplus from the extension options if
        # Cython.Distutils.extension.Extension is used, otherwise just
        # use what was parsed from the command-line or the configuration file.
        # cplus will also be set to true is extension.language is equal to
        # 'C++' or 'c++'.
        #try:
        #    create_listing = self.cython_create_listing or \
        #                        extension.cython_create_listing
        #    cplus = self.cython_cplus or \
        #                extension.cython_cplus or \
        #                (extension.language != None and \
        #                    extension.language.lower() == 'c++')
        #except AttributeError:
        #    create_listing = self.cython_create_listing
        #    cplus = self.cython_cplus or \
        #                (extension.language != None and \
        #                    extension.language.lower() == 'c++')

        create_listing = self.cython_create_listing or \
            getattr(extension, 'cython_create_listing', 0)
        line_directives = self.cython_line_directives or \
            getattr(extension, 'cython_line_directives', 0)
        no_c_in_traceback = self.no_c_in_traceback or \
            getattr(extension, 'no_c_in_traceback', 0)
        cplus = self.cython_cplus or getattr(extension, 'cython_cplus', 0) or \
                (extension.language and extension.language.lower() == 'c++')
        cython_gen_pxi = self.cython_gen_pxi or getattr(extension, 'cython_gen_pxi', 0)
        cython_gdb = self.cython_gdb or getattr(extension, 'cython_gdb', False)
        cython_compile_time_env = self.cython_compile_time_env or \
            getattr(extension, 'cython_compile_time_env', None)

        # Set up the include_path for the Cython compiler:
        #    1.    Start with the command line option.
        #    2.    Add in any (unique) paths from the extension
        #        cython_include_dirs (if Cython.Distutils.extension is used).
        #    3.    Add in any (unique) paths from the extension include_dirs
        includes = self.cython_include_dirs
        try:
            for i in extension.cython_include_dirs:
                if not i in includes:
                    includes.append(i)
        except AttributeError:
            pass
        for i in extension.include_dirs:
            if not i in includes:
                includes.append(i)

        # Set up Cython compiler directives:
        #    1. Start with the command line option.
        #    2. Add in any (unique) entries from the extension
        #         cython_directives (if Cython.Distutils.extension is used).
        directives = self.cython_directives
        if hasattr(extension, "cython_directives"):
            directives.update(extension.cython_directives)

        # Set the target_ext to '.c'.  Cython will change this to '.cpp' if
        # needed.
        if cplus:
            target_ext = '.cpp'
        else:
            target_ext = '.c'

        # Decide whether to drop the generated C files into the temp dir
        # or the source tree.

        if not self.inplace and (self.cython_c_in_temp
                or getattr(extension, 'cython_c_in_temp', 0)):
            target_dir = os.path.join(self.build_temp, "pyrex")
            for package_name in extension.name.split('.')[:-1]:
                target_dir = os.path.join(target_dir, package_name)
        else:
            target_dir = None

        newest_dependency = None
        for source in sources:
            (base, ext) = os.path.splitext(os.path.basename(source))
            if ext == ".py":
                # FIXME: we might want to special case this some more
                ext = '.pyx'
            if ext == ".pyx":              # Cython source file
                output_dir = target_dir or os.path.dirname(source)
                new_sources.append(os.path.join(output_dir, base + target_ext))
                cython_sources.append(source)
                cython_targets[source] = new_sources[-1]
            elif ext == '.pxi' or ext == '.pxd':
                if newest_dependency is None \
                        or newer(source, newest_dependency):
                    newest_dependency = source
            else:
                new_sources.append(source)

        if not cython_sources:
            return new_sources

        module_name = extension.name

        for source in cython_sources:
            target = cython_targets[source]
            depends = [source] + list(extension.depends or ())
            rebuild = self.force or newer_group(depends, target, 'newer')
            if not rebuild and newest_dependency is not None:
                rebuild = newer(newest_dependency, target)
            if rebuild:
                log.info("cythoning %s to %s", source, target)
                self.mkpath(os.path.dirname(target))
                if self.inplace:
                    output_dir = os.curdir
                else:
                    output_dir = self.build_lib
                options = CompilationOptions(cython_default_options,
                    use_listing_file = create_listing,
                    include_path = includes,
                    compiler_directives = directives,
                    output_file = target,
                    cplus = cplus,
                    emit_linenums = line_directives,
                    c_line_in_traceback = not no_c_in_traceback,
                    generate_pxi = cython_gen_pxi,
                    output_dir = output_dir,
                    gdb_debug = cython_gdb,
                    compile_time_env = cython_compile_time_env)
                result = cython_compile(source, options=options,
                                        full_module_name=module_name)
            else:
                log.info("skipping '%s' Cython extension (up-to-date)", target)

        return new_sources
Example #16
0
    def cython_sources(self, sources, extension):
        """
        Walk the list of source files in 'sources', looking for Cython
        source files (.pyx and .py).  Run Cython on all that are
        found, and return a modified 'sources' list with Cython source
        files replaced by the generated C (or C++) files.
        """
        new_sources = []
        cython_sources = []
        cython_targets = {}

        # Setup create_list and cplus from the extension options if
        # Cython.Distutils.extension.Extension is used, otherwise just
        # use what was parsed from the command-line or the configuration file.
        # cplus will also be set to true is extension.language is equal to
        # 'C++' or 'c++'.
        #try:
        #    create_listing = self.cython_create_listing or \
        #                        extension.cython_create_listing
        #    cplus = self.cython_cplus or \
        #                extension.cython_cplus or \
        #                (extension.language != None and \
        #                    extension.language.lower() == 'c++')
        #except AttributeError:
        #    create_listing = self.cython_create_listing
        #    cplus = self.cython_cplus or \
        #                (extension.language != None and \
        #                    extension.language.lower() == 'c++')

        create_listing = self.cython_create_listing or \
            getattr(extension, 'cython_create_listing', 0)
        line_directives = self.cython_line_directives or \
            getattr(extension, 'cython_line_directives', 0)
        no_c_in_traceback = self.no_c_in_traceback or \
            getattr(extension, 'no_c_in_traceback', 0)
        cplus = self.cython_cplus or getattr(extension, 'cython_cplus', 0) or \
                (extension.language and extension.language.lower() == 'c++')
        cython_gen_pxi = self.cython_gen_pxi or getattr(
            extension, 'cython_gen_pxi', 0)
        cython_gdb = self.cython_gdb or getattr(extension, 'cython_gdb', False)
        cython_compile_time_env = self.cython_compile_time_env or \
            getattr(extension, 'cython_compile_time_env', None)

        # Set up the include_path for the Cython compiler:
        #    1.    Start with the command line option.
        #    2.    Add in any (unique) paths from the extension
        #        cython_include_dirs (if Cython.Distutils.extension is used).
        #    3.    Add in any (unique) paths from the extension include_dirs
        includes = list(self.cython_include_dirs)
        try:
            for i in extension.cython_include_dirs:
                if i not in includes:
                    includes.append(i)
        except AttributeError:
            pass

        # In case extension.include_dirs is a generator, evaluate it and keep
        # result
        extension.include_dirs = list(extension.include_dirs)
        for i in extension.include_dirs:
            if i not in includes:
                includes.append(i)

        # Set up Cython compiler directives:
        #    1. Start with the command line option.
        #    2. Add in any (unique) entries from the extension
        #         cython_directives (if Cython.Distutils.extension is used).
        directives = dict(self.cython_directives)
        if hasattr(extension, "cython_directives"):
            directives.update(extension.cython_directives)

        # Set the target file extension for C/C++ mode.
        if cplus:
            target_ext = '.cpp'
        else:
            target_ext = '.c'

        # Decide whether to drop the generated C files into the temp dir
        # or the source tree.

        if not self.inplace and (self.cython_c_in_temp
                                 or getattr(extension, 'cython_c_in_temp', 0)):
            target_dir = os.path.join(self.build_temp, "pyrex")
            for package_name in extension.name.split('.')[:-1]:
                target_dir = os.path.join(target_dir, package_name)
        else:
            target_dir = None

        newest_dependency = None
        for source in sources:
            (base, ext) = os.path.splitext(os.path.basename(source))
            if ext == ".py":
                # FIXME: we might want to special case this some more
                ext = '.pyx'
            if ext == ".pyx":  # Cython source file
                output_dir = target_dir or os.path.dirname(source)
                new_sources.append(os.path.join(output_dir, base + target_ext))
                cython_sources.append(source)
                cython_targets[source] = new_sources[-1]
            elif ext == '.pxi' or ext == '.pxd':
                if newest_dependency is None \
                        or newer(source, newest_dependency):
                    newest_dependency = source
            else:
                new_sources.append(source)

        if not cython_sources:
            return new_sources

        try:
            from Cython.Compiler.Main \
                import CompilationOptions, \
                       default_options as cython_default_options, \
                       compile as cython_compile
            from Cython.Compiler.Errors import PyrexError
        except ImportError:
            e = sys.exc_info()[1]
            print("failed to import Cython: %s" % e)
            raise DistutilsPlatformError(
                "Cython does not appear to be installed")

        module_name = extension.name

        for source in cython_sources:
            target = cython_targets[source]
            depends = [source] + list(extension.depends or ())
            if (source[-4:].lower() == ".pyx"
                    and os.path.isfile(source[:-3] + "pxd")):
                depends += [source[:-3] + "pxd"]
            rebuild = self.force or newer_group(depends, target, 'newer')
            if not rebuild and newest_dependency is not None:
                rebuild = newer(newest_dependency, target)
            if rebuild:
                log.info("cythoning %s to %s", source, target)
                self.mkpath(os.path.dirname(target))
                if self.inplace:
                    output_dir = os.curdir
                else:
                    output_dir = self.build_lib
                options = CompilationOptions(
                    cython_default_options,
                    use_listing_file=create_listing,
                    include_path=includes,
                    compiler_directives=directives,
                    output_file=target,
                    cplus=cplus,
                    emit_linenums=line_directives,
                    c_line_in_traceback=not no_c_in_traceback,
                    generate_pxi=cython_gen_pxi,
                    output_dir=output_dir,
                    gdb_debug=cython_gdb,
                    compile_time_env=cython_compile_time_env)
                result = cython_compile(source,
                                        options=options,
                                        full_module_name=module_name)
            else:
                log.info("skipping '%s' Cython extension (up-to-date)", target)

        return new_sources
Example #17
0
def from_source(source,
                name=None,
                output_dir=None,
                check=False,
                keep=False,
                debug=False,
                ):
    out_file = (output_dir / name).add_ext(sysconfig.get_config_var('SO'))

    protocol = protocol_from_source(source, output_dir)
    if debug:
        protocol.set_property(('debug',), debug)

    temp_dir = Path.from_file(tempfile.gettempdir()) / name
    if not temp_dir.exists():
        temp_dir.makedirs()

    protocol_data = protocol.data()

    source_chks = hashlib.sha1(source.encode('utf-8')).hexdigest()
    protoc_chks = hashlib.sha1(protocol_data.encode('utf-8')).hexdigest()
    if out_file.exists():
        if check:
            checkfile_name = (output_dir / name).add_ext('.checksum')
            if checkfile_name.exists():
                with checkfile_name.open('rt') as stream:
                    source_ctrl = stream.readline().strip()
                    output_ctrl = stream.readline().strip()
                    protoc_ctrl = stream.readline().strip()
                with out_file.open('rb') as stream:
                    output_data = stream.read()
                    output_chks = hashlib.sha1(output_data).hexdigest()
                if (source_chks == source_ctrl
                and output_chks == output_ctrl
                and protoc_chks == protoc_ctrl):
                    return False
        out_file.remove()

    if name is None:
        name = protocol.properties.get('package')
    if name is None:
        raise NameNotDefined()

    path = temp_dir / name
    pyx_file = path.add_ext('.pyx')
    with pyx_file.open('w') as stream:
        stream.write(protocol_data)

    options = CompilationOptions(
        verbose=True,
        )
    cython_compile(pyx_file.str(), options=options)

    compiler = distutils.ccompiler.new_compiler(verbose=1)
    sysconfig.customize_compiler(compiler)

    if sys.platform == 'win32':
        protocyt_dir = Path.from_file(__file__).up()
        compiler.add_include_dir(str(protocyt_dir / 'includes'))
        libs_dir = Path.from_file(sysconfig.get_config_var('BINDIR')) / 'libs'
        compiler.add_library_dir(libs_dir.str())

    compiler.add_include_dir(sysconfig.get_python_inc())

    object_files = compiler.compile([path.add_ext('.c').str()],
        extra_postargs=['-fPIC'],
        output_dir=temp_dir.str())
    compiler.link_shared_lib(object_files, name, output_dir=temp_dir.str())

    compiler.move_file(
        compiler.library_filename(path.str(), 'shared'),
        out_file.str()
        )

    if not keep:
        temp_dir.remove()
        result = True
    else:
        result = temp_dir
    
    if check:
        checkfile_name = (output_dir / name).add_ext('.checksum')
        with out_file.open('rb') as stream:
            output_chks = hashlib.sha1(stream.read()).hexdigest()
        with checkfile_name.open('wt') as stream:
            stream.write('{0}\n{1}\n{2}\n'.format(
                source_chks, output_chks, protoc_chks))

    return result