Commit 49f7556c authored by Jürg Billeter's avatar Jürg Billeter Committed by Jürg Billeter

enhance commandline interface, add support for invoking c compiler update

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
parent 316765b7
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
......
/* 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 ();
}
......
......@@ -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 \
......
/* 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));
}
}
}
......@@ -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.
*
......
......@@ -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")]
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment