Created
May 13, 2017 22:20
-
-
Save darkoverlordofdata/2dd3fe13ba077c6303bc73e07b8fdfbb to your computer and use it in GitHub Desktop.
wrap valac for use from script (nodejs)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env vala | |
/** | |
* ValaC2 | |
* | |
* breaks valac into 2 steps with plugin pre/post processing | |
* this front end just collects all of the command line arguments and runs the coffeescript. | |
* | |
* command line flags are mangled to prevent the cli from expanding them. | |
* | |
* | |
* Adds 2 new optiona: | |
* --plugin=FILE | |
* plugin to call with the rest of the input params | |
* --builddir=DIRECTORY | |
* required location for out of tree build | |
* no in tree builds allowed | |
* | |
* use case: emscripten | |
* | |
* possibly over engineered, but it keeps the flags intact. | |
* | |
* using the command line interface described in valacompiler.vala | |
* @see https://github.com/GNOME/vala/blob/master/compiler/valacompiler.vala | |
*/ | |
using GLib; | |
class Valac2 { | |
static string builddir; | |
static string builder; | |
static string basedir; | |
static string directory; | |
static bool version; | |
static bool api_version; | |
[CCode (array_length = false, array_null_terminated = true)] | |
static string[] sources; | |
[CCode (array_length = false, array_null_terminated = true)] | |
static string[] vapi_directories; | |
[CCode (array_length = false, array_null_terminated = true)] | |
static string[] gir_directories; | |
[CCode (array_length = false, array_null_terminated = true)] | |
static string[] metadata_directories; | |
static string vapi_filename; | |
static string library; | |
static string shared_library; | |
static string gir; | |
[CCode (array_length = false, array_null_terminated = true)] | |
static string[] packages; | |
[CCode (array_length = false, array_null_terminated = true)] | |
static string[] fast_vapis; | |
static string target_glib; | |
[CCode (array_length = false, array_null_terminated = true)] | |
static string[] gresources; | |
static bool ccode_only; | |
static string header_filename; | |
static bool use_header; | |
static string internal_header_filename; | |
static string internal_vapi_filename; | |
static string fast_vapi_filename; | |
static bool vapi_comments; | |
static string symbocmd_filename; | |
static string includedir; | |
static bool compile_only; | |
static string output; | |
static bool debug; | |
static bool thread; | |
static bool mem_profiler; | |
static bool disable_assert; | |
static bool enable_checking; | |
static bool deprecated; | |
static bool hide_internal; | |
static bool experimental; | |
static bool experimental_non_null; | |
static bool gobject_tracing; | |
static bool disable_since_check; | |
static bool disable_warnings; | |
static string cc_command; | |
[CCode (array_length = false, array_null_terminated = true)] | |
static string[] cc_options; | |
static string pkg_config_command; | |
static string dump_tree; | |
static bool save_temps; | |
[CCode (array_length = false, array_null_terminated = true)] | |
static string[] defines; | |
static bool quiet_mode; | |
static bool verbose_mode; | |
static string profile; | |
static bool nostdpkg; | |
static bool enable_version_header; | |
static bool disable_version_header; | |
static bool fatal_warnings; | |
static bool disable_colored_output; | |
static string dependencies; | |
static string entry_point; | |
static bool run_output; | |
const OptionEntry[] options = { | |
{ "plugin", 0, 0, OptionArg.FILENAME, ref builder, "Plugin build process", "FILE" }, | |
{ "builddir", 0, 0, OptionArg.FILENAME, ref builddir, "Out of tree location for build", "DIRECTORY" }, | |
{ "vapidir", 0, 0, OptionArg.FILENAME_ARRAY, ref vapi_directories, "Look for package bindings in DIRECTORY", "DIRECTORY..." }, | |
{ "girdir", 0, 0, OptionArg.FILENAME_ARRAY, ref gir_directories, "Look for .gir files in DIRECTORY", "DIRECTORY..." }, | |
{ "metadatadir", 0, 0, OptionArg.FILENAME_ARRAY, ref metadata_directories, "Look for GIR .metadata files in DIRECTORY", "DIRECTORY..." }, | |
{ "pkg", 0, 0, OptionArg.STRING_ARRAY, ref packages, "Include binding for PACKAGE", "PACKAGE..." }, | |
{ "vapi", 0, 0, OptionArg.FILENAME, ref vapi_filename, "Output VAPI file name", "FILE" }, | |
{ "library", 0, 0, OptionArg.STRING, ref library, "Library name", "NAME" }, | |
{ "shared-library", 0, 0, OptionArg.STRING, ref shared_library, "Shared library name used in generated gir", "NAME" }, | |
{ "gir", 0, 0, OptionArg.STRING, ref gir, "GObject-Introspection repository file name", "NAME-VERSION.gir" }, | |
{ "basedir", 'b', 0, OptionArg.FILENAME, ref basedir, "Base source directory", "DIRECTORY" }, | |
{ "directory", 'd', 0, OptionArg.FILENAME, ref directory, "Change output directory from current working directory", "DIRECTORY" }, | |
{ "version", 0, 0, OptionArg.NONE, ref version, "Display version number", null }, | |
{ "api-version", 0, 0, OptionArg.NONE, ref api_version, "Display API version number", null }, | |
{ "ccode", 'C', 0, OptionArg.NONE, ref ccode_only, "Output C code", null }, | |
{ "header", 'H', 0, OptionArg.FILENAME, ref header_filename, "Output C header file", "FILE" }, | |
{ "use-header", 0, 0, OptionArg.NONE, ref use_header, "Use C header file", null }, | |
{ "includedir", 0, 0, OptionArg.FILENAME, ref includedir, "Directory used to include the C header file", "DIRECTORY" }, | |
{ "internal-header", 'h', 0, OptionArg.FILENAME, ref internal_header_filename, "Output internal C header file", "FILE" }, | |
{ "internal-vapi", 0, 0, OptionArg.FILENAME, ref internal_vapi_filename, "Output vapi with internal api", "FILE" }, | |
{ "fast-vapi", 0, 0, OptionArg.STRING, ref fast_vapi_filename, "Output vapi without performing symbol resolution", null }, | |
{ "use-fast-vapi", 0, 0, OptionArg.STRING_ARRAY, ref fast_vapis, "Use --fast-vapi output during this compile", null }, | |
{ "vapi-comments", 0, 0, OptionArg.NONE, ref vapi_comments, "Include comments in generated vapi", null }, | |
{ "deps", 0, 0, OptionArg.STRING, ref dependencies, "Write make-style dependency information to this file", null }, | |
{ "symbols", 0, 0, OptionArg.FILENAME, ref symbocmd_filename, "Output symbols file", "FILE" }, | |
{ "compile", 'c', 0, OptionArg.NONE, ref compile_only, "Compile but do not link", null }, | |
{ "output", 'o', 0, OptionArg.FILENAME, ref output, "Place output in file FILE", "FILE" }, | |
{ "debug", 'g', 0, OptionArg.NONE, ref debug, "Produce debug information", null }, | |
{ "thread", 0, 0, OptionArg.NONE, ref thread, "Enable multithreading support (DEPRECATED AND IGNORED)", null }, | |
{ "enable-mem-profiler", 0, 0, OptionArg.NONE, ref mem_profiler, "Enable GLib memory profiler", null }, | |
{ "define", 'D', 0, OptionArg.STRING_ARRAY, ref defines, "Define SYMBOL", "SYMBOL..." }, | |
{ "main", 0, 0, OptionArg.STRING, ref entry_point, "Use SYMBOL as entry point", "SYMBOL..." }, | |
{ "nostdpkg", 0, 0, OptionArg.NONE, ref nostdpkg, "Do not include standard packages", null }, | |
{ "disable-assert", 0, 0, OptionArg.NONE, ref disable_assert, "Disable assertions", null }, | |
{ "enable-checking", 0, 0, OptionArg.NONE, ref enable_checking, "Enable additional run-time checks", null }, | |
{ "enable-deprecated", 0, 0, OptionArg.NONE, ref deprecated, "Enable deprecated features", null }, | |
{ "hide-internal", 0, 0, OptionArg.NONE, ref hide_internal, "Hide symbols marked as internal", null }, | |
{ "enable-experimental", 0, 0, OptionArg.NONE, ref experimental, "Enable experimental features", null }, | |
{ "disable-warnings", 0, 0, OptionArg.NONE, ref disable_warnings, "Disable warnings", null }, | |
{ "fatal-warnings", 0, 0, OptionArg.NONE, ref fatal_warnings, "Treat warnings as fatal", null }, | |
{ "disable-since-check", 0, 0, OptionArg.NONE, ref disable_since_check, "Do not check whether used symbols exist in local packages", null }, | |
{ "enable-experimental-non-null", 0, 0, OptionArg.NONE, ref experimental_non_null, "Enable experimental enhancements for non-null types", null }, | |
{ "enable-gobject-tracing", 0, 0, OptionArg.NONE, ref gobject_tracing, "Enable GObject creation tracing", null }, | |
{ "cc", 0, 0, OptionArg.STRING, ref cc_command, "Use COMMAND as C compiler command", "COMMAND" }, | |
{ "Xcc", 'X', 0, OptionArg.STRING_ARRAY, ref cc_options, "Pass OPTION to the C compiler", "OPTION..." }, | |
{ "pkg-config", 0, 0, OptionArg.STRING, ref pkg_config_command, "Use COMMAND as pkg-config command", "COMMAND" }, | |
{ "dump-tree", 0, 0, OptionArg.FILENAME, ref dump_tree, "Write code tree to FILE", "FILE" }, | |
{ "save-temps", 0, 0, OptionArg.NONE, ref save_temps, "Keep temporary files", null }, | |
{ "profile", 0, 0, OptionArg.STRING, ref profile, "Use the given profile instead of the default", "PROFILE" }, | |
{ "quiet", 'q', 0, OptionArg.NONE, ref quiet_mode, "Do not print messages to the console", null }, | |
{ "verbose", 'v', 0, OptionArg.NONE, ref verbose_mode, "Print additional messages to the console", null }, | |
{ "no-color", 0, 0, OptionArg.NONE, ref disable_colored_output, "Disable colored output, alias for --color=never", null }, | |
{ "target-glib", 0, 0, OptionArg.STRING, ref target_glib, "Target version of glib for code generation", "MAJOR.MINOR" }, | |
{ "gresources", 0, 0, OptionArg.STRING_ARRAY, ref gresources, "XML of gresources", "FILE..." }, | |
{ "enable-version-header", 0, 0, OptionArg.NONE, ref enable_version_header, "Write vala build version in generated files", null }, | |
{ "disable-version-header", 0, 0, OptionArg.NONE, ref disable_version_header, "Do not write vala build version in generated files", null }, | |
{ "", 0, 0, OptionArg.FILENAME_ARRAY, ref sources, null, "FILE..." }, | |
{ null } | |
}; | |
static int main (string[] args) { | |
try { | |
var opt_context = new OptionContext ("- ValaC2"); | |
opt_context.set_help_enabled (true); | |
opt_context.add_main_entries (options, null); | |
opt_context.parse (ref args); | |
} catch (OptionError e) { | |
stdout.printf ("error: %s\n", e.message); | |
stdout.printf ("Run '%s --help' to see a full list of available command line options.\n", args[0]); | |
return 0; | |
} | |
if (version) { | |
stdout.printf ("ValaC2 Beta 0.0.1\n"); | |
return 0; | |
} | |
if (builddir == null) { | |
stderr.printf ("In tree build not allowed.\n"); | |
return 1; | |
} | |
if (builder == null) { | |
stderr.printf ("Build plugin required.\n"); | |
return 1; | |
} | |
if (sources == null && fast_vapis == null) { | |
stderr.printf ("No source file specified.\n"); | |
return 1; | |
} | |
/** Ok, call the back end */ | |
spawn(build()); | |
return 0; | |
} | |
/** mangle the flags so they pass thru unchanged */ | |
static string build() { | |
StringBuilder sb = new StringBuilder(); | |
sb.append(builder); | |
sb.append(" "); | |
sb.append("~~builddir "); | |
sb.append(builddir); | |
sb.append(" "); | |
if (ccode_only) sb.append("~C "); | |
if (save_temps) sb.append("~~save~temps "); | |
if (quiet_mode) sb.append("~~quiet "); | |
if (verbose_mode) sb.append("~~verbose "); | |
if (vapi_comments) sb.append("~~vapi~comments "); | |
if (compile_only) sb.append("~~compile~only "); | |
if (api_version) sb.append("~~api-version "); | |
if (use_header) sb.append("~~use~header "); | |
if (debug) sb.append("~~debug "); | |
if (thread) sb.append("~~thread "); | |
if (mem_profiler) sb.append("~~enable~mem~profiler "); | |
if (disable_assert) sb.append("~~disable~assert "); | |
if (enable_checking) sb.append("~~enable~checking "); | |
if (deprecated) sb.append("~~enable-deprecated "); | |
if (hide_internal) sb.append("~~hide~internal "); | |
if (experimental) sb.append("~~enable~experimental "); | |
if (experimental_non_null) sb.append("~~enable-experimental-non-null "); | |
if (gobject_tracing) sb.append("~~enable~gobject~tracing "); | |
if (disable_since_check) sb.append("~~disable~since~check "); | |
if (disable_warnings) sb.append("~~disable~warnings "); | |
if (nostdpkg) sb.append("~~nostdpkg "); | |
if (enable_version_header) sb.append("~~enable~version~header "); | |
if (disable_version_header) sb.append("~~disable~version~header "); | |
if (fatal_warnings) sb.append("~~fatal~warnings "); | |
if (disable_colored_output) sb.append("~~no-color "); | |
if (basedir != null) { | |
sb.append("~~basedir "); | |
sb.append(basedir); | |
sb.append(" "); | |
} | |
if (directory != null) { | |
sb.append("~~directory "); | |
sb.append(directory); | |
sb.append(" "); | |
} | |
if (vapi_directories != null) { | |
foreach (var v in vapi_directories) { | |
sb.append("~~vapidir "); | |
sb.append(v); | |
sb.append(" "); | |
} | |
} | |
if (gir_directories != null) { | |
foreach (var g in gir_directories) { | |
sb.append("~~girdir "); | |
sb.append(g); | |
sb.append(" "); | |
} | |
} | |
if (metadata_directories != null) { | |
foreach (var m in metadata_directories) { | |
sb.append("~~metadatadir "); | |
sb.append(m); | |
sb.append(" "); | |
} | |
} | |
if (vapi_filename != null) { | |
sb.append("~~vapi "); | |
sb.append(vapi_filename); | |
sb.append(" "); | |
} | |
if (library != null) { | |
sb.append("~~library "); | |
sb.append(library); | |
sb.append(" "); | |
} | |
if (shared_library != null) { | |
sb.append("~~shared~library "); | |
sb.append(shared_library); | |
sb.append(" "); | |
} | |
if (gir != null) { | |
sb.append("~~gir "); | |
sb.append(gir); | |
sb.append(" "); | |
} | |
if (packages != null) { | |
foreach (var p in packages) { | |
sb.append("~~pkg "); | |
sb.append(p); | |
sb.append(" "); | |
} | |
} | |
if (fast_vapis != null) { | |
foreach (var f in fast_vapis) { | |
sb.append("~~fast~vapi "); | |
sb.append(f); | |
sb.append(" "); | |
} | |
} | |
if (target_glib != null) { | |
sb.append("~~target~glib "); | |
sb.append(target_glib); | |
sb.append(" "); | |
} | |
if (gresources != null) { | |
foreach (var g in gresources) { | |
sb.append("~~gresources "); | |
sb.append(g); | |
sb.append(" "); | |
} | |
} | |
if (header_filename != null) { | |
sb.append("~~header~filename "); | |
sb.append(header_filename); | |
sb.append(" "); | |
} | |
if (internal_header_filename != null) { | |
sb.append("~~internal~header "); | |
sb.append(internal_header_filename); | |
sb.append(" "); | |
} | |
if (internal_vapi_filename != null) { | |
sb.append("~~internal~vapi "); | |
sb.append(internal_vapi_filename); | |
sb.append(" "); | |
} | |
if (fast_vapi_filename != null) { | |
sb.append("~~fast~vapi "); | |
sb.append(fast_vapi_filename); | |
sb.append(" "); | |
} | |
if (symbocmd_filename != null) { | |
sb.append("~~symbols "); | |
sb.append(symbocmd_filename); | |
sb.append(" "); | |
} | |
if (includedir != null) { | |
sb.append("~~includedir "); | |
sb.append(includedir); | |
sb.append(" "); | |
} | |
if (output != null) { | |
sb.append("~~output "); | |
sb.append(output); | |
sb.append(" "); | |
} | |
if (cc_command != null) { | |
sb.append("~~cc "); | |
sb.append(cc_command); | |
sb.append(" "); | |
} | |
if (cc_options != null) { | |
foreach (var o in cc_options) { | |
sb.append("~~Xcc "); | |
while (o.index_of("-")>-1) o = o.replace("-", "~"); | |
while (o.index_of(" ")>-1) o = o.replace(" ", "%20"); | |
sb.append(o); | |
sb.append(" "); | |
} | |
} | |
if (pkg_config_command != null) { | |
sb.append("~~pkg-config "); | |
sb.append(pkg_config_command); | |
sb.append(" "); | |
} | |
if (dump_tree != null) { | |
sb.append("~~dump~tree "); | |
sb.append(dump_tree); | |
sb.append(" "); | |
} | |
if (defines != null) { | |
foreach (var d in defines) { | |
sb.append("~~define "); | |
sb.append(d); | |
sb.append(" "); | |
} | |
} | |
if (profile != null) { | |
sb.append("~~profile "); | |
sb.append(profile); | |
sb.append(" "); | |
} | |
foreach (var s in sources) { | |
sb.append(s); | |
sb.append(" "); | |
} | |
return sb.str; | |
} | |
static void spawn(string cmd) { | |
stdout.printf("%s\n", cmd); | |
try { | |
string[] spawn_args = cmd.split(" "); | |
string[] spawn_env = Environ.get(); | |
string cmd_stdout; | |
string cmd_stderr; | |
int cmd_status; | |
Process.spawn_sync(null, | |
spawn_args, | |
spawn_env, | |
SpawnFlags.SEARCH_PATH, | |
null, | |
out cmd_stdout, | |
out cmd_stderr, | |
out cmd_status); | |
stdout.printf("stdout:\n"); | |
stdout.puts(cmd_stdout); | |
stdout.printf("stderr:\n"); | |
stdout.puts(cmd_stderr); | |
stdout.printf("status: %d\n", cmd_status); | |
} catch (SpawnError e) { | |
stdout.printf("Error: %s\n", e.message); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment