- Remove SDK PackageRef
- Remove pre & post imports
- Remove
nuget restorefrom sdk acquisition
With the change in place, the .NET Core Library csproj template will become:
<Project ToolsVersion="15.0" Sdk="Microsoft.NET.Sdk/1.0.0-rc2">
<PropertyGroup>
<TargetFramework>netstandard1.4</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="**\*.cs" />
<EmbeddedResource Include="**\*.resx" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="NETStandard.Library" Version="1.6" />
</ItemGroup>
</Project>
It is imperative that implicit <Imports> do not get persisted to disk. Andy is tracking this concern.
A new attribute is added to <Project> for representing SDKs: Sdk="Microsoft.NET.Sdk/1.0.0-RC2".
In RC3 and beyond, the element is used to assist in the acquisition experience. In RC2 it is used
to identify a pre-installed framework to be loaded. Specifically, when MSBuild discovers one of these elements it will inject implicit Imports before and after the current .proj file. An example:
This example .csproj file:
<Project Sdk="Microsoft.NET.Sdk/1.0.0-RC2" />
<Target Name="SayHi">
<Message Text="Hello, World" />
</Target>
</Project>
Is interepreted by MSBuild as:
<Project Sdk="Microsoft.NET.Sdk/1.0.0-RC2" />
<!-- Import all, in order listed -->
<Import Project="$(MSBuildSDKsPath)\%(___MSBuildSDK.Name)\%(___MSBuildSDK.Version)\build\InitialImport.props"
Condition="Exists('$(MSBuildSDKsPath)\%(___MSBuildSDK.Name)\%(___MSBuildSDK.Version)\build\InitialImport.props')" />
<Target Name="SayHi">
<Message Text="Hello, World" />
</Target>
<!-- Import all, in order listed -->
<Import Project="$(MSBuildSDKsPath)\%(___MSBuildSDK.Name)\%(___MSBuildSDK.Version)\build\FinalImport.targets"
Condition="Exists('$(MSBuildSDKsPath)\%(___MSBuildSDK.Name)\%(___MSBuildSDK.Version)\build\FinalImport.targets')" />
</Project>
<Project Sdk="Microsoft.NET.Sdk/1.0.0-RC2">
...
</Project>
<Project Sdk="Microsoft.NET.Sdk/1.0.0-RC2;
Microsoft.Web.Sdk/1.0.0-RC2">
...
</Project>
- Enable
<Project Sdk="">attribute - Enable InitialImport.props and FinalImport.targets injection based on the values in the SDK element
- Ensure we save the csproj correctly [the implicit imports remain implicit]
- Create InitialImport.props and FinalImport.targets
- Ship RC2 and beyond with 'clean' version numbers e.g:
1.0.0-RC2vs.1.0.0-alpha-20161104-2 - Add the SDK layouts to both VS and CLI
- Add SDKs to installation layout
- Pass MSBuildSDKsPath Environment Variable, to be interpreted as
$(MSBuildSDKsPath)for the sake of this document, to invocations of MSBuild as MSBuildSDKsPath
- In Visual Studio:
$(MSBuildExtensionsPath)\.dotnet\ - In CLI,
[ProgramFiles]\dotnet\sdk\{cli_version}\Extensions\
<Project Sdk="Microsoft.NET.Sdk/1.0.0-RC2;
FSharp/1.0.0-Beta;
MySDK">
<Target Name="SayHi">
<Message Text="Hello, World" />
</Target>
</Project>
- Because it is a project-level attribute, we get the immutability constraints desired.
- N/A
<project>
<SDK Name="Microsoft.NET.Sdk" Version="1.0.0-RC2" />
<SDK Name="FSharp" Version="1.0.0-Beta" />
<Message Text="Hello, World" />
</project>
<SDK>elements include namedNameandVersionattributes<SDK>elements can be listed separately, avoiding long value strings
<SDK>cannot behave like other MSBuild elements. It must be statically evaluatable and so cannot accept $(Properties). We could put a bunch of special rules in place, but this would be counterintuitive for MSBuild developers.
<project Microsoft.NET.Sdk="1.0.0-RC2"
FSharp="1.0.0-Beta">
<Message Text="Hello, World" />
</project>
- Not composing a single
;dilimited string
- Feels unnatural usage of XML
Why the hidden folder and why the coupling in naming to .NET? This could be used to make SDKs for platforms with no affinity to .NET. I think something like
$(MSBuildExtensionsPath)\Sdkswould be better.Why would msbuild in CLI use a different path from msbuild in VS? $(MSBuildExtensionsPath) is a concept in both, can't we just use the same subdirectory off of it?