SteveGilham / altcover

Cross-platform coverage gathering and processing tool set for dotnet/.Net Framework and Mono
MIT License
498 stars 18 forks source link

Mac MsBuild Error MSB3644: The reference assemblies for .NETFramework,Version=v4.x were not found. #78

Closed LittleCornerDev closed 4 years ago

LittleCornerDev commented 4 years ago

I am attempting to use altcover for a Xamarin.Forms project edited via VisualStudio on Mac.

When running dotnet test /p:AltCover=true, I keep getting an error about missing .NETFramework references and a prompt to download.

error MSB3644: The reference assemblies for .NETFramework,Version=v4.7 were not found. To resolve this, install the Developer Pack (SDK/Targeting Pack) for this framework version or retarget your application. You can download .NET Framework Developer Packs at https://aka.ms/msbuild/developerpacks

As the downloads are executables for Windows and not Mac, and since VisualStudio Mac uses Mono and .Net Core, I have found various references similar to this one about importing netfx.props to set paths accordingly.

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) Microsoft Corporation.  All Rights Reserved.  See License.txt in the project root for license information. -->
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <!-- When compiling .NET SDK 2.0 projects targeting .NET 4.x on Mono using 'dotnet build' you -->
    <!-- have to teach MSBuild where the Mono copy of the reference asssemblies is -->
    <TargetIsMono Condition="($(TargetFramework.StartsWith('net4')) OR $(TargetFrameworkVersion.StartsWith('v4.'))) AND '$(OS)' == 'Unix'">true</TargetIsMono>

    <!-- Look in the standard install locations -->
    <BaseFrameworkPathOverrideForMono Condition="'$(BaseFrameworkPathOverrideForMono)' == '' AND '$(TargetIsMono)' == 'true' AND EXISTS('/Library/Frameworks/Mono.framework/Versions/Current/lib/mono')">/Library/Frameworks/Mono.framework/Versions/Current/lib/mono</BaseFrameworkPathOverrideForMono>
    <BaseFrameworkPathOverrideForMono Condition="'$(BaseFrameworkPathOverrideForMono)' == '' AND '$(TargetIsMono)' == 'true' AND EXISTS('/usr/lib/mono')">/usr/lib/mono</BaseFrameworkPathOverrideForMono>
    <BaseFrameworkPathOverrideForMono Condition="'$(BaseFrameworkPathOverrideForMono)' == '' AND '$(TargetIsMono)' == 'true' 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)' == 'net45' OR '$(TargetFrameworkVersion)' == 'v4.5')">$(BaseFrameworkPathOverrideForMono)/4.5-api</FrameworkPathOverride>
    <FrameworkPathOverride Condition="'$(BaseFrameworkPathOverrideForMono)' != '' AND ('$(TargetFramework)' == 'net451' OR '$(TargetFrameworkVersion)' == 'v4.5.1')">$(BaseFrameworkPathOverrideForMono)/4.5.1-api</FrameworkPathOverride>
    <FrameworkPathOverride Condition="'$(BaseFrameworkPathOverrideForMono)' != '' AND ('$(TargetFramework)' == 'net452' OR '$(TargetFrameworkVersion)' == 'v4.5.2')">$(BaseFrameworkPathOverrideForMono)/4.5.2-api</FrameworkPathOverride>
    <FrameworkPathOverride Condition="'$(BaseFrameworkPathOverrideForMono)' != '' AND ('$(TargetFramework)' == 'net46' OR '$(TargetFrameworkVersion)' == 'v4.6')">$(BaseFrameworkPathOverrideForMono)/4.6-api</FrameworkPathOverride>
    <FrameworkPathOverride Condition="'$(BaseFrameworkPathOverrideForMono)' != '' AND ('$(TargetFramework)' == 'net461' OR '$(TargetFrameworkVersion)' == 'v4.6.1')">$(BaseFrameworkPathOverrideForMono)/4.6.1-api</FrameworkPathOverride>
    <FrameworkPathOverride Condition="'$(BaseFrameworkPathOverrideForMono)' != '' AND ('$(TargetFramework)' == 'net462' OR '$(TargetFrameworkVersion)' == 'v4.6.2')">$(BaseFrameworkPathOverrideForMono)/4.6.2-api</FrameworkPathOverride>
    <FrameworkPathOverride Condition="'$(BaseFrameworkPathOverrideForMono)' != '' AND ('$(TargetFramework)' == 'net47' OR '$(TargetFrameworkVersion)' == 'v4.7')">$(BaseFrameworkPathOverrideForMono)/4.7-api</FrameworkPathOverride>
    <FrameworkPathOverride Condition="'$(BaseFrameworkPathOverrideForMono)' != '' AND ('$(TargetFramework)' == 'net471' OR '$(TargetFrameworkVersion)' == 'v4.7.1')">$(BaseFrameworkPathOverrideForMono)/4.7.1-api</FrameworkPathOverride>
    <FrameworkPathOverride Condition="'$(BaseFrameworkPathOverrideForMono)' != '' AND ('$(TargetFramework)' == 'net472' OR '$(TargetFrameworkVersion)' == 'v4.7.2')">$(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>
</Project>

With debug messages, I see that I have:

  TargetFramework value is '', starts with net4 is 'False'
  TargetFrameworkVersion value is 'v4.7', starts with v4 is 'True'
  OS value is 'Unix'
  TargetIsMono value is 'true'
  BaseFrameworkPathOverrideForMono value is '/Library/Frameworks/Mono.framework/Versions/Current/lib/mono'
  FrameworkPathOverride value is '/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.7-api'
  EnableFrameworkPathOverride value is 'true'

I did an ls -la and verified that /Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.7-api exists and has content.

However, I still get the same MSB3644 error about missing .NETFramework references. As I am new to all these technologies, any thoughts/advice/help would be appreciated!

SteveGilham commented 4 years ago

Having not used Xamarin myself, I just want to make sure -- this is essentially a project that targets classic .net Framework-style Mono, right?

The scenario of dotnet test against such a project isn't one I've even considered before today. Indeed, this sort of build error -- asking for a framework targeting pack -- is why I still use classic-style projects for builds of the Framework/Mono version on Linux CI, rather than using multi-target modern-style with dotnet build throughout.

For the moment, the supported approach for such a project would be to explicitly instrument the code and and run the tests.

LittleCornerDev commented 4 years ago

Thank you. What you have mentioned about "multi-target" as well as other dependency reference errors I was having with my nUnit test project has led me to switching my nUnit project to one using .NET Core.

Dependency packages are now maintained via PackageReference in *.csproj instead of via packages.config, and dotnet test is executing successfully now that it is no longer looking for frameworks.

For future reference of anyone else who comes across this... In Visual Studio Mac, I changed nUnit project from:

Screen Shot 2020-03-10 at 11 08 29 PM

to:

Screen Shot 2020-03-10 at 11 08 41 PM
SteveGilham commented 4 years ago

I'll take that as having been successfully resolved, then.

SteveGilham commented 4 years ago

FYI -- if .NETFramework,Version=v4.7 had been what you were meaning, I've discovered that there's a very useful NuGet package containing the necessary reference assemblies for that -- and for various other .net versions -- that would allow such a thing to happen.