fix(quic): statically link MsQuic for Alpine nodes [CI]

This commit is contained in:
justme committed 2026-10-11 01:00:37 +08:00
1 parent 0d08e90dab
commit a44895d860
17 files changed
+363 -65

No files matched your search

@@ -23,4 +23,6 @@
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
<Import Project="Sdk.targets" Sdk="StuDev.AotAnywhere"
Condition="'$(UseAotAnywhere)' == 'true'" />
<Import Project="..\..\..\shared\MoShiro.Measurement\StaticMsQuic.targets"
Condition="'$(StaticMsQuic)' == 'true'" />
</Project>
@@ -33,4 +33,6 @@
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
<Import Project="Sdk.targets" Sdk="StuDev.AotAnywhere"
Condition="'$(UseAotAnywhere)' == 'true'" />
<Import Project="..\..\..\shared\MoShiro.Measurement\StaticMsQuic.targets"
Condition="'$(StaticMsQuic)' == 'true'" />
</Project>
@@ -23,4 +23,6 @@
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
<Import Project="Sdk.targets" Sdk="StuDev.AotAnywhere"
Condition="'$(UseAotAnywhere)' == 'true'" />
<Import Project="..\..\..\shared\MoShiro.Measurement\StaticMsQuic.targets"
Condition="'$(StaticMsQuic)' == 'true'" />
</Project>
@@ -3,6 +3,9 @@
<IsAotCompatible>true</IsAotCompatible>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition="'$(StaticMsQuic)' == 'true'">
<DefineConstants>$(DefineConstants);MOSHIRO_STATIC_MSQUIC</DefineConstants>
</PropertyGroup>
<ItemGroup>
<InternalsVisibleTo Include="MoShiro.Measurement.Tests" />
<AdditionalFiles Include="$(MSBuildThisFileDirectory)../../BannedSymbols.Node.txt" />
@@ -7,11 +7,13 @@ internal static class MsQuicRuntime
{
private const uint ApiVersion = 2;
private static readonly object s_gate = new();
#if !MOSHIRO_STATIC_MSQUIC
private static nint s_library;
private static nint s_api;
private static OpenVersionDelegate? s_open;
private static CloseDelegate? s_close;
private static readonly List<nint> s_supportLibraries = [];
#endif
private static nint s_api;
public static nint Api
{
@@ -19,6 +21,19 @@ internal static class MsQuicRuntime
{
lock (s_gate)
{
#if MOSHIRO_STATIC_MSQUIC
if (s_api == 0)
{
int status = OpenStatic(ApiVersion, out s_api);
if (status != 0 || s_api == 0)
{
s_api = 0;
throw new InvalidOperationException($"MsQuic API v{ApiVersion} could not be opened (status {status}).");
}
}
return s_api;
#else
if (s_api != 0)
{
return s_api;
@@ -57,6 +72,7 @@ internal static class MsQuicRuntime
}
return s_api;
#endif
}
}
}
@@ -65,6 +81,13 @@ internal static class MsQuicRuntime
{
lock (s_gate)
{
#if MOSHIRO_STATIC_MSQUIC
if (s_api != 0)
{
CloseStatic(s_api);
s_api = 0;
}
#else
if (s_api != 0)
{
s_close!(s_api);
@@ -83,9 +106,11 @@ internal static class MsQuicRuntime
}
s_supportLibraries.Clear();
#endif
}
}
#if !MOSHIRO_STATIC_MSQUIC
private static void LoadBundledSupportLibraries()
{
if (OperatingSystem.IsLinux())
@@ -106,13 +131,22 @@ internal static class MsQuicRuntime
s_supportLibraries.Add(handle);
}
}
#else
[DllImport("__Internal", EntryPoint = "MsQuicOpenVersion", CallingConvention = CallingConvention.Cdecl)]
private static extern int OpenStatic(uint version, out nint api);
[DllImport("__Internal", EntryPoint = "MsQuicClose", CallingConvention = CallingConvention.Cdecl)]
private static extern void CloseStatic(nint api);
#endif
public static T Function<T>(int index)
where T : Delegate => Marshal.GetDelegateForFunctionPointer<T>(Marshal.ReadIntPtr(Api, checked(index * IntPtr.Size)));
#if !MOSHIRO_STATIC_MSQUIC
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int OpenVersionDelegate(uint version, out nint api);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void CloseDelegate(nint api);
#endif
}
@@ -0,0 +1,32 @@
<Project>
<PropertyGroup>
<_MoShiroStaticMsQuicLibrary>$(MSBuildThisFileDirectory)../../../packaging/native/msquic/$(RuntimeIdentifier)/libmsquic.a</_MoShiroStaticMsQuicLibrary>
</PropertyGroup>
<PropertyGroup Condition="$(RuntimeIdentifier.StartsWith('linux-musl-'))">
<StaticExecutable>true</StaticExecutable>
<InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>
<ItemGroup>
<NativeLibrary Include="$(_MoShiroStaticMsQuicLibrary)" />
<DirectPInvoke Include="__Internal" />
<DirectPInvoke Include="System.Security.Cryptography.Native.OpenSsl" />
</ItemGroup>
<!-- The archive includes MsQuic, OpenSSL, and the .NET OpenSSL shim. -->
<Target Name="StaticMsQuicFixLinker" AfterTargets="SetupOSSpecificProps" BeforeTargets="AotAnywhereDirectLinkNative">
<ItemGroup>
<LinkerArg Remove="-Wl,--defsym,__xmknod=mknod" />
<NativeLibrary Remove="$(IlcFrameworkNativePath)libSystem.Security.Cryptography.Native.OpenSsl.a" />
<LinkerArg Remove="$(IlcFrameworkNativePath)libSystem.Security.Cryptography.Native.OpenSsl.a" />
</ItemGroup>
</Target>
<Target Name="ValidateStaticMsQuicArchive" BeforeTargets="AotAnywhereDirectLinkNative">
<Error Condition="!Exists('$(_MoShiroStaticMsQuicLibrary)')"
Text="Static MsQuic archive is missing for $(RuntimeIdentifier)." />
<Error Condition="'$(RuntimeFrameworkVersion)' != '10.0.12'"
Text="The vendored static MsQuic and crypto archive is validated with .NET runtime 10.0.12." />
</Target>
</Project>