dotnet / corert

This repo contains CoreRT, an experimental .NET Core runtime optimized for AOT (ahead of time compilation) scenarios, with the accompanying compiler toolchain.
http://dot.net
MIT License
2.91k stars 510 forks source link

Publishing a freestanding shared library prevents exports from being generated #8092

Open Michael-Kelley opened 4 years ago

Michael-Kelley commented 4 years ago

As in the title, publishing a shared library that doesn't use a runtime (as outlined here in ZeroSharp) and contains no entry point results in a DLL that has no exports.

Here are the relevant portions from my project file:

<PropertyGroup>
    ...

    <NoStdLib>true</NoStdLib>
    <NoConfig>true</NoConfig>
    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
    <GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute>
    <RuntimeMetadataVersion>v4.0.30319</RuntimeMetadataVersion>

    <IlcDisableReflection>true</IlcDisableReflection>
    <IlcSystemModule>Kernel</IlcSystemModule>

    <NativeLib>Shared</NativeLib>
</PropertyGroup>

...

<ItemGroup>
    <LinkerArg Include="/noentry" />
</ItemGroup>

<Target Name="CustomizeReferences" BeforeTargets="BeforeCompile" AfterTargets="FindReferenceAssembliesForReferences">
    <ItemGroup>
        <ReferencePathWithRefAssemblies Remove="@(ReferencePathWithRefAssemblies)" />
        <ReferencePath Remove="@(ReferencePath)" />
    </ItemGroup>
</Target>

And the function that should be exported:

[NativeCallable(EntryPoint = "kernel_main")]
public static void KernelMain() {
    ...
}

EDIT: Just to clarify, I can work around it by adding an /export entry for each function to my linker arguments, but it's far from ideal.

MichalStrehovsky commented 4 years ago

The relevant part of the MSBuild targets is around the ExportsFile property: https://github.com/dotnet/corert/blob/193e9d57e4e51cd7e61e385e2c790c43791a29b2/src/BuildIntegration/Microsoft.NETCore.Native.targets#L67

To investigate, I would start with running a build with diagnostic output turned on and checking how that property is set and whether the associated things happen (ilc.exe is invoked with --exportsfile and linker gets a /def: argument).