Example #1
0
def compile_module(space, modname, **kwds):
    """
    Build an extension module and return the filename of the resulting native
    code file.

    modname is the name of the module, possibly including dots if it is a module
    inside a package.

    Any extra keyword arguments are passed on to ExternalCompilationInfo to
    build the module (so specify your source with one of those).
    """
    modname = modname.split('.')[-1]
    eci = ExternalCompilationInfo(
        export_symbols=['init%s' % (modname,)],
        include_dirs=api.include_dirs,
        **kwds
        )
    eci = eci.convert_sources_to_files()
    dirname = (udir/uniquemodulename('module')).ensure(dir=1)
    soname = platform.platform.compile(
        [], eci,
        outputfilename=str(dirname/modname),
        standalone=False)
    from pypy.module.imp.importing import get_so_extension
    pydname = soname.new(purebasename=modname, ext=get_so_extension(space))
    soname.rename(pydname)
    return str(pydname)
Example #2
0
def test_gcc_ask():
    f = localudir.join("y.c")
    f.write("""
    #include <stdio.h>
    #include <test_gcc_ask.h>
    int main()
    {
       printf("hello\\n");
       return 0;
    }
    """)
    dir1 = localudir.join('test_gcc_ask_dir1').ensure(dir=1)
    dir2 = localudir.join('test_gcc_ask_dir2').ensure(dir=1)
    dir1.join('test_gcc_ask.h').write('/* hello world */\n')
    dir2.join('test_gcc_ask.h').write('#error boom\n')
    eci = ExternalCompilationInfo(include_dirs=[str(dir1)])
    # remove cache
    path = cache_file_path([f], eci, 'try_compile_cache')
    if path.check():
        path.remove()
    assert try_compile_cache([f], eci)
    assert try_compile_cache([f], eci)
    assert build_executable_cache([f], eci) == "hello\n"
    eci2 = ExternalCompilationInfo(include_dirs=[str(dir2)])
    err = py.test.raises(CompilationError, try_compile_cache, [f], eci2)
    print '<<<'
    print err
    print '>>>'
Example #3
0
def test_gcc_exec():
    f = localudir.join("x.c")
    f.write("""
    #include <stdio.h>
    #include <test_gcc_exec.h>
    int main()
    {
       printf("%d\\n", ANSWER);
       return 0;
    }
    """)
    dir1 = localudir.join('test_gcc_exec_dir1').ensure(dir=1)
    dir2 = localudir.join('test_gcc_exec_dir2').ensure(dir=1)
    dir1.join('test_gcc_exec.h').write('#define ANSWER 3\n')
    dir2.join('test_gcc_exec.h').write('#define ANSWER 42\n')
    eci = ExternalCompilationInfo(include_dirs=[str(dir1)])
    # remove cache
    path = cache_file_path([f], eci, 'build_executable_cache')
    if path.check():
        path.remove()
    res = build_executable_cache([f], eci)
    assert res == "3\n"
    assert build_executable_cache([f], eci) == "3\n"
    eci2 = ExternalCompilationInfo(include_dirs=[str(dir2)])
    assert build_executable_cache([f], eci2) == "42\n"
    f.write("#error BOOM\n")
    err = py.test.raises(CompilationError, build_executable_cache, [f], eci2)
    print '<<<'
    print err
    print '>>>'
Example #4
0
def compile_module(space, modname, **kwds):
    """
    Build an extension module and return the filename of the resulting native
    code file.

    modname is the name of the module, possibly including dots if it is a module
    inside a package.

    Any extra keyword arguments are passed on to ExternalCompilationInfo to
    build the module (so specify your source with one of those).
    """
    modname = modname.split('.')[-1]
    eci = ExternalCompilationInfo(export_symbols=['init%s' % (modname, )],
                                  include_dirs=api.include_dirs,
                                  **kwds)
    eci = eci.convert_sources_to_files()
    dirname = (udir / uniquemodulename('module')).ensure(dir=1)
    soname = platform.platform.compile([],
                                       eci,
                                       outputfilename=str(dirname / modname),
                                       standalone=False)
    from pypy.module.imp.importing import get_so_extension
    pydname = soname.new(purebasename=modname, ext=get_so_extension(space))
    soname.rename(pydname)
    return str(pydname)
Example #5
0
def llexternal_use_eci(compilation_info):
    """Return a dummy function that, if called in a RPython program,
    adds the given ExternalCompilationInfo to it."""
    eci = ExternalCompilationInfo(post_include_bits=['#define PYPY_NO_OP()'])
    eci = eci.merge(compilation_info)
    return llexternal('PYPY_NO_OP', [], lltype.Void,
                      compilation_info=eci, sandboxsafe=True, _nowrapper=True,
                      _callable=lambda: None)
Example #6
0
    def compilation_info(self):
        if not self.db:
            return ExternalCompilationInfo()

        gct = self.db.gctransformer
        return ExternalCompilationInfo(pre_include_bits=[
            '/* using %s */' % (gct.__class__.__name__, ),
            '#define MALLOC_ZERO_FILLED %d' % (gct.malloc_zero_filled, ),
        ])
