You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Mono.Unix dependency is declared for net462/net48 builds too, not just netstandard2.0 #1542
SIL.Core's published nuspec declares a dependency on Mono.Unix identically across all three target-framework dependency groups — .NETFramework4.6.2, .NETFramework4.8, and .NETStandard2.0 — even though the POSIX interop it provides is presumably only ever exercised on Linux via the netstandard2.0 build. From SIL.Core 17.0.0's nuspec:
Mono.Unix has never had a genuinely stable NuGet release — every version ever published (including the "final" ones) carries a hyphenated suffix (e.g. 7.1.0-final.1.21458.1), which NuGet's semver parsing treats as prerelease regardless of the label. Consumers restoring via classic nuget.exe install without -Prerelease (packages.config-style restore) get "Unable to resolve dependency 'Mono.Unix'" and fail outright.
Because the dependency is declared for the .NETFramework4.6.2/.NETFramework4.8 groups too, this breaks restore for Windows-only, .NET-Framework-only consumers that never touch the Linux/netstandard2.0 build at all and have no actual runtime need for POSIX interop. This is exactly what happened downstream in sillsdev/SIL.BuildTasks#88 — SIL.BuildTasks (an MSBuild-tasks-only package with net472/netstandard2.0 targets) picked up SIL.Core 17.0.0 and broke restore for Bloom, a Windows-only consumer, purely because of this transitive dependency edge.
Suggested fix
Scope the Mono.UnixPackageReference in SIL.Core's own .csproj to only the netstandard2.0 target, e.g.:
That would drop it from the .NETFramework4.6.2/.NETFramework4.8 dependency groups in the generated nuspec entirely, so any net46x/net48-only consumer stops needing to resolve it — without changing anything for netstandard2.0/Linux consumers, who would still need it (and would still need to work around its prerelease-only status some other way, which is a separate, harder problem this issue doesn't attempt to solve).
I concur, though I would recommend changing the TargetFramework check to netstandard2.0 or netstandard 2.1 or >= 'net5' (though you'd want to make sure that that didn't return false for net10.0, it might have to be a fairly elaborate condition). Because as long as the targeted framework is specified in the same file there's very very little chance of drift, but since the beginning of SIL.Core.csproj lists $(TargetFrameworks);netstandard2.0 then there's a chance that the TargetFrameworks list declared in Directory.Build.Props might at some point be updated to include net8.0 or net10.0 or net12.0. (Unlikely since it would require Microsoft open-sourcing the Windows.Forms API, but theoretically possible).
Eh, on second thought checking for == 'netstandard2.0' || == 'netstandard2.1' is almost certainly good enough, no need to complicate things with checking for >= net5.0 or whatever. We're probably never going to have the Windows.Forms libraries targeting net5.0 or higher, so my theoretical concern is probably never going to happen.
Did an experiment with Claude Code, and it found that the suggested TargetFramework == netstandard2.0 condition wouldn't compile. SIL.Core/Threading/GlobalMutex.cs includes using Mono.Unix.Native on line 9, which is needed by LinuxGlobalMutexAdapter. And SIL.Core/IO/FileModeOverride.cs has using Mono.Unix.Native on line 5, to enable the Syscall.umask call at line 63.
It cautioned that this would cause any software that runs using Mono on Linux to start failing with a FileNotFoundException (at runtime) when they try to access GlobalMutex or the GlobalWritingSystemRepository class (which uses FileModeOverride on Linux, which in turn needs Mono.Unix). But it also said that any such software could fix that runtime crash by including the Mono.Unix dependency themselves, with
Here's Claude's suggested patch, in full, removing the using Mono.Unix.Native from the places that asked for it but didn't actually need it, and updating the README with verbose (IMHO overly-verbose, as usual for Claude-generated text) instructions for any projects that still use Mono but are trying to update to recent SIL.Core versions to fix the runtime errors they will get when attempting to use GlobalMutex or GlobalWritingSystemRepository.
If this looks good, I can turn it into a PR. I have not yet tested it myself — I don't have Mono set up on my current computer, so that would take some effort. So I hesitate to open a PR until I have the ability to actually test it. But this might save others some time in creating a PR to fix this.
Note that if you ignore the overly-verbose comments, the actual code changes are quite small.
Activity
rmunn commentedon Sep 2, 2026
I concur, though I would recommend changing the
TargetFrameworkcheck to netstandard2.0 or netstandard 2.1 or>= 'net5'(though you'd want to make sure that that didn't return false fornet10.0, it might have to be a fairly elaborate condition). Because as long as the targeted framework is specified in the same file there's very very little chance of drift, but since the beginning of SIL.Core.csproj lists$(TargetFrameworks);netstandard2.0then there's a chance that the TargetFrameworks list declared in Directory.Build.Props might at some point be updated to include net8.0 or net10.0 or net12.0. (Unlikely since it would require Microsoft open-sourcing the Windows.Forms API, but theoretically possible).Eh, on second thought checking for
== 'netstandard2.0' || == 'netstandard2.1'is almost certainly good enough, no need to complicate things with checking for>= net5.0or whatever. We're probably never going to have the Windows.Forms libraries targeting net5.0 or higher, so my theoretical concern is probably never going to happen.rmunn commentedon Sep 2, 2026
Did an experiment with Claude Code, and it found that the suggested
TargetFramework == netstandard2.0condition wouldn't compile. SIL.Core/Threading/GlobalMutex.cs includesusing Mono.Unix.Nativeon line 9, which is needed by LinuxGlobalMutexAdapter. And SIL.Core/IO/FileModeOverride.cs hasusing Mono.Unix.Nativeon line 5, to enable the Syscall.umask call at line 63.Instead, Claude suggested the following fix:
It cautioned that this would cause any software that runs using Mono on Linux to start failing with a FileNotFoundException (at runtime) when they try to access GlobalMutex or the GlobalWritingSystemRepository class (which uses FileModeOverride on Linux, which in turn needs Mono.Unix). But it also said that any such software could fix that runtime crash by including the Mono.Unix dependency themselves, with
added to their .csproj files (or using
nuget install Mono.Unix -Prereleasefor projects using old-style .csproj files and apackages.configfile).rmunn commentedon Sep 2, 2026
Here's Claude's suggested patch, in full, removing the
using Mono.Unix.Nativefrom the places that asked for it but didn't actually need it, and updating the README with verbose (IMHO overly-verbose, as usual for Claude-generated text) instructions for any projects that still use Mono but are trying to update to recent SIL.Core versions to fix the runtime errors they will get when attempting to use GlobalMutex or GlobalWritingSystemRepository.If this looks good, I can turn it into a PR. I have not yet tested it myself — I don't have Mono set up on my current computer, so that would take some effort. So I hesitate to open a PR until I have the ability to actually test it. But this might save others some time in creating a PR to fix this.
Note that if you ignore the overly-verbose comments, the actual code changes are quite small.