Skip to content

Commit

Permalink
Add betterC probing for performance and for applications without drun…
Browse files Browse the repository at this point in the history
…time
  • Loading branch information
etcimon committed Dec 24, 2023
1 parent a86d81c commit 8742ca1
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 19 deletions.
30 changes: 22 additions & 8 deletions source/dub/compilers/compiler.d
Original file line number Diff line number Diff line change
Expand Up @@ -183,18 +183,32 @@ interface Compiler {
import dub.compilers.utils : generatePlatformProbeFile, readPlatformJsonProbe;
import std.string : format, strip;

auto fil = generatePlatformProbeFile();
NativePath fil = generatePlatformProbeFile!true();
auto result_betterC = execute(compiler_binary ~ args ~ "-betterC" ~ fil.toNativeString());
// expect a result <>0 for a betterC probe
BuildPlatform build_platform;
string ver;
bool retry;
try {
build_platform = readPlatformJsonProbe(result_betterC.output);
ver = determineVersion(compiler_binary, result_betterC.output).strip;
} catch(Exception e) {
logWarn(`Could not probe this compiler using betterC, reverting to druntime probe.`);
retry = true;
}
if (retry) {
fil = generatePlatformProbeFile!false();

auto result = execute(compiler_binary ~ args ~ fil.toNativeString());
enforce!CompilerInvocationException(result.status == 0,
format("Failed to invoke the compiler %s to determine the build platform: %s",
compiler_binary, result.output));
auto result = execute(compiler_binary ~ args ~ fil.toNativeString());
enforce!CompilerInvocationException(result.status == 0,
format("Failed to invoke the compiler %s to determine the build platform: %s",
compiler_binary, result.output));

auto build_platform = readPlatformJsonProbe(result.output);
build_platform = readPlatformJsonProbe(result.output);
ver = determineVersion(compiler_binary, result.output).strip;
}
build_platform.compilerBinary = compiler_binary;

auto ver = determineVersion(compiler_binary, result.output)
.strip;
if (ver.empty) {
logWarn(`Could not probe the compiler version for "%s". ` ~
`Toolchain requirements might be ineffective`, build_platform.compiler);
Expand Down
35 changes: 24 additions & 11 deletions source/dub/compilers/utils.d
Original file line number Diff line number Diff line change
Expand Up @@ -266,16 +266,28 @@ private enum probeEndMark = "__dub_probe_end__";
See_Also: `readPlatformProbe`
*/
NativePath generatePlatformProbeFile()
NativePath generatePlatformProbeFile(bool betterC = false)()
{
import dub.internal.vibecompat.core.file;
import dub.internal.vibecompat.data.json;
import dub.internal.utils;
import std.string : format;
enum moduleInfo = betterC ? q{
module object;
alias string = const(char)[];
alias size_t = uint;
template _d_arrayappendcTXImpl(Tarr : T[], T){
ref Tarr _d_arrayappendcTX(return ref scope Tarr px, size_t n) @trusted pure nothrow{return px;}
}
const(char)[][] _d_arrayappendcTX(return scope ref const(char)[][] px, size_t n){return px;}
Tarr _d_arrayappendT(Tarr : T[], T)(return ref scope Tarr x, scope Tarr y){return x;}
} : q{
module dub_platform_probe;
};

// try to not use phobos in the probe to avoid long import times
enum probe = q{
module dub_platform_probe;
%1$s

template toString(int v) { enum toString = v.stringof; }
string stringArray(string[] ary) {
Expand All @@ -288,7 +300,7 @@ NativePath generatePlatformProbeFile()
return res;
}

pragma(msg, `%1$s`
pragma(msg, `%2$s`
~ '\n' ~ `{`
~ '\n' ~ ` "compiler": "`~ determineCompiler() ~ `",`
~ '\n' ~ ` "frontendVersion": ` ~ toString!__VERSION__ ~ `,`
Expand All @@ -300,13 +312,13 @@ NativePath generatePlatformProbeFile()
~ '\n' ~ ` ` ~ determineArchitecture().stringArray
~ '\n' ~ ` ],`
~ '\n' ~ `}`
~ '\n' ~ `%2$s`);
~ '\n' ~ `%3$s`);

string[] determinePlatform() { %3$s }
string[] determineArchitecture() { %4$s }
string determineCompiler() { %5$s }
string[] determinePlatform() { %4$s }
string[] determineArchitecture() { %5$s }
string determineCompiler() { %6$s }

}.format(probeBeginMark, probeEndMark, platformCheck, archCheck, compilerCheck);
}.format(moduleInfo, probeBeginMark, probeEndMark, platformCheck, archCheck, compilerCheck);

auto path = getTempFile("dub_platform_probe", ".d");
writeFile(path, probe);
Expand All @@ -321,14 +333,15 @@ NativePath generatePlatformProbeFile()
*/
BuildPlatform readPlatformJsonProbe(string output)
{
import std.algorithm : map;
import std.algorithm : map, max;
import std.array : array;
import std.exception : enforce;
import std.ascii : newline;
import std.string;

// work around possible additional output of the compiler
auto idx1 = output.indexOf(probeBeginMark);
auto idx2 = output.lastIndexOf(probeEndMark);
auto idx1 = output.indexOf(probeBeginMark~newline~"{");
auto idx2 = output[max(0,idx1) .. $].indexOf(probeEndMark) + idx1;
enforce(idx1 >= 0 && idx1 < idx2,
"Unexpected platform information output - does not contain a JSON object.");
output = output[idx1+probeBeginMark.length .. idx2];
Expand Down

0 comments on commit 8742ca1

Please sign in to comment.