Closed ylatuya closed 1 year ago
In case someone has the same issue, this is workaround that pre-processes the list of libraries to relocate:
<UsingTask
TaskName="RemoveReindentifyDuplicates"
TaskFactory="RoslynCodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll" >
<ParameterGroup>
<Files ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
<Result ParameterType="Microsoft.Build.Framework.ITaskItem[]" Output="true" />
</ParameterGroup>
<Task>
<Using Namespace="System.Collections.Generic"/>
<Code Type="Fragment" Language="cs">
<![CDATA[
if (Files.Length > 0)
{
var itemsDict = new Dictionary<string, ITaskItem> ();
for (int i = 0; i < Files.Length; i++)
{
ITaskItem item = Files[i];
string targetPath = item.GetMetadata("TargetPath");
itemsDict[targetPath] = item;
}
Result = itemsDict.Values.ToArray();
}
]]>
</Code>
</Task>
</UsingTask>
<Target Name="CleanDynamicLibrariesToReidentify" AfterTargets="_ComputeDynamicLibrariesToReidentify" BeforeTargets="_InstallNameTool">
<RemoveReindentifyDuplicates Files="@(_DynamicLibraryToReidentify)">
<Output TaskParameter="Result" ItemName="_DistinctDynamicLibraryToReidentify" />
</RemoveReindentifyDuplicates>
<ItemGroup>
<_DynamicLibraryToReidentify Remove="@(_DynamicLibraryToReidentify)" />
<_DynamicLibraryToReidentify Include="@(_DistinctDynamicLibraryToReidentify)" />
</ItemGroup>
</Target>
The clean-up needs to be done a little bit earlier, in the list of _FileNativeReference.
<UsingTask TaskName="RemoveFileNativeReferenceDuplicates" TaskFactory="RoslynCodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
<ParameterGroup>
<Files ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
<Result ParameterType="Microsoft.Build.Framework.ITaskItem[]" Output="true" />
</ParameterGroup>
<Task>
<Using Namespace="System.Collections.Generic" />
<Code Type="Fragment" Language="cs">
<![CDATA[
if (Files.Length > 0)
{
var itemsDict = new Dictionary<string, ITaskItem> ();
for (int i = 0; i < Files.Length; i++)
{
ITaskItem item = Files[i];
string targetPath = item.GetMetadata("RelativePath");
itemsDict[targetPath] = item;
}
Result = itemsDict.Values.ToArray();
}
]]>
</Code>
</Task>
</UsingTask>
<Target Name="CleanFileNativeReference" AfterTargets="_ComputeFrameworkFilesToPublish" BeforeTargets="_ComputeDynamicLibrariesToReidentify">
<RemoveFileNativeReferenceDuplicates Files="@(_FileNativeReference)">
<Output TaskParameter="Result" ItemName="_DistincFileNativeReference" />
</RemoveFileNativeReferenceDuplicates>
<ItemGroup>
<_FileNativeReference Remove="@(_FileNativeReference)" />
<_FileNativeReference Include="@(_DistincFileNativeReference)" />
</ItemGroup>
</Target>
@rolfbjarne I have found a new scenario in which it's impossible to fix this issue even with the pre-processing step posted in my previous comments. The issue can be reproduced in a project that includes the following packages:
These packages includes files with the same name that will be installed in different output directories (they have different RelativePath):
Since in this example we have 2 files with the same name that are going to be installed in different places, we can't use the filtering method. That method worked because the RelativePath was the same so we were only considering the last frame.
This bug makes it impossible to use popular nuget's that uses CEF, such as the WebViewControl-Avalonia one. Would it make sense to prioritize it for .Net 7?
@rolfbjarne I have found a new scenario in which it's impossible to fix this issue even with the pre-processing step posted in my previous comments. The issue can be reproduced in a project that includes the following packages:
* cefglue.common * microsoft.netcore.app.runtime.osx-x64
These packages includes files with the same name that will be installed in different output directories (they have different RelativePath):
* cefglue.common/91.4472.31/bin/osx/libclrjit.dylib -> RelativePath = Contents\MonoBundle/\CefGlueBrowserProcess\libclrjit.dylib * microsoft.netcore.app.runtime.osx-x64/6.0.11/runtimes/osx-x64/native/libclrjit.dylib -> RelativePath = Contents\MonoBundle/libclrjit.dylib
Since in this example we have 2 files with the same name that are going to be installed in different places, we can't use the filtering method. That method worked because the RelativePath was the same so we were only considering the last frame.
This bug makes it impossible to use popular nuget's that uses CEF, such as the WebViewControl-Avalonia one. Would it make sense to prioritize it for .Net 7?
Since this is a slightly different bug, I will open a new issue for it. I have already a patch that fixes the problem.
Steps to Reproduce
Expected Behavior
The app bundle is created correctly
Actual Behavior
The app bundle creation fails in the InstallNameTool tasks due to a race in the re-identification of files. 2 different processes are using the same output file name: libgio-2.0.0.dylib.
Environment
See build logs
Build Logs
msbuild.binlog.zip
Example Project (If Possible)