xref: /petsc/src/binding/petsc4py/conf/cythonize.py (revision 030f984af8d8bb4c203755d35bded3c05b3d83ce)
1#!/usr/bin/env python
2import sys, os
3
4def cythonize(source,
5              output=None,
6              includes=(),
7              destdir_c=None,
8              destdir_h=None,
9              wdir=None):
10    from Cython.Compiler.Main import \
11         CompilationOptions, default_options, \
12         compile, \
13         PyrexError
14    from Cython.Compiler import Options
15    cwd = os.getcwd()
16    try:
17        if output is None:
18            name, _ = os.path.splitext(source)
19            output = name + '.c'
20        else:
21            name, _ = os.path.splitext(output)
22        outputs_c = [output]
23        outputs_h = [name + '.h', name + '_api.h']
24        # change working directory
25        if wdir:
26            os.chdir(wdir)
27        # run Cython on source
28        options = CompilationOptions(default_options)
29        if Options.directive_types['language_level'] is str:
30            options.language_level = '3str'
31        options.output_file = outputs_c[0]
32        options.include_path = list(includes)
33        Options.generate_cleanup_code = 3
34        any_failures = 0
35        try:
36            result = compile(source, options)
37            if result.num_errors > 0:
38                any_failures = 1
39        except (EnvironmentError, PyrexError):
40            e = sys.exc_info()[1]
41            sys.stderr.write(str(e) + '\n')
42            any_failures = 1
43        if any_failures:
44            for output in outputs_c + outputs_h:
45                try:
46                    os.remove(output)
47                except OSError:
48                    pass
49            return 1
50        # move ouputs
51        for destdir, outputs in (
52            (destdir_c, outputs_c),
53            (destdir_h, outputs_h)):
54            if destdir is None: continue
55            for output in outputs:
56                dest = os.path.join(
57                    destdir, os.path.basename(output))
58                try:
59                    os.remove(dest)
60                except OSError:
61                    pass
62                os.rename(output, dest)
63        #
64        return 0
65    #
66    finally:
67        os.chdir(cwd)
68
69
70if __name__ == "__main__":
71    sys.exit(
72        cythonize('petsc4py.PETSc.pyx',
73                  'petsc4py.PETSc.c',
74                  includes=['include'],
75                  destdir_h=os.path.join('include', 'petsc4py'),
76                  wdir='src')
77        or
78        cythonize(os.path.join('libpetsc4py', 'libpetsc4py.pyx'),
79                  includes=['include'],
80                  wdir='src')
81        )
82