2

So I'm using ILRepack, which as far as I understand, uses Mono.Cecil behind the scenes, to do ILWeaving. I'm running into a problem in my project, which ends up resulting in the following error as soon as I import, for example, Newtonsoft.Json version 13.0.1:

INFO: Writing output assembly to disk
System.ArgumentException: Member 'System.Void System.Runtime.CompilerServices.NullableAttribute::.ctor(System.Byte)' is declared in another module and needs to be imported
   at Mono.Cecil.MetadataBuilder.LookupToken(IMetadataTokenProvider provider)
   at Mono.Cecil.MetadataBuilder.AddCustomAttributes(ICustomAttributeProvider owner)
   at Mono.Cecil.MetadataBuilder.AddConstraints(GenericParameter generic_parameter, GenericParamConstraintTable table)
   at Mono.Cecil.MetadataBuilder.AddGenericParameters()
   at Mono.Cecil.MetadataBuilder.BuildTypes()
   at Mono.Cecil.MetadataBuilder.BuildModule()
   at Mono.Cecil.MetadataBuilder.BuildMetadata()
   at Mono.Cecil.ModuleWriter.BuildMetadata(ModuleDefinition module, MetadataBuilder metadata)
   at Mono.Cecil.ModuleWriter.Write(ModuleDefinition module, Disposable`1 stream, WriterParameters parameters)
   at Mono.Cecil.ModuleWriter.WriteModule(ModuleDefinition module, Disposable`1 stream, WriterParameters parameters)
   at Mono.Cecil.ModuleDefinition.Write(String fileName, WriterParameters parameters)
   at Mono.Cecil.AssemblyDefinition.Write(String fileName, WriterParameters parameters)
   at ILRepacking.ILRepack.Repack()
   at ILRepack.Lib.Task.ILRepack.Execute()

All I'm doing is adding it as a PackageReference, and when building in release mode, I get this error.

I realize the error message is quite specific, but after hours of attempts at solving this, I have been unable to. My biggest problem is I have no idea what "another module" means exactly.
This is a completely empty project except using the ILRepack package and importing Newtonsoft.Json.
It targets netstandard2.0, which I need to be the target. I cannot change this to a newer version for... reasons.
Building in release mode without Newtonsoft.Json works.
It also works building in debug, where ILRepack doesn't execute.
So this means that the necessary Attribute must exist, otherwise it wouldn't have compiled in debug, right?

I tried defining this attribute in my project manually, like so:

namespace System.Runtime.CompilerServices
{
    [AttributeUsage(
        AttributeTargets.Class |
        AttributeTargets.Event |
        AttributeTargets.Field |
        AttributeTargets.GenericParameter |
        AttributeTargets.Parameter |
        AttributeTargets.Property |
        AttributeTargets.ReturnValue,
        AllowMultiple = false,
        Inherited = false)]
    public class NullableAttribute : Attribute
    {
        public readonly byte[] NullableFlags;
        public NullableAttribute(byte flag)
        {
            NullableFlags = new byte[] { flag };
        }
        public NullableAttribute(byte[] flags)
        {
            NullableFlags = flags;
        }
    }
}

but even then, I get the above error. So where is Mono.Cecil actually looking for this attribute? And why is it not even enough for me to manually define it, in my project?

The ILRepack configuration I use is this:

  <Target Name="MergeTheThing" AfterTargets="build" Condition="$(Configuration.Contains('Release'))">
    <ItemGroup>
      <InputAssemblies Include="$(OutputPath)$(TargetName)$(TargetExt)" />
      <InputAssemblies Include="$(OutputPath)*.dll" Exclude="$(OutputPath)$(TargetName)$(TargetExt)" />
    </ItemGroup>
    <ItemGroup>
      <LibraryPath Include="$(OutputPath)" />
      <LibraryPath Include="$(VINTAGE_STORY)/Lib/" />
    </ItemGroup>
    <ItemGroup>
      <DoNotInternalizeAssemblies Include="VintagestoryAPI.dll" />
      <DoNotInternalizeAssemblies Include="VintagestoryLib.dll" />
      <DoNotInternalizeAssemblies Include="VSSurvivalMod.dll" />
      <DoNotInternalizeAssemblies Include="VSEssentials.dll" />
      <DoNotInternalizeAssemblies Include="VSCreativeMod.dll" />
      <DoNotInternalizeAssemblies Include="Newtonsoft.Json.dll" />
      <DoNotInternalizeAssemblies Include="0Harmony.dll" />
      <DoNotInternalizeAssemblies Include="protobuf-net.dll" />
      <DoNotInternalizeAssemblies Include="System.Data.SQLite.dll" />
    </ItemGroup>
    <ILRepack Parallel="true"
              DebugInfo="true"
              Verbose="true"
              Internalize="true"
              InternalizeExclude="@(DoNotInternalizeAssemblies)"
              Wildcards="true"
              InputAssemblies="@(InputAssemblies)"
              LibraryPath="@(LibraryPath)"
              KeyFile="$(AssemblyOriginatorKeyFile)"
              TargetKind="SameAsPrimaryAssembly"
              OutputFile="$(OutputPath)$(AssemblyName)$(TargetExt)"
              LogFile="output.txt"/>
  </Target>

What options do I have for telling Mono.Cecil where to look for this attribute? Or can I somehow make it ignore the attribute completely? I don't need to use it, I just need this to compile properly.

See the attached output.txt for a log file: output.txt
Inside this log file, I also noticed that it actually does import the NullableAttribute that I manually defined: Importing System.Runtime.CompilerServices.NullableAttribute from TestSolution4.dll, but why doesn't Mono.Cecil just use this one then?

Any help greatly appreciated!

Capsup
  • 87
  • 11

0 Answers0