Example #7
0
 def get_eci(self):
     from distutils import sysconfig
     python_inc = sysconfig.get_python_inc()
     eci = ExternalCompilationInfo(
         include_dirs=[python_inc],
         includes=["Python.h",
                   ],
         )
     return eci.merge(CBuilder.get_eci(self))
Example #8
0
 def __init__(self, translator, entrypoint, config, gcpolicy=None):
     self.translator = translator
     self.entrypoint = entrypoint
     self.entrypoint_name = self.entrypoint.func_name
     self.originalentrypoint = entrypoint
     self.config = config
     self.gcpolicy = gcpolicy    # for tests only, e.g. rpython/memory/
     if gcpolicy is not None and gcpolicy.requires_stackless:
         config.translation.stackless = True
     self.eci = ExternalCompilationInfo()
Example #9
0
 def get_eci(self):
     from distutils import sysconfig
     python_inc = sysconfig.get_python_inc()
     eci = ExternalCompilationInfo(
         include_dirs=[python_inc],
         includes=[
             "Python.h",
         ],
     )
     return eci.merge(CBuilder.get_eci(self))
Example #10
0
    def __init__(self, translator, standalone):

        # reset counters
        Node.nodename_count = {}
        self.eci = ExternalCompilationInfo()

        self.standalone = standalone
        self.translator = translator

        self.config = translator.config
Example #11
0
 def test_merge2(self):
     e1 = ExternalCompilationInfo(pre_include_bits=['1'],
                                  link_files=['1.c'])
     e2 = ExternalCompilationInfo(pre_include_bits=['2'],
                                  link_files=['1.c', '2.c'])
     e3 = ExternalCompilationInfo(pre_include_bits=['3'],
                                  link_files=['1.c', '2.c', '3.c'])
     e = e1.merge(e2)
     e = e.merge(e3, e3)
     assert e.pre_include_bits == ('1', '2', '3')
     assert e.link_files == ('1.c', '2.c', '3.c')
Example #12
0
 def test_convert_sources_to_c_files(self):
     eci = ExternalCompilationInfo(
         separate_module_sources = ['xxx'],
         separate_module_files = ['x.c'],
     )
     cache_dir = udir.join('test_convert_sources').ensure(dir=1)
     neweci = eci.convert_sources_to_files(cache_dir)
     assert not neweci.separate_module_sources
     res = neweci.separate_module_files
     assert len(res) == 2
     assert res[0] == 'x.c'
     assert str(res[1]).startswith(str(cache_dir))
     e = ExternalCompilationInfo()
     assert e.convert_sources_to_files() is e
Example #13
0
class ComplexCConfig:
    """
    Definitions of structure types defined by zlib and based on SimpleCConfig
    definitions.
    """
    _compilation_info_ = ExternalCompilationInfo(
        includes = includes
    )

    z_stream = rffi_platform.Struct(
        'z_stream',
        [('next_in', Bytefp),
         ('avail_in', uInt),
         ('total_in', uLong),

         ('next_out', Bytefp),
         ('avail_out', uInt),
         ('total_out', uLong),

         ('msg', rffi.CCHARP),

         ('zalloc', lltype.Ptr(
                    lltype.FuncType([voidpf, uInt, uInt], voidpf))),
         ('zfree', lltype.Ptr(
                    lltype.FuncType([voidpf, voidpf], lltype.Void))),

         ('opaque', voidpf),

         ('data_type', rffi.INT),
         ('adler', uLong),
         ('reserved', uLong)
         ])
Example #14
0
    def __init__(self):
        self.configure(CConfig)

        # we need an indirection via c functions to get macro calls working on llvm
        if hasattr(os, 'WCOREDUMP'):
            decl_snippet = """
            %(ret_type)s pypy_macro_wrapper_%(name)s (int status);
            """
            def_snippet = """
            %(ret_type)s pypy_macro_wrapper_%(name)s (int status) {
            return %(name)s(status);
            }
            """
            decls = []
            defs = []
            for name in self.w_star:
                data = {'ret_type': 'int', 'name': name}
                decls.append(decl_snippet % data)
                defs.append(def_snippet % data)
            h_source = decls + defs

            self.compilation_info = self.compilation_info.merge(
                ExternalCompilationInfo(
                post_include_lines = decls,
                separate_module_sources = ["\n".join(h_source)]
            ))
Example #15
0
class CConfig:
    """
    Definitions for platform integration.

    Note: this must be processed through platform.configure() to provide
    usable objects.  For example::

        CLOCK_T = platform.configure(CConfig)['CLOCK_T']
        register(function, [CLOCK_T], ...)

    """

    _compilation_info_ = ExternalCompilationInfo(
        includes=includes
    )
    if not sys.platform.startswith('win'):
        CLOCK_T = platform.SimpleType('clock_t', rffi.INT)

        TMS = platform.Struct(
            'struct tms', [('tms_utime', rffi.INT),
                           ('tms_stime', rffi.INT),
                           ('tms_cutime', rffi.INT),
                           ('tms_cstime', rffi.INT)])

    SEEK_SET = platform.DefinedConstantInteger('SEEK_SET')
    SEEK_CUR = platform.DefinedConstantInteger('SEEK_CUR')
    SEEK_END = platform.DefinedConstantInteger('SEEK_END')

    UTIMBUF     = platform.Struct('struct '+underscore_on_windows+'utimbuf',
                                  [('actime', rffi.INT),
                                   ('modtime', rffi.INT)])
