Commits

wlav committed eb98e4d

fix for Issue1422: there should be no need for $ROOTSYS if root-config is available
fix a test that was broken

  • Participants
  • Parent commits 3f578eb

Comments (0)

Files changed (4)

File pypy/module/cppyy/capi/reflex_capi.py

 srcpath = pkgpath.join("src")
 incpath = pkgpath.join("include")
 
+import commands
+(config_stat, incdir) = commands.getstatusoutput("root-config --incdir")
+
 if os.environ.get("ROOTSYS"):
-    import commands
-    (stat, incdir) = commands.getstatusoutput("root-config --incdir")
-    if stat != 0:        # presumably Reflex-only
+    if config_stat != 0:     # presumably Reflex-only
         rootincpath = [os.path.join(os.environ["ROOTSYS"], "include")]
         rootlibpath = [os.path.join(os.environ["ROOTSYS"], "lib64"), os.path.join(os.environ["ROOTSYS"], "lib")]
     else:
         rootincpath = [incdir]
         rootlibpath = commands.getoutput("root-config --libdir").split()
 else:
-    rootincpath = []
-    rootlibpath = []
+    if config_stat == 0:
+        rootincpath = [incdir]
+        rootlibpath = commands.getoutput("root-config --libdir").split()
+    else:
+        rootincpath = []
+        rootlibpath = []
 
 def identify():
     return 'Reflex'

File pypy/module/cppyy/test/Makefile

 
 ifeq ($(ROOTSYS),)
   genreflex=genreflex
-  cppflags=
+  cppflags=-I$(shell root-config --incdir) -L$(shell root-config --libdir)
 else
   genreflex=$(ROOTSYS)/bin/genreflex
   ifeq ($(wildcard $(ROOTSYS)/include),)     # standard locations used?

File pypy/module/cppyy/test/test_crossing.py

 import py, os, sys
+from pypy.interpreter.gateway import interp2app, unwrap_spec
+from rpython.translator.tool.cbuild import ExternalCompilationInfo
+from rpython.translator import platform
+from rpython.translator.gensupp import uniquemodulename
+from rpython.tool.udir import udir
+
+from pypy.module.cpyext import api
+from pypy.module.cpyext.state import State
+
 from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
 
+
 currpath = py.path.local(__file__).dirpath()
 test_dct = str(currpath.join("crossingDict.so"))
 
     if err:
         raise OSError("'make' failed (see stderr)")
 
+# from pypy/module/cpyext/test/test_cpyext.py; modified to accept more external
+# symbols and called directly instead of import_module
+def compile_extension_module(space, modname, symbols, **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).
+    """
+    state = space.fromcache(State)
+    api_library = state.api_lib
+    if sys.platform == 'win32':
+        kwds["libraries"] = [api_library]
+        # '%s' undefined; assuming extern returning int
+        kwds["compile_extra"] = ["/we4013"]
+    elif sys.platform == 'darwin':
+        kwds["link_files"] = [str(api_library + '.dylib')]
+    else:
+        kwds["link_files"] = [str(api_library + '.so')]
+        if sys.platform.startswith('linux'):
+            kwds["compile_extra"]=["-Werror=implicit-function-declaration"]
+
+    modname = modname.split('.')[-1]
+    eci = ExternalCompilationInfo(
+        export_symbols=['init%s' % (modname,)]+symbols,
+        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)
 
 class AppTestCrossing(AppTestCpythonExtensionBase):
     spaceconfig = dict(usemodules=['cpyext', 'cppyy', 'thread', '_rawffi', '_ffi',
                                    'array', 'itertools', 'rctime', 'binascii'])
 
     def setup_class(cls):
-        # following from AppTestCpythonExtensionBase, with cppyy added
-        cls.space.getbuiltinmodule("cpyext")
-        from pypy.module.imp.importing import importhook
-        importhook(cls.space, "os") # warm up reference counts
-        from pypy.module.cpyext.pyobject import RefcountState
-        state = cls.space.fromcache(RefcountState)
-        state.non_heaptypes_w[:] = []
-
-        # cppyy specific additions (not that the test_dct is loaded late
+        AppTestCpythonExtensionBase.setup_class.im_func(cls)
+        # cppyy specific additions (note that test_dct is loaded late
         # to allow the generated extension module be loaded first)
         cls.w_test_dct    = cls.space.wrap(test_dct)
         cls.w_pre_imports = cls.space.appexec([], """():
             import cppyy, ctypes""")    # prevents leak-checking complaints on ctypes
-        from pypy.module.imp.importing import get_so_extension
-        cls.w_soext = cls.space.wrap(get_so_extension(cls.space))
+
+    def setup_method(self, func):
+        AppTestCpythonExtensionBase.setup_method.im_func(self, func)
+
+        @unwrap_spec(name=str, init=str, body=str)
+        def load_cdll(space, name, init, body, w_symbols):
+            # the following is loosely from test_cpyext.py import_module; it
+            # is copied here to be able to tweak the call to
+            # compile_extension_module and to get a different return result
+            # than in that function
+            code = """
+            #include <Python.h>
+            %(body)s
+
+            void init%(name)s(void) {
+            %(init)s
+            }
+            """ % dict(name=name, init=init, body=body)
+            kwds = dict(separate_module_sources=[code])
+            symbols = [space.str_w(w_item) for w_item in space.fixedview(w_symbols)]
+            mod = compile_extension_module(space, name, symbols, **kwds)
+
+            # explicitly load the module as a CDLL rather than as a module
+            import ctypes
+            from pypy.module.imp.importing import get_so_extension
+            fullmodname = os.path.join(
+                os.path.dirname(mod), name + get_so_extension(space))
+            return ctypes.CDLL(fullmodname, ctypes.RTLD_GLOBAL)
+
+        self.w_load_cdll = self.space.wrap(interp2app(load_cdll))
 
     def test00_base_class(self):
         """Test from cpyext; only here to see whether the imported class works"""
 
         import os, ctypes
 
+        name = 'bar'
+
         init = """
         if (Py_IsInitialized())
             Py_InitModule("bar", methods);
         """
+
         # note: only the symbols are needed for C, none for python
         body = """
         long bar_unwrap(PyObject* arg)
             { NULL }
         };
         """
+        # explicitly load the module as a CDLL rather than as a module
+#        dirname = space.wrap(os.path.dirname(mod))
 
-        dirname = self.import_module(name='bar', init=init, body=body, load_it=False)
-        fullmodname = os.path.join(dirname, 'bar' + self.soext)
-        self.cmodule = ctypes.CDLL(fullmodname, ctypes.RTLD_GLOBAL)
+#        dirname = self.import_module(name='bar', init=init, body=body, load_it=False)
+#        fullmodname = os.path.join(dirname, name + self.soext)
+        self.cmodule = self.load_cdll(name, init, body, ['bar_unwrap', 'bar_wrap'])#ctypes.CDLL(fullmodname, ctypes.RTLD_GLOBAL)
 
     def test02_crossing_dict(self):
         """Test availability of all needed classes in the dict"""

File pypy/module/cppyy/test/test_pythonify.py

 test_dct = str(currpath.join("example01Dict.so"))
 
 def setup_module(mod):
+    # force removal of ROOTSYS for this one test, which serves as a test itself
+    if os.getenv("ROOTSYS"):
+        os.unsetenv("ROOTSYS")
     if sys.platform == 'win32':
         py.test.skip("win32 not supported so far")
     err = os.system("cd '%s' && make example01Dict.so" % currpath)