Commits

ariovistus committed 22eb183

added some compile flags

unittest, property, string_imports

Comments (0)

Files changed (16)

 ^examples/testdll/build/
 ^examples/pyind/pyind
 ^examples/pyind/pyind3
+^examples/pyind/build/
+^examples/pyd_unittests/build/
         self.with_main = True
         self.build_deimos = False
         self.optimize = False
-        self.versionFlagsFromExt = []
-        self.debugFlagsFromExt = []
+        self.version_flags_from_ext = []
+        self.debug_flags_from_ext = []
+        self.string_imports_from_ext = []
         # Get DMD/GDC specific info
         self._initialize()
         # _binpath
         # It is intended that this method be implemented by subclasses.
         raise NotImplementedError( "Cannot initialize DCompiler, use DMDDCompiler or GDCDCompiler instead.")
 
+    def init_d_opts(self, cmd, ext):
+            self.optimize = cmd.optimize or ext.pyd_optimize
+            self.with_pyd = ext.with_pyd
+            self.with_main = ext.with_main
+            self.build_deimos = ext.build_deimos
+            self.proj_name = ext.name
+            self.version_flags_from_ext = ext.version_flags
+            self.debug_flags_from_ext = ext.debug_flags
+            self.string_imports_from_ext = ext.string_imports
+            self.unittest_from_ext = ext.d_unittest
+            self.property_from_ext = ext.d_property
+
+
     def _def_file(self, output_dir, output_filename):
         """A list of options used to tell the linker how to make a dll/so. In
         DMD, it is the .def file. In GDC, it is
             os.makedirs(output_dir)
 
         binpath = _qp(self._binpath)
-        compileOpts = self._compileOpts
+        if self.build_exe:
+            compileOpts = self._exeCompileOpts
+        else:
+            compileOpts = self._compileOpts
         outputOpts = self._outputOpts
 
         includePathOpts = []
                 )
             sources.append((winpath(boilerplatePath,self.winonly), 'infra'))
 
+        for imp in self.string_imports_from_ext:
+            if not (os.path.isfile(imp) or os.path.isdir(imp)):
+                raise DistutilsFileError('String import file "%s" does not exist' %
+                        imp)
+
         userVersionAndDebugOpts = (
-              [self._versionOpt % v for v in self.versionFlagsFromExt] +
-              [self._debugOpt   % v for v in self.debugFlagsFromExt]
+              [self._versionOpt % v for v in self.version_flags_from_ext] +
+              [self._debugOpt   % v for v in self.debug_flags_from_ext]
         )
 
         # Optimization opts
                 os.makedirs(os.path.dirname(objName))
             objFiles.append(winpath(objName,self.winonly))
             outOpts[-1] = outOpts[-1] % _qp(winpath(objName,self.winonly))
+            unittestOpt = []
+            if self.unittest_from_ext:
+                unittestOpt.append(self._unittestOpt)
+            if self.property_from_ext:
+                unittestOpt.append(self._propertyOpt)
+            if self.string_imports_from_ext:
+                imps = set()
+                for imp in self.string_imports_from_ext:
+                    if os.path.isfile(imp):
+                        imps.add(os.path.dirname(os.path.abspath(imp)))
+                    else:
+                        imps.add(os.path.abspath(imp))
+                unittestOpt.extend([self._stringImportOpt % (imp,) 
+                    for imp in imps])
+
             cmdElements = (
-                [binpath] + extra_preargs + compileOpts +
+                [binpath] + extra_preargs + unittestOpt + compileOpts +
                 pythonVersionOpts + optimizationOpts +
                 includePathOpts + outOpts + userVersionAndDebugOpts +
                 [_qp(source)] + extra_postargs
 
         if self.build_exe:
             sharedOpts = []
+            linkOpts = self._exeLinkOpts
             pythonLibOpt = []
             if target_desc != cc.CCompiler.EXECUTABLE:
                 raise LinkError('This CCompiler implementation should be building'
                 raise LinkError('This CCompiler implementation should be building '
                     ' a shared object'
                 )
+            linkOpts = self._linkOpts
         # The python .lib file, if needed
         pythonLibOpt = self._lib_file(libraries)
         if pythonLibOpt:
             optimizationOpts = self._defaultOptimizeOpts
 
         cmdElements = (
-            [binpath] + extra_preargs + self._linkOpts + optimizationOpts +
+            [binpath] + extra_preargs + linkOpts + optimizationOpts +
             outputOpts + [pythonLibOpt] + objectOpts + libOpts + sharedOpts +
             extra_postargs
         )
     def _initialize(self):
         self.winonly = True
         # _compileOpts
-        self._compileOpts = ['-c']
+        self._exeCompileOpts = self._compileOpts = ['-c']
         # _outputOpts
         self._outputOpts = ['-of%s']
         # _linkOpts
-        self._linkOpts = []
+        self._exeLinkOpts = self._linkOpts = []
         # _includeOpts
         self._includeOpts = ['-I%s']
         # _versionOpt
         self._debugOpt = '-debug=%s'
         # _defaultOptimizeOpts
         self._defaultOptimizeOpts = ['-debug']
+        # _stringImportOpt
+        self._stringImportOpt = '-J%s'
+        # _propertyOpt
+        self._propertyOpt = '-property'
+        # _unittestOpt
+        self._unittestOpt = '-unittest'
         # _debugOptimizeOpts
-        self._debugOptimizeOpts = self._defaultOptimizeOpts + ['-unittest', '-g']
+        self._debugOptimizeOpts = self._defaultOptimizeOpts + [self._unittestOpt, '-g']
         # _releaseOptimizeOpts
         self._releaseOptimizeOpts = ['-version=Optimized', '-release', '-O', '-inline']
-        # StackThreads support
-        self._st_support = True
 
     #def link_opts(self, 
 
     _env_var = 'GDC_BIN'
 
     def _initialize(self):
+        self._exeCompileOpts = ['-c']
         # _compileOpts
         self._compileOpts = ['-fPIC', '-c']
         # _outputOpts
         self._outputOpts = ['-o', '%s']
+        self._exeLinkOpts = []
         # _linkOpts
         self._linkOpts = ['-fPIC', '-nostartfiles', '-shared']
         # _includeOpts
         self._debugOpt = '-fdebug=%s'
         # _defaultOptimizeOpts
         self._defaultOptimizeOpts = ['-fdebug']
+        # _stringImportOpt
+        self._stringImportOpt = '-J%s' 
+        # _propertyOpt
+        self._propertyOpt = '-fproperty' 
+        # _unittestOpt
+        self._unittestOpt = '-funittest'
         # _debugOptimizeOpts
-        self._debugOptimizeOpts = self._defaultOptimizeOpts + ['-g', '-funittest']
+        self._debugOptimizeOpts = self._defaultOptimizeOpts + ['-g', self._unittestOpt]
         # _releaseOptimizeOpts
         self._releaseOptimizeOpts = ['-fversion=Optimized', '-frelease', '-O3', '-finline-functions']
-        # StackThreads support
-        self._st_support = False
 
     def _def_file(self, output_dir, output_filename):
         return ['-Wl,-soname,' + os.path.basename(output_filename)]
     _env_var = 'LDC_BIN'
 
     def _initialize(self):
+        self._exeCompileOpts = ['-c']
         # _compileOpts
         self._compileOpts = ['-relocation-model=pic', '-c']
         # _outputOpts
         self._outputOpts = ['-of', '%s']
         self._linkOutputOpts = ['-o', '%s']
+        self._exeLinkOpts = []
         # _linkOpts
         self._linkOpts = ['-nostartfiles', '-shared','-Wl,--no-as-needed','-lphobos-ldc','-ldruntime-ldc', '-lrt','-lpthread','-ldl','-lm']
         # _includeOpts
         self._debugOpt = '-d-debug=%s'
         # _defaultOptimizeOpts
         self._defaultOptimizeOpts = ['-d-debug']
+        # _stringImportOpt
+        self._stringImportOpt = '-J=%s'
+        # _propertyOpt
+        self._propertyOpt = '-property'
+        # _unittestOpt
+        self._unittestOpt = '-unittest'
         # _debugOptimizeOpts
-        self._debugOptimizeOpts = self._defaultOptimizeOpts + ['-g', '-unittest']
+        self._debugOptimizeOpts = self._defaultOptimizeOpts + ['-g', self._unittestOpt]
         # _releaseOptimizeOpts
         self._releaseOptimizeOpts = ['-fversion=Optimized', '-release', '-O3', '-finline-functions']
-        # StackThreads support
-        self._st_support = False
 
     def _def_file(self, output_dir, output_filename):
         return ['-Wl,-soname,' + os.path.basename(output_filename)]

examples/arraytest/arraytest.d

     for (int i=0; i<5; ++i) {
         global_array[i] = new Foo(i);
     }
-    def!(get);
-    def!(set);
-    def!(test);
+    def!(get)();
+    def!(set)();
+    def!(test)();
     module_init();
     wrap_class!(
         Foo,

examples/hello/hello.d

 }
 
 extern(C) void PydMain() {
-    def!(hello);
+    def!(hello)();
     module_init();
 }

examples/inherit/inherit.d

 }
 
 extern(C) void PydMain() {
-    def!(call_poly);
-    def!(return_poly_base);
-    def!(return_poly_derived);
+    def!(call_poly)();
+    def!(return_poly_base)();
+    def!(return_poly_derived)();
 
     module_init();
 

examples/pyd_unittests/func_wrap.d

     assert(!supportsNArgs!(Foo5.__ctor)(5));
 }
 
+import std.stdio;
+enum string msg = import("important_message.txt");
 
-void main() {}
+void main() {
+    writeln(msg);
+}

examples/pyd_unittests/func_wrap3.d

 
 }
 
+import std.stdio;
+enum string msg = import("important_message.txt");
 
-void main() {}
+void main() {
+    writeln(msg);
+}

examples/pyd_unittests/important_message.txt

+My hovercraft is full of eels!

examples/pyd_unittests/setup.py

+# usage: python setup.py pydexe
+import sys
+if sys.argv[1] != 'pydexe':
+    print( "use pydexe, not %s" % sys.argv[1] )
+    sys.exit(1)
+from celerid.support import setup, Extension
+import platform
+maj = platform.python_version_tuple()[0] 
+
+projName = 'pyd_unittests'
+exts = [
+'pydobject','make_object','embedded','func_wrap','class_wrap','def','struct_wrap'
+        ];
+string_imports = {
+        'func_wrap': ["important_message.txt"]
+        }
+def ext(e):
+    if maj == "3":
+        return "%s3" % e
+    elif maj == "2":
+        return e
+    else:
+        assert False, "want python 2 or python 3"
+
+ext_modules = setup(
+    name=projName,
+    version='1.0',
+    ext_modules=[
+        Extension(ext(e), [ext(e)+".d"],
+            d_unittest=True,
+            string_imports = string_imports.get(e, [])
+            )
+            for e in exts 
+    ],
+)

examples/pyd_unittests/struct_wrap3.d

+import pyd.pyd, pyd.embedded;
+
+struct Foo1{
+    int i;
+    int j;
+    int k;
+
+    this(int _i, int _j, int _k) {
+        i=_i; j=_j; k=_k;
+    }
+
+    int bar() {
+        return i+j*k;
+    }
+}
+
+static this() {
+    on_py_init({
+    add_module!(ModuleName!"testing")();
+    });
+    on_py_init({
+    wrap_struct!(
+            Foo1,
+            ModuleName!"testing",
+            Init!(int,int,int),
+            Member!("i"),
+            Member!("j"),
+            Member!("k"),
+            Def!(Foo1.bar),
+            )();
+    }, PyInitOrdering.After);
+
+    py_init();
+}
+
+
+unittest {
+    py_stmts(q"{
+foo1 = Foo1(2,3,4);
+assert foo1.i == 2
+            }","testing");
+}
+
+void main(){}

examples/pyind/setup.py

 # usage: python setup.py pydexe
+import sys
+if sys.argv[1] != 'pydexe':
+    print( "use pydexe, not %s" % sys.argv[1] )
+    sys.exit(1)
 from celerid.support import setup, Extension
 import platform
 

examples/rawexample/rawexample.d

 extern(C)
 PyObject* Base_foo(PyObject* self, PyObject* args) {
     writefln("Base.foo");
-    return Py_INCREF(Py_None);
+    return Py_INCREF(Py_None());
 }
 
 extern(C)
 PyObject* Base_bar(PyObject* self, PyObject* args) {
     writefln("Base.bar");
-    return Py_INCREF(Py_None);
+    return Py_INCREF(Py_None());
 }
 
 PyMethodDef[] Base_methods = [
 extern(C)
 PyObject* Derived_bar(PyObject* self, PyObject* args) {
     writefln("Derived.bar");
-    return Py_INCREF(Py_None);
+    return Py_INCREF(Py_None());
 }
 
 PyMethodDef[] Derived_methods = [
 extern(C)
 PyObject* hello(PyObject* self, PyObject* args) {
     writefln("Hello, world!");
-    return Py_INCREF(Py_None);
+    return Py_INCREF(Py_None());
 }
 
 PyMethodDef[] rawexample_methods = [

examples/testdll/testdll.d

         }
         return result;
     }
-    int i() { return m_i; }
-    void i(int j) { m_i = j; }
+    @property int i() { return m_i; }
+    @property void i(int j) { m_i = j; }
     void a() {}
     void b() {}
     void c() {}
     ex_d_to_python(delegate int(A a) { return a.i; });
     ex_python_to_d(delegate A(int i) { A a; a.i = i; return a; });
 
-    def!(foo);
+    def!(foo)();
     // Python does not support function overloading. This requires us to wrap
     // an overloading function under a different name. Note that if the
     // overloaded function is not the lexically first, the type of the function
     // must be specified
-    def!(foo, PyName!"foo2", void function(int));
+    def!(foo, PyName!"foo2", void function(int))();
     pragma(msg, bar.mangleof);
-    def!(bar);
+    def!(bar)();
     // Default argument support - Now implicit!
-    def!(baz);
-    def!(spam);
-    def!(func_test);
-    def!(dg_test);
-    def!(throws);
-    def!(conv1);
-    def!(conv2);
+    def!(baz)();
+    def!(spam)();
+    def!(func_test)();
+    def!(dg_test)();
+    def!(throws)();
+    def!(conv1)();
+    def!(conv2)();
 
     module_init();
     wrap_class!(

patch_distutils.py

 def new_build_ext(self, ext):
     if isinstance(self.compiler, dcompiler.DCompiler):
         build = self.distribution.get_command_obj('build')
-        self.compiler.optimize = build.optimize or ext.pyd_optimize
-        self.compiler.with_pyd = ext.with_pyd
-        self.compiler.with_main = ext.with_main
-        self.compiler.build_deimos = ext.build_deimos
-        self.compiler.proj_name = ext.name
-        self.versionFlagsFromExt = ext.version_flags
-        self.debugFlagsFromExt = ext.debug_flags
+        self.compiler.init_d_opts(build, ext)
     _old_build_ext(self,ext)
 build_ext.build_ext.build_extension = new_build_ext
+import sys
+import os, os.path
+import subprocess
+from distutils.sysconfig import get_config_var
+here = os.getcwd()
+exe_ext = get_config_var("EXE")
+
+def check_exe(cmd):
+    subprocess.check_call([cmd + exe_ext])
+os.chdir("examples")
+os.chdir("hello")
+subprocess.check_call([sys.executable, "setup.py", "build"])
+subprocess.check_call([sys.executable, "test.py"])
+os.chdir("..")
+os.chdir("arraytest")
+subprocess.check_call([sys.executable, "setup.py", "build"])
+subprocess.check_call([sys.executable, "test.py"])
+os.chdir("..")
+os.chdir("inherit")
+subprocess.check_call([sys.executable, "setup.py", "build"])
+subprocess.check_call([sys.executable, "test.py"])
+os.chdir("..")
+os.chdir("rawexample")
+subprocess.check_call([sys.executable, "setup.py", "build"])
+subprocess.check_call([sys.executable, "test.py"])
+os.chdir("..")
+os.chdir("testdll")
+subprocess.check_call([sys.executable, "setup.py", "build"])
+subprocess.check_call([sys.executable, "test.py"])
+os.chdir("..")
+os.chdir("pyind")
+subprocess.check_call([sys.executable, "setup.py", "pydexe"])
+subprocess.check_call(["pyind" + exe_ext])
+os.chdir("..")
+os.chdir("pyd_unittests")
+subprocess.check_call([sys.executable, "setup.py", "pydexe"])
+check_exe("class_wrap")
+check_exe("def")
+check_exe("embedded")
+check_exe("func_wrap")
+check_exe("make_object")
+check_exe("pydobject")
+check_exe("struct_wrap")
+
         self.build_deimos = kwargs.pop('build_deimos', False)
         self.with_main = kwargs.pop('with_main', True)
         self.pyd_optimize = kwargs.pop('optimize', False)
+        self.d_unittest = kwargs.pop('d_unittest', False)
+        self.d_property = kwargs.pop('d_property', True)
+        self.string_imports = kwargs.pop('string_imports', [])
         if self.with_main and not self.with_pyd:
             # The special PydMain function should only be used when using Pyd
             self.with_main = False
             for ext in self.extensions:
                 self.per_ext(ext)
     def per_ext(self, ext):
-            self.compiler.optimize = self.optimize or ext.pyd_optimize
-            self.compiler.with_pyd = ext.with_pyd
-            self.compiler.with_main = ext.with_main
-            self.compiler.build_deimos = ext.build_deimos
-            self.compiler.proj_name = ext.name
-            self.versionFlagsFromExt = ext.version_flags
-            self.debugFlagsFromExt = ext.debug_flags
+            self.compiler.init_d_opts(self, ext)
             # mostly copied from distutils.command.build_ext
             sources = ext.sources
             if sources is None or type(sources) not in (list, tuple):