I was recently working with a dotnet project that used GitVersion to stamp builds with version numbers derived from the git history:
<!-- Directory.Packages.props -->
<PackageVersion Include="GitVersion.MsBuild" Version="6.2.0" />
The project also had a few other unusual build dependencies for a dotnet project — nodejs, Java, and others — so I decided to create a flake.nix to be able to quickly spin up a development environment with everything needed.
The problem was that the build started to fail:
.nuget/packages/gitversion.msbuild/6.2.0/tools/GitVersion.MsBuild.targets(26,9): error MSB3073: The command "dotnet --roll-forward Major "~/.nuget/packages/gitversion.msbuild/6.2.0/tools/net8.0/gitversion.dll"" exited with code 139.
Exit code 139 means a segmentation fault. We don't need the full dotnet build to reproduce this — we can run the GitVersion tool directly:
$ dotnet "~/.nuget/packages/gitversion.msbuild/6.2.0/tools/net8.0/gitversion.dll"
[1] 1256082 segmentation fault (core dumped) dotnet
With help of strace we can see that there's an attempt to load libssl (various versions), and every one of them fails:
$ strace dotnet "~/.nuget/packages/gitversion.msbuild/6.2.0/tools/net8.0/gitversion.dll" 2>&1 | grep ssl
openat(AT_FDCWD, "/nix/store/l0l2ll1lmylczj1ihqn351af2kyp5x19-glibc-2.42-51/lib/libssl.so.1.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/nix/store/r7vdyf8pwlqsgd5ydak9fmq3q1i5nm3m-xgcc-15.2.0-libgcc/lib/glibc-hwcaps/x86-64-v3/libssl.so.1.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/nix/store/r7vdyf8pwlqsgd5ydak9fmq3q1i5nm3m-xgcc-15.2.0-libgcc/lib/glibc-hwcaps/x86-64-v2/libssl.so.1.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/nix/store/r7vdyf8pwlqsgd5ydak9fmq3q1i5nm3m-xgcc-15.2.0-libgcc/lib/libssl.so.1.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/nix/store/l0l2ll1lmylczj1ihqn351af2kyp5x19-glibc-2.42-51/lib/libssl.so.3", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/nix/store/r7vdyf8pwlqsgd5ydak9fmq3q1i5nm3m-xgcc-15.2.0-libgcc/lib/libssl.so.3", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
The dlopen calls are searching in many places, just not the right ones. GitVersion bundles a native library (git2) that uses dlopen() to load libssl at runtime. On NixOS, libraries aren't in the usual /usr/lib paths, and dlopen doesn't respect RPATH — so the library simply can't find OpenSSL.
The fix is to add openssl to the dev shell and expose it via LD_LIBRARY_PATH in the flake.nix:
{
devShells.default = pkgs.mkShell {
# ...
packages = with pkgs; [
# ...
openssl
];
shellHook = ''
# git2-a418d9d.so (bundled with GitVersion) uses dlopen() to find libssl at runtime.
# Since dlopen doesn't use RPATH, we must expose openssl via LD_LIBRARY_PATH.
export LD_LIBRARY_PATH="${pkgs.openssl.out}/lib:$LD_LIBRARY_PATH"
'';
};
}
This is a recurring pattern on NixOS: any native dependency that's loaded via dlopen at runtime — rather than linked at build time — won't be found unless you explicitly set LD_LIBRARY_PATH. It's one of those things that "just works" on other distros but requires a bit of manual wiring on Nix.