-
-
Notifications
You must be signed in to change notification settings - Fork 229
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add betterC probing for performance and for applications without drun… #2753
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -177,27 +177,26 @@ interface Compiler { | |
args = arguments for the probe compilation | ||
arch_override = special handler for x86_mscoff | ||
*/ | ||
protected final BuildPlatform probePlatform(string compiler_binary, string[] args, | ||
string arch_override) | ||
protected final BuildPlatform probePlatform(string compiler_binary, string[] args, string arch_override) | ||
{ | ||
import dub.compilers.utils : generatePlatformProbeFile, readPlatformJsonProbe; | ||
import dub.compilers.utils : generatePlatformProbeFile, readPlatformSDLProbe; | ||
Geod24 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
import std.string : format, strip; | ||
|
||
auto fil = generatePlatformProbeFile(); | ||
NativePath fil = generatePlatformProbeFile(); | ||
|
||
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)); | ||
BuildPlatform build_platform; | ||
|
||
auto build_platform = readPlatformJsonProbe(result.output); | ||
build_platform = readPlatformSDLProbe(result.output); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Merge those two lines ? |
||
string 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); | ||
`Toolchain requirements might be ineffective`, build_platform.compiler); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Revert |
||
} | ||
else { | ||
build_platform.compilerVersion = ver; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,7 +8,7 @@ | |
module dub.compilers.utils; | ||
|
||
import dub.compilers.buildsettings; | ||
import dub.platform : BuildPlatform, archCheck, compilerCheck, platformCheck; | ||
import dub.platform : BuildPlatform, archCheck, compilerCheckPragmas, platformCheck, pragmaGen; | ||
import dub.internal.vibecompat.inet.path; | ||
import dub.internal.logging; | ||
|
||
|
@@ -268,78 +268,103 @@ private enum probeEndMark = "__dub_probe_end__"; | |
*/ | ||
NativePath generatePlatformProbeFile() | ||
{ | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Revert |
||
import dub.internal.vibecompat.core.file; | ||
import dub.internal.vibecompat.data.json; | ||
import dub.internal.utils; | ||
import std.string : format; | ||
|
||
enum moduleInfo = q{ | ||
module object; | ||
alias string = const(char)[]; | ||
}; | ||
|
||
// try to not use phobos in the probe to avoid long import times | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would also modify the comment so the next person knows the platform probe should not rely on the runtime to make your use case possible. |
||
enum probe = q{ | ||
module dub_platform_probe; | ||
|
||
template toString(int v) { enum toString = v.stringof; } | ||
string stringArray(string[] ary) { | ||
string res; | ||
foreach (i, e; ary) { | ||
if (i) | ||
res ~= ", "; | ||
res ~= '"' ~ e ~ '"'; | ||
} | ||
return res; | ||
} | ||
|
||
pragma(msg, `%1$s` | ||
~ '\n' ~ `{` | ||
~ '\n' ~ ` "compiler": "`~ determineCompiler() ~ `",` | ||
~ '\n' ~ ` "frontendVersion": ` ~ toString!__VERSION__ ~ `,` | ||
~ '\n' ~ ` "compilerVendor": "` ~ __VENDOR__ ~ `",` | ||
~ '\n' ~ ` "platform": [` | ||
~ '\n' ~ ` ` ~ determinePlatform().stringArray | ||
~ '\n' ~ ` ],` | ||
~ '\n' ~ ` "architecture": [` | ||
~ '\n' ~ ` ` ~ determineArchitecture().stringArray | ||
~ '\n' ~ ` ],` | ||
~ '\n' ~ `}` | ||
~ '\n' ~ `%2$s`); | ||
|
||
string[] determinePlatform() { %3$s } | ||
string[] determineArchitecture() { %4$s } | ||
string determineCompiler() { %5$s } | ||
|
||
}.format(probeBeginMark, probeEndMark, platformCheck, archCheck, compilerCheck); | ||
%1$s | ||
pragma(msg, `%2$s`); | ||
pragma(msg, `\n`); | ||
pragma(msg, `compiler`); | ||
%6$s | ||
pragma(msg, `\n`); | ||
pragma(msg, `frontendVersion "`); | ||
pragma(msg, __VERSION__.stringof); | ||
pragma(msg, `"\n`); | ||
pragma(msg, `compilerVendor "`); | ||
pragma(msg, __VENDOR__); | ||
pragma(msg, `"\n`); | ||
pragma(msg, `platform`); | ||
%4$s | ||
pragma(msg, `\n`); | ||
pragma(msg, `architecture `); | ||
%5$s | ||
pragma(msg, `\n`); | ||
pragma(msg, `%3$s`); | ||
}.format(moduleInfo, probeBeginMark, probeEndMark, pragmaGen(platformCheck), pragmaGen(archCheck), compilerCheckPragmas); | ||
|
||
auto path = getTempFile("dub_platform_probe", ".d"); | ||
writeFile(path, probe); | ||
|
||
return path; | ||
} | ||
|
||
|
||
/** | ||
Processes the JSON output generated by compiling the platform probe file. | ||
Processes the SDL output generated by compiling the platform probe file. | ||
|
||
See_Also: `generatePlatformProbeFile`. | ||
*/ | ||
BuildPlatform readPlatformJsonProbe(string output) | ||
BuildPlatform readPlatformSDLProbe(string output) | ||
{ | ||
import std.algorithm : map; | ||
import std.algorithm : map, max, splitter, joiner, count, filter; | ||
import std.array : array; | ||
import std.exception : enforce; | ||
import std.range : front; | ||
import std.ascii : newline; | ||
import std.string; | ||
import dub.internal.sdlang.parser; | ||
import dub.internal.sdlang.ast; | ||
import std.conv; | ||
|
||
// work around possible additional output of the compiler | ||
auto idx1 = output.indexOf(probeBeginMark); | ||
auto idx2 = output.lastIndexOf(probeEndMark); | ||
auto idx1 = output.indexOf(probeBeginMark ~ newline ~ "\\n"); | ||
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]; | ||
output = output[idx1 + probeBeginMark.length .. idx2].replace(newline, "").replace("\\n", "\n"); | ||
|
||
import dub.internal.vibecompat.data.json; | ||
auto json = parseJsonString(output); | ||
output = output.splitter("\n").filter!((e) => e.length > 0) | ||
.map!((e) { | ||
if (e.count("\"") == 0) | ||
{ | ||
return e ~ ` ""`; | ||
} | ||
return e; | ||
}) | ||
.joiner("\n").array().to!string; | ||
|
||
BuildPlatform build_platform; | ||
build_platform.platform = json["platform"].get!(Json[]).map!(e => e.get!string()).array(); | ||
build_platform.architecture = json["architecture"].get!(Json[]).map!(e => e.get!string()).array(); | ||
build_platform.compiler = json["compiler"].get!string; | ||
build_platform.frontendVersion = json["frontendVersion"].get!int; | ||
Tag sdl = parseSource(output); | ||
|
||
foreach (n; sdl.all.tags) | ||
{ | ||
switch (n.name) | ||
{ | ||
default: | ||
break; | ||
case "platform": | ||
build_platform.platform = n.values.map!(e => e.toString()).array(); | ||
break; | ||
case "architecture": | ||
build_platform.architecture = n.values.map!(e => e.toString()).array(); | ||
break; | ||
case "compiler": | ||
build_platform.compiler = n.values.front.toString(); | ||
break; | ||
case "frontendVersion": | ||
build_platform.frontendVersion = n.values.front.toString() | ||
.filter!((e) => e >= '0' && e <= '9').array().to!string | ||
.to!int; | ||
break; | ||
} | ||
} | ||
return build_platform; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unrelated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a minor annoyance when using vscode source control on windows, I was thinking it didn't require mention, nor its own pull request.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What artifacts does vscode generate ? We can keep it in this PR, I just could not tell where it's coming from.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is for the dub.exe and dub.pdb files that are generated when building under windows.