From 95073614cba754f286d66d1a39c2d012deb14aae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Otte=20S=C3=B8rensen?= Date: Fri, 9 Oct 2026 16:17:21 +0200 Subject: [PATCH 1/2] test: Hoist the Windows runtime list to a static field CA1861 flagged the inline array in FindImport_FindsFreeInTheLiblouisWeShip, the only analyzer warning left in the build (once per target framework). Co-Authored-By: Claude Opus 5.5 --- LibLouis.NET.Test/LiblouisHeapTests.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/LibLouis.NET.Test/LiblouisHeapTests.cs b/LibLouis.NET.Test/LiblouisHeapTests.cs index aaa7509..c32270a 100644 --- a/LibLouis.NET.Test/LiblouisHeapTests.cs +++ b/LibLouis.NET.Test/LiblouisHeapTests.cs @@ -17,6 +17,10 @@ public unsafe class LiblouisHeapTests { private static readonly string[] Tables = ["da-dk-g26.ctb", "da-dk-g16-markers.ctb"]; + // The C runtimes a mingw-built liblouis.dll can import free() from: msvcrt.dll for the gcc + // builds, ucrtbase.dll for llvm-mingw. + private static readonly string[] WindowsRuntimes = ["msvcrt.dll", "ucrtbase.dll"]; + private static string[] TablePaths() => [.. Tables.Select(t => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tables", t))]; @@ -123,7 +127,7 @@ public void FindImport_FindsFreeInTheLiblouisWeShip() nint module = NativeLibrary.Load("liblouis", typeof(LibLouis).Assembly, DllImportSearchPath.SafeDirectories); nint free = LiblouisHeap.FindImport((byte*)module, "free"u8); - nint[] runtimeFrees = [.. new[] { "msvcrt.dll", "ucrtbase.dll" } + nint[] runtimeFrees = [.. WindowsRuntimes .Select(name => NativeLibrary.TryLoad(name, out nint runtime) ? NativeLibrary.GetExport(runtime, "free") : 0)]; Assert.NotEqual(0, free); From 793a3e5940f2909cec80cd33262bc2034954eab5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Otte=20S=C3=B8rensen?= Date: Fri, 9 Oct 2026 16:20:38 +0200 Subject: [PATCH 2/2] build: Build the managed code with -warnaserror With the CA1861 warning gone the build is warning free, so keep it that way: the CI test job and build_managed_packages.sh, which builds what gets packed and published, now fail on any warning. The native runtime packages are left alone. Their dotnet pack only wraps prebuilt binaries, and its NuGet warnings (no readme) would fail it for nothing. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/build.yml | 1 + build/build_managed_packages.sh | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fe6fdfe..cb3a4d1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -106,6 +106,7 @@ jobs: run: > dotnet test LibLouis.NET.Test/LibLouis.NET.Test.csproj --configuration Release + -warnaserror -p:RestoreAdditionalProjectSources=${{ github.workspace }}/local-feed # Managed packages. Split from native-linux because building LibLouis.NET resolves diff --git a/build/build_managed_packages.sh b/build/build_managed_packages.sh index 08c3ca8..c141b16 100755 --- a/build/build_managed_packages.sh +++ b/build/build_managed_packages.sh @@ -21,7 +21,8 @@ if [ -n "${NUGET_LOCAL_FEED:-}" ]; then restore_args="-p:RestoreAdditionalProjectSources=$NUGET_LOCAL_FEED" fi -dotnet build --configuration Release $restore_args "$REPO_ROOT/LibLouis.NET.slnx" +# -warnaserror keeps the build warning free: a warning fails the packages rather than shipping. +dotnet build --configuration Release -warnaserror $restore_args "$REPO_ROOT/LibLouis.NET.slnx" if [ -z "${SKIP_TESTS:-}" ]; then dotnet test --configuration Release --no-build "$REPO_ROOT/LibLouis.NET.slnx"