Closed chucker closed 2 weeks ago
Hi @chucker , I'll look into it and get back to you.
Hi π Any update on this topic? We also faced this issue.
If @phmonte does not have time today (nor tomorrow), I'll give it a go.
@phmonte
The problem occurs when you publish code that uses Buildalyzer
in PublishSingleFile=true
mode.
Not when you analyze a project with a such profile π
I don't know how to simulate it in unit tests but your sample project is good for replicate this behavior.
I have change one line
from: var analyzer = manager.GetProject(@"../../../../ClassLibrary1/ClassLibrary1.csproj");
to: var analyzer = manager.GetProject(@"../ClassLibrary1/ClassLibrary1.csproj");
and start console in ConsoleApp1
folder.
As you can see for normal build everything works as expected
but when published as single file: dotnet publish -p PublishSingleFile=true ConsoleApp1.csproj
and runs bin/Debug/net6.0/win-x64/publish/ConsoleApp1.exe
its hangs (i have cancelled it after half minute).
It hangs somewhere in AnonymousPipeLoggerServer
starting from this line: https://github.com/phmonte/Buildalyzer/blob/main/src/Buildalyzer/ProjectAnalyzer.cs#L182
Best regards, Mateusz
@Karql thanks, now it's possible to reproduce, I'm investigating.
I believe I found the problem, it's here. It uses the dll address to send to msbuild, I'm testing some alternatives.
Nice catch π
This could be a problem... As I understand correctly, that dll needs to exists on the disk in order to pass its path to msbuild
.
For a moment, I wondered if it might be possible to get extract path from DOTNET_BUNDLE_EXTRACT_BASE_DIR
https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-environment-variables#dotnet_bundle_extract_base_dir
but from .NET5.0
only native dlls are extracted: https://github.com/dotnet/runtime/issues/43010
I hope you will find some alternatives π
Two ideas:
1) Exclude logger dll from single file.
2) Add possibility to specify path to logger similar like MSBUILD_EXE_PATH
The msbuild result is captured through the log, there is a custom log that does all this work, removing it will be a bit complex, I'm thinking about other alternatives keeping the dll.
Hi @Karql , I did some tests in the last few days, from extracting a dll to manipulating the assembly, unfortunately I was not successful. I believe the healthiest solution would be to remove the Buildalyzer.Logger package from the publish single file. There are some alternatives in this issue.
If you are really going to remove the dll from the publish single file and you are unsuccessful with the alternatives, let us know and we can think of an alternative (search in the current directory or by parameter).
@phmonte
I have seen the issue you mentioned π Did you manage to use this solution?
For me after use it its still hangs.
ConsoleApp1.Program.cs:
using Buildalyzer;
using Buildalyzer.Logger;
string loggerPath = typeof(BuildalyzerLogger).Assembly.Location;
Console.WriteLine($"Logger path: {loggerPath}");
var manager = new AnalyzerManager();
var analyzer = manager.GetProject(@"../ClassLibrary1/ClassLibrary1.csproj");
Console.WriteLine("1");
_ = analyzer.Build();
Console.WriteLine("2");
ConsoleApp1.csproj
...
<Target Name="ExplicitRemoveFromFilesToBundle" BeforeTargets="GenerateSingleFileBundle" DependsOnTargets="PrepareForBundle">
<ItemGroup>
<FilesToRemoveFromBundle Include="@(FilesToBundle)" Condition="$([System.String]::new('%(Filename)').ToLower().Contains('buildalyzer.logger'))" />
</ItemGroup>
<Message Text="FilesToRemoveFromBundle '@(FilesToRemoveFromBundle)'" Importance="high" />
<ItemGroup>
<FilesToBundle Remove="@(FilesToRemoveFromBundle)" />
</ItemGroup>
</Target>
<Target Name="CopyFilesToRemoveFromBundle" AfterTargets="Publish">
<Copy SourceFiles="@(FilesToRemoveFromBundle)" DestinationFolder="$(PublishDir)" />
<Message Text="Copied files to remove from bundle to '$(PublishDir)'" Importance="high" />
</Target>
...
but there is a small improvement - the path to the logger is good π
Screen from dump looks similar:
@Karql I ended up forgetting to mention it.
There are 2 dlls, could you test by removing them? -MsBuildPipeLogger.Logger.dll -Buildalyzer.logger.dll
I really believe it will solve your problem.
@phmonte
I can confirm that after excluding those two dlls application works as expected π
I wonder if adding some fallbacks would be a nice addition (somthing like searching msbuild
here: https://github.com/dotnet/msbuild/blob/main/src/Shared/BuildEnvironmentHelper.cs#L77).
I have three in my mind:
BUILDALYZER_LOGGER_DLL_PATH
msbuild
Thanks for confirming, I believe it's not the best solution, but it's the only one that enables PublishSingleFile due to current restrictions.
I will make some of your suggestions.
btw. I really appreciate your help π
Have a great day!
@Karql an environment variable was added for publish single file cases in version 7.0.2. Environment variable name: LoggerPathDll
I'll close the issue, any problems open a new one.
@phmonte π
If I publish a .NET 6 app with
PublishSingleFile
enabled (PublishReadyToRun
andPublishTrimmed
don't seem to be related to the issue), it hangs as soon as I callBuild()
.For example, make a fresh class library (its code doesn't matter), and a console app with the following
Program.cs
:If you build and run it, you get both console outputs within a few seconds.
But if you then create a publish profile with
PublishSingleFile
enabled, e.g.:and run that, it seems to hang after the first output.
My first hunch was that code trimming removed something crucial, but that seems to be inactive.
I tried to profile it, and it looks like some kind of deadlock?