Example #16
0
 def test_from_linker_flags(self):
     flags = ('-L/some/lib/path -L/other/lib/path '
              '-lmylib1 -lmylib2 -?1 -!2')
     eci = ExternalCompilationInfo.from_linker_flags(flags)
     assert eci.libraries == ('mylib1', 'mylib2')
     assert eci.library_dirs == ('/some/lib/path', '/other/lib/path')
     assert eci.link_extra == ('-?1', '-!2')
Example #17
0
def configure_boehm(platform=None):
    if platform is None:
        from pypy.translator.platform import platform
    if sys.platform == 'win32':
        import platform as host_platform # just to ask for the arch. Confusion-alert!
        if host_platform.architecture()[0] == '32bit':
            library_dir = 'Release'
            libraries = ['gc']
            includes=['gc.h']
        else:
            library_dir = ''
            libraries = ['gc64_dll']
            includes = ['gc.h']
    else:
        library_dir = ''
        libraries = ['gc', 'dl']
        includes=['gc/gc.h']
    eci = ExternalCompilationInfo(
        platform=platform,
        includes=includes,
        libraries=libraries,
        )
    return configure_external_library(
        'gc', eci,
        [dict(prefix='gc-', include_dir='include', library_dir=library_dir)],
        symbol='GC_init')
Example #18
0
 def test_merge(self):
     e1 = ExternalCompilationInfo(pre_include_bits=['1'],
                                  includes=['x.h'],
                                  post_include_bits=['p1'])
     e2 = ExternalCompilationInfo(
         pre_include_bits=['2'],
         includes=['x.h', 'y.h'],
         post_include_bits=['p2'],
     )
     e3 = ExternalCompilationInfo(pre_include_bits=['3'],
                                  includes=['y.h', 'z.h'],
                                  post_include_bits=['p1', 'p3'])
     e = e1.merge(e2, e3)
     assert e.pre_include_bits == ('1', '2', '3')
     assert e.includes == ('x.h', 'y.h', 'z.h')
     assert e.post_include_bits == ('p1', 'p2', 'p3')
Example #19
0
def add_extra_files(eci):
    srcdir = py.path.local(autopath.pypydir).join('translator', 'c', 'src')
    files = [
        srcdir / 'profiling.c',
        srcdir / 'debug_print.c',
    ]
    return eci.merge(ExternalCompilationInfo(separate_module_files=files))
Example #20
0
def eci_from_header(c_header_source, include_dirs=None):
    if include_dirs is None:
        include_dirs = []
    return ExternalCompilationInfo(
        post_include_bits=[c_header_source],
        include_dirs=include_dirs
    )
Example #21
0
    def build_main_for_shared(self, shared_library_name, entrypoint, exe_name):
        import time
        time.sleep(1)
        self.shared_library_name = shared_library_name
        # build main program
        eci = self.get_eci()
        kw = {}
        if self.translator.platform.cc == 'gcc':
            kw['libraries'] = [self.shared_library_name.purebasename[3:]]
            kw['library_dirs'] = [self.targetdir]
        else:
            kw['libraries'] = [self.shared_library_name.new(ext='')]
        eci = eci.merge(ExternalCompilationInfo(
            separate_module_sources=['''
                int %s(int argc, char* argv[]);

                int main(int argc, char* argv[])
                { return %s(argc, argv); }
                ''' % (entrypoint, entrypoint)
                ],
            **kw
            ))
        eci = eci.convert_sources_to_files(
            cache_dir=self.targetdir)
        return self.translator.platform.compile(
            [], eci,
            outputfilename=exe_name)
Example #22
0
    def test_pass_around_t_object(self):
        from pypy.rpython.annlowlevel import base_ptr_lltype
        T = base_ptr_lltype()

        class X(object):
            _TYPE = T
            x = 10

        def callback(x):
            return x.x

        c_source = py.code.Source("""
        long eating_callback(void *arg, long(*call)(void*))
        {
            return call(arg);
        }
        """)

        eci = ExternalCompilationInfo(separate_module_sources=[c_source],
                                      export_symbols=['eating_callback'])

        args = [T, rffi.CCallback([T], rffi.LONG)]
        eating_callback = rffi.llexternal('eating_callback',
                                          args,
                                          rffi.LONG,
                                          compilation_info=eci)

        res = eating_callback(X(), callback)
        assert res == 10
Example #23
0
 def test_frexp(self):
     if sys.platform != 'win32':
         eci = ExternalCompilationInfo(includes=['math.h'], libraries=['m'])
     else:
         eci = ExternalCompilationInfo(includes=['math.h'])
     A = lltype.FixedSizeArray(rffi.INT, 1)
     frexp = rffi.llexternal('frexp',
                             [rffi.DOUBLE, lltype.Ptr(A)],
                             rffi.DOUBLE,
                             compilation_info=eci)
     p = lltype.malloc(A, flavor='raw')
     res = frexp(2.5, p)
     assert res == 0.625
     assert p[0] == 2
     lltype.free(p, flavor='raw')
     assert not ALLOCATED  # detects memory leaks in the test
