diff --git a/source/dub/compilers/compiler.d b/source/dub/compilers/compiler.d index b346f14..eb534b0 100644 --- a/source/dub/compilers/compiler.d +++ b/source/dub/compilers/compiler.d @@ -172,10 +172,24 @@ void setTarget(ref BuildSettings settings, in BuildPlatform platform); /// Invokes the compiler using the given flags - void invoke(in BuildSettings settings, in BuildPlatform platform); + void invoke(in BuildSettings settings, in BuildPlatform platform, void delegate(int, string) output_callback); /// Invokes the underlying linker directly - void invokeLinker(in BuildSettings settings, in BuildPlatform platform, string[] objects); + void invokeLinker(in BuildSettings settings, in BuildPlatform platform, string[] objects, void delegate(int, string) output_callback); + + protected final void invokeTool(string[] args, void delegate(int, string) output_callback) + { + int status; + if (output_callback) { + auto result = execute(args); + output_callback(result.status, result.output); + status = result.status; + } else { + auto compiler_pid = spawnProcess(args); + status = compiler_pid.wait(); + } + enforce(status == 0, args[0] ~ " failed with exit code "~to!string(status)); + } } /// BuildPlatform specific settings, like needed libraries or additional diff --git a/source/dub/compilers/dmd.d b/source/dub/compilers/dmd.d index d007066..aa93705 100644 --- a/source/dub/compilers/dmd.d +++ b/source/dub/compilers/dmd.d @@ -161,19 +161,17 @@ settings.addDFlags("-of"~tpath.toNativeString()); } - void invoke(in BuildSettings settings, in BuildPlatform platform) + void invoke(in BuildSettings settings, in BuildPlatform platform, void delegate(int, string) output_callback) { auto res_file = getTempDir() ~ ("dub-build-"~uniform(0, uint.max).to!string~"-.rsp"); std.file.write(res_file.toNativeString(), join(settings.dflags.map!(s => s.canFind(' ') ? "\""~s~"\"" : s), "\n")); scope (exit) remove(res_file.toNativeString()); logDiagnostic("%s %s", platform.compilerBinary, join(cast(string[])settings.dflags, " ")); - auto compiler_pid = spawnProcess([platform.compilerBinary, "@"~res_file.toNativeString()]); - auto result = compiler_pid.wait(); - enforce(result == 0, "DMD compile run failed with exit code "~to!string(result)); + invokeTool([platform.compilerBinary, "@"~res_file.toNativeString()], output_callback); } - void invokeLinker(in BuildSettings settings, in BuildPlatform platform, string[] objects) + void invokeLinker(in BuildSettings settings, in BuildPlatform platform, string[] objects, void delegate(int, string) output_callback) { import std.string; auto tpath = Path(settings.targetPath) ~ getTargetFileName(settings, platform); @@ -185,7 +183,6 @@ static linkerargs = ["-g", "-gc", "-m32", "-m64", "-shared"]; args ~= settings.dflags.filter!(f => linkerargs.canFind(f))().array(); logDiagnostic("%s", args.join(" ")); - auto res = spawnProcess(args).wait(); - enforce(res == 0, "Link command failed with exit code "~to!string(res)); + invokeTool(args, output_callback); } } diff --git a/source/dub/compilers/gdc.d b/source/dub/compilers/gdc.d index 7a048cf..642aa0d 100644 --- a/source/dub/compilers/gdc.d +++ b/source/dub/compilers/gdc.d @@ -149,19 +149,17 @@ settings.addDFlags("-o", tpath.toNativeString()); } - void invoke(in BuildSettings settings, in BuildPlatform platform) + void invoke(in BuildSettings settings, in BuildPlatform platform, void delegate(int, string) output_callback) { auto res_file = getTempDir() ~ ("dub-build-"~uniform(0, uint.max).to!string~"-.rsp"); std.file.write(res_file.toNativeString(), join(settings.dflags.map!(s => escape(s)), "\n")); scope (exit) remove(res_file.toNativeString()); logDiagnostic("%s %s", platform.compilerBinary, join(cast(string[])settings.dflags, " ")); - auto compiler_pid = spawnProcess([platform.compilerBinary, "@"~res_file.toNativeString()]); - auto result = compiler_pid.wait(); - enforce(result == 0, "GDC compile run failed with exit code "~to!string(result)); + invokeTool([platform.compilerBinary, "@"~res_file.toNativeString()], output_callback); } - void invokeLinker(in BuildSettings settings, in BuildPlatform platform, string[] objects) + void invokeLinker(in BuildSettings settings, in BuildPlatform platform, string[] objects, void delegate(int, string) output_callback) { assert(false, "Separate linking not implemented for GDC"); } diff --git a/source/dub/compilers/ldc.d b/source/dub/compilers/ldc.d index 5dff8e3..e01109a 100644 --- a/source/dub/compilers/ldc.d +++ b/source/dub/compilers/ldc.d @@ -149,19 +149,17 @@ settings.addDFlags("-of"~tpath.toNativeString()); } - void invoke(in BuildSettings settings, in BuildPlatform platform) + void invoke(in BuildSettings settings, in BuildPlatform platform, void delegate(int, string) output_callback) { auto res_file = getTempDir() ~ ("dub-build-"~uniform(0, uint.max).to!string~"-.rsp"); std.file.write(res_file.toNativeString(), join(cast(string[])settings.dflags, "\n")); scope (exit) remove(res_file.toNativeString()); logDiagnostic("%s %s", platform.compilerBinary, join(cast(string[])settings.dflags, " ")); - auto compiler_pid = spawnProcess([platform.compilerBinary, "@"~res_file.toNativeString()]); - auto result = compiler_pid.wait(); - enforce(result == 0, "LDC compile run failed with exit code "~to!string(result)); + invokeTool([platform.compilerBinary, "@"~res_file.toNativeString()], output_callback); } - void invokeLinker(in BuildSettings settings, in BuildPlatform platform, string[] objects) + void invokeLinker(in BuildSettings settings, in BuildPlatform platform, string[] objects, void delegate(int, string) output_callback) { assert(false, "Separate linking not implemented for GDC"); } diff --git a/source/dub/generators/build.d b/source/dub/generators/build.d index 3e96cd0..40b1d57 100644 --- a/source/dub/generators/build.d +++ b/source/dub/generators/build.d @@ -71,7 +71,7 @@ auto buildsettings = targets[m_project.mainPackage.name].buildSettings; if (settings.run && !(buildsettings.options & BuildOptions.syntaxOnly)) { auto exe_file_path = Path(buildsettings.targetPath) ~ getTargetFileName(buildsettings, settings.platform); - runTarget(exe_file_path, buildsettings, settings.runArgs); + runTarget(exe_file_path, buildsettings, settings.runArgs, settings); } } @@ -347,7 +347,7 @@ // invoke the compiler logInfo("Running %s...", settings.platform.compilerBinary); - settings.compiler.invoke(buildsettings, settings.platform); + settings.compiler.invoke(buildsettings, settings.platform, settings.compileCallback); } else { // determine path for the temporary object file string tempobjname = buildsettings.targetName; @@ -369,14 +369,14 @@ settings.compiler.prepareBuildSettings(buildsettings, BuildSetting.commandLine); logInfo("Compiling..."); - settings.compiler.invoke(buildsettings, settings.platform); + settings.compiler.invoke(buildsettings, settings.platform, settings.compileCallback); logInfo("Linking..."); - settings.compiler.invokeLinker(lbuildsettings, settings.platform, [tempobj.toNativeString()]); + settings.compiler.invokeLinker(lbuildsettings, settings.platform, [tempobj.toNativeString()], settings.linkCallback); } } - void runTarget(Path exe_file_path, in BuildSettings buildsettings, string[] run_args) + void runTarget(Path exe_file_path, in BuildSettings buildsettings, string[] run_args, GeneratorSettings settings) { if (buildsettings.targetType == TargetType.executable) { auto cwd = Path(getcwd()); @@ -395,9 +395,14 @@ exe_path_string = "./" ~ exe_path_string; } logInfo("Running %s %s", exe_path_string, run_args.join(" ")); - auto prg_pid = spawnProcess(exe_path_string ~ run_args); - auto result = prg_pid.wait(); - enforce(result == 0, "Program exited with code "~to!string(result)); + if (settings.runCallback) { + auto res = execute(exe_path_string ~ run_args); + settings.runCallback(res.status, res.output); + } else { + auto prg_pid = spawnProcess(exe_path_string ~ run_args); + auto result = prg_pid.wait(); + enforce(result == 0, "Program exited with code "~to!string(result)); + } } else logInfo("Target is a library. Skipping execution."); } diff --git a/source/dub/generators/generator.d b/source/dub/generators/generator.d index 5a9fbf8..f7149f7 100644 --- a/source/dub/generators/generator.d +++ b/source/dub/generators/generator.d @@ -176,6 +176,9 @@ // only used for generator "build" bool run, force, direct, clean, rdmd; string[] runArgs; + void delegate(int status, string output) compileCallback; + void delegate(int status, string output) linkCallback; + void delegate(int status, string output) runCallback; }