]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
enhance commandline interface, add support for invoking c compiler update
authorJürg Billeter <j@bitron.ch>
Fri, 15 Jun 2007 09:47:47 +0000 (09:47 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Fri, 15 Jun 2007 09:47:47 +0000 (09:47 +0000)
2007-06-15  Jürg Billeter  <j@bitron.ch>

* vala/valacodecontext.vala, gobject/valaccodecompiler.vala,
  compiler/valacompiler.vala: enhance commandline interface, add support
  for invoking c compiler
* gobject/Makefile.am: update
* vapi/glib-2.0.vala: add shell-related utilities

svn path=/trunk/; revision=321

ChangeLog
compiler/valacompiler.vala
gobject/Makefile.am
gobject/valaccodecompiler.vala [new file with mode: 0644]
vala/valacodecontext.vala
vapi/glib-2.0.vala

index 6a9940861d0683fc1eb8005ef12cbf7bbdda78e8..fe615ba193b0259eafdd67c420d5cd3bca938cb7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2007-06-15  Jürg Billeter  <j@bitron.ch>
+
+       * vala/valacodecontext.vala, gobject/valaccodecompiler.vala,
+         compiler/valacompiler.vala: enhance commandline interface, add support
+         for invoking c compiler
+       * gobject/Makefile.am: update
+       * vapi/glib-2.0.vala: add shell-related utilities
+
 2007-06-05  Jürg Billeter  <j@bitron.ch>
 
        * gobject/valacodegeneratorassignment.vala: correct invocation of setter
index ac415e52f850fc1709b3f7033795b13a54c3578a..ee3a981f62dd2866540d3e54c7aa77ad2524e455 100644 (file)
@@ -1,6 +1,6 @@
 /* valacompiler.vala
  *
- * Copyright (C) 2006  Jürg Billeter
+ * Copyright (C) 2006-2007  Jürg Billeter
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -34,8 +34,15 @@ class Vala.Compiler {
        static string[] packages;
        static bool disable_memory_management;
 
+       static bool ccode_only;
+       static bool compile_only;
+       static string output;
+       static bool debug;
+       static int optlevel;
+       static bool disable_assert;
+       static bool enable_checking;
+
        private CodeContext context;
-       private List<string> added_packages;
 
        const OptionEntry[] options = {
                { "vapidir", 0, 0, OptionArg.FILENAME_ARRAY, out vapi_directories, "Look for package bindings in DIRECTORY", "DIRECTORY..." },
@@ -44,6 +51,13 @@ class Vala.Compiler {
                { "directory", 'd', 0, OptionArg.FILENAME, out directory, "Output directory", "DIRECTORY" },
                { "version", 0, 0, OptionArg.NONE, ref version, "Display version number", null },
                { "disable-memory-management", 0, 0, OptionArg.NONE, ref disable_memory_management, "Disable memory management", null },
+               { "ccode", 'C', 0, OptionArg.NONE, ref ccode_only, "Output C code", null },
+               { "compile", 'c', 0, OptionArg.NONE, ref compile_only, "Compile but do not link", null },
+               { "output", 'o', 0, OptionArg.FILENAME, out output, "Place output in file FILE", "FILE" },
+               { "debug", 'g', 0, OptionArg.NONE, ref debug, "Produce debug information", null },
+               { "optimize", 'O', 0, OptionArg.INT, ref optlevel, "Optimization level", "OPTLEVEL" },
+               { "disable-assert", 0, 0, OptionArg.NONE, ref disable_assert, "Disable assertions", null },
+               { "enable-checking", 0, 0, OptionArg.NONE, ref enable_checking, "Enable run-time checks", null },
                { "", 0, 0, OptionArg.FILENAME_ARRAY, out sources, null, "FILE..." },
                { null }
        };
@@ -88,8 +102,8 @@ class Vala.Compiler {
                return null;
        }
        
-       private bool add_package (string! pkg) {
-               if (added_packages.find_custom (pkg, strcmp) != null) {
+       private bool add_package (CodeContext! context, string! pkg) {
+               if (context.has_package (pkg)) {
                        // ignore multiple occurences of the same package
                        return true;
                }
@@ -100,7 +114,7 @@ class Vala.Compiler {
                        return false;
                }
                
-               added_packages.append (pkg);
+               context.add_package (pkg);
                
                context.add_source_file (new SourceFile (context, package_path, true));
                
@@ -110,7 +124,7 @@ class Vala.Compiler {
                        File.get_contents (deps_filename, out deps_content, null, null);
                        foreach (string dep in deps_content.split ("\n")) {
                                if (dep != "") {
-                                       if (!add_package (dep)) {
+                                       if (!add_package (context, dep)) {
                                                Report.error (null, "%s, dependency of %s, not found in specified Vala API directories".printf (dep, pkg));
                                        }
                                }
@@ -122,17 +136,31 @@ class Vala.Compiler {
        
        private int run () {
                context = new CodeContext ();
-               
+
+               /* support old command line interface */
+               if (!ccode_only && !compile_only && output == null) {
+                       ccode_only = true;
+               }
+
                context.library = library;
-               
+               context.memory_management = !disable_memory_management;
+               context.assert = !disable_assert;
+               context.checking = enable_checking;
+
+               context.ccode_only = ccode_only;
+               context.compile_only = compile_only;
+               context.output = output;
+               context.debug = debug;
+               context.optlevel = optlevel;
+
                /* default package */
-               if (!add_package ("glib-2.0")) {
+               if (!add_package (context, "glib-2.0")) {
                        Report.error (null, "glib-2.0 not found in specified Vala API directories");
                }
                
                if (packages != null) {
                        foreach (string package in packages) {
-                               if (!add_package (package)) {
+                               if (!add_package (context, package)) {
                                        Report.error (null, "%s not found in specified Vala API directories".printf (package));
                                }
                        }
@@ -213,7 +241,12 @@ class Vala.Compiler {
                        
                        library = null;
                }
-               
+
+               if (!ccode_only) {
+                       var ccompiler = new CCodeCompiler ();
+                       ccompiler.compile (context);
+               }
+
                return quit ();
        }
        
index ff4ea8044063225fe4debf463d478c86438f3523..248aec5d7ae695af4f15b5d5419933ffe96610e6 100644 (file)
@@ -12,6 +12,9 @@ lib_LTLIBRARIES = \
 
 libvala_la_SOURCES = \
        gobject.vala.stamp \
+       valaccodecompiler.c \
+       valaccodecompiler.h \
+       valaccodecompiler.vala \
        valaclassregisterfunction.c \
        valaclassregisterfunction.h \
        valaclassregisterfunction.vala \
@@ -56,6 +59,7 @@ libvala_la_SOURCES = \
 gobjectincludedir = $(includedir)/vala-1.0/gobject
 
 gobjectinclude_HEADERS = \
+       valaccodecompiler.h \
        valaclassregisterfunction.h \
        valacodegenerator.h \
        valacodegeneratorassignment.h \
diff --git a/gobject/valaccodecompiler.vala b/gobject/valaccodecompiler.vala
new file mode 100644 (file)
index 0000000..97703e3
--- /dev/null
@@ -0,0 +1,95 @@
+/* valaccodecompiler.vala
+ *
+ * Copyright (C) 2007  Jürg Billeter
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ *
+ * Author:
+ *     Jürg Billeter <j@bitron.ch>
+ */
+
+using GLib;
+
+/**
+ * Interface to the C compiler.
+ */
+public class Vala.CCodeCompiler {
+       public CCodeCompiler () {
+       }
+
+       /**
+        * Compile generated C code to object code and optionally link object
+        * files.
+        *
+        * @param context a code context
+        */
+       public void compile (CodeContext! context) {
+               string pc = "pkg-config --cflags";
+               if (!context.compile_only) {
+                       pc += " --libs";
+               }
+               foreach (string pkg in context.get_packages ()) {
+                       pc += " " + pkg;
+               }
+               string pkgflags;
+               int exit_status;
+               Error err = null;
+               if (!Process.spawn_command_line_sync (pc, out pkgflags, null, ref exit_status, out err)) {
+                       Report.error (null, err.message);
+                       return;
+               } else if (exit_status != 0) {
+                       Report.error (null, "pkg-config exited with status %d".printf (exit_status));
+                       return;
+               }
+
+               // TODO compile the C code files in parallel
+
+               string cmdline = "cc";
+               if (context.debug) {
+                       cmdline += " -g";
+               }
+               cmdline += " -O%d".printf (context.optlevel);
+               if (context.compile_only) {
+                       cmdline += " -c";
+               } else if (context.output != null) {
+                       cmdline += " -o " + Shell.quote (context.output);
+               }
+               cmdline += " " + pkgflags;
+
+               /* we're only interested in non-pkg source files */
+               var source_files = context.get_source_files ();
+               foreach (SourceFile file in source_files) {
+                       if (!file.pkg) {
+                               cmdline += " " + Shell.quote (file.get_csource_filename ());
+                       }
+               }
+
+               bool success = Process.spawn_command_line_sync (cmdline, null, null, ref exit_status, out err);
+
+               /* remove generated C source and header files */
+               foreach (SourceFile file in source_files) {
+                       if (!file.pkg) {
+                               File.unlink (file.get_csource_filename ());
+                               File.unlink (file.get_cheader_filename ());
+                       }
+               }
+
+               if (!success) {
+                       Report.error (null, err.message);
+               } else if (exit_status != 0) {
+                       Report.error (null, "cc exited with status %d".printf (exit_status));
+               }
+       }
+}
index 40d64d85b6f5bdee5f699342b41e8e2c264e0715..c8abd5ba6d994d3a7560f54fd2e4abc43ce70080 100644 (file)
@@ -34,6 +34,46 @@ public class Vala.CodeContext {
         */
        public string library { get; set; }
 
+       /**
+        * Enable automatic memory management.
+        */
+       public bool memory_management { get; set; }
+
+       /**
+        * Enable run-time checks for programming errors.
+        */
+       public bool assert { get; set; }
+
+       /**
+        * Enable additional run-time checks.
+        */
+       public bool checking { get; set; }
+
+       /**
+        * Output C code, don't compile to object code.
+        */
+       public bool ccode_only { get; set; }
+
+       /**
+        * Compile but do not link.
+        */
+       public bool compile_only { get; set; }
+
+       /**
+        * Output filename.
+        */
+       public string output { get; set; }
+
+       /**
+        * Produce debug information.
+        */
+       public bool debug { get; set; }
+
+       /**
+        * Optimization level.
+        */
+       public int optlevel { get; set; }
+
        /**
         * Specifies the optional module initialization method.
         */
@@ -43,7 +83,9 @@ public class Vala.CodeContext {
        private Symbol! root = new Symbol ();
        
        List<SourceFileCycle> cycles;
-       
+
+       private List<string> packages;
+
        /**
         * Returns the root symbol of the code tree.
         *
@@ -70,7 +112,35 @@ public class Vala.CodeContext {
        public void add_source_file (SourceFile! file) {
                source_files.append (file);
        }
-       
+
+       /**
+        * Returns a copy of the list of used packages.
+        *
+        * @return list of used packages
+        */
+       public List<weak string> get_packages () {
+               return packages.copy ();
+       }
+
+       /**
+        * Returns whether the specified package is being used.
+        *
+        * @param pkg a package name
+        * @return    true if the specified package is being used
+        */
+       public bool has_package (string! pkg) {
+               return packages.find_custom (pkg, strcmp) != null;
+       }
+
+       /**
+        * Adds the specified package to the list of used packages.
+        *
+        * @param pkg a package name
+        */
+       public void add_package (string! pkg) {
+               packages.append (pkg);
+       }
+
        /**
         * Visits the complete code tree file by file.
         *
index 0aaff0b977bd99ea8c768315b820433bf2ba03f6..4e43bb1e5a1f78f889dd0820fa68828680f4ae6c 100644 (file)
@@ -1219,6 +1219,14 @@ namespace GLib {
        [CCode (cname = "stderr", cheader_filename = "stdio.h")]
        public static File stderr;
 
+       /* Shell-related Utilities */
+
+       public struct Shell {
+               public static bool parse_argv (string! command_line, ref int argcp, out string[] argvp, out Error error);
+               public static string! quote (string! unquoted_string);
+               public static string! unquote (string! quoted_string, out Error error);
+       }
+
        /* Commandline option parser */
 
        [ReferenceType (free_function = "g_option_context_free")]