question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Include the major version when referencing *.so libraries

See original GitHub issue

Describe the bug

Linux distributions typically split libraries like libgpiod into multiple packages.

One specific split is between libgpiod and libgpiod-dev, where the former contains the necessary binaries and symlinks to run programs while the latter is meant for development, where you (traditionally) invoke a linker to produce a binary. The latter typically uses the unversioned symlink to simplify the build and the binary referencing the library then includes the versioned reference. In this split, the full version (libgpiod.so.2.1.3) and a symlink with the major version (libgpiod.so.2) are in the main package, the unversioned symlink (libgpiod.so) is in the -dev package, which doesn’t get installed per default.

For example for Ubuntu:

Embedded distributions like Yocto per default do not install the -dev package into the image when you declare a runtime dependency on a library. Including the -dev package in the image can have unwanted side-effects of pulling in other development dependencies (for example I ended up with a Python interpreter in my image for a different -dev package in the past)

My own Yocto image doesn’t include any -dev packages, so in order to use the LibGpiodDriver in my code, I have to “translate” the DllImport string by

static MyType()
    => NativeLibrary.SetDllImportResolver(typeof(GpioDriver).Assembly, libgpiodFixup);

private static IntPtr libgpiodFixup(string libraryName, Assembly assembly, DllImportSearchPath? searchPath)
{
    if (libraryName == "libgpiod")
        if (NativeLibrary.TryLoad("libgpiod.so.2", assembly, searchPath, out var result))
            return result;
    return IntPtr.Zero;
}

However, this “trick” only works exactly once per assembly (only one resolver per assembly), and the NativeLibrary API is meant to be used within the library requiring a specialized resolver. If System.Device.Gpio would decide to start using that functionality in the future, my own fixup would be broken.

Since the C# interop code typically relies on a specific major ABI version when declaring methods from an external library like libgpiod, that major version should be included in the DllImport instead of the unversioned .so.

Steps to reproduce

Run code using LibGpiodDriver on a Linux image without the libgpiod-dev package.

Expected behavior Run without exception.

Actual behavior DllNotFoundException

Versions used

Add following information:

  • dotnet --info on the machine being used to build
.NET Core SDK (reflecting any global.json):
 Version:   3.1.101
 Commit:    b377529961

Runtime Environment:
 OS Name:     ubuntu
 OS Version:  18.04
 OS Platform: Linux
 RID:         ubuntu.18.04-x64
 Base Path:   /usr/share/dotnet/sdk/3.1.101/

Host (useful for support):
  Version: 3.1.1
  Commit:  a1388f194c

.NET Core SDKs installed:
  2.2.402 [/usr/share/dotnet/sdk]
  3.0.102 [/usr/share/dotnet/sdk]
  3.1.101 [/usr/share/dotnet/sdk]

.NET Core runtimes installed:
  Microsoft.AspNetCore.All 2.2.8 [/usr/share/dotnet/shared/Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.2.8 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.0.2 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.1 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.2.8 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.0.2 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.1 [/usr/share/dotnet/shared/Microsoft.NETCore.App]

To install additional .NET Core runtimes or SDKs:
  https://aka.ms/dotnet-download
  • dotnet --info on the machine where app is being run
  It was not possible to find any installed .NET Core SDKs
  Did you mean to run .NET Core SDK commands? Install a .NET Core SDK from:
      https://aka.ms/dotnet-download

Host (useful for support):
  Version: 3.1.3
  Commit:  4a9f85e9f8

.NET Core SDKs installed:
  No SDKs were found.

.NET Core runtimes installed:
  Microsoft.AspNetCore.App 3.1.3 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 3.1.3 [/usr/share/dotnet/shared/Microsoft.NETCore.App]

To install additional .NET Core runtimes or SDKs:
  https://aka.ms/dotnet-download
  • Version of System.Device.Gpio package: 1.0.0

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:6 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
joperezrcommented, Jun 30, 2020

I see, yeah I think depending on the major version seems reasonable to me.

0reactions
krwqcommented, Mar 23, 2023

[Triage] If we fix this libgpiod can be used without installing dev package. Bumping priority.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Version indication in the file name for a shared library
1 Answer. Programs using your library should link with libNAME.so if they want the latest version, with libNAME. so. X if they want...
Read more >
the major version number of shared library - linux
The idea of the shared library version (called "soname") is that is reflects binary compatibility. When your program is linked to ...
Read more >
Shared library versions - dcreager.net
1. Version info ... First, you assign your shared library a **version info**. Like a traditional version number, this consists of three numbers, ......
Read more >
Major vs. Minor Versions in SharePoint Online
How do you decide between Major vs. Minor Versions in SharePoint Online? I explain in great detail in this article.
Read more >
Versioning and .NET libraries
A software library is rarely complete in version 1.0. ... CONSIDER only including a major version in the AssemblyVersion. e.g. Library 1.0 ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found