Example #24
0
    def define_callback_simple(cls):
        c_source = py.code.Source("""
        int mystuff(int(*cb)(int, int))
        {
            return cb(40, 2) + cb(3, 4);
        }
        """)
        eci = ExternalCompilationInfo(separate_module_sources=[c_source])
        S = lltype.GcStruct('S', ('x', lltype.Signed))
        CALLBACK = lltype.FuncType([lltype.Signed, lltype.Signed],
                                   lltype.Signed)
        z = rffi.llexternal('mystuff', [lltype.Ptr(CALLBACK)],
                            lltype.Signed,
                            compilation_info=eci)

        def mycallback(a, b):
            gc.collect()
            return a + b

        def f():
            p = lltype.malloc(S)
            p.x = 100
            result = z(mycallback)
            return result * p.x

        return f
Example #25
0
    def cmds_objects(self, base, standalone):
        use_gcc = self.genllvm.config.translation.llvm_via_c
        if use_gcc:
            self.cmds.append("llc %s.bc -march=c -f -o %s.c" % (base, base))
            self.cmds.append("gcc %s.c -c -O3 -fomit-frame-pointer" % base)
        else:
            model = ''
            if not standalone:
                model = ' -relocation-model=pic'

            self.cmds.append("llc %s %s.bc -f -o %s.s" % (model, base, base))
            self.cmds.append("as %s.s -o %s.o" % (base, base))

        include_opts = get_incdirs(self.genllvm.eci)

        # compile separate files
        # XXX rxe: why do we want to run a c compiler, when we run llvm
        # compiler - these seems a step backwards IMHO ?????
        libraries = set()
        for filename in self.genllvm.eci.separate_module_files:
            assert filename.endswith(".c")
            objname = filename[:-2] + ".o"
            libraries.add(objname)
            self.cmds.append("gcc %s -c %s -O3 -o %s" %
                             (filename, include_opts, objname))

        attrs = self.genllvm.eci._copy_attributes()
        attrs['libraries'] = tuple(libraries) + attrs['libraries']
        self.genllvm.eci = ExternalCompilationInfo(**attrs)
Example #26
0
 def build_winerror_to_errno():
     """Build a dictionary mapping windows error numbers to POSIX errno.
     The function returns the dict, and the default value for codes not
     in the dict."""
     # Prior to Visual Studio 8, the MSVCRT dll doesn't export the
     # _dosmaperr() function, which is available only when compiled
     # against the static CRT library.
     from pypy.translator.platform import platform, Windows
     static_platform = Windows()
     if static_platform.name == 'msvc':
         static_platform.cflags = ['/MT']  # static CRT
         static_platform.version = 0       # no manifest
     cfile = udir.join('dosmaperr.c')
     cfile.write(r'''
             #include <errno.h>
             int main()
             {
                 int i;
                 for(i=1; i < 65000; i++) {
                     _dosmaperr(i);
                     if (errno == EINVAL)
                         continue;
                     printf("%d\t%d\n", i, errno);
                 }
                 return 0;
             }''')
     exename = static_platform.compile(
         [cfile], ExternalCompilationInfo(),
         outputfilename = "dosmaperr",
         standalone=True)
     output = os.popen(str(exename))
     errors = dict(map(int, line.split())
                   for line in output)
     return errors, errno.EINVAL
Example #27
0
File: eci.py Project: enyst/plexnet
def get_rsdl_compilation_info():
    if sys.platform == 'darwin':
        eci = ExternalCompilationInfo(
            includes = ['SDL.h'],
            include_dirs = ['/Library/Frameworks/SDL.framework/Headers'],
            link_files = [
                str(py.magic.autopath().dirpath().join('macosx-sdl-main/SDLMain.m')),
            ],
            frameworks = ['SDL', 'Cocoa']
        )
    else:
        eci = ExternalCompilationInfo(
            includes=['SDL.h'],
            )
        eci = eci.merge(ExternalCompilationInfo.from_config_tool('sdl-config'))
    return eci
Example #28
0
    def test_string_reverse(self):
        c_source = py.code.Source("""
        #include <string.h>
        #include <Python.h>
        #include <src/mem.h>

        char *f(char* arg)
        {
            char *ret;
            /* lltype.free uses OP_RAW_FREE, we must allocate
             * with the matching function
             */
            OP_RAW_MALLOC(strlen(arg) + 1, ret, char*)
            strcpy(ret, arg);
            return ret;
        }
        """)
        eci = ExternalCompilationInfo(separate_module_sources=[c_source],
                                      post_include_bits=['char *f(char*);'])
        z = llexternal('f', [CCHARP], CCHARP, compilation_info=eci)

        def f():
            s = str2charp("xxx")
            l_res = z(s)
            res = charp2str(l_res)
            lltype.free(l_res, flavor='raw')
            free_charp(s)
            return len(res)

        xf = self.compile(f, [], backendopt=False)
        assert xf(expected_extra_mallocs=-1) == 3
