-
-
Notifications
You must be signed in to change notification settings - Fork 95
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
Handle self-contained apps #194
Conversation
This reverts commit fd3d5f0.
The change wasn't I initially intended as an optimization, I was getting errors where the apphost wasn't found. Buildalyzer will perform a design time build, which shouldn't be trying to copy native dependencies required for running the app. Is there a particular issue you are facing? Edit - ah I see the Stryker .NET issue 👀 |
Yeah there are some real world problems due to this :) If you know a proper way to set this to "false" only for apps that are not self-contained, I'd be happy to adjust the PR. For me it's a bit of voodoo. |
This is probably the key. We want to set it to "false" most of the time, except under certain conditions. Ideally we'd be able to grab something like Don't have time to take a close look right now, but if @slang25 or someone else wants to figure out a good way to toggle this flag based on the project, that's where I think we need to go. |
Okay so I'm continuing to look into that... I've figured out that Buildalyzer fails for self-contained apps when the Also, the original problem is therefore also fixed if we pass this option to the But I don't completely understand if this is an expected behavior? Is Buildalyzer expected to fail for design-time builds in this case? And what are the risks of universally setting this flag to false then? |
I'll need to research why some of the tests are turning off design time builds but generally we want that to be the default because it's much faster, though turning it off as an option shouldn't cause any other problems besides a loss of performance (and possibly loosing a little extra diagnostic information which you may or may not be looking for). Here's more info on design time builds: https://github.com/dotnet/project-system/blob/main/docs/design-time-builds.md. If turning off design time builds work for this scenario, then that suggests that one of the targets being skipped due to the design time build might make things work - we might be able to light up just that target without totally resorting to a full build, especially if we have some sort of clue that the project is a self contained app. Though if changing the app host setting also works, that's okay too. Given that we have a set of scenarios that only works when it's false and a different set that only works when it's true, I'd like to figure how to make both work out of the box. If we can't figure out what the value should be before doing a build, maybe we pick the most common, run the build, check the error condition, and then automatically rerun it with a toggled flag if it failed for this reason. |
Alright, so I pushed some changes... This basically looks if there is "self-contained" element in the project file and doesn't add "UseAppHost" if so. The implementation is trivial but I checked it's enough at least for the original use-case. |
/// return a <see cref="Microsoft.Build.Execution.ProjectInstance"/> without building the project. | ||
/// </param> | ||
/// <returns>A new build environment with the specified targets.</returns> | ||
public BuildEnvironment WithTargetsToBuild(params string[] targets) => |
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's the thinking behind removing this clone method - was it a mistake or am I missing the reason it needed to come out?
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.
So this method needs to be otherwise adjusted in the light of the changes above. Which is doable but looks like it's not used anywhere... Moreover, I tracked the git history and looks like it wasn't used even once added (in a quite a big commit) so I though it was some temp convenience at some point not needed currently anymore.
I could be wrong, but I think the way Stryker is using Buildalyzer falls under the Thinking back, another time I've ran into Buildalyzer "clobbering" existing properties is the I'm thinking rather than baking in lots of smarts around detecting when to set a property, or handing back explicit control over the value, perhaps there should be a configure list of properties you want Buildalyzer to "leave alone". I think this could reduce complexity in the long run, and solve the OP issue. I could remove some workarounds in my projects too. So if Stryker would continue to use AnalyzerManager manager = new AnalyzerManager();
manager.AddPreservedProperty("UseAppHost"); // Naming stuff is hard
... Then any place internally that sets a property would check this list of properties to preserve, and you get the MSBuild evaluated value, otherwise you end up re-implementing the SDKs, or maintaining good approximations. |
@slang25 Stryker uses default (true) as of now, see this discussion. But I like your thinking in general. I don't believe I'll be able and have time to implement this though... |
Before I merge this in and we go down further down the toggling AppHost creation path, I'm going to take a quick step back and see if I can figure out why we needed to disable it in the first place. It's clear that toggling that property seems to impact the ability to build certain .NET 6 projects (like those with implicit usings), but what's not clear to me is how Visual Studio can still perform design-time builds of those same projects. I feel like we're missing some newer magic dust and if I can figure out that, then this whole problem solves itself. Looking at it over my lunch break today so stay tuned... |
Sure, and enjoy your lunch! :) |
Okay, I think I've got a handle on this. The underlying issue is that the default design-time builds were running some non-design-time targets, which in turn made parts fail because everything wasn't working well together. For example, the underlying cause of the failure in #185 which led to setting I think the answer is to swap out the targets for design-time builds with a different set of design-time specific targets. This gets a little tricky since the list at https://github.com/dotnet/project-system/blob/main/docs/design-time-builds.md#targets-that-run-during-design-time-builds appears to be exclusive to Visual Studio. In fact, it's not totally clear that "design-time" is actually completely and totally available outside Visual Studio. Here's the full set of targets Visual Studio uses for a design-time build, many of which aren't available through the SDK alone because they're in a special Visual Studio targets file: It does seem like I can get close enough with a subset of those though: Combined with setting the other global properties that indicate a design-time build I think we might have it. Still testing and might need some additional iteration, but getting closer I think. At a minimum I've create some additional integration tests that look at More to come... |
Okay, that was sort of a dead end, but it got me in the right direction. We still need to run the So now the trick is which global properties to set that successfully builds
Reasonably sure I've got it this time: That includes new test projects for self-contained executables, .NET 6 I'm going to close out this PR in favor of my incoming commit - thanks a ton for the work here @psfinaki! We wouldn't have ended up in the "right" place without your work pushing it forward. |
Thanks @psfinaki & @daveaglick, my original PR was a misstep, I had no idea the VS design-time behaviour was so involved, I just thought it was a few magic properties 😆 @daveaglick what's the VS extension that shows the MSBuild magic there? |
@daveaglick thanks a bunch for the proper fix! I've verified it locally for the Stryker case and it works there as expected :) Looking for to the release! |
@psfinaki All tests were green including the external open source project integration tests, so just released and new version should be showing up on NuGet soon. @slang25 The magic is in the Project System Tools Visual Studio extension. It logs every build including design-time ones and then lets you open them in the MSBuild Log Viewer. I can honestly say that if it weren't for those two tools, there's no way Buildalyzer would exist. |
@daveaglick It might be worth comparing notes with the OmniSharp folk, they are solving roughly the same problem. |
As per the docs,
Therefore this commit broke Buildalyzer for self-contained apps (the usecase is here).
I'm not an MSBuild expert to handle this more elegantly so just reverting the original "optimization" :(