question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

CopyRefAssembly Could not extract the MVID from reference assembly

See original GitHub issue

Following up on https://github.com/dotnet/fsharp/pull/12334, I’ve noticed that a project B (csproj) cannot consume a reference assembly of a project A (fsproj) because the mvid cannot be read from the assembly.

Project structure:

A.fsproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net7.0</TargetFramework>
    <GenerateDocumentationFile>true</GenerateDocumentationFile>
    <DotnetFscCompilerPath>C:\Users\nojaf\Projects\fsharp\artifacts\bin\fsc\Debug\net6.0\fsc.dll</DotnetFscCompilerPath>
    <OtherFlags>--refout:obj\Debug\net7.0\refint\A.dll</OtherFlags>
    <ProduceReferenceAssembly>true</ProduceReferenceAssembly>
  </PropertyGroup>

  <ItemGroup>
    <Compile Include="Library.fs" />
  </ItemGroup>

</Project>

B.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <ItemGroup>
    <ProjectReference Include="..\A\A.fsproj" />
    
  </ItemGroup>

  <PropertyGroup>
    <TargetFramework>net7.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <ProduceReferenceAssembly>true</ProduceReferenceAssembly>
  </PropertyGroup>

</Project>

Expected behavior

dotnet build of B.csproj will find the reference assembly of project A that was specified using the refout flag.

Actual behavior

In the MSBuild log we saw the following:

Could not extract the MVID from “obj\Debug\net7.0\refint\A.dll”. Are you sure it is a reference assembly?

This warning was logged by CopyRefAssembly,

https://github.com/dotnet/roslyn/blob/b7838e90db7c7f1de309f8ef314e0aa8bfc6dab1/src/Compilers/Core/MSBuildTask/CopyRefAssembly.cs#L56

The main problem is that the mvid guid is empty.

The current Number of Sections inside the COFF Header is 3, whereas compared to a C# reference assembly this is 4. The .mvid section is missing from the F# generation.

The MSBuild task uses this section to read that guid.

https://github.com/dotnet/roslyn/blob/b7838e90db7c7f1de309f8ef314e0aa8bfc6dab1/src/Compilers/Core/MSBuildTask/MvidReader.cs#L90-L137

This entire section could be added around

https://github.com/dotnet/fsharp/blob/36af364b538cde99d8de8df93db241af53329f22/src/Compiler/AbstractIL/ilwrite.fs#L3884-L3886

Similar to .text, .sdata, .reloc I would assume. Conditional logic could be implemented using options.referenceAssemblyOnly.

Known workarounds

Besides adding the additional section, it is possible to extract the guid currently from the Module metadata table. We were able to read it using:

#r "nuget: System.Reflection.Metadata"

open System.IO
open System.Reflection.PortableExecutable

let refDll = @"C:\Users\nojaf\Projects\reference-assemblies-sample\A\obj\Debug\net7.0\refint\A.dll"
let embeddedReader = new PEReader(File.OpenRead refDll)
let sourceReader = embeddedReader.GetMetadataReader()
let loc = sourceReader.GetModuleDefinition().Mvid
let mvid = sourceReader.GetGuid(loc)

So, from a certain point of view, the mvid is there. Just not in the way that CopyRefAssembly reads it.

Related information

Provide any related information (optional):

  • Operating system: Win11
  • .NET Runtime kind: .NET 7 preview 4
  • local compiler, main at 5b1a3ae5d16fe93af1f8b055ab0be5bb5e47ff20

//cc @dsyme @vzarytovskii @baronfel @jaredpar

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:7 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
jaredparcommented, May 31, 2022

Yeah, we probably should start emitting it as part of our work of FSharp.Build support of refassemblies.

Agree. The code in CopyRefAssembly is pretty standard for reading an MVID from a PE file. If this task is erroring then likely many other tools in the .NET ecosystem will similarly fail to read the F# ref assembly.

1reaction
vzarytovskiicommented, May 31, 2022

Yeah, we probably should start emitting it as part of our work of FSharp.Build support of refassemblies.

Read more comments on GitHub >

github_iconTop Results From Across the Web

roslyn/docs/features/refout.md at main
mvid " containing a copy of the MVID, when emitting ref assemblies. This makes it easy for CopyRefAssembly to extract and compare MVIDs...
Read more >
error MSB4018: The "CopyRefAssembly" task failed ...
This error just seems to happen randomly. I've done an internet search, but nothing turns up. If I clean out the bin, obj,...
Read more >
ResolveAssemblyReference Task - MSBuild
Specifies an app.config file from which to parse and extract ... If true, referenced assemblies will not be copied locally if they are...
Read more >
Dotnet MSBuild fails in docker when source generated file ...
The library project references a source generator NuGet package ... failing because the class file that is generated "could not be found".
Read more >
Getting errors of mismatched MVID - SonarQube
We opened an internal ticket to fix this issue (SONARSEC-2690 for reference, but you cannot access the JIRA project as the taint analysis ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found