codegen: Infer error parameter from abstract/virtual method implementations
[vala-gnome.git] / codegen / valaccodecompiler.vala
blob52161b4229a427755e2e0812479407bf0999db5b
1 /* valaccodecompiler.vala
3 * Copyright (C) 2007-2009 Jürg Billeter
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 * Author:
20 * Jürg Billeter <j@bitron.ch>
23 using GLib;
25 /**
26 * Interface to the C compiler.
28 public class Vala.CCodeCompiler {
29 public CCodeCompiler () {
32 static bool package_exists(string package_name, string? pkg_config_command = "pkg-config") {
33 string pc = pkg_config_command + " --exists " + package_name;
34 int exit_status;
36 try {
37 Process.spawn_command_line_sync (pc, null, null, out exit_status);
38 return (0 == exit_status);
39 } catch (SpawnError e) {
40 Report.error (null, e.message);
41 return false;
45 /**
46 * Compile generated C code to object code and optionally link object
47 * files.
49 * @param context a code context
51 public void compile (CodeContext context, string? cc_command, string[] cc_options, string? pkg_config_command = null) {
52 bool use_pkgconfig = false;
54 if (pkg_config_command == null) {
55 pkg_config_command = "pkg-config";
58 string pc = pkg_config_command + " --cflags";
59 if (!context.compile_only) {
60 pc += " --libs";
62 use_pkgconfig = true;
63 pc += " gobject-2.0";
64 foreach (string pkg in context.get_packages ()) {
65 if (package_exists (pkg, pkg_config_command)) {
66 use_pkgconfig = true;
67 pc += " " + pkg;
70 string pkgflags = "";
71 if (use_pkgconfig) {
72 try {
73 int exit_status;
74 Process.spawn_command_line_sync (pc, out pkgflags, null, out exit_status);
75 if (exit_status != 0) {
76 Report.error (null, "pkg-config exited with status %d".printf (exit_status));
77 return;
79 } catch (SpawnError e) {
80 Report.error (null, e.message);
81 return;
85 // TODO compile the C code files in parallel
87 if (cc_command == null) {
88 cc_command = "cc";
90 string cmdline = cc_command;
91 if (context.debug) {
92 cmdline += " -g";
94 if (context.compile_only) {
95 cmdline += " -c";
96 } else if (context.output != null) {
97 string output = context.output;
98 if (context.directory != null && context.directory != "" && !Path.is_absolute (context.output)) {
99 output = "%s%c%s".printf (context.directory, Path.DIR_SEPARATOR, context.output);
101 cmdline += " -o " + Shell.quote (output);
104 /* we're only interested in non-pkg source files */
105 var source_files = context.get_source_files ();
106 foreach (SourceFile file in source_files) {
107 if (file.file_type == SourceFileType.SOURCE) {
108 cmdline += " " + Shell.quote (file.get_csource_filename ());
111 var c_source_files = context.get_c_source_files ();
112 foreach (string file in c_source_files) {
113 cmdline += " " + Shell.quote (file);
116 // add libraries after source files to fix linking
117 // with --as-needed and on Windows
118 cmdline += " " + pkgflags.strip ();
119 foreach (string cc_option in cc_options) {
120 cmdline += " " + Shell.quote (cc_option);
123 if (context.verbose_mode) {
124 stdout.printf ("%s\n", cmdline);
127 try {
128 int exit_status;
129 Process.spawn_command_line_sync (cmdline, null, null, out exit_status);
130 if (exit_status != 0) {
131 Report.error (null, "cc exited with status %d".printf (exit_status));
133 } catch (SpawnError e) {
134 Report.error (null, e.message);
137 /* remove generated C source and header files */
138 foreach (SourceFile file in source_files) {
139 if (file.file_type == SourceFileType.SOURCE) {
140 if (!context.save_csources) {
141 FileUtils.unlink (file.get_csource_filename ());