Skip to content

Commit

Permalink
Fix linking the outputs of the compilation (dotnet#76)
Browse files Browse the repository at this point in the history
Before this change, running link.exe on the output of the compilation produced `LINK : fatal error LNK1561: entry point must be defined`.

This took longer to figure out than I would be willing to admit.

There are two things at play - linker uses the presence of a method named `main` or `wmain` to choose between setting `wmainCRTStartup` or `mainCRTStartup` as the actual entrypoint of the application (C apps don't start with `main` - they start in the C runtime library that calls `main`).

In dotnet#21 we deleted the `__fail_fast` method from main.cpp and then in dotnet#72 we also removed the compiler reference to the now non-existent symbol. The obscure result of that was that main.obj stopped being part of the linking set because nothing now references symbols from it. When linker looks for `main` or `wmain`, it only looks at object files that are already part of the linking set.

As a result, linker didn't inject `wmainCRTStartup` as the entrypoint and we failed with the above message.

It looks like the only way out is to hardcode the CRT implementation detail here. We were already hardcoding it, but for other reasons.

We also need to set the subsystem since the autodetection is failing.
  • Loading branch information
MichalStrehovsky authored Aug 31, 2020
1 parent 63d5e0f commit a19596e
Showing 1 changed file with 7 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,20 @@ The .NET Foundation licenses this file to you under the MIT license.
<NativeLibrary Include="crypt32.lib" />
</ItemGroup>

<PropertyGroup>
<IlcProcessEntrypoint Condition="$(IlcProcessEntrypoint) == ''">wmainCRTStartup</IlcProcessEntrypoint>
</PropertyGroup>

<ItemGroup>
<LinkerArg Condition="$(NativeLib) == 'Shared'" Include="/DLL" />
<LinkerArg Include="@(NativeLibrary->'&quot;%(Identity)&quot;')" />
<LinkerArg Include="/NOLOGO /MANIFEST:NO" />
<LinkerArg Condition="$(NativeDebugSymbols) == 'true'" Include="/DEBUG" />
<!-- The runtime is not compatible with jump stubs inserted by incremental linking. -->
<LinkerArg Include="/INCREMENTAL:NO" />
<LinkerArg Condition="'$(OutputType)' == 'WinExe'" Include="/SUBSYSTEM:WINDOWS /ENTRY:wmainCRTStartup" />
<LinkerArg Condition="'$(OutputType)' == 'WinExe'" Include="/SUBSYSTEM:WINDOWS" />
<LinkerArg Condition="'$(OutputType)' == 'Exe'" Include="/SUBSYSTEM:CONSOLE" />
<LinkerArg Condition="'$(OutputType)' == 'WinExe' or '$(OutputType)' == 'Exe'" Include="/ENTRY:$(IlcProcessEntrypoint)" />
<LinkerArg Include="/NATVIS:&quot;$(MSBuildThisFileDirectory)CoreRTNatVis.natvis&quot;" />
</ItemGroup>

Expand Down

0 comments on commit a19596e

Please sign in to comment.