Embed flag for Cython modules
authorRobert Bradshaw <robertwb@math.washington.edu>
Tue, 21 Apr 2009 08:38:25 +0000 (01:38 -0700)
committerRobert Bradshaw <robertwb@math.washington.edu>
Tue, 21 Apr 2009 08:38:25 +0000 (01:38 -0700)
Cython/Compiler/CmdLine.py
Cython/Compiler/ModuleNode.py
Cython/Compiler/Options.py

index 2c8ed428a3b0f2f0261380ecc389eb981a143d7d..f48cfb58456efe56c846dbf01613a504d1424f36 100644 (file)
@@ -38,6 +38,7 @@ Options:
   -a, --annotate                 Produce a colorized HTML version of the source.
   --line-directives              Produce #line directives pointing to the .pyx source
   --cplus                        Output a c++ rather than c file.
+  --embed                        Embed the Python interpreter in a main() method.
   --directive <name>=<value>[,<name=value,...] Overrides a compiler directive
 """
 
@@ -72,6 +73,7 @@ def parse_command_line(args):
     options = CompilationOptions(default_options)
     sources = []
     while args:
+        print args
         if args[0].startswith("-"):
             option = pop_arg()
             if option in ("-V", "--version"):
@@ -89,6 +91,8 @@ def parse_command_line(args):
                 options.obj_only = 0
             elif option in ("-+", "--cplus"):
                 options.cplus = 1
+            elif option == "--embed":
+                Options.embed = True
             elif option.startswith("-I"):
                 options.include_path.append(get_param(option))
             elif option == "--include-dir":
index 5b45ecc37b6bd1386c1241f60fcf710a58e03bc3..97d5f2180eddaa37c15a6a940efc01efd5eb1ec7 100644 (file)
@@ -275,6 +275,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         self.generate_module_init_func(modules[:-1], env, code)
         code.mark_pos(None)
         self.generate_module_cleanup_func(env, code)
+        if Options.embed:
+            self.generate_main_method(env, code)
         self.generate_filename_table(code)
         self.generate_utility_functions(env, code, h_code)
 
@@ -1734,6 +1736,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         code.putln("Py_INCREF(Py_None); return Py_None;")
         code.putln('}')
 
+    def generate_main_method(self, env, code):
+        code.globalstate.use_utility_code(main_method.specialize(module_name=env.module_name))
+
     def generate_filename_init_call(self, code):
         code.putln("%s();" % Naming.fileinit_cname)
 
@@ -2442,3 +2447,20 @@ static __Pyx_RefnannyAPIStruct *__Pyx_Refnanny = NULL;
 #define __Pyx_XGIVEREF(r) if((r) == NULL) ; else __Pyx_GIVEREF(r)
 #define __Pyx_XGOTREF(r) if((r) == NULL) ; else __Pyx_GOTREF(r)
 """)
+
+main_method = UtilityCode(
+impl = """
+int main(int argc, char** argv) {
+    int r;
+    Py_Initialize();
+    PySys_SetArgv(argc, argv);
+#if PY_MAJOR_VERSION < 3
+        init%(module_name)s();
+#else
+        PyInit_%(module_name)s(name);
+#endif
+    r = PyErr_Occurred();
+    Py_Finalize();
+    return r;
+}
+""")
\ No newline at end of file
index c397aeaf6078d896573cd86450429f6c3932544b..286b143c7763a71754c00d306cc2d61cbcb0ece5 100644 (file)
@@ -53,6 +53,11 @@ optimize_simple_methods = 1
 # Append the c file and line number to the traceback for exceptions. 
 c_line_in_traceback = 1
 
+# Whether or not to embed the Python interpreter, for use in making a 
+# standalone executable. This will provide a main() method which simply 
+# executes the body of this module. 
+embed = False
+
 
 # Declare pragmas
 option_defaults = {