Skip to content

Add .NET DLL for SDK projection to NuGet package#40182

Open
florelis wants to merge 1 commit intomicrosoft:feature/wsl-for-appsfrom
florelis:csNuget
Open

Add .NET DLL for SDK projection to NuGet package#40182
florelis wants to merge 1 commit intomicrosoft:feature/wsl-for-appsfrom
florelis:csNuget

Conversation

@florelis
Copy link
Copy Markdown
Member

Summary of the Pull Request

  • Updates the build process to create a new DLL, wslcsdkcs.dll, that will include the SDK projection for C#.
  • Updates the SDK NuGet's .targets files to include the new DLL and make better use of NuGet folder conventions.

PR Checklist

  • Closes: Link to issue #xxx
  • Communication: I've discussed this with core contributors already. If work hasn't been agreed, this work might be rejected
  • Tests: Added/updated if needed and all pass
  • Localization: All end user facing strings can be localized
  • Dev docs: Added/updated if needed
  • Documentation updated: If checked, please file a pull request on our docs repo and link it here: #xxx

Detailed Description of the Pull Request / Additional comments

  • Added a new local CMake package for C# targets, which allows setting shared properties like the target framework. This was extracted from the existing wslsettings target and reused for the new wslcsdkcs.
  • Updated the .NET .targets to use a proper TFM (net8.0 instead of net), to check $(PlatformTarget) as a fallback when $(RuntimeIdentifier) is not set.
  • Moved the native binaries in the NuGet from runtimes\win-<arch>\ to runtimes\win-<arch>\native\, where MSBuild knows to automatically reference and copy them for .NET projects using $(RuntimeIdentifier)

Validation Steps Performed

Manually created C# projects and confirmed that the right files were being referenced and copied. More proper validation will come later in the form of sample apps.

@florelis florelis requested a review from a team as a code owner April 14, 2026 22:48
Copilot AI review requested due to automatic review settings April 14, 2026 22:48
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds support for shipping a C# projection DLL (wslcsdkcs.dll) in the Microsoft.WSL.Containers NuGet package, and updates build/targets logic so consumers get correct native asset layout and copy behavior.

Changes:

  • Introduces a CMake helper (configure_csharp_target) and a new C# CMake target for wslcsdkcs.
  • Updates NuGet package layout to place native binaries under runtimes/win-<arch>/native/ and adds new MSBuild targets for net8.0.
  • Updates CMake package config and NuGet spec to reference the new locations and include the new managed DLL.

Reviewed changes

