Skip to content

Commit 2b6c1eb

Browse files
fix(pack): make Reactor.csproj find analyzer DLL at platform-qualified path
Backs out the AppendPlatformToOutputPath=false approach (which broke unit tests with CS2012 file-lock contention on Reactor.Localization.Generator/obj/Debug/netstandard2.0/...) in favor of teaching Reactor.csproj's <None Include> globs about the inherited- Platform layout. The cause of the original clean-machine pack failure is unchanged: when mur pack-local runs `dotnet pack -p:Platform=x64` (or ARM64), the inherited Platform cascades to the transitive Reactor.Analyzers and Reactor.Localization.Generator builds, which then land at bin\<Platform>\<Configuration>\netstandard2.0\. But Reactor.csproj's pack glob hardcoded bin\<Configuration>\netstandard2.0\ (no Platform segment), so pack couldn't find the file on a freshly-cloned machine. Pinning AppendPlatformToOutputPath=false on the analyzers fixed pack-local but removed bin/obj segregation across Platform values, which let two concurrent transitive compiles (e.g. dotnet test + ProjectReference deduplication race) collide on the same obj\Debug\netstandard2.0\ output path. CI Unit Tests caught this with: CSC : error CS2012: Cannot open '...obj\Debug\netstandard2.0\ Reactor.Localization.Generator.dll' for writing -- The process cannot access the file ... because it is being used by another process. New approach: Reactor.csproj computes $(_ReactorAnalyzerBinDir) = bin\<Configuration>\netstandard2.0 when Platform is empty or AnyCPU, OR = bin\<Platform>\<Configuration>\netstandard2.0 when Platform is x64 / ARM64. Pack now finds the analyzers in either layout. The analyzer csprojs go back to their stock SDK behavior, preserving per-Platform obj/bin segregation that prevents the build-graph race. Verified locally: - mur pack-local from a wiped bin/obj tree succeeds on ARM64 host (analyzers land in bin\ARM64\Debug\, Reactor.csproj finds them). - Plain dotnet build src/Reactor (no -p:Platform) would land analyzers at bin\Debug\, also found by the conditional binding. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent dee53ef commit 2b6c1eb

3 files changed

Lines changed: 16 additions & 19 deletions

File tree

src/Reactor.Analyzers/Reactor.Analyzers.csproj

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,6 @@
1212
<!-- Bundled into Microsoft.UI.Reactor.nupkg — does not ship as its own
1313
package. See docs/specs/022-packaging-and-distribution.md §5. -->
1414
<IsPackable>false</IsPackable>
15-
16-
<!-- Analyzers are platform-independent netstandard2.0 IL. Without this,
17-
when Reactor.csproj is packed with `-p:Platform=x64` (or ARM64) the
18-
inherited Platform cascades into this transitive build and the
19-
output lands at bin\x64\Debug\netstandard2.0\ — but Reactor.csproj's
20-
<None Include="...\bin\$(Configuration)\netstandard2.0\..."> for
21-
packing the analyzer DLL has no $(Platform) segment and breaks pack
22-
on a clean machine (no prior AnyCPU build to fall back to).
23-
AppendPlatformToOutputPath=false pins us to bin\$(Configuration)\
24-
regardless of inherited Platform. -->
25-
<AppendPlatformToOutputPath>false</AppendPlatformToOutputPath>
2615
</PropertyGroup>
2716

2817
<ItemGroup>

src/Reactor.Localization.Generator/Reactor.Localization.Generator.csproj

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,6 @@
99
<IsRoslynComponent>true</IsRoslynComponent>
1010
<RootNamespace>Microsoft.UI.Reactor.Localization.Generator</RootNamespace>
1111
<AssemblyName>Reactor.Localization.Generator</AssemblyName>
12-
13-
<!-- See Reactor.Analyzers.csproj for the full rationale: Reactor.csproj's
14-
<None Include="...\bin\$(Configuration)\netstandard2.0\..."> pack
15-
glob has no $(Platform) segment, so this transitive source-generator
16-
build must not append the inherited Platform to its OutputPath. -->
17-
<AppendPlatformToOutputPath>false</AppendPlatformToOutputPath>
1812
</PropertyGroup>
1913

2014
<ItemGroup>

src/Reactor/Reactor.csproj

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,24 @@
102102
against the framework itself), so their build outputs must already
103103
exist before pack — verified by the AssertAnalyzerDllsExist target
104104
below. -->
105+
<!-- Resolve the per-build output dir of the analyzer ProjectReferences.
106+
MSBuild propagates $(Platform) to transitive builds: with no
107+
-p:Platform (e.g. plain `dotnet build`), the analyzer lands at
108+
bin\$(Configuration)\netstandard2.0\; with -p:Platform=x64/ARM64
109+
(e.g. `mur pack-local`), it lands at bin\$(Platform)\$(Configuration)\
110+
netstandard2.0\ because <AppendPlatformToOutputPath> defaults to
111+
true. Compute the path accordingly so pack finds the DLL in either
112+
layout — without this, pack-local on a clean machine fails with
113+
NU3168/CS2012 because the platform-less path has nothing in it. -->
114+
<PropertyGroup>
115+
<_ReactorAnalyzerBinDir Condition="'$(Platform)' == '' or '$(Platform)' == 'AnyCPU'">bin\$(Configuration)\netstandard2.0</_ReactorAnalyzerBinDir>
116+
<_ReactorAnalyzerBinDir Condition="'$(_ReactorAnalyzerBinDir)' == ''">bin\$(Platform)\$(Configuration)\netstandard2.0</_ReactorAnalyzerBinDir>
117+
</PropertyGroup>
118+
105119
<ItemGroup>
106-
<None Include="..\Reactor.Analyzers\bin\$(Configuration)\netstandard2.0\Reactor.Analyzers.dll"
120+
<None Include="..\Reactor.Analyzers\$(_ReactorAnalyzerBinDir)\Reactor.Analyzers.dll"
107121
Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
108-
<None Include="..\Reactor.Localization.Generator\bin\$(Configuration)\netstandard2.0\Reactor.Localization.Generator.dll"
122+
<None Include="..\Reactor.Localization.Generator\$(_ReactorAnalyzerBinDir)\Reactor.Localization.Generator.dll"
109123
Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
110124
<None Include="..\..\LICENSE" Pack="true" PackagePath="" Visible="false" />
111125
<!-- Agent kit packed into the NuGet at `agentkit/`: SKILL.md, every

0 commit comments

Comments
 (0)