Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions src/coreclr/clr.featuredefines.props
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,5 @@

<DefineConstants Condition="'$(ProfilingSupportedBuild)' == 'true'">$(DefineConstants);PROFILING_SUPPORTED</DefineConstants>
<DefineConstants Condition="'$(FeatureProfAttach)' == 'true'">$(DefineConstants);FEATURE_PROFAPI_ATTACH_DETACH</DefineConstants>

<DefineConstants Condition="'$(TargetsUnix)' == 'true'">$(DefineConstants);TARGET_UNIX</DefineConstants>
<DefineConstants Condition="'$(TargetsWindows)' == 'true'">$(DefineConstants);TARGET_WINDOWS</DefineConstants>
<DefineConstants Condition="'$(TargetsOSX)' == 'true'">$(DefineConstants);TARGET_OSX</DefineConstants>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,17 @@
<SupportsX86Intrinsics Condition="'$(Platform)' == 'x64' or ('$(Platform)' == 'x86' and '$(TargetsUnix)' != 'true')">true</SupportsX86Intrinsics>
<ILLinkSharedDirectory>$(MSBuildThisFileDirectory)ILLink\</ILLinkSharedDirectory>
</PropertyGroup>
<PropertyGroup>
<DefineConstants Condition="'$(TargetsUnix)' == 'true'">$(DefineConstants);TARGET_UNIX</DefineConstants>
<DefineConstants Condition="'$(TargetsWindows)' == 'true'">$(DefineConstants);TARGET_WINDOWS</DefineConstants>
<DefineConstants Condition="'$(TargetsOSX)' == 'true'">$(DefineConstants);TARGET_OSX</DefineConstants>
<DefineConstants Condition="'$(TargetsiOS)' == 'true'">$(DefineConstants);TARGET_IOS</DefineConstants>
<DefineConstants Condition="'$(TargetstvOS)' == 'true'">$(DefineConstants);TARGET_TVOS</DefineConstants>
<DefineConstants Condition="'$(TargetsBrowser)' == 'true'">$(DefineConstants);TARGET_BROWSER</DefineConstants>
<DefineConstants Condition="'$(TargetsAndroid)' == 'true'">$(DefineConstants);TARGET_ANDROID</DefineConstants>
<DefineConstants Condition="'$(TargetsLinux)' == 'true'">$(DefineConstants);TARGET_LINUX</DefineConstants>
<DefineConstants Condition="'$(TargetsFreeBSD)' == 'true'">$(DefineConstants);TARGET_FREEBSD</DefineConstants>
</PropertyGroup>
<ItemGroup>
<ILLinkSubstitutionsXmls Include="$(ILLinkSharedDirectory)ILLink.Substitutions.Shared.xml" />
<!-- TODO: Enable these substitutions files for more platforms once https://github.com/mono/linker/issues/1260 is fixed -->
Expand Down
192 changes: 192 additions & 0 deletions src/libraries/System.Private.CoreLib/src/System/OperatingSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ namespace System
{
public sealed class OperatingSystem : ISerializable, ICloneable
{
#if TARGET_UNIX && !TARGET_OSX
private static readonly string s_osPlatformName = Interop.Sys.GetUnixName();
#endif

private readonly Version _version;
private readonly PlatformID _platform;
private readonly string? _servicePack;
Expand Down Expand Up @@ -79,5 +83,193 @@ public string VersionString
return _versionString;
}
}

/// <summary>
/// Indicates whether the current application is running on the specified platform.
/// </summary>
/// <param name="platform">Case-insensitive platform name. Examples: Browser, Linux, FreeBSD, Android, iOS, macOS, tvOS, watchOS, Windows.</param>
public static bool IsOSPlatform(string platform)
{
if (platform == null)
{
throw new ArgumentNullException(nameof(platform));
}

#if TARGET_BROWSER
return platform.Equals("BROWSER", StringComparison.OrdinalIgnoreCase);
#elif TARGET_WINDOWS
return platform.Equals("WINDOWS", StringComparison.OrdinalIgnoreCase);
#elif TARGET_OSX
return platform.Equals("OSX", StringComparison.OrdinalIgnoreCase) || platform.Equals("MACOS", StringComparison.OrdinalIgnoreCase);
#elif TARGET_UNIX
return platform.Equals(s_osPlatformName, StringComparison.OrdinalIgnoreCase);
#else
#error Unknown OS
#endif
}

/// <summary>
/// Check for the OS with a >= version comparison. Used to guard APIs that were added in the given OS release.
/// </summary>
/// <param name="platform">Case-insensitive platform name. Examples: Browser, Linux, FreeBSD, Android, iOS, macOS, tvOS, watchOS, Windows.</param>
/// <param name="major">Major OS version number.</param>
/// <param name="minor">Minor OS version number (optional).</param>
/// <param name="build">Build OS version number (optional).</param>
/// <param name="revision">Revision OS version number (optional).</param>
public static bool IsOSPlatformVersionAtLeast(string platform, int major, int minor = 0, int build = 0, int revision = 0)
=> IsOSPlatform(platform) && IsOSVersionAtLeast(major, minor, build, revision);

