3 * Copyright (C) 2006-2012 Jürg Billeter
4 * Copyright (C) 1996-2002, 2004, 2005, 2006 Free Software Foundation, Inc.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 * Jürg Billeter <j@bitron.ch>
27 private const string DEFAULT_COLORS
= "error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01";
29 static string basedir
;
30 static string directory
;
32 static bool api_version
;
33 [CCode (array_length
= false, array_null_terminated
= true)]
34 static string[] sources
;
35 [CCode (array_length
= false, array_null_terminated
= true)]
36 static string[] vapi_directories
;
37 [CCode (array_length
= false, array_null_terminated
= true)]
38 static string[] gir_directories
;
39 [CCode (array_length
= false, array_null_terminated
= true)]
40 static string[] metadata_directories
;
41 static string vapi_filename
;
42 static string library
;
43 static string shared_library
;
45 [CCode (array_length
= false, array_null_terminated
= true)]
46 static string[] packages
;
47 [CCode (array_length
= false, array_null_terminated
= true)]
48 static string[] fast_vapis
;
49 static string target_glib
;
50 [CCode (array_length
= false, array_null_terminated
= true)]
51 static string[] gresources
;
52 [CCode (array_length
= false, array_null_terminated
= true)]
53 static string[] gresources_directories
;
55 static bool ccode_only
;
56 static bool abi_stability
;
57 static string header_filename
;
58 static bool use_header
;
59 static string internal_header_filename
;
60 static string internal_vapi_filename
;
61 static string fast_vapi_filename
;
62 static bool vapi_comments
;
63 static string symbols_filename
;
64 static string includedir
;
65 static bool compile_only
;
69 static bool mem_profiler
;
70 static bool disable_assert
;
71 static bool enable_checking
;
72 static bool deprecated
;
73 static bool hide_internal
;
74 static bool experimental
;
75 static bool experimental_non_null
;
76 static bool gobject_tracing
;
77 static bool disable_since_check
;
78 static bool disable_warnings
;
79 static string cc_command
;
80 [CCode (array_length
= false, array_null_terminated
= true)]
81 static string[] cc_options
;
82 static string pkg_config_command
;
83 static string dump_tree
;
84 static bool save_temps
;
85 [CCode (array_length
= false, array_null_terminated
= true)]
86 static string[] defines
;
87 static bool quiet_mode
;
88 static bool verbose_mode
;
89 static string profile
;
91 static bool enable_version_header
;
92 static bool disable_version_header
;
93 static bool fatal_warnings
;
94 static bool disable_colored_output
;
95 static Report
.Colored colored_output
= Report
.Colored
.AUTO
;
96 static string dependencies
;
98 static string entry_point
;
100 static bool run_output
;
101 static string run_args
;
103 private CodeContext context
;
105 const OptionEntry
[] options
= {
106 { "vapidir", 0, 0, OptionArg
.FILENAME_ARRAY
, ref vapi_directories
, "Look for package bindings in DIRECTORY", "DIRECTORY..." },
107 { "girdir", 0, 0, OptionArg
.FILENAME_ARRAY
, ref gir_directories
, "Look for .gir files in DIRECTORY", "DIRECTORY..." },
108 { "metadatadir", 0, 0, OptionArg
.FILENAME_ARRAY
, ref metadata_directories
, "Look for GIR .metadata files in DIRECTORY", "DIRECTORY..." },
109 { "pkg", 0, 0, OptionArg
.STRING_ARRAY
, ref packages
, "Include binding for PACKAGE", "PACKAGE..." },
110 { "vapi", 0, 0, OptionArg
.FILENAME
, ref vapi_filename
, "Output VAPI file name", "FILE" },
111 { "library", 0, 0, OptionArg
.STRING
, ref library
, "Library name", "NAME" },
112 { "shared-library", 0, 0, OptionArg
.STRING
, ref shared_library
, "Shared library name used in generated gir", "NAME" },
113 { "gir", 0, 0, OptionArg
.STRING
, ref gir
, "GObject-Introspection repository file name", "NAME-VERSION.gir" },
114 { "basedir", 'b', 0, OptionArg
.FILENAME
, ref basedir
, "Base source directory", "DIRECTORY" },
115 { "directory", 'd', 0, OptionArg
.FILENAME
, ref directory
, "Change output directory from current working directory", "DIRECTORY" },
116 { "version", 0, 0, OptionArg
.NONE
, ref version
, "Display version number", null },
117 { "api-version", 0, 0, OptionArg
.NONE
, ref api_version
, "Display API version number", null },
118 { "ccode", 'C', 0, OptionArg
.NONE
, ref ccode_only
, "Output C code", null },
119 { "header", 'H', 0, OptionArg
.FILENAME
, ref header_filename
, "Output C header file", "FILE" },
120 { "use-header", 0, 0, OptionArg
.NONE
, ref use_header
, "Use C header file", null },
121 { "includedir", 0, 0, OptionArg
.FILENAME
, ref includedir
, "Directory used to include the C header file", "DIRECTORY" },
122 { "internal-header", 'h', 0, OptionArg
.FILENAME
, ref internal_header_filename
, "Output internal C header file", "FILE" },
123 { "internal-vapi", 0, 0, OptionArg
.FILENAME
, ref internal_vapi_filename
, "Output vapi with internal api", "FILE" },
124 { "fast-vapi", 0, 0, OptionArg
.STRING
, ref fast_vapi_filename
, "Output vapi without performing symbol resolution", null },
125 { "use-fast-vapi", 0, 0, OptionArg
.STRING_ARRAY
, ref fast_vapis
, "Use --fast-vapi output during this compile", null },
126 { "vapi-comments", 0, 0, OptionArg
.NONE
, ref vapi_comments
, "Include comments in generated vapi", null },
127 { "deps", 0, 0, OptionArg
.STRING
, ref dependencies
, "Write make-style dependency information to this file", null },
128 { "symbols", 0, 0, OptionArg
.FILENAME
, ref symbols_filename
, "Output symbols file", "FILE" },
129 { "compile", 'c', 0, OptionArg
.NONE
, ref compile_only
, "Compile but do not link", null },
130 { "output", 'o', 0, OptionArg
.FILENAME
, ref output
, "Place output in file FILE", "FILE" },
131 { "debug", 'g', 0, OptionArg
.NONE
, ref debug
, "Produce debug information", null },
132 { "thread", 0, 0, OptionArg
.NONE
, ref thread
, "Enable multithreading support (DEPRECATED AND IGNORED)", null },
133 { "enable-mem-profiler", 0, 0, OptionArg
.NONE
, ref mem_profiler
, "Enable GLib memory profiler", null },
134 { "define", 'D', 0, OptionArg
.STRING_ARRAY
, ref defines
, "Define SYMBOL", "SYMBOL..." },
135 { "main", 0, 0, OptionArg
.STRING
, ref entry_point
, "Use SYMBOL as entry point", "SYMBOL..." },
136 { "nostdpkg", 0, 0, OptionArg
.NONE
, ref nostdpkg
, "Do not include standard packages", null },
137 { "disable-assert", 0, 0, OptionArg
.NONE
, ref disable_assert
, "Disable assertions", null },
138 { "enable-checking", 0, 0, OptionArg
.NONE
, ref enable_checking
, "Enable additional run-time checks", null },
139 { "enable-deprecated", 0, 0, OptionArg
.NONE
, ref deprecated
, "Enable deprecated features", null },
140 { "hide-internal", 0, 0, OptionArg
.NONE
, ref hide_internal
, "Hide symbols marked as internal", null },
141 { "enable-experimental", 0, 0, OptionArg
.NONE
, ref experimental
, "Enable experimental features", null },
142 { "disable-warnings", 0, 0, OptionArg
.NONE
, ref disable_warnings
, "Disable warnings", null },
143 { "fatal-warnings", 0, 0, OptionArg
.NONE
, ref fatal_warnings
, "Treat warnings as fatal", null },
144 { "disable-since-check", 0, 0, OptionArg
.NONE
, ref disable_since_check
, "Do not check whether used symbols exist in local packages", null },
145 { "enable-experimental-non-null", 0, 0, OptionArg
.NONE
, ref experimental_non_null
, "Enable experimental enhancements for non-null types", null },
146 { "enable-gobject-tracing", 0, 0, OptionArg
.NONE
, ref gobject_tracing
, "Enable GObject creation tracing", null },
147 { "cc", 0, 0, OptionArg
.STRING
, ref cc_command
, "Use COMMAND as C compiler command", "COMMAND" },
148 { "Xcc", 'X', 0, OptionArg
.STRING_ARRAY
, ref cc_options
, "Pass OPTION to the C compiler", "OPTION..." },
149 { "pkg-config", 0, 0, OptionArg
.STRING
, ref pkg_config_command
, "Use COMMAND as pkg-config command", "COMMAND" },
150 { "dump-tree", 0, 0, OptionArg
.FILENAME
, ref dump_tree
, "Write code tree to FILE", "FILE" },
151 { "save-temps", 0, 0, OptionArg
.NONE
, ref save_temps
, "Keep temporary files", null },
152 { "profile", 0, 0, OptionArg
.STRING
, ref profile
, "Use the given profile instead of the default", "PROFILE" },
153 { "quiet", 'q', 0, OptionArg
.NONE
, ref quiet_mode
, "Do not print messages to the console", null },
154 { "verbose", 'v', 0, OptionArg
.NONE
, ref verbose_mode
, "Print additional messages to the console", null },
155 { "no-color", 0, 0, OptionArg
.NONE
, ref disable_colored_output
, "Disable colored output, alias for --color=never", null },
156 { "color", 0, OptionFlags
.OPTIONAL_ARG
, OptionArg
.CALLBACK
, (void*) option_parse_color
, "Enable color output, options are 'always', 'never', or 'auto'", "WHEN" },
157 { "target-glib", 0, 0, OptionArg
.STRING
, ref target_glib
, "Target version of glib for code generation", "MAJOR.MINOR" },
158 { "gresources", 0, 0, OptionArg
.FILENAME_ARRAY
, ref gresources
, "XML of gresources", "FILE..." },
159 { "gresourcesdir", 0, 0, OptionArg
.FILENAME_ARRAY
, ref gresources_directories
, "Look for resources in DIRECTORY", "DIRECTORY..." },
160 { "enable-version-header", 0, 0, OptionArg
.NONE
, ref enable_version_header
, "Write vala build version in generated files", null },
161 { "disable-version-header", 0, 0, OptionArg
.NONE
, ref disable_version_header
, "Do not write vala build version in generated files", null },
162 { "run-args", 0, 0, OptionArg
.STRING
, ref run_args
, "Arguments passed to directly compiled executeable", null },
163 { "abi-stability", 0, 0, OptionArg
.NONE
, ref abi_stability
, "Enable support for ABI stability", null },
164 { OPTION_REMAINING
, 0, 0, OptionArg
.FILENAME_ARRAY
, ref sources
, null, "FILE..." },
168 static bool option_parse_color (string option_name
, string? val
, void* data
) throws OptionError
{
170 case "auto": colored_output
= Report
.Colored
.AUTO
; break;
171 case "never": colored_output
= Report
.Colored
.NEVER
; break;
173 case "always": colored_output
= Report
.Colored
.ALWAYS
; break;
174 default: throw new OptionError
.FAILED ("Invalid --color argument '%s'", val
);
179 private int quit () {
180 if (context
.report
.get_errors () == 0 && context
.report
.get_warnings () == 0) {
183 if (context
.report
.get_errors () == 0 && (!fatal_warnings
|| context
.report
.get_warnings () == 0)) {
185 stdout
.printf ("Compilation succeeded - %d warning(s)\n", context
.report
.get_warnings ());
190 stdout
.printf ("Compilation failed: %d error(s), %d warning(s)\n", context
.report
.get_errors (), context
.report
.get_warnings ());
197 context
= new
CodeContext ();
198 CodeContext
.push (context
);
200 if (disable_colored_output
) {
201 colored_output
= Report
.Colored
.NEVER
;
204 if (colored_output
!= Report
.Colored
.NEVER
) {
205 unowned
string env_colors
= Environment
.get_variable ("VALA_COLORS");
206 if (env_colors
!= null) {
207 context
.report
.set_colors (env_colors
, colored_output
);
209 context
.report
.set_colors (DEFAULT_COLORS
, colored_output
);
214 // default to build executable
215 if (!ccode_only
&& !compile_only
&& output
== null) {
216 // strip extension if there is one
217 // else we use the default output file of the C compiler
218 if (sources
[0].last_index_of_char ('.') != -1) {
219 int dot
= sources
[0].last_index_of_char ('.');
220 output
= Path
.get_basename (sources
[0].substring (0, dot
));
224 context
.assert
= !disable_assert
;
225 context
.checking
= enable_checking
;
226 context
.deprecated
= deprecated
;
227 context
.since_check
= !disable_since_check
;
228 context
.hide_internal
= hide_internal
;
229 context
.experimental
= experimental
;
230 context
.experimental_non_null
= experimental_non_null
;
231 context
.gobject_tracing
= gobject_tracing
;
232 context
.report
.enable_warnings
= !disable_warnings
;
233 context
.report
.set_verbose_errors (!quiet_mode
);
234 context
.verbose_mode
= verbose_mode
;
235 context
.version_header
= !disable_version_header
;
237 context
.ccode_only
= ccode_only
;
238 if (ccode_only
&& cc_options
!= null) {
239 Report
.warning (null, "-X has no effect when -C or --ccode is set");
241 context
.abi_stability
= abi_stability
;
242 context
.compile_only
= compile_only
;
243 context
.header_filename
= header_filename
;
244 if (header_filename
== null && use_header
) {
245 Report
.error (null, "--use-header may only be used in combination with --header");
247 context
.use_header
= use_header
;
248 context
.internal_header_filename
= internal_header_filename
;
249 context
.symbols_filename
= symbols_filename
;
250 context
.includedir
= includedir
;
251 context
.output
= output
;
252 if (output
!= null && ccode_only
) {
253 Report
.warning (null, "--output and -o have no effect when -C or --ccode is set");
255 if (basedir
== null) {
256 context
.basedir
= CodeContext
.realpath (".");
258 context
.basedir
= CodeContext
.realpath (basedir
);
260 if (directory
!= null) {
261 context
.directory
= CodeContext
.realpath (directory
);
263 context
.directory
= context
.basedir
;
265 context
.vapi_directories
= vapi_directories
;
266 context
.vapi_comments
= vapi_comments
;
267 context
.gir_directories
= gir_directories
;
268 context
.metadata_directories
= metadata_directories
;
269 context
.debug
= debug
;
270 context
.mem_profiler
= mem_profiler
;
271 context
.save_temps
= save_temps
;
272 if (ccode_only
&& save_temps
) {
273 Report
.warning (null, "--save-temps has no effect when -C or --ccode is set");
275 if (profile
== "posix") {
276 context
.profile
= Profile
.POSIX
;
277 context
.add_define ("POSIX");
278 } else if (profile
== "gobject-2.0" || profile
== "gobject" || profile
== null) {
280 context
.profile
= Profile
.GOBJECT
;
281 context
.add_define ("GOBJECT");
283 Report
.error (null, "Unknown profile %s".printf (profile
));
285 nostdpkg
|= fast_vapi_filename
!= null;
286 context
.nostdpkg
= nostdpkg
;
288 context
.entry_point_name
= entry_point
;
290 context
.run_output
= run_output
;
292 if (pkg_config_command
== null) {
293 pkg_config_command
= Environment
.get_variable ("PKG_CONFIG") ??
"pkg-config";
295 context
.pkg_config_command
= pkg_config_command
;
297 if (defines
!= null) {
298 foreach (string define
in defines
) {
299 context
.add_define (define
);
303 for (int i
= 2; i
<= 42; i
+= 2) {
304 context
.add_define ("VALA_0_%d".printf (i
));
307 if (context
.profile
== Profile
.POSIX
) {
309 /* default package */
310 context
.add_external_package ("posix");
312 } else if (context
.profile
== Profile
.GOBJECT
) {
315 if (target_glib
!= null && target_glib
.scanf ("%d.%d", out glib_major
, out glib_minor
) != 2) {
316 Report
.error (null, "Invalid format for --target-glib");
319 context
.target_glib_major
= glib_major
;
320 context
.target_glib_minor
= glib_minor
;
321 if (context
.target_glib_major
!= 2) {
322 Report
.error (null, "This version of valac only supports GLib 2");
325 for (int i
= 16; i
<= glib_minor
; i
+= 2) {
326 context
.add_define ("GLIB_2_%d".printf (i
));
330 /* default packages */
331 context
.add_external_package ("glib-2.0");
332 context
.add_external_package ("gobject-2.0");
336 if (packages
!= null) {
337 foreach (string package
in packages
) {
338 context
.add_external_package (package
);
343 if (fast_vapis
!= null) {
344 foreach (string vapi
in fast_vapis
) {
345 var rpath
= CodeContext
.realpath (vapi
);
346 var source_file
= new
SourceFile (context
, SourceFileType
.FAST
, rpath
);
347 context
.add_source_file (source_file
);
349 context
.use_fast_vapi
= true;
352 context
.gresources
= gresources
;
353 context
.gresources_directories
= gresources_directories
;
355 if (context
.report
.get_errors () > 0 || (fatal_warnings
&& context
.report
.get_warnings () > 0)) {
359 if (context
.profile
== Profile
.GOBJECT
) {
360 context
.codegen
= new
GDBusServerModule ();
362 context
.codegen
= new
CCodeDelegateModule ();
365 bool has_c_files
= false;
366 bool has_h_files
= false;
368 foreach (string source
in sources
) {
369 if (context
.add_source_filename (source
, run_output
, true)) {
370 if (source
.has_suffix (".c")) {
372 } else if (source
.has_suffix (".h")) {
378 if (ccode_only
&& (has_c_files
|| has_h_files
)) {
379 Report
.warning (null, "C header and source files are ignored when -C or --ccode is set");
382 if (context
.report
.get_errors () > 0 || (fatal_warnings
&& context
.report
.get_warnings () > 0)) {
386 var parser
= new
Parser ();
387 parser
.parse (context
);
389 var genie_parser
= new Genie
.Parser ();
390 genie_parser
.parse (context
);
392 var gir_parser
= new
GirParser ();
393 gir_parser
.parse (context
);
395 if (context
.report
.get_errors () > 0 || (fatal_warnings
&& context
.report
.get_warnings () > 0)) {
399 if (fast_vapi_filename
!= null) {
400 var interface_writer
= new
CodeWriter (CodeWriterType
.FAST
);
401 interface_writer
.write_file (context
, fast_vapi_filename
);
407 if (context
.report
.get_errors () > 0 || (fatal_warnings
&& context
.report
.get_warnings () > 0)) {
411 if (!ccode_only
&& !compile_only
&& library
== null) {
412 // building program, require entry point
413 if (!has_c_files
&& context
.entry_point
== null) {
414 Report
.error (null, "program does not contain a static `main' method");
418 if (dump_tree
!= null) {
419 var code_writer
= new
CodeWriter (CodeWriterType
.DUMP
);
420 code_writer
.write_file (context
, dump_tree
);
423 if (context
.report
.get_errors () > 0 || (fatal_warnings
&& context
.report
.get_warnings () > 0)) {
427 context
.codegen
.emit (context
);
429 if (context
.report
.get_errors () > 0 || (fatal_warnings
&& context
.report
.get_warnings () > 0)) {
433 if (vapi_filename
== null && library
!= null) {
434 // keep backward compatibility with --library option
435 vapi_filename
= "%s.vapi".printf (library
);
438 if (library
!= null) {
440 if (context
.profile
== Profile
.GOBJECT
) {
441 string gir_base
= Path
.get_basename (gir
);
442 long gir_len
= gir_base
.length
;
443 int last_hyphen
= gir_base
.last_index_of_char ('-');
445 if (last_hyphen
== -1 || !gir_base
.has_suffix (".gir")) {
446 Report
.error (null, "GIR file name `%s' is not well-formed, expected NAME-VERSION.gir".printf (gir
));
448 string gir_namespace
= gir_base
.substring (0, last_hyphen
);
449 string gir_version
= gir_base
.substring (last_hyphen
+ 1, gir_len
- last_hyphen
- 5);
450 gir_version
.canon ("0123456789.", '?');
451 if (gir_namespace
== "" || gir_version
== "" || !gir_version
[0].isdigit () || gir_version
.contains ("?")) {
452 Report
.error (null, "GIR file name `%s' is not well-formed, expected NAME-VERSION.gir".printf (gir
));
454 var gir_writer
= new
GIRWriter ();
456 // put .gir file in current directory unless -d has been explicitly specified
457 string gir_directory
= ".";
458 if (directory
!= null) {
459 gir_directory
= context
.directory
;
462 gir_writer
.write_file (context
, gir_directory
, gir
, gir_namespace
, gir_version
, library
, shared_library
);
473 Report
.warning (null, "--gir has no effect without --library");
478 // The GIRWriter places the gir_namespace and gir_version into the top namespace, so write the vapi after that stage
479 if (vapi_filename
!= null) {
480 var interface_writer
= new
CodeWriter ();
482 // put .vapi file in current directory unless -d has been explicitly specified
483 if (directory
!= null && !Path
.is_absolute (vapi_filename
)) {
484 vapi_filename
= "%s%c%s".printf (context
.directory
, Path
.DIR_SEPARATOR
, vapi_filename
);
487 interface_writer
.write_file (context
, vapi_filename
);
490 if (internal_vapi_filename
!= null) {
491 if (internal_header_filename
== null ||
492 header_filename
== null) {
493 Report
.error (null, "--internal-vapi may only be used in combination with --header and --internal-header");
497 var interface_writer
= new
CodeWriter (CodeWriterType
.INTERNAL
);
499 if (context
.includedir
!= null) {
500 var prefixed_header_filename
= Path
.build_path ("/", context
.includedir
, Path
.get_basename (header_filename
));
501 var prefixed_internal_header_filename
= Path
.build_path ("/", context
.includedir
, Path
.get_basename (internal_header_filename
));
502 interface_writer
.set_cheader_override (prefixed_header_filename
, prefixed_internal_header_filename
);
504 interface_writer
.set_cheader_override (header_filename
, internal_header_filename
);
507 string vapi_filename
= internal_vapi_filename
;
509 // put .vapi file in current directory unless -d has been explicitly specified
510 if (directory
!= null && !Path
.is_absolute (vapi_filename
)) {
511 vapi_filename
= "%s%c%s".printf (context
.directory
, Path
.DIR_SEPARATOR
, vapi_filename
);
514 interface_writer
.write_file (context
, vapi_filename
);
516 internal_vapi_filename
= null;
519 if (dependencies
!= null) {
520 context
.write_dependencies (dependencies
);
523 if (context
.report
.get_errors () > 0 || (fatal_warnings
&& context
.report
.get_warnings () > 0)) {
528 var ccompiler
= new
CCodeCompiler ();
529 if (cc_command
== null && Environment
.get_variable ("CC") != null) {
530 cc_command
= Environment
.get_variable ("CC");
532 if (cc_options
== null) {
533 ccompiler
.compile (context
, cc_command
, new
string[] { });
535 ccompiler
.compile (context
, cc_command
, cc_options
);
542 static int run_source (string[] args
) {
544 var opt_context
= new
OptionContext ("- Vala Interpreter");
545 opt_context
.set_help_enabled (true);
546 opt_context
.add_main_entries (options
, null);
547 opt_context
.parse (ref args
);
548 } catch (OptionError e
) {
549 stdout
.printf ("%s\n", e
.message
);
550 stdout
.printf ("Run '%s --help' to see a full list of available command line options.\n", args
[0]);
555 stdout
.printf ("Vala %s\n", Vala
.BUILD_VERSION
);
557 } else if (api_version
) {
558 stdout
.printf ("%s\n", Vala
.API_VERSION
);
562 if (sources
== null) {
563 stderr
.printf ("No source file specified.\n");
567 output
= "%s/%s.XXXXXX".printf (Environment
.get_tmp_dir (), Path
.get_basename (sources
[0]));
568 int outputfd
= FileUtils
.mkstemp (output
);
574 compile_only
= false;
576 disable_warnings
= true;
579 shared_library
= null;
581 var compiler
= new
Compiler ();
582 int ret
= compiler
.run ();
587 FileUtils
.close (outputfd
);
588 if (FileUtils
.chmod (output
, 0700) != 0) {
589 FileUtils
.unlink (output
);
593 string[] target_args
= { output
};
594 if (run_args
!= null) {
595 string[] target_run_args
= run_args
.split (" ");
596 foreach (string arg
in target_run_args
) {
603 var loop
= new
MainLoop ();
604 int child_status
= 0;
606 Process
.spawn_async (null, target_args
, null, SpawnFlags
.CHILD_INHERITS_STDIN
| SpawnFlags
.DO_NOT_REAP_CHILD
, null, out pid
);
608 FileUtils
.unlink (output
);
609 ChildWatch
.add (pid
, (pid
, status
) => {
610 child_status
= (status
& 0xff00) >> 8;
617 } catch (SpawnError e
) {
618 stdout
.printf ("%s\n", e
.message
);
623 static int main (string[] args
) {
625 Intl
.setlocale (LocaleCategory
.ALL
, "");
627 if (Path
.get_basename (args
[0]) == "vala" || Path
.get_basename (args
[0]) == "vala" + Config
.PACKAGE_SUFFIX
) {
628 return run_source (args
);
632 var opt_context
= new
OptionContext ("- Vala Compiler");
633 opt_context
.set_help_enabled (true);
634 opt_context
.add_main_entries (options
, null);
635 opt_context
.parse (ref args
);
636 } catch (OptionError e
) {
637 stdout
.printf ("%s\n", e
.message
);
638 stdout
.printf ("Run '%s --help' to see a full list of available command line options.\n", args
[0]);
643 stdout
.printf ("Vala %s\n", Vala
.BUILD_VERSION
);
645 } else if (api_version
) {
646 stdout
.printf ("%s\n", Vala
.API_VERSION
);
650 if (sources
== null && fast_vapis
== null) {
651 stderr
.printf ("No source file specified.\n");
655 var compiler
= new
Compiler ();
656 return compiler
.run ();