Line data Source code
1 : /* valaccodecompiler.vala
2 : *
3 : * Copyright (C) 2007-2009 Jürg Billeter
4 : *
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.
9 :
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.
14 :
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
18 : *
19 : * Author:
20 : * Jürg Billeter <j@bitron.ch>
21 : */
22 :
23 : using GLib;
24 :
25 : /**
26 : * Interface to the C compiler.
27 : */
28 2496 : public class Vala.CCodeCompiler {
29 1664 : public CCodeCompiler () {
30 : }
31 :
32 : /**
33 : * Compile generated C code to object code and optionally link object
34 : * files.
35 : *
36 : * @param context a code context
37 : */
38 1664 : public void compile (CodeContext context, string? cc_command, string[] cc_options) {
39 832 : string pc = "";
40 832 : if (context.profile == Profile.GOBJECT) {
41 824 : pc += " gobject-2.0";
42 : }
43 3334 : foreach (string pkg in context.get_packages ()) {
44 2502 : if (context.pkg_config_exists (pkg)) {
45 2476 : pc += " " + pkg;
46 : }
47 : }
48 : string? pkgflags;
49 832 : if (pc.length > 0) {
50 824 : pkgflags = context.pkg_config_compile_flags (pc);
51 824 : if (pkgflags == null) {
52 0 : return;
53 : }
54 : } else {
55 8 : pkgflags = "";
56 : }
57 :
58 : // TODO compile the C code files in parallel
59 :
60 832 : if (cc_command == null) {
61 0 : cc_command = "cc";
62 : }
63 832 : string cmdline = cc_command;
64 832 : if (context.debug) {
65 0 : cmdline += " -g";
66 : }
67 832 : if (context.compile_only) {
68 0 : cmdline += " -c";
69 832 : } else if (context.output != null) {
70 832 : string output = context.output;
71 832 : if (context.directory != null && context.directory != "" && !Path.is_absolute (context.output)) {
72 832 : output = "%s%c%s".printf (context.directory, Path.DIR_SEPARATOR, context.output);
73 : }
74 832 : cmdline += " -o " + Shell.quote (output);
75 : }
76 :
77 : /* we're only interested in non-pkg source files */
78 1664 : var source_files = context.get_source_files ();
79 7500 : foreach (SourceFile file in source_files) {
80 3334 : if (file.file_type == SourceFileType.SOURCE) {
81 832 : cmdline += " " + Shell.quote (file.get_csource_filename ());
82 : }
83 : }
84 1664 : var c_source_files = context.get_c_source_files ();
85 832 : foreach (string file in c_source_files) {
86 0 : cmdline += " " + Shell.quote (file);
87 : }
88 :
89 : // add libraries after source files to fix linking
90 : // with --as-needed and on Windows
91 832 : cmdline += " " + pkgflags.strip ();
92 79872 : foreach (string cc_option in cc_options) {
93 39104 : cmdline += " " + Shell.quote (cc_option);
94 : }
95 :
96 832 : if (context.verbose_mode) {
97 0 : print ("%s\n", cmdline);
98 : }
99 :
100 832 : try {
101 : int exit_status;
102 832 : Process.spawn_command_line_sync (cmdline, null, null, out exit_status);
103 832 : if (exit_status != 0) {
104 0 : Report.error (null, "cc exited with status %d", exit_status);
105 : }
106 : } catch (SpawnError e) {
107 0 : Report.error (null, e.message);
108 : }
109 :
110 : /* remove generated C source and header files */
111 832 : if (!context.save_csources) {
112 0 : foreach (SourceFile file in source_files) {
113 0 : if (file.file_type == SourceFileType.SOURCE) {
114 0 : FileUtils.unlink (file.get_csource_filename ());
115 : }
116 : }
117 : }
118 : }
119 : }
|