From: Jürg Billeter Date: Fri, 15 Jun 2007 09:47:47 +0000 (+0000) Subject: enhance commandline interface, add support for invoking c compiler update X-Git-Tag: VALA_0_1_0~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=49f7556c39a2dce8ae54d2c769d9c837f92802ca;p=thirdparty%2Fvala.git enhance commandline interface, add support for invoking c compiler update 2007-06-15 Jürg Billeter * 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 --- diff --git a/ChangeLog b/ChangeLog index 6a9940861..fe615ba19 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2007-06-15 Jürg Billeter + + * 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 * gobject/valacodegeneratorassignment.vala: correct invocation of setter diff --git a/compiler/valacompiler.vala b/compiler/valacompiler.vala index ac415e52f..ee3a981f6 100644 --- a/compiler/valacompiler.vala +++ b/compiler/valacompiler.vala @@ -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 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 (); } diff --git a/gobject/Makefile.am b/gobject/Makefile.am index ff4ea8044..248aec5d7 100644 --- a/gobject/Makefile.am +++ b/gobject/Makefile.am @@ -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 index 000000000..97703e3cd --- /dev/null +++ b/gobject/valaccodecompiler.vala @@ -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 + */ + +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)); + } + } +} diff --git a/vala/valacodecontext.vala b/vala/valacodecontext.vala index 40d64d85b..c8abd5ba6 100644 --- a/vala/valacodecontext.vala +++ b/vala/valacodecontext.vala @@ -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 cycles; - + + private List 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 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. * diff --git a/vapi/glib-2.0.vala b/vapi/glib-2.0.vala index 0aaff0b97..4e43bb1e5 100644 --- a/vapi/glib-2.0.vala +++ b/vapi/glib-2.0.vala @@ -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")]