[pypy-svn] r49054 - in pypy/branch/rewrite-compilation-logic: . pypy/rlib pypy/rpython/lltypesystem pypy/rpython/lltypesystem/module pypy/rpython/lltypesystem/test pypy/rpython/module pypy/rpython/tool pypy/rpython/tool/test pypy/translator/c pypy/translator/c/test pypy/translator/tool pypy/translator/tool/test
fijal at codespeak.net
fijal at codespeak.net
Sat Nov 24 19:00:45 CET 2007
Author: fijal
Date: Sat Nov 24 19:00:44 2007
New Revision: 49054
Added:
pypy/branch/rewrite-compilation-logic/
- copied from r49053, pypy/dist/
Modified:
pypy/branch/rewrite-compilation-logic/pypy/rlib/_rsocket_rffi.py
pypy/branch/rewrite-compilation-logic/pypy/rlib/rposix.py
pypy/branch/rewrite-compilation-logic/pypy/rpython/lltypesystem/ll2ctypes.py
pypy/branch/rewrite-compilation-logic/pypy/rpython/lltypesystem/lltype.py
pypy/branch/rewrite-compilation-logic/pypy/rpython/lltypesystem/module/ll_math.py
pypy/branch/rewrite-compilation-logic/pypy/rpython/lltypesystem/rffi.py
pypy/branch/rewrite-compilation-logic/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
pypy/branch/rewrite-compilation-logic/pypy/rpython/lltypesystem/test/test_rffi.py
pypy/branch/rewrite-compilation-logic/pypy/rpython/module/ll_termios.py
pypy/branch/rewrite-compilation-logic/pypy/rpython/tool/rffi_platform.py
pypy/branch/rewrite-compilation-logic/pypy/rpython/tool/rfficache.py
pypy/branch/rewrite-compilation-logic/pypy/rpython/tool/test/test_rffi_platform.py
pypy/branch/rewrite-compilation-logic/pypy/translator/c/genc.py
pypy/branch/rewrite-compilation-logic/pypy/translator/c/node.py
pypy/branch/rewrite-compilation-logic/pypy/translator/c/test/test_genc.py
pypy/branch/rewrite-compilation-logic/pypy/translator/tool/cbuild.py
pypy/branch/rewrite-compilation-logic/pypy/translator/tool/test/test_cbuild.py
Log:
(fijal, arigo, xoraxax) In-progress checkin of rewriting compilation
logic. Tries to sort out the need of includes include_dirs, libraries
and friends.
Modified: pypy/branch/rewrite-compilation-logic/pypy/rlib/_rsocket_rffi.py
==============================================================================
--- pypy/dist/pypy/rlib/_rsocket_rffi.py (original)
+++ pypy/branch/rewrite-compilation-logic/pypy/rlib/_rsocket_rffi.py Sat Nov 24 19:00:44 2007
@@ -4,6 +4,7 @@
from pypy.rpython.tool import rffi_platform as platform
from pypy.rpython.lltypesystem.rffi import CCHARP
from pypy.rlib.rposix import get_errno as geterrno
+from pypy.translator.tool.cbuild import ExternalCompilationInfo
from pypy.rlib.rarithmetic import intmask, r_uint
import os
@@ -51,9 +52,13 @@
COND_HEADER = ''
constants = {}
+eci = ExternalCompilationInfo(
+ pre_include_lines = (HEADER + COND_HEADER).split("\n"),
+ includes = includes
+)
class CConfig:
- _header_ = HEADER + COND_HEADER
+ _compilation_info_ = eci
# constants
linux = platform.Defined('linux')
MS_WINDOWS = platform.Defined('_WIN32')
@@ -376,10 +381,10 @@
for _name, _header in cond_includes:
if getattr(cConfig, _name) is not None:
includes.append(_header)
+ eci = ExternalCompilationInfo(includes=includes, libraries=libraries)
def external(name, args, result):
- return rffi.llexternal(name, args, result,
- includes=includes, libraries=libraries,
+ return rffi.llexternal(name, args, result, compilation_info=eci,
calling_conv=calling_conv)
if _POSIX:
Modified: pypy/branch/rewrite-compilation-logic/pypy/rlib/rposix.py
==============================================================================
--- pypy/dist/pypy/rlib/rposix.py (original)
+++ pypy/branch/rewrite-compilation-logic/pypy/rlib/rposix.py Sat Nov 24 19:00:44 2007
@@ -1,5 +1,6 @@
from pypy.rpython.lltypesystem.rffi import CConstant, CExternVariable
from pypy.rpython.lltypesystem import lltype, ll2ctypes
+from pypy.translator.tool.cbuild import ExternalCompilationInfo
class CConstantErrno(CConstant):
# these accessors are used when calling get_errno() or set_errno()
@@ -15,6 +16,10 @@
assert index == 0
ll2ctypes.TLS.errno = value
-get_errno, set_errno = CExternVariable(lltype.Signed, 'errno', CConstantErrno,
- includes=['errno.h'], sandboxsafe=True)
+errno_eci = ExternalCompilationInfo(
+ includes=['errno.h']
+)
+
+get_errno, set_errno = CExternVariable(lltype.Signed, 'errno', errno_eci,
+ CConstantErrno, sandboxsafe=True)
Modified: pypy/branch/rewrite-compilation-logic/pypy/rpython/lltypesystem/ll2ctypes.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/ll2ctypes.py (original)
+++ pypy/branch/rewrite-compilation-logic/pypy/rpython/lltypesystem/ll2ctypes.py Sat Nov 24 19:00:44 2007
@@ -513,15 +513,6 @@
# ____________________________________________
-def compile_c_snippet(name, source):
- from pypy.tool.udir import udir
- cname = udir.join(name + '.c')
- f = cname.open('w')
- f.write(source)
- f.write('\n')
- f.close()
- return cache_c_module([cname], name)
-
def get_ctypes_callable(funcptr, calling_conv):
if not ctypes:
raise ImportError("ctypes is needed to use ll2ctypes")
@@ -534,16 +525,12 @@
except AttributeError:
pass
- sources = getattr(funcptr._obj, 'sources', None)
- if sources:
- assert len(sources) == 1
- dllname = compile_c_snippet(funcptr._obj._name, sources[0])
- libraries = [dllname]
- else:
- libraries = getattr(funcptr._obj, 'libraries', None)
+ eci = funcptr._obj.compilation_info
+ libraries = list(eci.libraries)
+ funcname = funcptr._obj._name
+ eci = eci.make_shared_lib()
FUNCTYPE = lltype.typeOf(funcptr).TO
- funcname = funcptr._obj._name
if not libraries:
cfunc = get_on_lib(standard_c_lib, funcname)
# XXX magic: on Windows try to load the function from 'kernel32' too
Modified: pypy/branch/rewrite-compilation-logic/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lltype.py (original)
+++ pypy/branch/rewrite-compilation-logic/pypy/rpython/lltypesystem/lltype.py Sat Nov 24 19:00:44 2007
@@ -413,9 +413,8 @@
def __init__(self, args, result):
for arg in args:
assert isinstance(arg, LowLevelType)
- # -- disable the following check for the benefits of rffi --
- if isinstance(arg, ContainerType):
- raise TypeError, "function arguments can only be primitives or pointers"
+ # There are external C functions eating raw structures, not
+ # pointers, don't check args not being container types
self.ARGS = tuple(args)
assert isinstance(result, LowLevelType)
if isinstance(result, ContainerType):
Modified: pypy/branch/rewrite-compilation-logic/pypy/rpython/lltypesystem/module/ll_math.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/module/ll_math.py (original)
+++ pypy/branch/rewrite-compilation-logic/pypy/rpython/lltypesystem/module/ll_math.py Sat Nov 24 19:00:44 2007
@@ -4,6 +4,7 @@
from pypy.rpython.lltypesystem import lltype, rffi
from pypy.tool.sourcetools import func_with_new_name
from pypy.rlib import rposix
+from pypy.translator.tool.cbuild import ExternalCompilationInfo
math_frexp = rffi.llexternal('frexp', [rffi.DOUBLE, rffi.INTP], rffi.DOUBLE,
sandboxsafe=True)
@@ -55,9 +56,11 @@
else:
raise ValueError("math domain error")
+eci = ExternalCompilationInfo(libraries=['m'])
+
def new_unary_math_function(name):
c_func = rffi.llexternal(name, [rffi.DOUBLE], rffi.DOUBLE,
- sandboxsafe=True, libraries=['m'])
+ compilation_info=eci, sandboxsafe=True)
def ll_math(x):
_error_reset()
@@ -69,7 +72,7 @@
def new_binary_math_function(name):
c_func = rffi.llexternal(name, [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE,
- sandboxsafe=True, libraries=['m'])
+ compilation_info=eci, sandboxsafe=True)
def ll_math(x, y):
_error_reset()
Modified: pypy/branch/rewrite-compilation-logic/pypy/rpython/lltypesystem/rffi.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rffi.py (original)
+++ pypy/branch/rewrite-compilation-logic/pypy/rpython/lltypesystem/rffi.py Sat Nov 24 19:00:44 2007
@@ -10,6 +10,7 @@
from pypy.rlib.unroll import unrolling_iterable
from pypy.tool.sourcetools import func_with_new_name
from pypy.rpython.tool.rfficache import platform
+from pypy.translator.tool.cbuild import ExternalCompilationInfo
import os
class CConstant(Symbolic):
@@ -25,8 +26,8 @@
def lltype(self):
return self.TP
-def llexternal(name, args, result, _callable=None, sources=[], includes=[],
- libraries=[], include_dirs=[], library_dirs=[],
+def llexternal(name, args, result, _callable=None,
+ compilation_info=ExternalCompilationInfo(),
sandboxsafe=False, threadsafe='auto',
canraise=False, _nowrapper=False, calling_conv='c'):
"""Build an external function that will invoke the C function 'name'
@@ -48,11 +49,7 @@
if _callable is None:
_callable = ll2ctypes.LL2CtypesCallable(ext_type, calling_conv)
funcptr = lltype.functionptr(ext_type, name, external='C',
- sources=tuple(sources),
- includes=tuple(includes),
- libraries=tuple(libraries),
- include_dirs=tuple(include_dirs),
- library_dirs=tuple(library_dirs),
+ compilation_info=compilation_info,
_callable=_callable,
_safe_not_sandboxed=sandboxsafe,
_debugexc=True, # on top of llinterp
@@ -220,7 +217,9 @@
return lltype.Ptr(CArray(tp))
CArray._annspecialcase_ = 'specialize:memo'
-def COpaque(name, hints=None, **kwds):
+def COpaque(name, hints=None, compilation_info=None):
+ if compilation_info is None:
+ compilation_info = ExternalCompilationInfo()
if hints is None:
hints = {}
else:
@@ -230,11 +229,7 @@
def lazy_getsize():
from pypy.rpython.tool import rffi_platform
k = {}
- for _name, value in kwds.items():
- if _name in ['includes', 'include_dirs', 'libraries',
- 'library_dirs']:
- k['_%s_' % _name] = value
- return rffi_platform.sizeof(name, '', **k)
+ return rffi_platform.sizeof(name, compilation_info)
hints['getsize'] = lazy_getsize
return lltype.OpaqueType(name, hints)
@@ -242,12 +237,13 @@
def COpaquePtr(*args, **kwds):
return lltype.Ptr(COpaque(*args, **kwds))
-def CExternVariable(TYPE, name, _CConstantClass=CConstant, includes=[],
- include_dirs=[], sandboxsafe=False):
+def CExternVariable(TYPE, name, eci, _CConstantClass=CConstant,
+ sandboxsafe=False):
"""Return a pair of functions - a getter and a setter - to access
the given global C variable.
"""
from pypy.translator.c.primitive import PrimitiveType
+ from pypy.translator.tool.cbuild import ExternalCompilationInfo
# XXX we cannot really enumerate all C types here, do it on a case-by-case
# basis
if TYPE == CCHARPP:
@@ -264,15 +260,18 @@
c_getter = "%(c_type)s %(getter_name)s () { return %(name)s; }" % locals()
c_setter = "void %(setter_name)s (%(c_type)s v) { %(name)s = v; }" % locals()
- lines = ["#include <%s>" % i for i in includes]
+ lines = ["#include <%s>" % i for i in eci.includes]
lines.append(c_getter)
lines.append(c_setter)
sources = ('\n'.join(lines),)
-
- kwds = {'includes': includes, 'sources':sources,
- 'include_dirs':include_dirs, 'sandboxsafe': sandboxsafe}
- getter = llexternal(getter_name, [], TYPE, **kwds)
- setter = llexternal(setter_name, [TYPE], lltype.Void, **kwds)
+ new_eci = eci.merge(ExternalCompilationInfo(
+ separate_module_sources = sources
+ ))
+
+ getter = llexternal(getter_name, [], TYPE, compilation_info=new_eci,
+ sandboxsafe=sandboxsafe)
+ setter = llexternal(setter_name, [TYPE], lltype.Void,
+ compilation_info=new_eci, sandboxsafe=sandboxsafe)
return getter, setter
## # XXX THIS IS ONLY A QUICK HACK TO MAKE IT WORK
Modified: pypy/branch/rewrite-compilation-logic/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_ll2ctypes.py (original)
+++ pypy/branch/rewrite-compilation-logic/pypy/rpython/lltypesystem/test/test_ll2ctypes.py Sat Nov 24 19:00:44 2007
@@ -9,6 +9,7 @@
from pypy.rpython.lltypesystem.ll2ctypes import ALLOCATED
from pypy.rpython.annlowlevel import llhelper
from pypy.rlib import rposix
+from pypy.translator.tool.cbuild import ExternalCompilationInfo
class TestLL2Ctypes(object):
@@ -139,8 +140,9 @@
assert not ALLOCATED # detects memory leaks in the test
def test_strlen(self):
+ eci = ExternalCompilationInfo(includes=['string.h'])
strlen = rffi.llexternal('strlen', [rffi.CCHARP], rffi.SIZE_T,
- includes=['string.h'])
+ compilation_info=eci)
s = rffi.str2charp("xxx")
res = strlen(s)
rffi.free_charp(s)
@@ -152,19 +154,22 @@
assert not ALLOCATED # detects memory leaks in the test
def test_func_not_in_clib(self):
+ eci = ExternalCompilationInfo(libraries=['m'])
foobar = rffi.llexternal('I_really_dont_exist', [], lltype.Signed)
py.test.raises(NotImplementedError, foobar)
foobar = rffi.llexternal('I_really_dont_exist', [], lltype.Signed,
- libraries=['m']) # math library
+ compilation_info=eci) # math library
py.test.raises(NotImplementedError, foobar)
+ eci = ExternalCompilationInfo(libraries=['m', 'z'])
foobar = rffi.llexternal('I_really_dont_exist', [], lltype.Signed,
- libraries=['m', 'z']) # math and zlib
+ compilation_info=eci) # math and zlib
py.test.raises(NotImplementedError, foobar)
+ eci = ExternalCompilationInfo(libraries=['I_really_dont_exist_either'])
foobar = rffi.llexternal('I_really_dont_exist', [], lltype.Signed,
- libraries=['I_really_dont_exist_either'])
+ compilation_info=eci)
py.test.raises(NotImplementedError, foobar)
assert not ALLOCATED # detects memory leaks in the test
@@ -229,9 +234,9 @@
assert not ALLOCATED # detects memory leaks in the test
def test_strchr(self):
+ eci = ExternalCompilationInfo(includes=['string.h'])
strchr = rffi.llexternal('strchr', [rffi.CCHARP, rffi.INT],
- rffi.CCHARP,
- includes=['string.h'])
+ rffi.CCHARP, compilation_info=eci)
s = rffi.str2charp("hello world")
res = strchr(s, ord('r'))
assert res[0] == 'r'
@@ -243,11 +248,11 @@
assert not ALLOCATED # detects memory leaks in the test
def test_frexp(self):
+ eci = ExternalCompilationInfo(includes=['math.h'],
+ libraries=['m'])
A = lltype.FixedSizeArray(rffi.INT, 1)
frexp = rffi.llexternal('frexp', [rffi.DOUBLE, lltype.Ptr(A)],
- rffi.DOUBLE,
- includes=['math.h'],
- libraries=['m'])
+ rffi.DOUBLE, compilation_info=eci)
p = lltype.malloc(A, flavor='raw')
res = frexp(2.5, p)
assert res == 0.625
@@ -256,10 +261,11 @@
assert not ALLOCATED # detects memory leaks in the test
def test_rand(self):
+ eci = ExternalCompilationInfo(includes=['stdlib.h'])
rand = rffi.llexternal('rand', [], rffi.INT,
- includes=['stdlib.h'])
+ compilation_info=eci)
srand = rffi.llexternal('srand', [rffi.UINT], lltype.Void,
- includes=['stdlib.h'])
+ compilation_info=eci)
srand(rffi.r_uint(123))
res1 = rand()
res2 = rand()
@@ -274,11 +280,13 @@
assert not ALLOCATED # detects memory leaks in the test
def test_opaque_obj(self):
- includes = ['sys/time.h', 'time.h']
- TIMEVALP = rffi.COpaquePtr('struct timeval', includes=includes)
- TIMEZONEP = rffi.COpaquePtr('struct timezone', includes=includes)
+ eci = ExternalCompilationInfo(
+ includes = ['sys/time.h', 'time.h']
+ )
+ TIMEVALP = rffi.COpaquePtr('struct timeval', compilation_info=eci)
+ TIMEZONEP = rffi.COpaquePtr('struct timezone', compilation_info=eci)
gettimeofday = rffi.llexternal('gettimeofday', [TIMEVALP, TIMEZONEP],
- rffi.INT, includes=includes)
+ rffi.INT, compilation_info=eci)
ll_timevalp = lltype.malloc(TIMEVALP.TO, flavor='raw')
ll_timezonep = lltype.malloc(TIMEZONEP.TO, flavor='raw')
res = gettimeofday(ll_timevalp, ll_timezonep)
@@ -582,12 +590,13 @@
assert not ALLOCATED # detects memory leaks in the test
def test_get_errno(self):
+ eci = ExternalCompilationInfo(includes=['string.h'])
if sys.platform.startswith('win'):
underscore_on_windows = '_'
else:
underscore_on_windows = ''
strlen = rffi.llexternal('strlen', [rffi.CCHARP], rffi.SIZE_T,
- includes=['string.h'])
+ compilation_info=eci)
os_write = rffi.llexternal(underscore_on_windows+'write',
[rffi.INT, rffi.CCHARP, rffi.SIZE_T],
rffi.SIZE_T)
@@ -650,23 +659,6 @@
assert isinstance(b[2], rffi.r_singlefloat)
assert abs(float(b[2]) - 2.2) < 1E-6
- def test_cfunc_returning_newly_allocated(self):
- py.test.skip("complains about a double free")
- from crypt import crypt as pycrypt
- crypt = rffi.llexternal('crypt', [rffi.CCHARP, rffi.CCHARP],
- rffi.CCHARP,
- libraries=['crypt'])
-
- s1 = rffi.str2charp("pass")
- s2 = rffi.str2charp("ab")
- r = crypt(s1, s2)
- rffi.free_charp(s1)
- rffi.free_charp(s2)
- res = rffi.charp2str(r)
- assert res == pycrypt("pass", "ab")
- rffi.free_charp(r)
- assert not ALLOCATED
-
def test_different_signatures(self):
fcntl_int = rffi.llexternal('fcntl', [rffi.INT, rffi.INT, rffi.INT],
rffi.INT)
@@ -677,7 +669,36 @@
fcntl_int(12345, 1, 0)
def test_llexternal_source(self):
- fn = rffi.llexternal('fn', [], rffi.INT, sources = ["int fn() { return 42; }"])
+ eci = ExternalCompilationInfo(
+ separate_module_sources = ["int fn() { return 42; }"]
+ )
+ fn = rffi.llexternal('fn', [], rffi.INT, compilation_info=eci)
res = fn()
assert res == 42
+ def test_prebuilt_constant(self):
+ source = py.code.Source("""
+ int x = 3;
+ char** z = NULL;
+ """)
+
+ eci = ExternalCompilationInfo(post_include_lines=source.lines)
+
+ get_x, set_x = rffi.CExternVariable(lltype.Signed, 'x', eci)
+ get_z, set_z = rffi.CExternVariable(rffi.CCHARPP, 'z', eci)
+
+ def f():
+ one = get_x()
+ set_x(13)
+ return one + get_x()
+
+ def g():
+ l = rffi.liststr2charpp(["a", "b", "c"])
+ try:
+ set_z(l)
+ return rffi.charp2str(get_z()[2])
+ finally:
+ rffi.free_charpp(l)
+
+ assert f() == 16
+ assert g() == "c"
Modified: pypy/branch/rewrite-compilation-logic/pypy/rpython/lltypesystem/test/test_rffi.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_rffi.py (original)
+++ pypy/branch/rewrite-compilation-logic/pypy/rpython/lltypesystem/test/test_rffi.py Sat Nov 24 19:00:44 2007
@@ -13,6 +13,7 @@
from pypy.translator.translator import graphof
from pypy.conftest import option
from pypy.objspace.flow.model import summary
+from pypy.translator.tool.cbuild import ExternalCompilationInfo
def test_basic():
c_source = py.code.Source("""
@@ -21,7 +22,9 @@
return (x + 3);
}
""")
- z = llexternal('z', [Signed], Signed, sources=[c_source])
+
+ eci = ExternalCompilationInfo(separate_module_sources=[c_source])
+ z = llexternal('z', [Signed], Signed, eci)
def f():
return z(8)
Modified: pypy/branch/rewrite-compilation-logic/pypy/rpython/module/ll_termios.py
==============================================================================
--- pypy/dist/pypy/rpython/module/ll_termios.py (original)
+++ pypy/branch/rewrite-compilation-logic/pypy/rpython/module/ll_termios.py Sat Nov 24 19:00:44 2007
@@ -15,11 +15,14 @@
from pypy.rpython import rclass
from pypy.rlib import rtermios
from pypy.rpython.tool import rffi_platform
+from pypy.translator.tool.cbuild import ExternalCompilationInfo
-includes = ['termios.h', 'unistd.h']
+eci = ExternalCompilationInfo(
+ includes = ['termios.h', 'unistd.h']
+)
class CConfig:
- _includes_ = includes
+ _compilation_info_ = eci
NCCS = rffi_platform.DefinedConstantInteger('NCCS')
NCCS = rffi_platform.configure(CConfig)['NCCS']
@@ -39,7 +42,7 @@
('c_cc', lltype.FixedSizeArray(CC_T, NCCS)))
def c_external(name, args, result):
- return rffi.llexternal(name, args, result, includes=includes)
+ return rffi.llexternal(name, args, result, compilation_info=eci)
c_tcsetattr = c_external('tcsetattr', [INT, INT, TERMIOSP], INT)
c_cfgetispeed = c_external('cfgetispeed', [TERMIOSP], SPEED_T)
Modified: pypy/branch/rewrite-compilation-logic/pypy/rpython/tool/rffi_platform.py
==============================================================================
--- pypy/dist/pypy/rpython/tool/rffi_platform.py (original)
+++ pypy/branch/rewrite-compilation-logic/pypy/rpython/tool/rffi_platform.py Sat Nov 24 19:00:44 2007
@@ -5,6 +5,7 @@
from pypy.rpython.lltypesystem import rffi
from pypy.rpython.lltypesystem import llmemory
from pypy.tool.gcc_cache import build_executable_cache, try_compile_cache
+from pypy.translator.tool.cbuild import ExternalCompilationInfo
from pypy.tool.udir import udir
import distutils
@@ -12,39 +13,44 @@
#
# Helpers for simple cases
+def eci_from_header(c_header_source):
+ return ExternalCompilationInfo(
+ pre_include_lines=c_header_source.split("\n")
+ )
+
def getstruct(name, c_header_source, interesting_fields):
class CConfig:
- _header_ = c_header_source
+ _compilation_info_ = eci_from_header(c_header_source)
STRUCT = Struct(name, interesting_fields)
return configure(CConfig)['STRUCT']
def getsimpletype(name, c_header_source, ctype_hint=rffi.INT):
class CConfig:
- _header_ = c_header_source
+ _compilation_info_ = eci_from_header(c_header_source)
TYPE = SimpleType(name, ctype_hint)
return configure(CConfig)['TYPE']
def getconstantinteger(name, c_header_source):
class CConfig:
- _header_ = c_header_source
+ _compilation_info_ = eci_from_header(c_header_source)
CONST = ConstantInteger(name)
return configure(CConfig)['CONST']
def getdefined(macro, c_header_source):
class CConfig:
- _header_ = c_header_source
+ _compilation_info_ = eci_from_header(c_header_source)
DEFINED = Defined(macro)
return configure(CConfig)['DEFINED']
def has(name, c_header_source):
class CConfig:
- _header_ = c_header_source
+ _compilation_info_ = eci_from_header(c_header_source)
HAS = Has(name)
return configure(CConfig)['HAS']
-def sizeof(name, c_header_source, **kwds):
+def sizeof(name, eci, **kwds):
class CConfig:
- _header_ = c_header_source
+ _compilation_info_ = eci
SIZE = SizeOf(name)
for k, v in kwds.items():
setattr(CConfig, k, v)
@@ -85,12 +91,7 @@
def write_header(self):
f = self.f
CConfig = self.config
- # NB: the _header_ must be printed before everything else,
- # because it might contain #defines that need to appear before
- # any system #include.
- print >> f, getattr(CConfig, '_header_', '') # optional
- for path in getattr(CConfig, '_includes_', ()): # optional
- print >> f, '#include <%s>' % (path,)
+ CConfig._compilation_info_.write_c_header(f)
print >> f, C_HEADER
print >> f
@@ -122,12 +123,8 @@
self.start_main()
self.f.write(question + "\n")
self.close()
- include_dirs = getattr(self.config, '_include_dirs_', [])
- libraries = getattr(self.config, '_libraries_', [])
- library_dirs = getattr(self.config, '_library_dirs_', [])
- return try_compile_cache([self.path], include_dirs=include_dirs,
- libraries=libraries,
- library_dirs=library_dirs)
+ eci = self.config._compilation_info_
+ return try_compile_cache([self.path], eci)
def configure(CConfig):
"""Examine the local system by running the C compiler.
@@ -135,6 +132,9 @@
what should be inspected; configure() returns a dict mapping
names to the results.
"""
+ for attr in ['_includes_', '_libraries_', '_sources_', '_library_dirs_',
+ '_include_dirs_', '_header_']:
+ assert not hasattr(CConfig, attr), "Found legacy attribut %s on CConfig" % (attr,)
entries = []
for key in dir(CConfig):
value = getattr(CConfig, key)
@@ -153,11 +153,8 @@
writer.write_entry_main(key)
writer.close()
- include_dirs = getattr(CConfig, '_include_dirs_', [])
- libraries = getattr(CConfig, '_libraries_', [])
- library_dirs = getattr(CConfig, '_library_dirs_', [])
- infolist = list(run_example_code(writer.path, include_dirs,
- libraries, library_dirs))
+ eci = CConfig._compilation_info_
+ infolist = list(run_example_code(writer.path, eci))
assert len(infolist) == len(entries)
resultinfo = {}
@@ -503,10 +500,8 @@
}
"""
-def run_example_code(filepath, include_dirs=[], libraries=[], library_dirs=[]):
- output = build_executable_cache([filepath], include_dirs=include_dirs,
- libraries=libraries,
- library_dirs=library_dirs)
+def run_example_code(filepath, eci):
+ output = build_executable_cache([filepath], eci)
section = None
for line in output.splitlines():
line = line.strip()
Modified: pypy/branch/rewrite-compilation-logic/pypy/rpython/tool/rfficache.py
==============================================================================
--- pypy/dist/pypy/rpython/tool/rfficache.py (original)
+++ pypy/branch/rewrite-compilation-logic/pypy/rpython/tool/rfficache.py Sat Nov 24 19:00:44 2007
@@ -1,12 +1,12 @@
-""" This file creates and maintains _cache/stdtypes.py, which
-keeps information about C type sizes
-"""
+# XXX This is completely outdated file, kept here only for bootstrapping
+# reasons. If you touch it, try removing it
import py
import os
import distutils
-from pypy.translator.tool.cbuild import build_executable
+from pypy.translator.tool.cbuild import build_executable, \
+ ExternalCompilationInfo
from pypy.tool.udir import udir
from pypy.tool.autopath import pypydir
from pypy.rlib import rarithmetic
@@ -31,7 +31,8 @@
''' % (include_string, add_source, str(question)))
c_file = udir.join("gcctest.c")
c_file.write(c_source)
- return build_executable_cache([c_file], compiler_exe=compiler_exe)
+ eci = ExternalCompilationInfo()
+ return build_executable_cache([c_file], eci, compiler_exe=compiler_exe)
def sizeof_c_type(c_typename, **kwds):
question = 'printf("%%d", sizeof(%s));' % (c_typename,);
Modified: pypy/branch/rewrite-compilation-logic/pypy/rpython/tool/test/test_rffi_platform.py
==============================================================================
--- pypy/dist/pypy/rpython/tool/test/test_rffi_platform.py (original)
+++ pypy/branch/rewrite-compilation-logic/pypy/rpython/tool/test/test_rffi_platform.py Sat Nov 24 19:00:44 2007
@@ -3,6 +3,7 @@
from pypy.rpython.lltypesystem import lltype
from pypy.rpython.lltypesystem import rffi
from pypy.tool.udir import udir
+from pypy.translator.tool.cbuild import ExternalCompilationInfo
def import_ctypes():
try:
@@ -109,11 +110,12 @@
test_h.write('#define XYZZY 42\n')
class CConfig:
- _header_ = """ /* a C comment */
- #include <stdio.h>
- #include <test_ctypes_platform.h>
- """
- _include_dirs_ = [str(udir)]
+ _compilation_info_ = ExternalCompilationInfo(
+ pre_include_lines = ["/* a C comment */",
+ "#include <stdio.h>",
+ "#include <test_ctypes_platform.h>"],
+ include_dirs = [str(udir)]
+ )
FILE = rffi_platform.Struct('FILE', [])
ushort = rffi_platform.SimpleType('unsigned short')
@@ -127,14 +129,14 @@
def test_ifdef():
class CConfig:
- _header_ = """ /* a C comment */
-#define XYZZY 42
-typedef int foo;
-struct s {
- int i;
- double f;
-};
-"""
+ _compilation_info_ = ExternalCompilationInfo(
+ post_include_lines = ['/* a C comment */',
+ '#define XYZZY 42',
+ 'typedef int foo;',
+ 'struct s {',
+ 'int i;',
+ 'double f;'
+ '};'])
s = rffi_platform.Struct('struct s', [('i', rffi.INT)],
ifdef='XYZZY')
@@ -152,16 +154,17 @@
def test_nested_structs():
class CConfig:
- _header_ = """
-struct x {
- int foo;
- unsigned long bar;
- };
-struct y {
- char c;
- struct x x;
- };
-"""
+ _compilation_info_ = ExternalCompilationInfo(
+ post_include_lines="""
+ struct x {
+ int foo;
+ unsigned long bar;
+ };
+ struct y {
+ char c;
+ struct x x;
+ };
+ """.split("\n"))
x = rffi_platform.Struct("struct x", [("bar", rffi.SHORT)])
y = rffi_platform.Struct("struct y", [("x", x)])
@@ -193,4 +196,4 @@
assert not rffi_platform.has("x", "#include <some/path/which/cannot/exist>")
def test_sizeof():
- assert rffi_platform.sizeof("char", "") == 1
+ assert rffi_platform.sizeof("char", ExternalCompilationInfo()) == 1
Modified: pypy/branch/rewrite-compilation-logic/pypy/translator/c/genc.py
==============================================================================
--- pypy/dist/pypy/translator/c/genc.py (original)
+++ pypy/branch/rewrite-compilation-logic/pypy/translator/c/genc.py Sat Nov 24 19:00:44 2007
@@ -6,7 +6,7 @@
from pypy.translator.c.extfunc import pre_include_code_lines
from pypy.translator.llsupport.wrapper import new_wrapper
from pypy.translator.gensupp import uniquemodulename, NameManager
-from pypy.translator.tool.cbuild import so_ext
+from pypy.translator.tool.cbuild import so_ext, ExternalCompilationInfo
from pypy.translator.tool.cbuild import compile_c_module
from pypy.translator.tool.cbuild import build_executable, CCompiler, ProfOpt
from pypy.translator.tool.cbuild import import_module_from_directory
@@ -24,8 +24,8 @@
_compiled = False
modulename = None
- def __init__(self, translator, entrypoint, config, libraries=None,
- gcpolicy=None):
+ def __init__(self, translator, entrypoint, config,
+ eci=ExternalCompilationInfo(), gcpolicy=None):
self.translator = translator
self.entrypoint = entrypoint
self.entrypoint_name = self.entrypoint.func_name
@@ -34,11 +34,8 @@
if gcpolicy is not None and gcpolicy.requires_stackless:
config.translation.stackless = True
self.config = config
-
- if libraries is None:
- libraries = []
- self.libraries = libraries
self.exports = {}
+ self.eci = eci
def build_database(self):
translator = self.translator
@@ -65,7 +62,8 @@
self.db = db
# we need a concrete gcpolicy to do this
- self.libraries += db.gcpolicy.gc_libraries()
+ self.eci = self.eci.merge(ExternalCompilationInfo(
+ libraries=db.gcpolicy.gc_libraries()))
# 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())
@@ -77,19 +75,19 @@
self.exports[self.entrypoint_name] = pf
self.c_entrypoint_name = pfname
db.complete()
-
- # add library dependencies
- seen = dict.fromkeys(self.libraries)
- for node in db.globalcontainers():
- if hasattr(node, 'libraries'):
- for library in node.libraries:
- if library not in seen:
- self.libraries.append(library)
- seen[library] = True
+
+ self.collect_compilation_info()
return db
have___thread = None
+ def collect_compilation_info(self):
+ 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:
@@ -112,7 +110,6 @@
db = self.build_database()
pf = self.getentrypointptr()
pfname = db.get(pf)
- extra_info = extra_information(db)
if self.modulename is None:
self.modulename = uniquemodulename('testing')
modulename = self.modulename
@@ -128,27 +125,21 @@
CBuilder.have___thread = check_under_under_thread()
if not self.standalone:
assert not self.config.translation.instrument
- cfile, extra, include_dirs, library_dirs = \
- gen_source(db, modulename, targetdir,
- defines = defines,
- exports = self.exports,
- libraries = self.libraries,
- extra_info = extra_info)
+ cfile, extra = gen_source(db, modulename, targetdir, self.eci,
+ defines = defines,
+ exports = self.exports)
else:
if self.config.translation.instrument:
defines['INSTRUMENT'] = 1
if CBuilder.have___thread:
if not self.config.translation.no__thread:
defines['USE___THREAD'] = 1
- cfile, extra, include_dirs, library_dirs = \
- gen_source_standalone(db, modulename, targetdir,
- entrypointname = pfname,
- defines = defines,
- extra_info = extra_info)
+ 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
- self.include_dirs = include_dirs.keys()
- self.library_dirs = library_dirs.keys()
if self.standalone:
self.gen_makefile(targetdir)
return cfile
@@ -636,23 +627,8 @@
print >> f, '\treturn error;'
print >> f, '}'
-def extra_information(database):
- includes = {}
- sources = {}
- include_dirs = {}
- library_dirs = {}
- for node in database.globalcontainers():
- for attrname in ['includes', 'sources', 'include_dirs', 'library_dirs']:
- if hasattr(node, attrname):
- for elem in getattr(node, attrname):
- locals()[attrname][elem] = True
- includes = includes.keys()
- includes.sort()
- return {'includes':includes, 'sources':sources,
- 'include_dirs':include_dirs, 'library_dirs':library_dirs}
-
-def gen_source_standalone(database, modulename, targetdir,
- entrypointname, defines={}, extra_info={}):
+def gen_source_standalone(database, modulename, targetdir, eci,
+ entrypointname, defines={}):
assert database.standalone
if isinstance(targetdir, str):
targetdir = py.path.local(targetdir)
@@ -710,12 +686,10 @@
print >>fi, "#define INSTRUMENT_NCOUNTER %d" % n
fi.close()
- return filename, sg.getextrafiles(), extra_info.get('include_dirs', None),\
- extra_info.get('library_dirs', None)
+ return filename, sg.getextrafiles()
-def gen_source(database, modulename, targetdir, defines={}, exports={},
- libraries=[], extra_info={}):
+def gen_source(database, modulename, targetdir, eci, defines={}, exports={}):
assert not database.standalone
if isinstance(targetdir, str):
targetdir = py.path.local(targetdir)
@@ -741,11 +715,11 @@
for line in database.gcpolicy.pre_gc_code():
print >> fi, line
- for include in extra_info.get('includes', []):
- print >> fi, '#include <%s>' % (include,)
+ eci.write_c_header(fi)
+ fi.close()
+
for source in extra_info.get('sources', []):
print >> f, source
- fi.close()
if database.translator is None or database.translator.rtyper is None:
preimplementationlines = []
@@ -769,13 +743,10 @@
#
pypy_include_dir = autopath.this_dir
f = targetdir.join('setup.py').open('w')
- include_dirs = extra_info.get('include_dirs', [])
- library_dirs = extra_info.get('library_dirs', [])
f.write(SETUP_PY % locals())
f.close()
- return filename, sg.getextrafiles(), include_dirs,\
- library_dirs
+ return filename, sg.getextrafiles()
SETUP_PY = '''
Modified: pypy/branch/rewrite-compilation-logic/pypy/translator/c/node.py
==============================================================================
--- pypy/dist/pypy/translator/c/node.py (original)
+++ pypy/branch/rewrite-compilation-logic/pypy/translator/c/node.py Sat Nov 24 19:00:44 2007
@@ -13,7 +13,7 @@
from pypy.translator.c.primitive import PrimitiveType
from pypy.rlib.rarithmetic import isinf, isnan
from pypy.translator.c import extfunc
-
+from pypy.translator.tool.cbuild import ExternalCompilationInfo
def needs_gcheader(T):
if not isinstance(T, ContainerType):
@@ -698,9 +698,8 @@
else:
self.name = (forcename or
db.namespace.uniquename('g_' + self.basename()))
- for attrname in 'libraries', 'include_dirs', 'includes', 'sources', 'library_dirs':
- if hasattr(obj, attrname):
- setattr(self, attrname, getattr(obj, attrname))
+ self.compilation_info = getattr(obj, 'compilation_info',
+ ExternalCompilationInfo())
self.make_funcgens()
#self.dependencies = {}
self.typename = db.gettype(T) #, who_asks=self)
Modified: pypy/branch/rewrite-compilation-logic/pypy/translator/c/test/test_genc.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_genc.py (original)
+++ pypy/branch/rewrite-compilation-logic/pypy/translator/c/test/test_genc.py Sat Nov 24 19:00:44 2007
@@ -10,6 +10,7 @@
from pypy.objspace.flow.model import Block, Link, FunctionGraph
from pypy.tool.udir import udir
from pypy.translator.tool.cbuild import make_module_from_c
+from pypy.translator.tool.cbuild import ExternalCompilationInfo
from pypy.translator.gensupp import uniquemodulename
from pypy.translator.backendopt.all import backend_optimizations
from pypy.translator.interactive import Translation
Modified: pypy/branch/rewrite-compilation-logic/pypy/translator/tool/cbuild.py
==============================================================================
--- pypy/dist/pypy/translator/tool/cbuild.py (original)
+++ pypy/branch/rewrite-compilation-logic/pypy/translator/tool/cbuild.py Sat Nov 24 19:00:44 2007
@@ -8,6 +8,7 @@
from pypy.tool.ansi_print import ansi_log
log = py.log.Producer("cbuild")
py.log.setconsumer("cbuild", ansi_log)
+from pypy.tool.udir import udir
debug = 0
@@ -16,6 +17,8 @@
_ATTRIBUTES = ['pre_include_lines', 'includes', 'include_dirs',
'post_include_lines', 'libraries', 'library_dirs',
'separate_module_sources', 'separate_module_files']
+ _AVOID_DUPLICATES = ['separate_module_files', 'libraries', 'includes',
+ 'include_dirs', 'library_dirs']
def __init__(self,
pre_include_lines = [],
@@ -60,6 +63,54 @@
# XXX custom hash and eq functions, they should be compared
# by contents
+ def merge(self, *others):
+ others = list(others)
+ attrs = {}
+ for name in self._ATTRIBUTES:
+ if name not in self._AVOID_DUPLICATES:
+ s = []
+ for i in [self] + others:
+ s += getattr(i, name)
+ attrs[name] = s
+ else:
+ s = set()
+ attr = []
+ for one in [self] + others:
+ for elem in getattr(one, name):
+ if elem not in s:
+ s.add(elem)
+ attr.append(elem)
+ attrs[name] = attr
+ return ExternalCompilationInfo(**attrs)
+
+ def write_c_header(self, fileobj):
+ for line in self.pre_include_lines:
+ print >> fileobj, line
+ for path in self.includes:
+ print >> fileobj, '#include <%s>' % (path,)
+ for line in self.post_include_lines:
+ print >> fileobj, line
+
+ def convert_sources_to_files(self, cache_dir=None):
+ if cache_dir is None:
+ cache_dir = udir.join('module_cache').ensure(dir=1)
+ num = 0
+ files = []
+ for source in self.separate_module_sources:
+ while 1:
+ filename = cache_dir.join('module_%d.c' % num)
+ num += 1
+ if not filename.check():
+ break
+ filename.write(source)
+ files.append(str(filename))
+ d = {}
+ for attr in self._ATTRIBUTES:
+ d[attr] = getattr(self, attr)
+ d['separate_module_sources'] = ()
+ d['separate_module_files'] += tuple(files)
+ return ExternalCompilationInfo(**d)
+
if sys.platform == 'win32':
so_ext = '.dll'
else:
@@ -94,17 +145,24 @@
opt += '/Op'
gcv['OPT'] = opt
-def compile_c_module(cfiles, modname, include_dirs=[], libraries=[],
- library_dirs=[]):
+def compile_c_module(cfiles, modname, eci):
#try:
# from distutils.log import set_threshold
# set_threshold(10000)
#except ImportError:
# print "ERROR IMPORTING"
# pass
- include_dirs = list(include_dirs)
+ cfiles = [py.path.local(f) for f in cfiles]
+ tmpdir = udir.join("modcache").ensure(dir=1)
+ num = 0
+ for source in eci.separate_module_sources:
+ c_file = tmpdir.join('mod_%d.c' % num)
+ c_file.write(source)
+ cfiles.append(c_file)
+ cfiles += eci.separate_module_files
+ include_dirs = list(eci.include_dirs)
include_dirs.append(py.path.local(pypydir).join('translator', 'c'))
- library_dirs = list(library_dirs)
+ library_dirs = list(eci.library_dirs)
if sys.platform == 'darwin': # support Fink & Darwinports
for s in ('/sw/', '/opt/local/'):
if s + 'include' not in include_dirs and \
@@ -114,8 +172,9 @@
os.path.exists(s + 'lib'):
library_dirs.append(s + 'lib')
- dirpath = cfiles[0].dirpath()
+ dirpath = py.path.local(modname).dirpath()
lastdir = dirpath.chdir()
+ libraries = eci.libraries
ensure_correct_math()
try:
if debug: print "modname", modname
@@ -195,9 +254,9 @@
raise
finally:
lastdir.chdir()
+ return modname + so_ext
-def cache_c_module(cfiles, modname, cache_dir=None,
- include_dirs=[], libraries=[]):
+def cache_c_module(cfiles, modname, eci, cache_dir=None):
""" Same as build c module, but instead caches results.
XXX currently there is no way to force a recompile, so this is pretty
useless as soon as the sources (or headers they depend on) change :-/
@@ -210,14 +269,12 @@
cache_dir = py.path.local(cache_dir)
assert cache_dir.check(dir=1) # XXX
modname = str(cache_dir.join(modname))
- compile_c_module(cfiles, modname, include_dirs=include_dirs,
- libraries=libraries)
- return modname + so_ext
+ return compile_c_module(cfiles, modname, eci)
-def make_module_from_c(cfile, include_dirs=None, libraries=[]):
+def make_module_from_c(cfile, eci):
cfile = py.path.local(cfile)
modname = cfile.purebasename
- compile_c_module([cfile], modname, include_dirs, libraries)
+ compile_c_module([cfile], modname, eci)
return import_module_from_directory(cfile.dirpath(), modname)
def import_module_from_directory(dir, modname):
@@ -267,16 +324,15 @@
class CCompiler:
- def __init__(self, cfilenames, outputfilename=None, include_dirs=[],
- libraries=[], library_dirs=[], compiler_exe=None,
- profbased=None):
+ def __init__(self, cfilenames, eci, outputfilename=None,
+ compiler_exe=None, profbased=None):
self.cfilenames = cfilenames
ext = ''
self.compile_extra = []
self.link_extra = []
- self.libraries = list(libraries)
- self.include_dirs = list(include_dirs)
- self.library_dirs = list(library_dirs)
+ self.libraries = list(eci.libraries)
+ self.include_dirs = list(eci.include_dirs)
+ self.library_dirs = list(eci.library_dirs)
self.compiler_exe = compiler_exe
self.profbased = profbased
if not sys.platform in ('win32', 'darwin'): # xxx
Modified: pypy/branch/rewrite-compilation-logic/pypy/translator/tool/test/test_cbuild.py
==============================================================================
--- pypy/dist/pypy/translator/tool/test/test_cbuild.py (original)
+++ pypy/branch/rewrite-compilation-logic/pypy/translator/tool/test/test_cbuild.py Sat Nov 24 19:00:44 2007
@@ -1,7 +1,9 @@
import py, sys
from pypy.tool.udir import udir
-from pypy.translator.tool.cbuild import build_executable, cache_c_module
+from pypy.translator.tool.cbuild import build_executable, cache_c_module,\
+ ExternalCompilationInfo
+from subprocess import Popen, PIPE, STDOUT
def test_simple_executable():
print udir
@@ -14,7 +16,8 @@
return 0;
}
""")
- testexec = build_executable([t])
+ eci = ExternalCompilationInfo()
+ testexec = build_executable([t], eci)
out = py.process.cmdexec(testexec)
assert out.startswith('hello world')
@@ -30,8 +33,81 @@
csourcedir = pypydir.join('translator', 'c', 'src')
include_dirs = [str(csourcedir.dirpath())]
files = [csourcedir.join('thread.c')]
- cache_c_module(files, '_thread', cache_dir=udir, include_dirs=include_dirs,
- libraries=['pthread'])
+ eci = ExternalCompilationInfo(
+ include_dirs=include_dirs,
+ libraries=['pthread']
+ )
+ cache_c_module(files, '_thread', eci, cache_dir=udir)
cdll = ctypes.CDLL(str(udir.join('_thread.so')))
assert hasattr(cdll, 'RPyThreadLockInit')
+
+class TestEci:
+ def setup_class(cls):
+ tmpdir = udir.ensure('testeci', dir=1)
+ c_file = tmpdir.join('module.c')
+ c_file.write(py.code.Source('''
+ int sum(int x, int y)
+ {
+ return x + y;
+ }
+ '''))
+ cls.modfile = c_file
+ cls.tmpdir = tmpdir
+
+ def test_standalone(self):
+ tmpdir = self.tmpdir
+ c_file = tmpdir.join('stand1.c')
+ c_file.write('''
+ #include <math.h>
+ #include <stdio.h>
+
+ int main()
+ {
+ printf("%f\\n", pow(2.0, 2.0));
+ }''')
+ eci = ExternalCompilationInfo(
+ libraries = ['m'],
+ )
+ output = build_executable([c_file], eci)
+ p = Popen(output, stdout=PIPE, stderr=STDOUT)
+ p.wait()
+ assert p.stdout.readline().startswith('4.0')
+
+ def test_merge(self):
+ e1 = ExternalCompilationInfo(
+ pre_include_lines = ['1'],
+ includes = ['x.h'],
+ post_include_lines = ['p1']
+ )
+ e2 = ExternalCompilationInfo(
+ pre_include_lines = ['2'],
+ includes = ['x.h', 'y.h'],
+ post_include_lines = ['p2'],
+ )
+ e3 = ExternalCompilationInfo(
+ pre_include_lines = ['3'],
+ includes = ['y.h', 'z.h'],
+ post_include_lines = ['p3']
+ )
+ e = e1.merge(e2, e3)
+ assert e.pre_include_lines == ('1', '2', '3')
+ assert e.includes == ('x.h', 'y.h', 'z.h')
+ assert e.post_include_lines == ('p1', 'p2', 'p3')
+
+ 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))
+
+ def test_compile_c_files_to_ofiles(self):
+ pass
+
More information about the Pypy-commit
mailing list