You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
SourceLink doesn't work well with WPF projects #91
Microsoft.Managed.Core.targets(90,5): SourceRoot items must include at least one top-level (not nested) item when DeterministicSourcePaths is true [C:\Temp\WpfApp1\WpfApp1\WpfApp1_3qoc4wf0_wpftmp.csproj]
is reported when building with /p:ContinuousIntegrationBuild=true.
Due to NuGet/Home#5894 - WPF projects do not import .props and .targets files from NuGet packages.
The issue in Newtonsoft.Json is related but different than the WPF issue.
When DeterministicSourcePaths is enabled the compiler needs to know the set of directories that all source code resides under. This set is specified by SourceRoot items.
In projects that reference SourceLink package SourceRoot items are populated by SourceLink since it knows where the repository root is.
In projects that do not reference SourceLink package this SourceRoot is undefined and hence the compiler doesn’t know how to normalize the paths and reports the error [1].
The recommendation is to include the SourceLink package reference to all projects in the repo (even to test projects). This can be easily accomplished via adding Directory.Build.props file in the root of the repository that includes the SoruceLink package:
[1] The compiler does not infer the source root(s) based on source file paths it is given as this might produce confusing results. Consider a repo with two projects:
If the compiler inferred the source roots for these projects they would be .../src/ProjectA/ and .../src/ProjectB/ and the paths embedded in DLLs and PDBs to Program.cs files would be /_/Program.cs for both .../src/ProjectA/Program.cs and .../src/ProjectB/Program.cs. So it would be impossible to distinguish which Program.cs is which.
In my case I have a src project with .NET Framework and a test project, building and packaging in a Jenkins. So that I need to turn on DeterministicSourcePaths for the msbuild.exe. (Turn on ContinuousIntegrationBuild has no effects at all.)
Then the work around suggested above won't work anymore, as the Property value supplied at command line to msbuild.exe overrides csproj settings. In order to "remove" the test project from sourcelink process, I need to add this to the test csproj file:
Since you do not import Microsoft.Net.Sdk and do not set Deterministic then ContinuousIntegrationBuild has no effect since only affects deterministic builds.
(InitializeSourceRootMappedPaths target) ->
C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\bin\Roslyn\Microsoft.Managed.Core.targets(90,5): error : SourceRoot items must include at least one top-level (
not nested) item when DeterministicSourcePaths is true [C:\github\xxx\src\Shared.Utilities\tests\Shared.Utilities.Test.csproj]
0 Warning(s)
1 Error(s)
msbuild on the src csproj alone would work, if msbuild the solution file, which including the test project, would give above error.
Right, so that's because you don't have SourceLink and you switch DeterministicSourcePaths to true. I guess I do not understand why you don't want SourceLink in your testing project.
@tmat The reason to use SourceLink is because I'm nuget packaging my library code into nupkg, but I'm not packaging my tests, at least in my case, test project was run to verify the library project then the lib nupkg is produced on Jenkins.
For lack of a better place than this long-closed issue:
What helped me was not to just disable DeterministicSourcePaths for the WPF project, but to set a dummy SourceRoot for the MapSourceRoot task to find, like this, which can be put in a Directory.Build.targets to apply to all WPF projects of the repo:
<Project>
<Target Name="WpfSourceLinkWorkaround" BeforeTargets="InitializeSourceRootMappedPaths" Condition="'$(UseWPF)' == 'true' And $(DeterministicSourcePaths)">
<!-- WPF causes an error with SourceLink because its build targets create a temporary project without a PackageReference to SourceLink, see https://github.com/dotnet/sourcelink/issues/91,
causing the @SourceRoot property to be unexpectedly empty for the MapSourceRoot task
For context, see https://github.com/dotnet/roslyn/blob/main/src/Compilers/Core/MSBuildTask/Microsoft.Managed.Core.targets
and https://github.com/dotnet/roslyn/blob/main/src/Compilers/Core/MSBuildTask/MapSourceRoots.cs
This workaround sets the SourceRoot manually to some deterministic value to keep the promise given by having DeterministicSourcePaths set to true -->
<Message Text="using deterministic source path workaround for WPF project instead of SourceLink" />
<ItemGroup>
<!-- There needs to be at least one SourceRoot defined, its value does not seem to matter as long as it ends with a directory separator -->
<SourceRoot Include="\" />
</ItemGroup>
</Target>
</Project>
The workaround above by @shuebner stopped working in VS 17.8.0 Preview 4.0:
Directory.Build.props(28,92): error MSB4100: Expected "$(DeterministicSourcePaths)" to evaluate to a boolean instead of "", in condition "'$(UseWPF)' == 'true' And $(DeterministicSourcePaths)".
I belive it can be fixed by changing the condition to Condition="'$(UseWPF)' == 'true' And $(DeterministicSourcePaths) != ''"
anyone can confirm this is okay?
Activity
tmat commentedon Jun 13, 2018
The workaround is to add
to the .csproj file.
JamesNK commentedon Jun 23, 2018
I get this in
Newtonsoft.Json.TestsandNewtonsoft.Json.TestConsolewhen I build. I'm guessing becauseIsPackableis false?JamesNK commentedon Jun 24, 2018
Or is the issue that I am building an entire solution and source link doesn't like multiple
csprojs?I've fixed the error by adding the code above to the two test projects - https://github.com/JamesNK/Newtonsoft.Json/pull/1746/files#diff-9d91529ee3797584a27061bbad1d49ceR16
tmat commentedon Jun 27, 2018
The issue in Newtonsoft.Json is related but different than the WPF issue.
When
DeterministicSourcePathsis enabled the compiler needs to know the set of directories that all source code resides under. This set is specified bySourceRootitems.In projects that reference SourceLink package
SourceRootitems are populated by SourceLink since it knows where the repository root is.In projects that do not reference SourceLink package this
SourceRootis undefined and hence the compiler doesn’t know how to normalize the paths and reports the error [1].The recommendation is to include the SourceLink package reference to all projects in the repo (even to test projects). This can be easily accomplished via adding
Directory.Build.propsfile in the root of the repository that includes the SoruceLink package:[1] The compiler does not infer the source root(s) based on source file paths it is given as this might produce confusing results. Consider a repo with two projects:
If the compiler inferred the source roots for these projects they would be
.../src/ProjectA/and.../src/ProjectB/and the paths embedded in DLLs and PDBs toProgram.csfiles would be/_/Program.csfor both.../src/ProjectA/Program.csand.../src/ProjectB/Program.cs. So it would be impossible to distinguish whichProgram.csis which.xied75 commentedon Aug 13, 2018
In my case I have a src project with .NET Framework and a test project, building and packaging in a Jenkins. So that I need to turn on DeterministicSourcePaths for the msbuild.exe. (Turn on ContinuousIntegrationBuild has no effects at all.)
Then the work around suggested above won't work anymore, as the Property value supplied at command line to msbuild.exe overrides csproj settings. In order to "remove" the test project from sourcelink process, I need to add this to the test csproj file:
tmat commentedon Aug 13, 2018
Does your project set
Deterministicproperty to true?Why do you need to remove it?
xied75 commentedon Aug 15, 2018
@tmat
if you mean /Deterministic to the Roslyn, I didn't set it.
Because I don't want to install SourceLink nuget package into my testing project, and then the compile would error out.
tmat commentedon Aug 15, 2018
Since you do not import Microsoft.Net.Sdk and do not set Deterministic then ContinuousIntegrationBuild has no effect since only affects deterministic builds.
What error does it report?
xied75 commentedon Aug 15, 2018
msbuild on the src csproj alone would work, if msbuild the solution file, which including the test project, would give above error.
tmat commentedon Aug 15, 2018
Right, so that's because you don't have SourceLink and you switch DeterministicSourcePaths to true. I guess I do not understand why you don't want SourceLink in your testing project.
xied75 commentedon Aug 16, 2018
@tmat The reason to use SourceLink is because I'm nuget packaging my library code into nupkg, but I'm not packaging my tests, at least in my case, test project was run to verify the library project then the lib nupkg is produced on Jenkins.
Move development NuGet dependencies into Directory.Build.props
Disable deterministic source paths for WPF
shuebner commentedon Oct 29, 2021
For lack of a better place than this long-closed issue:
What helped me was not to just disable DeterministicSourcePaths for the WPF project, but to set a dummy SourceRoot for the MapSourceRoot task to find, like this, which can be put in a Directory.Build.targets to apply to all WPF projects of the repo:
Dunge commentedon Oct 23, 2023
The workaround above by @shuebner stopped working in VS 17.8.0 Preview 4.0:
I belive it can be fixed by changing the condition to
Condition="'$(UseWPF)' == 'true' And $(DeterministicSourcePaths) != ''"anyone can confirm this is okay?
tmat commentedon Oct 23, 2023
@Dunge looks good to me. Does the issue (without workaround) reproduce when using .NET 8 SDK?
Dunge commentedon Oct 23, 2023
@tmat you are right, I do not remember the error that forced me to add this workaround a few years ago, but it doesn't seem necessary anymore.