Example #29
0
    def define_callback_simple(cls):
        import gc
        from pypy.rpython.lltypesystem import lltype, rffi
        from pypy.rpython.annlowlevel import llhelper
        from pypy.translator.tool.cbuild import ExternalCompilationInfo

        c_source = py.code.Source("""
        int mystuff(int(*cb)(int, int))
        {
            return cb(40, 2) + cb(3, 4);
        }
        """)
        eci = ExternalCompilationInfo(separate_module_sources=[c_source])
        S = lltype.GcStruct('S', ('x', lltype.Signed))
        CALLBACK = lltype.FuncType([lltype.Signed, lltype.Signed],
                                   lltype.Signed)
        z = rffi.llexternal('mystuff', [lltype.Ptr(CALLBACK)], lltype.Signed,
                            compilation_info=eci)

        def mycallback(a, b):
            gc.collect()
            return a + b

        def f():
            p = lltype.malloc(S)
            p.x = 100
            result = z(mycallback)
            return result * p.x

        return f
Example #30
0
    def test_prebuilt_constant(self):
        py.test.skip("Think how to do it sane")
        h_source = py.code.Source("""
        int x = 3;
        char** z = NULL;
        #endif
        """)
        h_include = udir.join('constants.h')
        h_include.write(h_source)

        eci = ExternalCompilationInfo(
            includes=['stdio.h', str(h_include.basename)],
            include_dirs=[str(udir)])

        get_x, set_x = CExternVariable(lltype.Signed, 'x', eci)
        get_z, set_z = CExternVariable(CCHARPP, 'z', eci)

        def f():
            one = get_x()
            set_x(13)
            return one + get_x()

        def g():
            l = liststr2charpp(["a", "b", "c"])
            try:
                set_z(l)
                return charp2str(get_z()[2])
            finally:
                free_charpp(l)

        fn = self.compile(f, [])
        assert fn() == 16
        gn = self.compile(g, [])
        assert gn() == "c"
Example #31
0
    def eating_callback(self):
        h_source = py.code.Source("""
        #ifndef _CALLBACK_H
        #define _CALLBACK_H
        extern long eating_callback(long arg, long(*call)(long));
        #endif /* _CALLBACK_H */
        """)

        h_include = udir.join('callback.h')
        h_include.write(h_source)

        c_source = py.code.Source("""
        long eating_callback(long arg, long(*call)(long))
        {
            long res = call(arg);
            if (res == -1)
              return -1;
            return res;
        }
        """)

        eci = ExternalCompilationInfo(includes=['callback.h'],
                                      include_dirs=[str(udir)],
                                      separate_module_sources=[c_source],
                                      export_symbols=['eating_callback'])

        args = [LONG, CCallback([LONG], LONG)]
        eating_callback = llexternal('eating_callback',
                                     args,
                                     LONG,
                                     compilation_info=eci)

        return eating_callback
Example #32
0
def generate_macro_wrapper(name, macro, functype, eci):
    """Wraps a function-like macro inside a real function, and expose
    it with llexternal."""

    # Generate the function call
    from pypy.translator.c.database import LowLevelDatabase
    from pypy.translator.c.support import cdecl
    wrapper_name = 'pypy_macro_wrapper_%s' % (name,)
    argnames = ['arg%d' % (i,) for i in range(len(functype.ARGS))]
    db = LowLevelDatabase()
    implementationtypename = db.gettype(functype, argnames=argnames)
    if functype.RESULT is lltype.Void:
        pattern = '%s { %s(%s); }'
    else:
        pattern = '%s { return %s(%s); }'
    source = pattern % (
        cdecl(implementationtypename, wrapper_name),
        macro, ', '.join(argnames))

    # Now stuff this source into a "companion" eci that will be used
    # by ll2ctypes.  We replace eci._with_ctypes, so that only one
    # shared library is actually compiled (when ll2ctypes calls the
    # first function)
    ctypes_eci = eci.merge(ExternalCompilationInfo(
            separate_module_sources=[source],
            export_symbols=[wrapper_name],
            ))
    if hasattr(eci, '_with_ctypes'):
        ctypes_eci = eci._with_ctypes.merge(ctypes_eci)
    eci._with_ctypes = ctypes_eci
    func = llexternal(wrapper_name, functype.ARGS, functype.RESULT,
                      compilation_info=eci, _nowrapper=True)
    # _nowrapper=True returns a pointer which is not hashable
    return lambda *args: func(*args)
Example #33
0
    def return_char(self, signed):
        ctype_pref = ["un", ""][signed]
        rffi_type = [UCHAR, SIGNEDCHAR][signed]
        h_source = py.code.Source("""
        %ssigned char returnchar(void)
        {
            return 42;
        }
        """ % (ctype_pref, ))
        h_file = udir.join("opaque2%s.h" % (ctype_pref, ))
        h_file.write(h_source)

        from pypy.rpython.tool import rffi_platform
        eci = ExternalCompilationInfo(includes=[h_file.basename],
                                      include_dirs=[str(udir)])
        ll_returnchar = llexternal('returnchar', [],
                                   rffi_type,
                                   compilation_info=eci)

        def f():
            result = ll_returnchar()
            return result

        f1 = self.compile(f, [])
        assert f1() == chr(42)
