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
52 public void compile (CodeContext context
, string? cc_command
, string[] cc_options
) {
53 bool use_pkgconfig
= false;
55 string pc
= "pkg-config --cflags";
56 if (!context
.compile_only
) {
59 if (context
.profile
== Profile
.GOBJECT
) {
66 foreach (string pkg
in context
.get_packages ()) {
67 if (package_exists (pkg
)) {
76 Process
.spawn_command_line_sync (pc
, out pkgflags
, null, out exit_status
);
77 if (exit_status
!= 0) {
78 Report
.error (null, "pkg-config exited with status %d".printf (exit_status
));
81 } catch (SpawnError e
) {
82 Report
.error (null, e
.message
);
87 // TODO compile the C code files in parallel
89 if (cc_command
== null) {
92 string cmdline
= cc_command
;
96 if (context
.compile_only
) {
98 } else if (context
.output
!= null) {
99 string output
= context
.output
;
100 if (context
.directory
!= null && context
.directory
!= "" && !Path
.is_absolute (context
.output
)) {
101 output
= "%s%c%s".printf (context
.directory
, Path
.DIR_SEPARATOR
, context
.output
);
103 cmdline
+= " -o " + Shell
.quote (output
);
106 /* we're only interested in non-pkg source files */
107 var source_files
= context
.get_source_files ();
108 foreach (SourceFile file
in source_files
) {
109 if (!file
.external_package
) {
110 cmdline
+= " " + Shell
.quote (file
.get_csource_filename ());
113 var c_source_files
= context
.get_c_source_files ();
114 foreach (string file
in c_source_files
) {
115 cmdline
+= " " + Shell
.quote (file
);
118 // add libraries after source files to fix linking
119 // with --as-needed and on Windows
120 cmdline
+= " " + pkgflags
.strip ();
121 foreach (string cc_option
in cc_options
) {
122 cmdline
+= " " + Shell
.quote (cc_option
);
125 if (context
.verbose_mode
) {
126 stdout
.printf ("%s\n", cmdline
);
131 Process
.spawn_command_line_sync (cmdline
, null, null, out exit_status
);
132 if (exit_status
!= 0) {
133 Report
.error (null, "cc exited with status %d".printf (exit_status
));
135 } catch (SpawnError e
) {
136 Report
.error (null, e
.message
);
139 /* remove generated C source and header files */
140 foreach (SourceFile file
in source_files
) {
141 if (!file
.external_package
) {
142 if (!context
.save_csources
) {
143 FileUtils
.unlink (file
.get_csource_filename ());