git clone https://github.com/ADFCommunity/Adfc.Msbuild
cd Adfc.Msbuild
git checkout feature/crossplat
msbuild /t:restore,build Adfc.Msbuild.sln
msbuild samples\OneConfig
dotnet msbuild samples\OneConfig
This repo is a msbuild task for a custom project type. I tried to get it to run cross platform, but the dotnet cli doesn't appear to be able to load my task's dependencies (which are in the same directory as my task's dependencies).
If you want to reproduce this bug without cloning my repo, create an assembly that targets net46 and netstandard1.5. Add Newtonsoft.Json as a dependency (or any other nuget package), and the relevant Microsoft.Build packages needed to create a task. Edit the csproj to set the property CopyLocalLockFileAssemblies
to true
, so dependencies are in the same bindebugTFM directory as your assembly. Write a MSBuild task that uses the nuget package, in any minimal way. Create a separate msbuild proj file that uses the task from your assembly. Run it using the Windows msbuild.exe, and the build will succeed. Run it using dotnet msbuild
and the dependency assembly will fail to load.
dotnet msbuild samples\OneConfig
should be successful, just as msbuild.exe samples\OneConfig
was.
The .NET Core MSBuild task crashes, unable to load Newtonsoft.Json.dll, while the MSBuild.exe run completes successfully.
C:\git\Adfc.Msbuild\src\Adfc.Msbuild\bin\Debug\Adfc.Msbuild.targets(23,5): error : exception trying to load file System.IO.FileLoadException: Could not load file or assembly 'Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'. Could not find or load a specific file. (Exception from HRESULT: 0x80131621)\r [C:\git\Adfc.Msbuild\samples\OneConfig\OneConfig.proj]
C:\git\Adfc.Msbuild\src\Adfc.Msbuild\bin\Debug\Adfc.Msbuild.targets(23,5): error : File name: 'Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'\r [C:\git\Adfc.Msbuild\samples\OneConfig\OneConfig.proj]
C:\git\Adfc.Msbuild\src\Adfc.Msbuild\bin\Debug\Adfc.Msbuild.targets(23,5): error : at Adfc.Msbuild.JsonFileLoader.Parse(String text, String identity)\r [C:\git\Adfc.Msbuild\samples\OneConfig\OneConfig.proj]
C:\git\Adfc.Msbuild\src\Adfc.Msbuild\bin\Debug\Adfc.Msbuild.targets(23,5): error : at Adfc.Msbuild.AdfcBuild.<LoadJsonFiles>d__10.MoveNext() in C:\git\Adfc.Msbuild\src\Adfc.Msbuild\AdfcBuild.cs:line 69\r [C:\git\Adfc.Msbuild\samples\OneConfig\OneConfig.proj]
C:\git\Adfc.Msbuild\src\Adfc.Msbuild\bin\Debug\Adfc.Msbuild.targets(23,5): error : \r [C:\git\Adfc.Msbuild\samples\OneConfig\OneConfig.proj]
C:\git\Adfc.Msbuild\src\Adfc.Msbuild\bin\Debug\Adfc.Msbuild.targets(23,5): error : [C:\git\Adfc.Msbuild\samples\OneConfig\OneConfig.proj]
.NET Command Line Tools (2.0.0)
Product Information:
Version: 2.0.0
Commit SHA-1 hash: cdcd1928c9
Runtime Environment:
OS Name: Windows
OS Version: 10.0.16273
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\2.0.0\
Microsoft .NET Core Shared Framework Host
Version : 2.0.0
Build : e8b8861ac7faf042c87a5c2f9f2d04c98b69f28d
Seems like dependency resolution is somehow different from the one in Visual Studio. The same projects compile in VS without an error. Adding a reference to a package that is included with the current .NET Core SDK (eg. Newtonsoft.Json
version 9.0.1) does not produce the error, indicating that dotnet build
loads the task dll's dependencies from the SDK folder instead of the task dll folder.
This is the same underlying issue as https://github.com/Microsoft/msbuild/issues/2484
Is there some workaround for this? I have a similar issue with a completely different project.
Using version 9.0.1 of Newtonsoft.Json works, as BalassaMarton said, assuming you're also having a problem with Newtonsoft.Json.
@zivkan Yes, I have the exactly the same problem, but it is not very good solution. If .NET Core CLI will start shipping a different version of Newtonsoft.Json - we will have to upgrade as well and at this point, we will lose compatibility with the previous version. Note that the whole point is to achieve portability with using .NET Standard and .NET Core CLI.
@zivkan I notice you are compiling your custom MSBuild task against the net46 target framework. I was unable to get ANTLR 4's code generation task working in this form, but when I changed it to target netstandard1.5, it started working.
Also, after prolonged problems with Json.NET in various build-related scenarios, the StyleCop Analyzers project finally switched to using an embedded JSON parser (LightJson). You can find our implementation here (with bug fixes and tests):
https://github.com/DotNetAnalyzers/StyleCopAnalyzers/tree/master/StyleCop.Analyzers/StyleCop.Analyzers/LightJson
@VHaravy You asked for a workaround, not a solution :)
Hopefully by the time the .NET Core CLI changes the version it bundles there will be a solution. Also, given that the .NET Core CLI from the earliest versions (the oldest version I have on my machine is 1.0.0-preview2), right to the current version, bundle the same version of Newtonsoft.Json, it appears that the team may be aware of the issue and keeps shipping the same version to avoid breaking compatibility. If that's correct, then there's minimal risk that they will start shipping a different version until a solution is available.
An idea for another workaround is to ship a .exe with your build tools, rather than a .dll that has a MSBuild task, and execute that. I don't know what that means with regards to reporting errors and warnings to Visual Studio though. Worst case you need a normal MSBuild custom task that starts your executable and uses IPC to get the logging information. Poor man's app domains :)
My guess about the root cause is that .NET Core doesn't support App Domains, and MSBuild loads Newtonsoft.Json v9.0.1 before loading our custom assembly. Without being able to load our custom assembly in a new app domain, there's no way to unload Newtonsoft.Json v9 and load the version our code depends on. If I'm right about this being the cause of the problem, then I don't expect a solution any time soon.
@sharwell When I first started playing around with MSBuild tasks running in .NET Core, I found that msbuild.exe on Windows would not load .NET Standard assemblies. Therefore, to make my task work both msbuild and dotnet cli, I need to ship both net46 and netstandard1.5 assemblies, and choose which one to load in my targets file: https://github.com/ADFCommunity/Adfc.Msbuild/blob/feature/crossplat/src/Adfc.Msbuild/build/Adfc.Msbuild.targets
Therefore, to make my task work both msbuild and dotnet cli, I need to ship both net46 and netstandard1.5 assemblies, and choose which one to load in my targets file.
Yes, I had to do the same thing as well.
Same here.
I'm suffering similar problems loading another .dll.
This test project works like a charm when compiled from VS but fails to compile from cli, not being able to load RoslynCodeTaskFactory.dll
.
Could anybody confirm whether it can be this same issue or it may be something else?
I am running into a similar issue here. Is there a solution for this?
I'm having a similar issue. Any solutions yet?
The biggest step for this will be with microsoft/msbuild#1754. That should transparently resolve some of the harder conflicts with, for example, Newtonsoft.Json.
Most helpful comment
I am running into a similar issue here. Is there a solution for this?