Example #34
0
    def test_stringstar(self):
        c_source = """
        #include <string.h>
        
        int f(char *args[]) {
            char **p = args;
            int l = 0;
            while (*p) {
                l += strlen(*p);
                p++;
            }
            return (l);
        }
        """
        eci = ExternalCompilationInfo(separate_module_sources=[c_source])
        z = llexternal('f', [CCHARPP], Signed, compilation_info=eci)

        def f():
            l = ["xxx", "x", "xxxx"]
            ss = liststr2charpp(l)
            result = z(ss)
            free_charpp(ss)
            return result

        xf = self.compile(f, [], backendopt=False)
        assert xf() == 8
Example #35
0
 def test_make_shared_lib(self):
     eci = ExternalCompilationInfo(
         separate_module_sources = ['''
         int get()
         {
             return 42;
         }''']
     )
     neweci = eci.compile_shared_lib()
     assert len(neweci.libraries) == 1
     try:
         import ctypes
     except ImportError:
         py.test.skip("Need ctypes for that test")
     assert ctypes.CDLL(neweci.libraries[0]).get() == 42
     assert not neweci.separate_module_sources
     assert not neweci.separate_module_files
Example #36
0
 def test_merge2(self):
     e1 = ExternalCompilationInfo(
         pre_include_bits  = ['1'],
         link_files = ['1.c']
     )
     e2 = ExternalCompilationInfo(
         pre_include_bits  = ['2'],
         link_files = ['1.c', '2.c']
     )
     e3 = ExternalCompilationInfo(
         pre_include_bits  = ['3'],
         link_files = ['1.c', '2.c', '3.c']
     )
     e = e1.merge(e2)
     e = e.merge(e3, e3)
     assert e.pre_include_bits == ('1', '2', '3')
     assert e.link_files == ('1.c', '2.c', '3.c')
Example #37
0
 def test_from_linker_flags(self):
     flags = ('-L/some/lib/path -L/other/lib/path '
              '-lmylib1 -lmylib2 -?1 -!2')
     eci = ExternalCompilationInfo.from_linker_flags(flags)
     assert eci.libraries == ('mylib1', 'mylib2')
     assert eci.library_dirs == ('/some/lib/path',
                                 '/other/lib/path')
     assert eci.link_extra == ('-?1', '-!2')
Example #38
0
    def test_platforms(self):
        from pypy.translator.platform import Platform

        class Maemo(Platform):
            def __init__(self, cc=None):
                self.cc = cc
        
        eci = ExternalCompilationInfo(platform=Maemo())
        eci2 = ExternalCompilationInfo()
        assert eci != eci2
        assert hash(eci) != hash(eci2)
        assert repr(eci) != repr(eci2)
        py.test.raises(Exception, eci2.merge, eci)
        assert eci.merge(eci).platform == Maemo()
        assert (ExternalCompilationInfo(platform=Maemo(cc='xxx')) !=
                ExternalCompilationInfo(platform=Maemo(cc='yyy')))
        assert (repr(ExternalCompilationInfo(platform=Maemo(cc='xxx'))) !=
                repr(ExternalCompilationInfo(platform=Maemo(cc='yyy'))))
Example #39
0
 def test_from_compiler_flags(self):
     flags = ('-I/some/include/path -I/other/include/path '
              '-DMACRO1 -D_MACRO2=baz -?1 -!2')
     eci = ExternalCompilationInfo.from_compiler_flags(flags)
     assert eci.pre_include_bits == ('#define MACRO1 1',
                                     '#define _MACRO2 baz')
     assert eci.includes == ()
     assert eci.include_dirs == ('/some/include/path',
                                 '/other/include/path')
     assert eci.compile_extra == ('-?1', '-!2')
Example #40
0
 def test_merge(self):
     e1 = ExternalCompilationInfo(
         pre_include_bits   = ['1'],
         includes           = ['x.h'],
         post_include_bits  = ['p1']
     )
     e2 = ExternalCompilationInfo(
         pre_include_bits   = ['2'],
         includes           = ['x.h', 'y.h'],
         post_include_bits  = ['p2'],
     )
     e3 = ExternalCompilationInfo(
         pre_include_bits   = ['3'],
         includes           = ['y.h', 'z.h'],
         post_include_bits  = ['p1', 'p3']
     )
     e = e1.merge(e2, e3)
     assert e.pre_include_bits == ('1', '2', '3')
     assert e.includes == ('x.h', 'y.h', 'z.h')
     assert e.post_include_bits == ('p1', 'p2', 'p3')
