-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Build for desktop framework on non-windows platforms #335
Comments
We would like this to work, but haven't had the time yet to invest in it. I would prefer that msbuild common targets could resolve the mono targeting pack directory, rather than special work in the SDK to locate it. |
Here's the current code that resolves the Mono reference assemblies: Someone (dotnet/SDK or core MSBuild) could call into this code to get the path. (There is also an environment variable available to override the path). |
Aside: That class has a super general name, no docs, and only actually finds the directory on non-Windows. I think there should be a root reference assembly directory resolved by msbuild that works on all platforms, and we should use that throughout. It is super strange to me that when we call this, we then have to handle windows separately:
This should all be in one place. |
So it looks like msbuild already has $(TargetFrameworkRootPath) which the user can override (but we wouldn't respect). However, it seems to not set it to non-empty when the task uses a default value. Here's how I'd like things to work:
@rainersigwald @jeffkl What do you think? |
Agreed that ALL the logic should exist in one place. Another aside here is that this code needs to run/work at runtime of the app because things like ASP.NET MVC Razor View compilation needs to find these assemblies. That's the reason at least part of this code (the non-windows part) is contained in DependencyModel - which is used both at build and run time. |
If msbuild can safely take a dependency on the same thing that finds it at runtime, then we can truly have only one place. Regardless of duplication, though, everything running in the build to resolve this directory the same way GetReferenceAssemblyPaths does. Otherwise, there's a mismatch where RAR can respect $(TargetFrameworkRootPath) set by user, but other code in the SDK cannot, etc. |
Maybe the most appropriate thing to do here is for the tooling (MSBuild, SDK, etc) to write the location into the .deps.json file during "build" so it can be used by "run". The DependencyModel can use that value as one more place to look for ref assemblies. During "publish" the value wouldn't get written into the .deps.json file because the ref assemblies get copied to the "refs" folder. Thus a published app doesn't need to get the location Reference Assemlies folder, since it won't exist on the end-users machine. |
@eerhardt That sounds like the right place to land indeed. |
Wouldn't it be simpler - from a end-user perspective - to pull the complete set of reference assemblies as a NuGet package? Similar to referencing |
We have talked informally about having classic targeting packs available as nuget packages before. @terrajobst, any plans there? |
We've had https://dotnet.myget.org/feed/dotnet-core/package/nuget/Microsoft.TargetingPack.NETFramework.v4.6.2 (and other .NET framework versions) for a while, but they're only used for internal builds and aren't published to nuget.org. I think they contain the same assemblies as the real targeting pack. |
@mellinoe IIRC I tried to use those (for a different, internal project) and they were missing some key parts. I once talked about this offline with @akoeplinger, but didn't reach a conclusion. MSBuild on .NET Core doesn't support finding references in all the same ways we do on Mono/Desktop framework. Most relevant is probably GAC resolution, but targeting packs are also important. As mentioned above, those should be nugetizable--in which case you could probably get stuff built pretty well. There are some other task differences though ( The deps-file approach for run does seem reasonable to me too (given the current CLI run behavior). |
I don't care at all about GAC resolution. If your build depends on it, it's busted as far as I'm concerned. We never should have gone to the GAC for compilation references. I've removed GAC from the default RAR search paths in the SDK. Targeting packs via nuget would certainly be nice, but do we need to block on it? What's the harm in probing for xbuild-frameworks? As far as other differences (GenerateResources), we should distinguish between what are temporary gaps and what is fundamentally never going to work on Core. |
I hope that this gets resolved by RTM. Currently this makes the csproj variant of the .NET CLI a non-starter for most of my projects. |
this feature would allow roundtripping projects between vs and vs4mac. right now, you can't do that if they have TargetFrameworks like net461;netcoreapp1.0 |
Has this been worked on for preview 4 of the CLI? |
After checking I confirm that this is still an issue with preview 4. Are there any known workarounds? |
I'm taking a look at doing something simple to unblock this. |
Thanks, even passing in some magic property would help. |
So as a workaround, explicitly passing/setting TargetFrameworkRootPath with path to xbuild-frameworks (e.g. /p:TargetFrameworkRootPath=/usr/lib/mono/xbuild-frameworks) should work, but doesn't. The issue is that the mono redist list files have a redirect of the TargetFrameworkDirectory to somewhere else. msbuild understands this redirect, but currently only if it's actually running on Mono: :( |
I did try that workaround and it did not work as you mentioned. Mono happens to redirect 4.6.x down to 4.5 to the 4.0 directory for example. It also does not list all the assemblies, relying on the automatic selection of all assemblies in the specified directory instead. |
Can we open an issue against msbuild to have the behaviour change? Or have they mentioned that this will not change? |
Any progress here? |
I asked on the msbuild repo but no one answered so far. |
fyi I've had success using the targeting pack nuget (adding the <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp1.0;net461</TargetFrameworks>
<RuntimeIdentifiers>osx.10.11-x64;win7-x64</RuntimeIdentifiers>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'net461' ">
<RuntimeIdentifier>win7-x64</RuntimeIdentifier>
<FrameworkPathOverride>$(NuGetPackageRoot)microsoft.targetingpack.netframework.v4.6.1\1.0.1\lib\net461\</FrameworkPathOverride>
</PropertyGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net461' ">
<PackageReference Include="Microsoft.TargetingPack.NETFramework.v4.6.1" Version="1.0.1" ExcludeAssets="All" PrivateAssets="All" />
</ItemGroup>
</Project> |
I tried out a slightly modified form of @wadewegner's Gist for
I've probably missed something, but I can't really tell what from this output. Do I need to, e.g., copy the Targeting Pack assemblies to the publish folder, or make my libraries target |
Hi there, I also updated my project like the example by @dasMulli but for net472. My build throws a couple of warnings and the error at the end that
Upon some investigation, and searching through the .nuget/packages: find /home/gaviriar/.nuget/ -name "*mscorlib.dll"
It seems like the |
@gaviriar I think something is a bit off in your project file for this workaround, just tested building for 4.7.2 using: <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp2.1;net472</TargetFrameworks>
<RestoreAdditionalProjectSources>$(RestoreAdditionalProjectSources);https://dotnet.myget.org/F/dotnet-core/api/v3/index.json</RestoreAdditionalProjectSources>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'net472' ">
<FrameworkPathOverride>$(PkgMicrosoft_TargetingPack_NETFramework_v4_7_2)\lib\net472\</FrameworkPathOverride>
</PropertyGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net472' ">
<PackageReference Include="Microsoft.TargetingPack.NETFramework.v4.7.2" Version="1.0.0" ExcludeAssets="All" PrivateAssets="All" GeneratePathProperty="true" />
</ItemGroup>
</Project> Note that the |
This technique doesn't seem to work right for me, quite (on macOS): <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net461;netstandard2.0</TargetFrameworks>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'net461'">
<FrameworkPathOverride>$(NuGetPackageRoot)microsoft.targetingpack.netframework.v4.6.1\1.0.1\lib\net461\</FrameworkPathOverride>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net461'">
<PackageReference Include="Microsoft.TargetingPack.NETFramework.v4.6.1" Version="1.0.1" />
</ItemGroup>
</Project> The top of the stack of errors:
Maybe has something changed since this workaround was first suggested? Is my path override incorrect? |
I am also interested to know. It has been a while since this issue is around. Wondering if any solutions are available in the meantime. |
… ongoing issue, see: dotnet/sdk#335
Without a targeting pack running dotnet build on a mac/ubuntu will fail with a "Reference assemblies were not found".Adding these targeting pack will allow happy roundtripping between windows and mac or ubuntu. See dotnet/sdk#335 for more details
- Removed Fake build, using Cake instead - Removed unused install.ps1 for MtHost - Organize all Samples into a subdirectory - Organize common properties into common.props and signing.props - Update readme.md with nuget package links - Support Appveyor build on ubuntu and windows - Ubuntu builds will only run tests on netcore/netstandard and to support this added netfx.props to projects as described [here](dotnet/sdk#335 (comment)) - windows tests run on full framework + netstandard
@dsyme's solution (slightly modified below) seems to work perfectly on Ubuntu and Mac using Azure DevOps. <PropertyGroup Label="Build net4xx on Mono" Condition="$(TargetFramework.StartsWith('net4')) and '$(OS)' == 'Unix'">
<!-- See https://www.cafe-encounter.net/p2312/multi-targetting-net-framework-and-net-core-in-a-single-project -->
<!-- When compiling .NET Core SDK 2.0 projects targeting .NET 4.x.x on Mono using 'dotnet build' you have to -->
<!-- tell MSBuild where the Mono copy of the reference assemblies is. Looks in the standard install locations. -->
<BaseFrameworkPathOverrideForMono Condition="'$(BaseFrameworkPathOverrideForMono)' == '' AND EXISTS('/Library/Frameworks/Mono.framework/Versions/Current/lib/mono')">/Library/Frameworks/Mono.framework/Versions/Current/lib/mono</BaseFrameworkPathOverrideForMono>
<BaseFrameworkPathOverrideForMono Condition="'$(BaseFrameworkPathOverrideForMono)' == '' AND EXISTS('/usr/lib/mono')">/usr/lib/mono</BaseFrameworkPathOverrideForMono>
<BaseFrameworkPathOverrideForMono Condition="'$(BaseFrameworkPathOverrideForMono)' == '' AND EXISTS('/usr/local/lib/mono')">/usr/local/lib/mono</BaseFrameworkPathOverrideForMono>
<!-- If we found Mono reference assemblies, then use them. -->
<FrameworkPathOverride Condition="'$(BaseFrameworkPathOverrideForMono)' != '' AND '$(TargetFramework)' == 'net40'">$(BaseFrameworkPathOverrideForMono)/4.0-api</FrameworkPathOverride>
<FrameworkPathOverride Condition="'$(BaseFrameworkPathOverrideForMono)' != '' AND '$(TargetFramework)' == 'net45'">$(BaseFrameworkPathOverrideForMono)/4.5-api</FrameworkPathOverride>
<FrameworkPathOverride Condition="'$(BaseFrameworkPathOverrideForMono)' != '' AND '$(TargetFramework)' == 'net451'">$(BaseFrameworkPathOverrideForMono)/4.5.1-api</FrameworkPathOverride>
<FrameworkPathOverride Condition="'$(BaseFrameworkPathOverrideForMono)' != '' AND '$(TargetFramework)' == 'net452'">$(BaseFrameworkPathOverrideForMono)/4.5.2-api</FrameworkPathOverride>
<FrameworkPathOverride Condition="'$(BaseFrameworkPathOverrideForMono)' != '' AND '$(TargetFramework)' == 'net46'">$(BaseFrameworkPathOverrideForMono)/4.6-api</FrameworkPathOverride>
<FrameworkPathOverride Condition="'$(BaseFrameworkPathOverrideForMono)' != '' AND '$(TargetFramework)' == 'net461'">$(BaseFrameworkPathOverrideForMono)/4.6.1-api</FrameworkPathOverride>
<FrameworkPathOverride Condition="'$(BaseFrameworkPathOverrideForMono)' != '' AND '$(TargetFramework)' == 'net462'">$(BaseFrameworkPathOverrideForMono)/4.6.2-api</FrameworkPathOverride>
<FrameworkPathOverride Condition="'$(BaseFrameworkPathOverrideForMono)' != '' AND '$(TargetFramework)' == 'net47'">$(BaseFrameworkPathOverrideForMono)/4.7-api</FrameworkPathOverride>
<FrameworkPathOverride Condition="'$(BaseFrameworkPathOverrideForMono)' != '' AND '$(TargetFramework)' == 'net471'">$(BaseFrameworkPathOverrideForMono)/4.7.1-api</FrameworkPathOverride>
<FrameworkPathOverride Condition="'$(BaseFrameworkPathOverrideForMono)' != '' AND '$(TargetFramework)' == 'net472'">$(BaseFrameworkPathOverrideForMono)/4.7.2-api</FrameworkPathOverride>
<EnableFrameworkPathOverride Condition="'$(BaseFrameworkPathOverrideForMono)' != ''">true</EnableFrameworkPathOverride>
<!-- Add the Facades directory. Not sure how else to do this. Necessary at least for .NET 4.5 -->
<AssemblySearchPaths Condition="'$(BaseFrameworkPathOverrideForMono)' != ''">$(FrameworkPathOverride)/Facades;$(AssemblySearchPaths)</AssemblySearchPaths>
</PropertyGroup> However, this does not work with |
The path forward here is dotnet/designs#33 (comment) Please try those packages. We will not be investigating issues with workarounds like above. |
Based on dotnet/designs#33 (comment), All I had to do was add <ItemGroup>
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies"
Version="1.0.0-preview.2"
PrivateAssets="All" />
</ItemGroup> To the csproj I was trying to build, and everything worked! |
The |
…d-by: Vlada Shubina <[email protected]> * initial release notes for v4 to track as we go * added dotnet#320 --------- Co-authored-by: Vlada Shubina <[email protected]>
The dotnet CLI allowed to build
net*
targets on mac and linux using the reference assemblies installed with mono. It seems this is not supported by the targets inMicrosoft.NET.Sdk
. For fun, I also tried referencing the targeting pack NuGets which also didn't work.Is there a plan for bringing back support for building
net*
projects on linux/mac? Or should it already work?The text was updated successfully, but these errors were encountered: