Skip to content

nirin/msbuild-sdks

Repository files navigation

MSBuild SDKs

MSBuild SDKs are used to configure and extend your build. MSBuild v15 introduced a concept of an SDK reference (similar to an Import). Any project that references one or more SDKs are commonly referred to as an SDK-style project. So, MSBuild v15+ is required for the SDK-style project to work.

Thus, an MSBuild SDK, in a nutshell, is an encapsulated (packaged and versioned) set of MSBuild props, targets and tasks that offer a specific set of functionalities to any project build.

Using MSBuild SDKs

An MSBuild SDK is referenced through

  1. The Sdk attribute on the top-level Project element.

    <Project Sdk="My.Custom.Sdk" />
    <!-- With Version -->
    <Project Sdk="My.Custom.Sdk/1.0.0" />
  2. The Sdk child element under the Project element.

    <Sdk Name="My.Custom.Sdk" />
    <!-- With Version -->
    <Sdk Name="My.Custom.Sdk" Version="1.0.0"/>
  3. The Sdk attribute on the Import element.

    <Import Sdk="My.Custom.Sdk" Project="Sdk.props" />
    <!-- With Version -->
    <Import Sdk="My.Custom.Sdk/1.0.0" Project="Sdk.targets" />
    <!-- With a Custom props/targets within SDK -->
    <Import Sdk="My.Other.Sdk" Project="Path/To/Custom.targets" />
    <Import Sdk="My.Other.Sdk" Project="../Path/To/Custom.props" />

These SDK-style projects looks like this:

<Project Sdk="My.Custom.Sdk">
    <PropertyGroup>
        <MyCustomSdkProperty>value</MyCustomSdkProperty>
    </PropertyGroup>
</Project>

As you can see, the project file is greatly simplified because of the encapsulation.

At evaluation time, MSBuild implicitly imports the Sdk.props at the top and Sdk.targets at the bottom of the project like this:

<Project>
  <Import Project="Sdk.props" Sdk="My.Custom.Sdk"/>

    <PropertyGroup>
        <MyCustomSdkProperty>value</MyCustomSdkProperty>
    </PropertyGroup>

  <Import Project="Sdk.targets" Sdk="My.Custom.Sdk"/>
</Project>

By default, MSBuild requires that the SDKs must be installed prior to using them. But, for MSBuild v15.6+, the SDKs can be referenced as NuGet packages instead. In which case, the package (SDK) version can also be specified separately in the global.json file like this:

{
    "msbuild-sdks":
    {
        "My.Custom.Sdk": "1.1.0",
        "My.Other.Sdk": "1.2.0-preview",
    }
}

See Using MSBuild project SDKs guide on Microsoft Docs for more information on how project SDKs work and how project SDKs are resolved.

Available SDKs

MyGet: MSBuild-SDKs NuGet: NIRIN

Bare SDKs

Supports creating projects that do not compile to an assembly. This is usually the base SDK for other SDKs listed here.

MSBuild.Core.Sdk

Supports creating projects that do not compile to an assembly. This is usually the base SDK for other SDKs listed here.

MSBuild.Common.Sdk

Basic SDKs

Supports creating projects that do not compile to an assembly. This is usually the base SDK for other SDKs listed here.

MSBuild.Project.Sdk

Supports creating Shared projects that contain properties and items which are shared between multiple projects. But they themselves remain a separate non-interactive project in the solution tree.

MSBuild.Sharing.Sdk

Supports creating MSBuild solutions which are MSBuild projects that indicate what projects to include when building your solution tree. They are an evolution of the classic Visual Studio solution (.sln) files.

MSBuild.Solution.Sdk

Platform SDKs

Supports creating Managed runtime targeting projects using Managed frameworks and languages (Annex, Mono (.NET), Swift, Java, etc…). This is usually the base SDK for other specific Managed Runtime SDKs listed here.

MSBuild.Managed.Sdk

Supports creating Native runtime targeting projects using Native frameworks and languages (ASM, FORTRAN, C/C++, SLang, Rust, etc…). This is usually the base SDK for other specific Native Runtime SDKs listed here.

MSBuild.Native.Sdk

Support SDKs

Supports managing Native and Managed references via various sources such as packages from a central repository. Also supports global references and central versioning via Solution SDK.

MSBuild.Dependencies.Sdk

Supports creating any type of package for any type of project with built-in support for basic Archives (ZIP, 7Z, RAR, IMG, ISO, etc…), platform-specific (MSI, MSU, MSP, MSIX, AppX, etc…) and platform-agnostic (NuGet, VCPKG, JAR, JSP, DEP, etc…) packaging.

MSBuild.Packaging.Sdk

.NET SDKs

Supports creating .NET projects that include building for .NET Framework (Windows), .NET Core (Windows, Linux, MacOS), Mono (Windows, Linux, MacOS), Xamarin (based on Mono) runtimes.

MSBuild.NET.Sdk

An MSBuild Extension package for automatically including various framework-specific (ASP.NET, UAP, WPF, Xamarin) and platform-specific (Android, Apple, Tizen, Web, Windows) default build items in .NET projects. You can use this package in any SDK-style projects that uses Microsoft.NET.Sdk. The MSBuild.NET.Extras.Sdk already includes these defaults.

MSBuild.NET.DefaultItems MSBuild.NET.DefaultItems

Adds a few extra extensions to the SDK-style projects that are currently not available in Microsoft.NET.Sdk SDK. Like, support for older frameworks and its profiles. It also enables multi-targeting among them.

MSBuild.NET.Extras.Sdk MSBuild.NET.Extras.Sdk

Supports only .NET Framework on Windows. Redirects to the original MSBuild files that were included as a part of .NET Framework in Windows. This is for our internal projects only.

MSBuild.NET.Inbox.Sdk MSBuild.NET.Inbox.Sdk

Supports only .NET Framework on Windows. Contains the original .NET Framework Build files that were included with MSBuild. Use them to slowly migrate your legacy projects to SDK-style.

MSBuild.NET.Legacy.Sdk

Supports NuGet Restore and Pack targets for common MSBuild projects. It's basically an SDK wrapper around Restore targets (NuGet.Build.Tasks) and Pack targets (NuGet.Build.Tasks.Pack) optimized for SDK-style projects.

NuGet.Build.Sdk

Supports NuGet Package authoring with a custom Project System support. It's basically an SDK wrapper around NuGet.Build.Packaging aka NuGetizer-3000 project, with targets optimized for SDK-style projects.

NuGet.Packaging.Sdk

Contributing

Most of the SDKs in this repository are experimental and in-development. They are used to test-out and validate new ideas and are mostly used for internal projects. Furthermore, they start with bits and pieces of existing logic from other open-source projects, Visual Studio, Windows and other platform SDKs. As such, the code will be definitely breaking and are not recommended for production usage.

Contributions are welcome, but I don't have any strict guidelines for contributors to follow. Just infer the design, style guidelines and general direction of the SDK implementation from the codebase. If you have any questions, feel free to create an issue, and I'll do my best to answer your queries. I'll also create formal guidelines when I start to receive a few public contributions.

At this point, there are a lot missing from the codebase to properly author and maintain production-ready SDKs. First is the testing framework for the SDKs, next is the project/solution templates and finally the docs. Once these are done, the SDKs can be used regularly.

Disclaimer

As mentioned above, the SDKs are experimental and in-development. This space is used for learning and experimenting with MSBuild. As such, the code published here is only for reference purposes since, it might contain de-compiled sources that may not be open source. The SDKs are published to NuGet only when they are ready for broader usage and has a feature set descriptive of their intended usage. They are also published to MyGet regularly, but it is considered a volatile source.

If possible and allowed, some ideas here will also be contributed back to the original source. One such example is the addition of BaseOutputPath to the MSBuild Common targets. It was done in dotnet/msbuild#5238.