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
20 * Jürg Billeter <j@bitron.ch>
26 * Interface to the C compiler.
28 public class Vala
.CCodeCompiler
{
29 public CCodeCompiler () {
32 static bool package_exists(string package_name
) {
33 string pc
= "pkg-config --exists " + package_name
;
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
);
46 * Compile generated C code to object code and optionally link object
49 * @param context a code context
51 public void compile (CodeContext context
, string? cc_command
, string[] cc_options
) {
52 bool use_pkgconfig
= false;
54 string pc
= "pkg-config --cflags";
55 if (!context
.compile_only
) {
58 if (context
.profile
== Profile
.GOBJECT
) {
65 foreach (string pkg
in context
.get_packages ()) {
66 if (package_exists (pkg
)) {
75 Process
.spawn_command_line_sync (pc
, out pkgflags
, null, out exit_status
);
76 if (exit_status
!= 0) {
77 Report
.error (null, "pkg-config exited with status %d".printf (exit_status
));
80 } catch (SpawnError e
) {
81 Report
.error (null, e
.message
);
86 // TODO compile the C code files in parallel
88 if (cc_command
== null) {
91 string cmdline
= cc_command
;
95 if (context
.compile_only
) {
97 } else if (context
.output
!= null) {
98 string output
= context
.output
;
99 if (context
.directory
!= null && context
.directory
!= "" && !Path
.is_absolute (context
.output
)) {
100 output
= "%s%c%s".printf (context
.directory
, Path
.DIR_SEPARATOR
, context
.output
);
102 cmdline
+= " -o " + Shell
.quote (output
);
105 /* we're only interested in non-pkg source files */
106 var source_files
= context
.get_source_files ();
107 foreach (SourceFile file
in source_files
) {
108 if (file
.file_type
== SourceFileType
.SOURCE
) {
109 cmdline
+= " " + Shell
.quote (file
.get_csource_filename ());
112 var c_source_files
= context
.get_c_source_files ();
113 foreach (string file
in c_source_files
) {
114 cmdline
+= " " + Shell
.quote (file
);
117 // add libraries after source files to fix linking
118 // with --as-needed and on Windows
119 cmdline
+= " " + pkgflags
.strip ();
120 foreach (string cc_option
in cc_options
) {
121 cmdline
+= " " + Shell
.quote (cc_option
);
124 if (context
.verbose_mode
) {
125 stdout
.printf ("%s\n", cmdline
);
130 Process
.spawn_command_line_sync (cmdline
, null, null, out exit_status
);
131 if (exit_status
!= 0) {
132 Report
.error (null, "cc exited with status %d".printf (exit_status
));
134 } catch (SpawnError e
) {
135 Report
.error (null, e
.message
);
138 /* remove generated C source and header files */
139 foreach (SourceFile file
in source_files
) {
140 if (file
.file_type
== SourceFileType
.SOURCE
) {
141 if (!context
.save_csources
) {
142 FileUtils
.unlink (file
.get_csource_filename ());