Example #41
0
class CBuilder(object):
    c_source_filename = None
    _compiled = False
    modulename = None
    
    def __init__(self, translator, entrypoint, config, gcpolicy=None):
        self.translator = translator
        self.entrypoint = entrypoint
        self.entrypoint_name = self.entrypoint.func_name
        self.originalentrypoint = entrypoint
        self.config = config
        self.gcpolicy = gcpolicy    # for tests only, e.g. rpython/memory/
        if gcpolicy is not None and gcpolicy.requires_stackless:
            config.translation.stackless = True
        self.eci = ExternalCompilationInfo()

    def build_database(self):
        translator = self.translator

        gcpolicyclass = self.get_gcpolicyclass()

        if self.config.translation.gcrootfinder == "asmgcc":
            if not self.standalone:
                raise NotImplementedError("--gcrootfinder=asmgcc requires standalone")

        if self.config.translation.stackless:
            if not self.standalone:
                raise Exception("stackless: only for stand-alone builds")
            
            from pypy.translator.stackless.transform import StacklessTransformer
            stacklesstransformer = StacklessTransformer(
                translator, self.originalentrypoint,
                stackless_gc=gcpolicyclass.requires_stackless)
            self.entrypoint = stacklesstransformer.slp_entry_point
        else:
            stacklesstransformer = None

        db = LowLevelDatabase(translator, standalone=self.standalone,
                              gcpolicyclass=gcpolicyclass,
                              stacklesstransformer=stacklesstransformer,
                              thread_enabled=self.config.translation.thread,
                              sandbox=self.config.translation.sandbox)
        self.db = db
        
        # give the gc a chance to register interest in the start-up functions it
        # need (we call this for its side-effects of db.get())
        list(db.gcpolicy.gc_startup_code())

        # build entrypoint and eventually other things to expose
        pf = self.getentrypointptr()
        pfname = db.get(pf)
        self.c_entrypoint_name = pfname
        db.complete()

        self.collect_compilation_info(db)
        return db

    have___thread = None

    def collect_compilation_info(self, db):
        # we need a concrete gcpolicy to do this
        self.eci = self.eci.merge(ExternalCompilationInfo(
            libraries=db.gcpolicy.gc_libraries()))

        all = []
        for node in self.db.globalcontainers():
            eci = getattr(node, 'compilation_info', None)
            if eci:
                all.append(eci)
        self.eci = self.eci.merge(*all)

    def get_gcpolicyclass(self):
        if self.gcpolicy is None:
            name = self.config.translation.gctransformer
            if self.config.translation.gcrootfinder == "stackless":
                name = "%s+stacklessgc" % (name,)
            elif self.config.translation.gcrootfinder == "llvmgc":
                name = "%s+llvmgcroot" % (name,)
            elif self.config.translation.gcrootfinder == "asmgcc":
                name = "%s+asmgcroot" % (name,)
            return gc.name_to_gcpolicy[name]
        return self.gcpolicy

    # use generate_source(defines=DEBUG_DEFINES) to force the #definition
    # of the macros that enable debugging assertions
    DEBUG_DEFINES = {'RPY_ASSERT': 1,
                     'RPY_LL_ASSERT': 1}

    def generate_source(self, db=None, defines={}):
        assert self.c_source_filename is None
        translator = self.translator

        if db is None:
            db = self.build_database()
        pf = self.getentrypointptr()
        pfname = db.get(pf)
        if self.modulename is None:
            self.modulename = uniquemodulename('testing')
        modulename = self.modulename
        targetdir = udir.ensure(modulename, dir=1)
        
        self.targetdir = targetdir
        defines = defines.copy()
        if self.config.translation.countmallocs:
            defines['COUNT_OP_MALLOCS'] = 1
        if self.config.translation.sandbox:
            defines['RPY_SANDBOXED'] = 1
        if CBuilder.have___thread is None:
            CBuilder.have___thread = check_under_under_thread()
        if not self.standalone:
            assert not self.config.translation.instrument
            cfile, extra = gen_source(db, modulename, targetdir, self.eci,
                                      defines = defines)
        else:
            if self.config.translation.instrument:
                defines['INSTRUMENT'] = 1
            if CBuilder.have___thread:
                if not self.config.translation.no__thread:
                    defines['USE___THREAD'] = 1
            # explicitely include python.h and exceptions.h
            # XXX for now, we always include Python.h
            from distutils import sysconfig
            python_inc = sysconfig.get_python_inc()
            pypy_include_dir = autopath.this_dir
            self.eci = self.eci.merge(ExternalCompilationInfo(
                include_dirs=[python_inc, pypy_include_dir],
            ))
            cfile, extra = gen_source_standalone(db, modulename, targetdir,
                                                 self.eci,
                                                 entrypointname = pfname,
                                                 defines = defines)
        self.c_source_filename = py.path.local(cfile)
        self.extrafiles = extra
        if self.standalone:
            self.gen_makefile(targetdir)
        return cfile

    def generate_graphs_for_llinterp(self, db=None):
        # prepare the graphs as when the source is generated, but without
        # actually generating the source.
        if db is None:
            db = self.build_database()
        graphs = db.all_graphs()
        db.gctransformer.prepare_inline_helpers(graphs)
        for node in db.containerlist:
            if isinstance(node, FuncNode):
                for funcgen in node.funcgens:
                    funcgen.patch_graph(copy_graph=False)
        return db
Example #42
0
 def test_from_config_tool(self):
     sdlconfig = py.path.local.sysfind('sdl-config')
     if not sdlconfig:
         py.test.skip("sdl-config not installed")
     eci = ExternalCompilationInfo.from_config_tool('sdl-config')
     assert 'SDL' in eci.libraries
