-
Notifications
You must be signed in to change notification settings - Fork 330
Consolidate OS detection to OsConstants #4255
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
| // See the LICENSE file in the project root for more information. | ||
|
|
||
| using System.Runtime.InteropServices; | ||
|
|
||
| namespace Microsoft.Data.SqlClient; | ||
|
|
||
| /// <summary> | ||
| /// Provides platform detection flags for OS-specific code paths. | ||
| /// </summary> | ||
| /// <remarks> | ||
| /// These constants are computed at runtime and cached as static readonly fields. This design | ||
| /// allows the JIT compiler to elide branches in hot paths based on whether the OS flags are known | ||
| /// constants at JIT compilation time. | ||
| /// </remarks> | ||
| internal static class OsConstants | ||
| { | ||
| /// <summary> | ||
| /// Gets a value indicating whether the runtime is executing on Windows. | ||
| /// </summary> | ||
| internal static readonly bool IsWindows; | ||
|
|
||
| /// <summary> | ||
| /// Gets a value indicating whether the runtime is executing on Linux. | ||
| /// </summary> | ||
| internal static readonly bool IsLinux; | ||
|
|
||
| /// <summary> | ||
| /// Gets a value indicating whether the runtime is executing on macOS. | ||
| /// </summary> | ||
| internal static readonly bool IsMacOS; | ||
|
|
||
| #if NET | ||
| /// <summary> | ||
| /// Gets a value indicating whether the runtime is executing on FreeBSD. | ||
| /// </summary> | ||
| /// <remarks> | ||
| /// FreeBSD support is only available in .NET 5+ and later. This field will be | ||
| /// <c>false</c> on .NET Framework or if the runtime does not support FreeBSD detection. | ||
| /// </remarks> | ||
| internal static readonly bool IsFreeBSD; | ||
| #endif | ||
|
|
||
| /// <summary> | ||
| /// Initializes platform detection flags by querying <see cref="RuntimeInformation"/>. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This impacts IL trimming, which runs at publish time. The IL trimmer needs to be able to statically see that I've linked against the CI artifacts and confirmed that the IL trimmer can't analyze the static constructor, so I think this rules out everything besides exposing properties which returns the value of Incidentally, exposing it as a field or a property also blocks .NET Framework from removing dead code paths (which in turn can consume the inlining budget), which is why IsWindows is currently a |
||
| /// </summary> | ||
| /// <remarks> | ||
| /// We use a static constructor instead of a module initializer ([ModuleInitializer]) to avoid | ||
| /// the CA2255 security concern. Module initializers can be problematic because: 1. They run in | ||
| /// an unpredictable order relative to other initialization code. 2. They run before the app | ||
| /// initialization sequence, potentially before security policies are set. 3. They can | ||
| /// complicate debugging and profiling. | ||
| /// | ||
| /// Using a static constructor ensures initialization happens in a well-defined, type-safe | ||
| /// manner that is compatible with the CLR's type loading guarantees. | ||
| /// | ||
| /// The trade-off is that the OS flags won't be initialized until the OsConstants type is first | ||
| /// accessed, which may cause a slight delay in a hot path, but only once. | ||
| /// </remarks> | ||
| static OsConstants() | ||
| { | ||
| IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); | ||
| IsLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux); | ||
| IsMacOS = RuntimeInformation.IsOSPlatform(OSPlatform.OSX); | ||
| #if NET | ||
| IsFreeBSD = RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD); | ||
| #endif | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't strictly true - you can run .NET Framework on non-Windows.
We're conflating .NET Framework and Windows elsewhere, and we will deal with that later.