Skip to content

Conversation

@MarkpageBxl
Copy link

This PR adds Linux support to the .NET language extension, which currently only supports Windows.

This involves the following:

  • Creating scripts for building and shipping the Linux native library. PowerShell was chosen as a scripting language to serve as a potential base for a cross-platform script.
  • The Windows-specific APIs used in the native library have been augmented with Linux library calls, guarded by standard preprocessor defines.
  • Due to differences in the .NET runtime lookup logic in hostfxr between Linux and Windows, using a hardcoded hostfxr library path was a no go for portability (e.g. .NET packages on RHEL and Debian do not install .NET in the same base directories). Instead, we make use of nethost (in the form of the libnethost.a static library provided by the .NET runtime) to first do the hostfxr lookup. This approach has the advantage of honoring DOTNET_ROOT and install_location files if they exist, which hostfxr does not.

Additionally, this bumps references to net6.0 up to net8.0, since the former is EOL.

At this point, this has been tested manually on SQL Server running on Ubuntu 22.04 LTS. A .NET 8.0 assembly was successfully executed.

SQL Server on Linux expects a .tar.gz file instead of a .zip when using
CREATE EXTERNAL LANGUAGE.
We will use the nethost to locate the system's installed hostfxr, as
using a local libhostfxr.so breaks the .NET runtime lookup.

nethost contains the logic needed to find the .NET root based on the
DOTNET_ROOT environment variable or the install_location configuration
file, which we will require for .NET runtime lookup on diverging Linux
distributions (e.g. RHEL and Debian packages not installing .NET in the
same base directories).
@MarkpageBxl
Copy link
Author

@microsoft-github-policy-service agree company="Raincode srl"

@@ -0,0 +1,106 @@
#!/usr/bin/env pwsh
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are we using powershell script for linux instead of bash script?

Copy link
Author

Choose a reason for hiding this comment

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

As written in the description, PowerShell was chosen as a scripting language to serve as a potential base for a cross-platform script. If this is not desired, I can rewrite it in bash.

Copy link
Contributor

Choose a reason for hiding this comment

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

Do you mean this script can be used for both windows/linux now or we should have a follow-up work item for this?

Copy link

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

This PR adds Linux support to the .NET language extension, which previously only supported Windows. The changes include:

  • Platform-specific conditional compilation using preprocessor defines to support both Windows and Linux
  • Integration of nethost library for dynamic hostfxr lookup on Linux (avoiding hardcoded paths)
  • Updated build artifacts and project files to target .NET 8.0 (from .NET 6.0, which is EOL)
  • Platform-specific APIs for file operations, dynamic library loading, and path handling

Reviewed Changes

Copilot reviewed 12 out of 13 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
Microsoft.SqlServer.CSharpExtensionTest.csproj Updated target framework from net6.0 to net8.0
Microsoft.SqlServer.CSharpExtension.csproj Updated target framework from net6.0 to net8.0
RegexSample.csproj Updated target framework from net6.0 to net8.0
Logger.cpp Removed Windows-specific includes (stdio.h, windows.h)
Logger.h Removed stdio.h include
DotnetEnvironment.cpp Added platform-specific code for library loading, path handling, and hostfxr lookup using nethost
DotnetEnvironment.h Added platform-specific macros and definitions for path separators and string types
nativecsharpextension.h Guarded windows.h include with platform check
nethost.h Added header file for nethost API
libnethost.a Added static library for nethost (Linux)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +51 to +55
#if defined(_WIN32) || defined(WINDOWS)
m_root_path(to_utf16_str(language_path))
#else
m_root_path(language_path)
#endif
Copy link

Copilot AI Nov 10, 2025

Choose a reason for hiding this comment

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

[nitpick] The conditional initialization of m_root_path in the constructor initializer list could be simplified. Consider using a helper function to convert the path conditionally, which would make the code cleaner and easier to maintain. For example, create a convert_path(const std::string& path) function that returns either the UTF-16 or UTF-8 version based on the platform.

Copilot uses AI. Check for mistakes.
Comment on lines +168 to +172
char buffer[4096];
size_t buffer_size = sizeof(buffer);
if (get_hostfxr_path(buffer, &buffer_size, nullptr) != 0) {
return false;
}
Copy link

Copilot AI Nov 10, 2025

Choose a reason for hiding this comment

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

[nitpick] The hardcoded buffer size of 4096 bytes should be defined as a named constant (e.g., constexpr size_t HOSTFXR_PATH_BUFFER_SIZE = 4096;) to improve code maintainability and make it easier to adjust if needed.

Copilot uses AI. Check for mistakes.
#include "DotnetEnvironment.h"
#include "Logger.h"

#if defined(_WIN32) || defined(WINDOWS)
Copy link

Copilot AI Nov 10, 2025

Choose a reason for hiding this comment

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

[nitpick] The platform check uses both _WIN32 and WINDOWS macros. The _WIN32 macro is the standard Microsoft compiler define for Windows (both 32-bit and 64-bit). The WINDOWS macro appears to be custom. Consider using only _WIN32 for consistency with common practice, or document why both are needed if there's a specific reason.

Copilot uses AI. Check for mistakes.
@SicongLiu2000
Copy link
Contributor

@MarkpageBxl , have you ever met this error:

Error: Could not find a part of the path
'/home/mssql_satellite/externallibrariessandboxprivatepath'

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