Copilot reviewed 11 out of 12 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/windows/wslsettings/CMakeLists.txt Switches to shared C# target configuration helper and removes duplicated per-target settings.
src/windows/WslcSDK/csharp/Projection.cs Adds placeholder C# source for the new projection DLL.
src/windows/WslcSDK/csharp/CMakeLists.txt Adds new C# shared library target wslcsdkcs.
nuget/Microsoft.WSL.Containers/cmake/Microsoft.WSL.ContainersConfig.cmake Updates imported DLL path to native/ subfolder.
nuget/Microsoft.WSL.Containers/build/net8.0/Microsoft.WSL.Containers.targets Adds net8-specific copy logic (RID/PlatformTarget fallback) and erroring.
nuget/Microsoft.WSL.Containers/build/net/Microsoft.WSL.Containers.targets Removes old net targets file.
nuget/Microsoft.WSL.Containers/build/native/Microsoft.WSL.Containers.targets Updates native targets and attempts DLL copy via MSBuild items.
nuget/Microsoft.WSL.Containers/build/Microsoft.WSL.Containers.common.targets Removes common targets file previously used for copying/erroring.
nuget/Microsoft.WSL.Containers.nuspec.in Adds wslcsdkcs.dll and moves native DLLs under native/.
cmake/findCSharp.cmake Adds configure_csharp_target() helper (C# flags + Windows SDK MSBuild properties).
CMakeLists.txt Adds find_package(CSharp) and adds the new C# subdirectory build.
.gitignore Normalizes *.etl entry and adds *.lscache.

Comment on lines 1 to +3
set(TargetApp wslsettings)

project(${TargetApp} LANGUAGES CSharp)
configure_csharp_target(${TargetApp})
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

configure_csharp_target() calls target_compile_options()/set_target_properties() on the passed target. In this file it’s invoked before the wslsettings CMake target is created, which will cause CMake configuration to fail. Move the configure_csharp_target(${TargetApp}) call to after the corresponding add_executable() / add_library() (or alter the helper to only set directory-level config until the target exists).

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,28 @@
function(configure_csharp_target TARGET)
project(${TARGET} LANGUAGES CSharp)
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling project() inside a helper function (and potentially multiple times across subdirectories/targets) has broad global side effects in CMake (e.g., resets project variables, may affect language enablement and toolchain behavior). Prefer enabling C# once at the top-level (e.g., enable_language(CSharp) after find_package(CSharp) or in the top-level project(...) LANGUAGES ... CSharp) and keep configure_csharp_target() limited to setting target properties/options.

Suggested change
project(${TARGET} LANGUAGES CSharp)
if(NOT CMAKE_CSharp_COMPILER)
message(FATAL_ERROR
"C# language is not enabled before calling configure_csharp_target(${TARGET}). "
"Enable it once at the top level with project(... LANGUAGES CSharp) or enable_language(CSharp)."
)
endif()

Copilot uses AI. Check for mistakes.
Comment on lines +4 to +8
# Set the C# language version (defaults to 3.0).
set(CMAKE_CSharp_FLAGS "/langversion:latest")

target_compile_options(
${TARGET}
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

set(CMAKE_CSharp_FLAGS ...) inside a CMake function only affects that function’s scope, so the language-version flag is unlikely to be applied to targets outside the function body (or to subsequent targets). Apply the language version via target_compile_options(${TARGET} PRIVATE \"/langversion:latest\"), or set the variable with PARENT_SCOPE/directory property if you truly intend it to be global.

Suggested change
# Set the C# language version (defaults to 3.0).
set(CMAKE_CSharp_FLAGS "/langversion:latest")
target_compile_options(
${TARGET}
# Set the C# language version (defaults to 3.0) for this target.
target_compile_options(
${TARGET}
PRIVATE "/langversion:latest"

Copilot uses AI. Check for mistakes.
find_package(VERSION REQUIRED)
find_package(MC REQUIRED)
find_package(Appx REQUIRED)
find_package(CSharp REQUIRED)
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For CMake module-mode package discovery, find_package(CSharp) expects a module named FindCSharp.cmake. The PR adds cmake/findCSharp.cmake (lowercase 'f'), which will fail on case-sensitive filesystems. Rename the module to FindCSharp.cmake (and ensure it’s on CMAKE_MODULE_PATH).

Suggested change
find_package(CSharp REQUIRED)
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/cmake/findCSharp.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/cmake/findCSharp.cmake")
else()
find_package(CSharp REQUIRED)
endif()

Copilot uses AI. Check for mistakes.
Comment on lines +15 to +20
<group targetFramework="net8.0" />
</dependencies>
</metadata>
<files>
<file src="${CMAKE_SOURCE_DIR_NATIVE}\src\windows\WslcSDK\wslcsdk.h" target="include"/>
<file src="${CMAKE_SOURCE_DIR_NATIVE}\bin\x64\Release\wslcsdkcs.dll" target="lib\net8.0"/>
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The build configuration sets DOTNET_TARGET_FRAMEWORK to a Windows-specific TFM (e.g., net8.0-windows...), but the NuGet asset is being placed under lib\\net8.0 (and targets under build\\net8.0). This can lead to incorrect NuGet TFM selection/compatibility (e.g., allowing restore for non-Windows net8.0 projects) and mismatched asset resolution. Either (a) package under a Windows TFM folder (e.g., lib\\net8.0-windows... / build\\net8.0-windows...) consistent with what you build, or (b) change the build to actually target net8.0 if the assembly is platform-agnostic.

Suggested change
<group targetFramework="net8.0" />
</dependencies>
</metadata>
<files>
<file src="${CMAKE_SOURCE_DIR_NATIVE}\src\windows\WslcSDK\wslcsdk.h" target="include"/>
<file src="${CMAKE_SOURCE_DIR_NATIVE}\bin\x64\Release\wslcsdkcs.dll" target="lib\net8.0"/>
<group targetFramework="net8.0-windows" />
</dependencies>
</metadata>
<files>
<file src="${CMAKE_SOURCE_DIR_NATIVE}\src\windows\WslcSDK\wslcsdk.h" target="include"/>
<file src="${CMAKE_SOURCE_DIR_NATIVE}\bin\x64\Release\wslcsdkcs.dll" target="lib\net8.0-windows"/>

Copilot uses AI. Check for mistakes.
Comment on lines +15 to +20
<group targetFramework="net8.0" />
</dependencies>
</metadata>
<files>
<file src="${CMAKE_SOURCE_DIR_NATIVE}\src\windows\WslcSDK\wslcsdk.h" target="include"/>
<file src="${CMAKE_SOURCE_DIR_NATIVE}\bin\x64\Release\wslcsdkcs.dll" target="lib\net8.0"/>
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The build configuration sets DOTNET_TARGET_FRAMEWORK to a Windows-specific TFM (e.g., net8.0-windows...), but the NuGet asset is being placed under lib\\net8.0 (and targets under build\\net8.0). This can lead to incorrect NuGet TFM selection/compatibility (e.g., allowing restore for non-Windows net8.0 projects) and mismatched asset resolution. Either (a) package under a Windows TFM folder (e.g., lib\\net8.0-windows... / build\\net8.0-windows...) consistent with what you build, or (b) change the build to actually target net8.0 if the assembly is platform-agnostic.

Suggested change
<group targetFramework="net8.0" />
</dependencies>
</metadata>
<files>
<file src="${CMAKE_SOURCE_DIR_NATIVE}\src\windows\WslcSDK\wslcsdk.h" target="include"/>
<file src="${CMAKE_SOURCE_DIR_NATIVE}\bin\x64\Release\wslcsdkcs.dll" target="lib\net8.0"/>
<group targetFramework="net8.0-windows" />
</dependencies>
</metadata>
<files>
<file src="${CMAKE_SOURCE_DIR_NATIVE}\src\windows\WslcSDK\wslcsdk.h" target="include"/>
<file src="${CMAKE_SOURCE_DIR_NATIVE}\bin\x64\Release\wslcsdkcs.dll" target="lib\net8.0-windows"/>

Copilot uses AI. Check for mistakes.
Comment on lines +22 to +24
<ItemGroup>
<ReferenceCopyLocalPaths Include="$(MSBuildThisFileDirectory)..\..\runtimes\win-$(Platform)\native\wslcsdk.dll" />
</ItemGroup>
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ReferenceCopyLocalPaths is primarily used by managed build pipelines (RAR/CopyLocal) and typically won’t copy anything for native .vcxproj consumers. Also, $(Platform) is often ARM64 (uppercase) in VS, while the package folder is win-arm64 (lowercase), so the path can be wrong. For native projects, add an explicit MSBuild Target that copies the DLL to $(TargetDir) (or uses Content + CopyToOutputDirectory) and normalize/map platforms (e.g., ARM64 -> arm64, Win32 -> x86 if relevant).

Copilot uses AI. Check for mistakes.
</Choose>

<Target Name="WSLCSDK_ErrorPlatform" BeforeTargets="PrepareForBuild" Condition="'$(_wslcSdkInvalidPlatform)' != ''">
<Error Text="wslcsdk.dll could not be copied because the $(_wslcSdkInvalidPlatformProperty) '$(_wslcSdkInvalidPlatform)' is not supported." />
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new error doesn’t indicate which values are supported. Consider including expected values in the message (e.g., mention supported RIDs *-x64/*-arm64 or PlatformTarget values x64/arm64) to reduce build-triage time.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants