msbuild icon indicating copy to clipboard operation
msbuild copied to clipboard

Custom target in ProjectB runs too late for consuming ProjectA

Open AlexanderRydberg opened this issue 2 months ago • 0 comments

Issue Description

Im unable to build a csproj that depends on another csproj that has custom targets. Getting different results on dotnet vs msbuild.exe depending on using sln, slnx or csproj

ProjectB generates files in a Target

<Target Name="RunLBeforeBuildStepgen" BeforeTargets="BeforeBuild" >
	<Message Text="=== Generating localizations ===" Importance="high" />
       <WriteLinesToFile File="Localizations.js" Lines="Localization data generated before build." />
</Target>

ProjectA depend on some files generated by ProjectB. ProjectA have this in its libman.json:

{
  "version": "1.0",
  "defaultProvider": "filesystem",
  "libraries": [
    {
      "library": "../../ProjectB/",
        "files": [ "Localizations.js" ],
      "destination": "wwwroot/assets/l10n/"
    }
  ]
}

dotnet build .\ProjectA\ProjectA\ProjectA.csproj fails:

Restore complete (0.3s)
    info NETSDK1057: You are using a preview version of .NET. See: https://aka.ms/dotnet-support-policy
  ProjectA net8.0 failed with 2 error(s) (0.1s)
    D:\Nuget\microsoft.web.librarymanager.build\3.0.71\build\Microsoft.Web.LibraryManager.Build.targets(35,9): error
      System.AggregateException: One or more errors occurred. (The "../../ProjectB/" library could not be resolved by th
      e "filesystem" provider)
       ---> Microsoft.Web.LibraryManager.Contracts.InvalidLibraryException: The "../../ProjectB/" library could not be r
      esolved by the "filesystem" provider
         at Microsoft.Web.LibraryManager.Providers.FileSystem.FileSystemProvider.GetStreamAsync(ILibraryInstallationStat
      e state, String file, CancellationToken cancellationToken)
         --- End of inner exception stack trace ---
         at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
         at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
         at Microsoft.Web.LibraryManager.Providers.FileSystem.FileSystemProvider.<>c__DisplayClass9_1.<InstallAsync>b__0
      ()
         at Microsoft.Web.LibraryManager.Build.Contracts.HostInteraction.WriteFileAsync(String path, Func`1 content, ILi
      braryInstallationState state, CancellationToken cancellationToken)
         at Microsoft.Web.LibraryManager.Providers.FileSystem.FileSystemProvider.InstallAsync(ILibraryInstallationState
      desiredState, CancellationToken cancellationToken)
    libman.json : error LIB000: An unknown exception occurred

Trying to supply as much info as possible.

Steps to Reproduce

Repo to repro https://github.com/AlexanderRydberg/LibraryManagerTargetIssue

--- Wont build --- Build csproj with msbuild

$msbuildPath = "C:\Program Files\Microsoft Visual Studio\18\Professional\MSBuild\Current\Bin\MSBuild.exe"
&"$msbuildPath" .\ProjectA\ProjectA\ProjectA.csproj '/t:Clean' /p:Configuration=Release
&"$msbuildPath" .\ProjectA\ProjectA\ProjectA.csproj '/t:Build' /r /m /p:Configuration=Release

Build csproj with dotnet

dotnet clean .\ProjectA\ProjectA\ProjectA.csproj
dotnet build .\ProjectA\ProjectA\ProjectA.csproj

Build csproj with dotnet

dotnet clean .\ProjectA\ProjectA\ProjectA.csproj
dotnet build .\ProjectA\ProjectA\ProjectA.csproj

Building slnx with dotnet

dotnet clean .\ProjectA\ProjectA.slnx
dotnet build .\ProjectA\ProjectA.slnx

--- Will build --- Building slnx with msbuild

$msbuildPath = "C:\Program Files\Microsoft Visual Studio\18\Professional\MSBuild\Current\Bin\MSBuild.exe"

# Make sure we always start from a clean state
&"$msbuildPath" .\ProjectA\ProjectA.slnx /r '/t:Clean' /m /p:Configuration=Release
&"$msbuildPath" .\ProjectA\ProjectA.slnx /r '/t:Restore;Rebuild' /m /p:Configuration=Release
&"$msbuildPath" .\ProjectA\ProjectA.slnx /r '/t:Clean' /m /p:Configuration=Release
&"$msbuildPath" .\ProjectA\ProjectA.slnx /r '/t:Build' /m /p:Configuration=Release

Buillding sln with msbuild

# create sln file
dotnet new sln -n Project
dotnet sln Project.sln add .\ProjectA\ProjectA\ProjectA.csproj
dotnet sln Project.sln add .\ProjectB\ProjectB.csproj

$msbuildPath = "C:\Program Files\Microsoft Visual Studio\18\Professional\MSBuild\Current\Bin\MSBuild.exe"
&"$msbuildPath" .\Project.sln '/t:Clean' /m /p:Configuration=Release
&"$msbuildPath" .\Project.sln /r '/t:Restore;Rebuild' /m /p:Configuration=Release
&"$msbuildPath" .\Project.sln '/t:Clean' /m /p:Configuration=Release
&"$msbuildPath" .\Project.sln /r '/t:Build' /m /p:Configuration=Release

Expected Behavior

ProjectB and all its targets should build before ProjectA no matter if we build slnx, sln or csproj.

If we add this to slnx, it works:

<Solution>
  <Project Path="../ProjectB/ProjectB.csproj" />
  <Project Path="ProjectA/ProjectA.csproj">
    <BuildDependency Project="../ProjectB/ProjectB.csproj" />
  </Project>
</Solution>

Actual Behavior

ProjectB and its targets isnt finished before ProjectA starts

Analysis

I created an issue on the LibraryManager-repo here: https://github.com/aspnet/LibraryManager/issues/808 but we suspect that its maybe msbuild and/or CLI that has a bug.

Versions & Configurations

MSBuild version 18.0.5+e22287bf1 for .NET Framework
18.0.5.56406

Dotnet --version

dotnet --info
.NET SDK:
 Version:           10.0.100
 Commit:            b0f34d51fc
 Workload version:  10.0.100-manifests.5fb86115
 MSBuild version:   18.0.2+b0f34d51f

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.26200
 OS Platform: Windows
 RID:         win-x64
 Base Path:   C:\Program Files\dotnet\sdk\10.0.100\

.NET workloads installed:
There are no installed workloads to display.
Configured to use workload sets when installing new manifests.
No workload sets are installed. Run "dotnet workload restore" to install a workload set.

Host:
  Version:      10.0.0
  Architecture: x64
  Commit:       b0f34d51fc

.NET SDKs installed:
  6.0.425 [C:\Program Files\dotnet\sdk]
  7.0.410 [C:\Program Files\dotnet\sdk]
  8.0.416 [C:\Program Files\dotnet\sdk]
  9.0.308 [C:\Program Files\dotnet\sdk]
  10.0.100-rc.1.25451.107 [C:\Program Files\dotnet\sdk]
  10.0.100 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.33 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 8.0.22 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 9.0.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 10.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.33 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 8.0.22 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 9.0.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 10.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 6.0.33 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 8.0.22 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 9.0.11 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 10.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Other architectures found:
  x86   [C:\Program Files (x86)\dotnet]
    registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]

Environment variables:
  Not set

global.json file:
  Not found

Learn more:
  https://aka.ms/dotnet/info

Download .NET:
  https://aka.ms/dotnet/download

AlexanderRydberg avatar Nov 29 '25 15:11 AlexanderRydberg