TargetExt defaults to ".dll" on .NETCore and .NETStandard even if the OutputType is ".exe": https://github.com/dotnet/sdk/blob/90e8a529be026d06fc8965d460927193aca5b005/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.BeforeCommon.targets#L74-L75
Starting with ".NETCoreApp, Version=3.0", UseAppHost defaults to true: https://github.com/dotnet/sdk/blob/372e67d51167792db2fdaeebf48b6d8fb962e713/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.RuntimeIdentifierInference.targets#L110
The _NativeExecutableExtension defaults to true as the DefaultAppHostRuntimeIdentifier on Windows is "win-x64":
https://github.com/dotnet/sdk/blob/master/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.targets#L67
The _GetAppHostPaths target sets the AppHostIntermediatePath property (based on _NativeExecutableExtension which defaults to ".exe" because auf UseAppHost is true) which then is added to the None ItemGroup determined to be copied to the output directory:
https://github.com/dotnet/sdk/blob/master/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.targets#L491-L497

The issue is that such a file is never produced as the TargetExt defaults to ".dll". If I got this right this means that every app ".NETCoreApp, Version=3.0" with OutputType "Exe" fails to copy its content to the output directory. This would be big break and I'm sure this would have already been caught. I assume I'm missing something here.
cc @nguerrera @dsplaisted @ericstj
OK the reason why this only affects CoreFx is that we don't build an apphost, means the _CreateAppHost target never runs. This looks like a bug when ResolveTargetingPacks and _CreateAppHost nerver ran ran (https://github.com/dotnet/sdk/blob/ff80c824a9e62ec721b467c9f6b0b407fbb14fa0/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.TargetingPackResolution.targets#L161-L162) but _ComputeNETCoreBuildOutputFiles expects the host to be present.
@dsplaisted any recommendation what we should do with targetingpack/frameworkreference in CoreFx? We currently opt-out of it by setting DisableImplicitFrameworkReferences (https://github.com/dotnet/corefx/blob/master/Directory.Build.props#L288) as we are building our own references which we compile against. When removing the flag conflict resolution picks the right assemblies but it doesn't seem right and it results in a huge slowdown in the build process.
Currently in a PR I hacked the RuntimeFramework to be set to compute the correct runtimeOptions in runtimeconfig.json: https://github.com/dotnet/corefx/pull/38151/commits/c26e45751e9944173bcf3c9be8e5e1b17ed7b94e.
Would it make sense to set FrameworkReference after restore but before the SDK evaluation begins? How would we create an apphost without using the targeting pack? The host source path is determined here: https://github.com/dotnet/sdk/blob/ff80c824a9e62ec721b467c9f6b0b407fbb14fa0/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.TargetingPackResolution.targets#L243
We should probably either act as UseAppHost=false or fall with an appropriate message if UseAppHost is true and no apphost pack is resolved.
I don't think we've thought about app host without framework reference.
It almost feels like what you want is to specify a framework reference to microsoft.netcore.app, but with compilation assets excluded...
We should probably either act as UseAppHost=false
Agreed. For the time being I set that property but we might want to create apphosts at some point.
fall with an appropriate message if UseAppHost is true and no apphost pack is resolved
Agreed, throwing seems the right choice here.
It almost feels like what you want is to specify a framework reference to microsoft.netcore.app, but with compilation assets excluded...
Exactly. Specifying the framework reference + having the apphost so that sdk support is available without interfering with references.
Is this something we want/should fix for 3.0 or ok to move to backlog?
Is it common to not use a targeting pack with netcoreapp3.0? We aren't blocked by this.
No, it is not common. I think we can get away with moving it to backlog if you are not blocked.
Still I would like to know if there's a way to support CoreFx going forward here.
If we were to make this scenario supported without tricks, I think we would add some metadata to a FrameworkReference a la ExcludeAssets="Compile" on PackageReference. This would allow the apphost to be resolved and still persist the runtime side of the framework reference to runtimeconfig.
That plus better diagnostics for any case where you managed to have no resolved app host but useapphost=true.
In my mind, this is what this issue tracks now. And the question is the priority of doing it. Make sense?
Yeah. Makes sense.
I think the SDK should have a test case for what it looks like to build a project without framework reference and compose references on our own. That way when new features/fixes break this it's clearer and the SDK has the ability to look at it and create an intentional override/disable path. Otherwise we'll end up growing an ugly set of workarounds that neither side is happy with.
In the past we could rely on a couple properties like DisableImplicitFrameworkReference and maybe something to turn off deps/runtimeconfig, but lately it seems like each milestone grows the set of workarounds we accumulate for this scenario.
Make sense?
Yes makes sense. I understand that this is not critical for customers but for partners like aspnetcore and us it is. How much work do you think this would be?
Most helpful comment
Yeah. Makes sense.
I think the SDK should have a test case for what it looks like to build a project without framework reference and compose references on our own. That way when new features/fixes break this it's clearer and the SDK has the ability to look at it and create an intentional override/disable path. Otherwise we'll end up growing an ugly set of workarounds that neither side is happy with.
In the past we could rely on a couple properties like DisableImplicitFrameworkReference and maybe something to turn off deps/runtimeconfig, but lately it seems like each milestone grows the set of workarounds we accumulate for this scenario.