/// <summary>
/// Indicates whether the current application is running as WASM in a Browser.
/// </summary>
public static bool IsBrowser() =>
#if TARGET_BROWSER
true;
#else
false;
#endif

/// <summary>
/// Indicates whether the current application is running on Linux.
/// </summary>
public static bool IsLinux() =>
#if TARGET_LINUX
true;
#else
false;
#endif

/// <summary>
/// Indicates whether the current application is running on FreeBSD.
/// </summary>
public static bool IsFreeBSD() =>
#if TARGET_FREEBSD
true;
#else
false;
#endif

/// <summary>
/// Check for the FreeBSD version (returned by 'uname') with a >= version comparison. Used to guard APIs that were added in the given FreeBSD release.
/// </summary>
public static bool IsFreeBSDVersionAtLeast(int major, int minor = 0, int build = 0, int revision = 0)
=> IsFreeBSD() && IsOSVersionAtLeast(major, minor, build, revision);

/// <summary>
/// Indicates whether the current application is running on Android.
/// </summary>
public static bool IsAndroid() =>
#if TARGET_ANDROID
true;
#else
false;
#endif

/// <summary>
/// Check for the Android version (returned by 'uname') with a >= version comparison. Used to guard APIs that were added in the given Android release.
/// </summary>
public static bool IsAndroidVersionAtLeast(int major, int minor = 0, int build = 0, int revision = 0)
=> IsAndroid() && IsOSVersionAtLeast(major, minor, build, revision);

/// <summary>
/// Indicates whether the current application is running on iOS.
/// </summary>
public static bool IsIOS() =>
#if TARGET_IOS
true;
#else
false;
#endif

/// <summary>
/// Check for the iOS version (returned by 'libobjc.get_operatingSystemVersion') with a >= version comparison. Used to guard APIs that were added in the given iOS release.
/// </summary>
public static bool IsIOSVersionAtLeast(int major, int minor = 0, int build = 0)
=> IsIOS() && IsOSVersionAtLeast(major, minor, build, 0);

/// <summary>
/// Indicates whether the current application is running on macOS.
/// </summary>
public static bool IsMacOS() =>
#if TARGET_OSX
true;
#else
false;
#endif

/// <summary>
/// Check for the macOS version (returned by 'libobjc.get_operatingSystemVersion') with a >= version comparison. Used to guard APIs that were added in the given macOS release.
/// </summary>
public static bool IsMacOSVersionAtLeast(int major, int minor = 0, int build = 0)
=> IsMacOS() && IsOSVersionAtLeast(major, minor, build, 0);

/// <summary>
/// Indicates whether the current application is running on tvOS.
/// </summary>
public static bool IsTvOS() =>
#if TARGET_TVOS
true;
#else
false;
#endif

/// <summary>
/// Check for the tvOS version (returned by 'libobjc.get_operatingSystemVersion') with a >= version comparison. Used to guard APIs that were added in the given tvOS release.
/// </summary>
public static bool IsTvOSVersionAtLeast(int major, int minor = 0, int build = 0)
=> IsTvOS() && IsOSVersionAtLeast(major, minor, build, 0);

/// <summary>
/// Indicates whether the current application is running on watchOS.
/// </summary>
public static bool IsWatchOS() =>
#if TARGET_WATCHOS
true;
#else
false;
#endif

/// <summary>
/// Check for the watchOS version (returned by 'libobjc.get_operatingSystemVersion') with a >= version comparison. Used to guard APIs that were added in the given watchOS release.
/// </summary>
public static bool IsWatchOSVersionAtLeast(int major, int minor = 0, int build = 0)
=> IsWatchOS() && IsOSVersionAtLeast(major, minor, build, 0);

/// <summary>
/// Indicates whether the current application is running on Windows.
/// </summary>
public static bool IsWindows() =>
#if TARGET_WINDOWS
true;
#else
false;
#endif

/// <summary>
/// Check for the Windows version (returned by 'RtlGetVersion') with a >= version comparison. Used to guard APIs that were added in the given Windows release.
/// </summary>
public static bool IsWindowsVersionAtLeast(int major, int minor = 0, int build = 0, int revision = 0)
=> IsWindows() && IsOSVersionAtLeast(major, minor, build, revision);

private static bool IsOSVersionAtLeast(int major, int minor, int build, int revision)
{
Version current = Environment.OSVersion.Version;

if (current.Major != major)
{
return current.Major > major;
}
if (current.Minor != minor)
{
return current.Minor > minor;
}
if (current.Build != build)
{
return current.Build > build;
}

return current.Revision >= revision
|| (current.Revision == -1 && revision == 0); // it is unavailable on OSX and Environment.OSVersion.Version.Revision returns -1
}
}
}
Loading