MSBuildSdks
MSBuildSdks copied to clipboard
Remove TargetFramework requirement from Microsoft.Build.NoTargets SDK
The NoTargets SDK seems to require TargetFramework
. Without it I get:
MSB4044 The "ResolvePackageAssets" task was not given a value for the required parameter "TargetFramework".
Can that requirement be removed? The readme says NoTargets is "useful for utility projects that just copy files, build packages, or any other function where an assembly is not compiled". I have no need for a target framework in my case, and have dependency packages that should not be tied to a target framework either.
The NoTargets
SDK reuses a lot of the logic in Microsoft.NET.Sdk
and just disables things related to compiling an assembly. Unfortunately that means that some things are required like TargetFramework
. We could add a default value in Microsoft.Build.NoTargets
but we were worried that if it was set to something like net6.0
you might get other errors about projects not being compatible and you wouldn't know what's going on since the value was set for you implicitly.
One way around this is to set a value for TargetFramework
in a common import like Directory.Build.props
:
<Project>
<PropertyGroup>
<!--
Set TargetFramework to net6.0 for all projects using Microsoft.Build.NoTargets so that each project
doesn't need to declare it
-->
<TargetFramework Condition="'$(UsingMicrosoftNoTargetsSdk)' == 'true'">net6.0</TargetFramework>
</PropertyGroup>
</Project>
If we could get consensus on what the default TargetFramework should be for everyone, I'm open to adding to Microsoft.Build.NoTargets
.
Thanks for the backstory. Sounds like doing it more right would involve bigger changes and/or a "copy and modify" of the existing SDK.
But it would provide a couple benefits I could use:
- Less confusion for devs reading my project file.
- If my project builds a "tools only" or "build only" NuGet package (common use for NoTargets SDK), other "tools only" and "build only" dependency packages wouldn't end up under a target-framework group in my package's dependencies, thus avoiding unneeded "wrong target framework" errors for consumers. There may need to be a new per-dependency configuration here, not sure.
- Current workaround is to move package info into a .nuspec file referenced via
<NuspecFile>
in the .cspproj. Since I need access to that info in MSBuild, have to pass all the package data to the .nuspec via<NuspecProperties>
, which is ugly compared to the beautiful, clean way assembly-containing NuGet packages are defined nowadays.
- Current workaround is to move package info into a .nuspec file referenced via
It seems like there's good potential for the NoTargets SDK, but it could use more refinement to avoid confusion and hard-to-read workarounds.
If we could get consensus on what the default TargetFramework should be for everyone, I'm open to adding to
Microsoft.Build.NoTargets
.
It seems like netstandard2.0
could be that - it's the most compatible. Besides some earlier netstandard
versions, I suppose, but those seem to be way out of date by now.
If the target framework continues to be configurable by the user's project that uses NoTargets
, then I think it would be acceptable to use netstandard2.0
.
Having a default target framework is different than not requiring one, such as the NuGet dependencies example in my comment.
I'd rather it be explicit than pretend it isn't a requirement but it is (just defaulted).
@JVimes You can use <SuppressDependenciesWhenPacking>true</SuppressDependenciesWhenPacking>
for build tools that don't have any TargetFramework dependent references. It will modify the nuspec to remove the targets, allowing any consumer to reference your package. You still need a TargetFramework set in your package, but it essentially becomes a no-op.
@JVimes You can use
<SuppressDependenciesWhenPacking>true</SuppressDependenciesWhenPacking>
for build tools that don't have any TargetFramework dependent references. It will modify the nuspec to remove the targets, allowing any consumer to reference your package. You still need a TargetFramework set in your package, but it essentially becomes a no-op.
@kkirkfield, it also removes any dependency from the package.
Handwriting a nuspec is easy. I can even replace tokens using nuget.exe.
But managing dependencies using any tooling is not possible for handwriting a nuspec. NoTargets
works with every tooling any other SDK works, including central package management.
Maybe what's missing is a Microsoft.Build.NuGet.Sdk
SDK.
Alternatively - there is an ambient property in the SDK called BundledNETCoreAppTargetFrameworkVersion
that's set that could be a safe default for a TFM to use: <TargetFramework Condition="'$(TargetFramework)' == ''>net$(BundledNETCoreAppTargetFrameworkVersion)</TargetFramework>
.
This property is set in the installer when creating the SDK bundles and has been around for several versions.
But that still defines a TFM. Right, @baronfel?