Example #43
0
        log(cmdline)
        err = os.system(cmdline)
        if err:
            raise Exception("gcc command failed")

    do("g++ -g -c '%s' -o '%s' `%s --cppflags`" % (cname, o1name, llvm_config))
    do("g++ -g -c '%s' -o '%s' `%s --cppflags`" % (cppname, o2name, llvm_config))
    do("g++ -g -shared '%s' '%s' -o '%s'" % (o1name, o2name, libname) +
       " `%s --cflags --ldflags --libs jit engine`" % llvm_config)

ctypes_compilation_info = ExternalCompilationInfo(
    library_dirs = [dirname],
    libraries    = ['pypy_cache_llvm'],
)

compilation_info = ExternalCompilationInfo.from_linker_flags(
    os.popen("%s --ldflags --libs jit engine" % llvm_config, 'r').read())

compilation_info = compilation_info.merge(ExternalCompilationInfo(
    link_extra = [o1name, o2name],
    use_cpp_linker = True,
    ))

compilation_info._with_ctypes = ctypes_compilation_info

_teardown = None

def set_teardown_function(fn):
    global _teardown
    _teardown = fn

def teardown_now():
Example #44
0
def configure_external_library(name, eci, configurations,
                               symbol=None, _cache={}):
    """try to find the external library.
    On Unix, this simply tests and returns the given eci.

    On Windows, various configurations may be tried to compile the
    given eci object.  These configurations are a list of dicts,
    containing:
    
    - prefix: if an absolute path, will prefix each include and
              library directories.  If a relative path, the external
              directory is searched for directories which names start
              with the prefix.  The last one in alphabetical order
              chosen, and becomes the prefix.

    - include_dir: prefix + include_dir is added to the include directories
    
    - library_dir: prefix + library_dir is added to the library directories
    """

    if sys.platform != 'win32':
        configurations = []
    
    key = (name, eci)
    try:
        return _cache[key]
    except KeyError:
        last_error = None

        # Always try the default configuration
        if {} not in configurations:
            configurations.append({})

        for configuration in configurations:
            prefix = configuration.get('prefix', '')
            include_dir = configuration.get('include_dir', '')
            library_dir = configuration.get('library_dir', '')

            if prefix and not os.path.isabs(prefix):
                import glob

                entries = glob.glob(str(PYPY_EXTERNAL_DIR.join(prefix + '*')))
                if entries:
                    # Get last version
                    prefix = sorted(entries)[-1]
                else:
                    continue

            include_dir = os.path.join(prefix, include_dir)
            library_dir = os.path.join(prefix, library_dir)

            eci_lib = ExternalCompilationInfo(
                include_dirs=include_dir and [include_dir] or [],
                library_dirs=library_dir and [library_dir] or [],
                )
            eci_lib = eci_lib.merge(eci)

            # verify that this eci can be compiled
            try:
                verify_eci(eci_lib)
            except CompilationError, e:
                last_error = e
            else:
                _cache[key] = eci_lib
                return eci_lib

        # Nothing found
        if last_error:
            raise last_error
        else:
            raise CompilationError("Library %s is not installed" % (name,))
Example #45
0
import sys
from pypy.rpython.lltypesystem import lltype, rffi
from pypy.rpython.tool import rffi_platform as platform
from pypy.translator.tool.cbuild import ExternalCompilationInfo
from pypy.rlib.rsdl import RSDL


if sys.platform == 'darwin':
    eci = ExternalCompilationInfo(
        includes = ['SDL_mixer.h'],
        frameworks = ['SDL_mixer'],
        include_dirs = ['/Library/Frameworks/SDL_Mixer.framework/Headers']
    )
else:
    eci = ExternalCompilationInfo(
        includes=['SDL_mixer.h'],
        libraries=['SDL_mixer'],
    )

eci = eci.merge(RSDL.eci)
eci = eci.merge(eci)
eci = eci.merge(eci)

ChunkPtr             = lltype.Ptr(lltype.ForwardReference())

class CConfig:
    _compilation_info_ = eci

    Chunk              = platform.Struct('Mix_Chunk', [('allocated', rffi.INT),
                                                       ('abuf', RSDL.Uint8P),
                                                       ('alen', RSDL.Uint32),
Example #46
0
import py
from pypy.tool.autopath import pypydir
from pypy.rpython.lltypesystem import lltype, llmemory, rffi
from pypy.translator.tool.cbuild import ExternalCompilationInfo
from pypy.rpython.tool import rffi_platform
import sys


cdir = py.path.local(pypydir) / 'translator' / 'c'

eci = ExternalCompilationInfo(
    include_dirs = [cdir],
    includes = ['src/stacklet/stacklet.h'],
    separate_module_sources = ['#include "src/stacklet/stacklet.c"\n'],
)
if sys.platform == 'win32':
    eci.separate_module_files += (cdir / "src/stacklet/switch_x86_msvc.asm", )
    eci.export_symbols += (
        'stacklet_newthread',
        'stacklet_deletethread',
        'stacklet_new',
        'stacklet_switch',
        'stacklet_destroy',
        '_stacklet_translate_pointer',
        )

rffi_platform.verify_eci(eci.convert_sources_to_files())

def llexternal(name, args, result, **kwds):
    return rffi.llexternal(name, args, result, compilation_info=eci,
                           _nowrapper=True, **kwds)