-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Skip MSBuild and call only CSC for simple file-based apps #49528
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
base: main
Are you sure you want to change the base?
Conversation
272c4ca
to
e9eae7a
Compare
@@ -32,6 +32,7 @@ | |||
<add key="richnav" value="https://pkgs.dev.azure.com/azure-public/vside/_packaging/vs-buildservices/nuget/v3/index.json" /> | |||
<!-- mstest dependencies --> | |||
<add key="test-tools" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/test-tools/nuget/v3/index.json" /> | |||
<add key="temporary" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/general-testing/nuget/v3/index.json" /> |
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 should go away before the PR is merged. I'm using this to get a test build of the BuildClient package before dotnet/roslyn#78986 is merged and we have an official build.
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.
nice!
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.
Concern: How is output handled? MSBuild has lots of handling of error situations and things. So, skipping that, what do we see when doing certain "normal" failure scenarios? I see some of the tests handle some of the CS#### errors. I'm not familiar with how/if MSBuild translates or supersedes those.
@RikkiGibson @chsienki @jaredpar for reviews, thanks |
var tmp = new DirectoryInfo(tmpPath[..^1]); // No trailing slash in order to properly check the link target | ||
if (tmp.LinkTarget != null && path.StartsWith(tmpPath) && tmp.ResolveLinkTarget(true) is { } linkTarget) | ||
{ | ||
return Path.Combine(linkTarget.FullName, path[tmpPath.Length..]); |
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.
Should we assert that path
starts with tmpPath
?
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.
Doesn't seem necessary, it's in the condition: path.StartsWith(tmpPath)
@@ -74,6 +76,12 @@ public static string GetMessage() | |||
} | |||
"""; | |||
|
|||
/// <summary> | |||
/// Used when we need an out-of-tree base test directory to avoid having implicit build files | |||
/// like Directory.Build.props in scope and negating the optimizations we want to test. |
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 is possible for these files to be dumped into Path.GetTempPath
. Consider that on Windows this could very easily happen if a user is playing with a repro and ends up dumping a Directory.Build.props
file into the temp folder (the writer of this comment, may have done this several times).
If we want this path to be fully resistant we should put Directory.Build.props / targets / packages / etc ... into the OutOfTreeBaseDirectory
folder. Have them all be empty and explicitly not search above for any other ones. That will more fully isolate the build.
Note: we had to do this in roslyn for this exact reason 😦
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.
If we had Directory.Build.props in the test folder, the CSC optimization would not kick in though. We would need to extend the optimization logic somehow to recognize those empty files.
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.
Hmm ...
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.
Okay ... new strategy: fail the test if the temp directory has any of those files.
string fileDirectory = Path.GetDirectoryName(EntryPointFileFullPath) ?? string.Empty; | ||
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(EntryPointFileFullPath); | ||
|
||
string objDir = Path.Join(ArtifactsPath, "obj", "debug"); |
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.
Currently is there an ability to say dotnet run app.cs -c Release
?
Directory.CreateDirectory(binDir); | ||
|
||
string assemblyAttributes = Path.Join(objDir, $".NETCoreApp,Version=v{TargetFrameworkVersion}.AssemblyAttributes.cs"); | ||
if (ShouldEmit(assemblyAttributes)) |
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.
Could you please explain why we need the ability to create the auxiliary files here? I was hoping these would just be on disk from a previous msbuild run, and if they are not, then we just run msbuild and save the csc optimization for the next time.
Part of #48011.
With this PR, simple file-based apps (with no
#:
directives, no implicit build files, no command-line-property
switches) use C# compiler (via the compiler server), skipping MSBuild altogether. That can improve time ofdotnet run file.cs
significantly as the following table shows.(UPDATE: Figured out that "no build" is slower than "csc" because the csc optimized path doesn't need to invoke MSBuild to do project evaluation to figure out the target command to run, whereas the no-build path still does that. I will look into improving that in a follow up.)
The next step will be to skip MSBuild for more complex file-based apps as well (by reusing csc arguments from the previous msbuild run).
Resolves #49478 (sdk and runtime version is now included in the cache and build isn't skipped if those are different between the previous and current run).