Hacker Read top | best | new | newcomments | leaders | about | bookmarklet login

> Cause the situation on Linux is absurd! You pass some flags -L and -l to the compiler/linker, the linker links something and nobody knows what. Then when you run your executable it has to locate this something again, and you can only pray that your libc and binutils/llvm agree on search paths & order. In most cases this does not work, and you must manually pass -Wl,-rpath,/some/path to add a search path. Nobody guarantees that what the linker links is what the runtime linker uses.

The issue you're missing is that the build directory is usually not the location of the final binary objects. The actual absolute path of libfoo.so may well be in /builds/runner/foo-package-4df78af0/build/prefix/lib/libfoo.so, which is unlikely to exist on anyone other than the CI's machine (and even on the CI machine itself for too much longer). The actual location will usually be /usr/lib64/libfoo.so, but the library that is linked against may well not be there at the time of linking (particularly in the case where a package is building both a library and an executable that depends on said library in the same package).

What you really want is for the relative path to the library to stored in the executable. Unless what you want is to actually use the globally-installed library and not one you're building at the same time. There's no single solution that fits every use case!



view as:

Of course you can't guarantee that the library will get installed to the directory you think it'll get installed to, since there's no unified installer system for all Linux distributions. So even a relative path doesn't necessarily work. The best you can do is hope that the Freedesktop filesystem hierarchy is being followed, but that forces installing software for all users at once instead of per user, despite Linux supposedly being a multiuser OS.

In Nix and friends, they don't do relocation at all. So you know where the libs are on everybody's filesystem.

> The actual location will usually be /usr/lib64/libfoo.so

Usually indeed, for distro's that pretty much support one single version of every library. But this is no longer true for Nix, Spack, Gentoo Prefix and Guix, all these package managers/distro's have in common that there should be no default search paths where all libraries are dumped into.

How about `--copy-link-path-as-rpath` and `--copy-link-path-as-rpath-ignore=/build/dir`, so that ld continues to copy the soname to dt_needed, and registers rpath of non-build dirs. Then Nix, Spack, ... can simply use these flags in their linker wrapper.


I think most people designing build systems (I'm one of them) would prefer to explicitly set the paths at each point rather than have gcc ferry values between inputs behind the scenes.

My build system will have already resolved all these paths. It's very easy to interpolate these paths into the command to call the compiler.


And some build systems already have an option to add these RPATHs, e.g. https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_R...

Legal | privacy