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
, string? pkg_config_command
= "pkg-config") {
33 string pc
= pkg_config_command
+ " --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
, 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
) {
64 foreach (string pkg
in context
.get_packages ()) {
65 if (package_exists (pkg
, pkg_config_command
)) {
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
));
79 } catch (SpawnError e
) {
80 Report
.error (null, e
.message
);
85 // TODO compile the C code files in parallel
87 if (cc_command
== null) {
90 string cmdline
= cc_command
;
94 if (context
.compile_only
) {
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
);
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 ());