Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Meson wraps installed libraries in architecture folder on Ubuntu 19.04 (and possibly other debian based systems) #5925

Open
mokafolio opened this issue Sep 15, 2019 · 3 comments

Comments

@mokafolio
Copy link

mokafolio commented Sep 15, 2019

I created a simple test case over here.
This bug might relate to #1972 (possibly duplicate, I am not sure anymore :) )

Here is the build file:

project('MyLib', 'cpp', default_options : ['cpp_std=c++14'])

install_headers(['MyLib/MyLib.hpp'],
	subdir: 'MyLib'
)

incDirs = include_directories('.')

lib = library('MyLib', 
        ['MyLib/MyLib.cpp'],
        include_directories : incDirs,
        install: true)

exe = executable('HelloWorld',
	sources: ['main.cpp'],
	include_directories: incDirs,
	link_with: lib,
	install: true,
)

When simply calling meson build && cd build && sudo ninja install i'd expect the library to be installed to /usr/local/lib and the executable to /usr/local/bin. The executable ends up in bin, but unfortunately the library ends up in /usr/local/lib/x86_64-linux-gnu. Despite being odd default behavior, it is not a default library search path resulting in the library not being found when trying to run the installed binary, i.e. when running HelloWorld afterwards, I get:
HelloWorld: error while loading shared libraries: libMyLib.so: cannot open shared object file: No such file or directory

Workarounds:
The only way to make this work right now is to explicitly set libdir to lib, i.e. meson --libdir=lib build or to explicitly set the install_rpath on the executable to point to the correct place, i.e. something like this:
executable(..., install_rpath: join_paths(get_option('prefix'), get_option('libdir')), ...)`

Please let me know if I am missing anything. Would love to find a fix for this!

@maiphi
Copy link

maiphi commented May 25, 2020

In the function default_libdir() defined in mesonlib.py, debian-like systems get special treatment:

def default_libdir() -> str:
    if is_debianlike():
        try:
            pc = subprocess.Popen(['dpkg-architecture', '-qDEB_HOST_MULTIARCH'],
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.DEVNULL)
            (stdo, _) = pc.communicate()
            if pc.returncode == 0:
                archpath = stdo.decode().strip()
                return 'lib/' + archpath
        except Exception:
            pass
    if is_freebsd():
        return 'lib'
    if os.path.isdir('/usr/lib64') and not os.path.islink('/usr/lib64'):
        return 'lib64'
    return 'lib'

I just tried it on Debian 10 and Ubuntu 18.04, where dpkg-architecture -qDEB_HOST_MULTIARCH prints "x86_64-linux-gnu", so that libdir="lib/x86_64-linux-gnu" (which is not in the linker search path) instead of "lib". Can anyone explain why this was done this way? It seems to me that the solution of the problem is to remove the the is_debianlike special case entirely.

The only workaround I see that doesn't require user interaction is to set libdir=lib in the default_options of the project declaration. Then close your eyes and hope that it doesn't break on any of your target systems.

@jpakkane
Copy link
Member

jpakkane commented May 27, 2020

Can anyone explain why this was done this way?

Because it is the default when installing to /usr where it is in the linker search path. That is the common case and distros really like it when we do that by default. According to /etc/ld.so.conf/*, /usr/local/lib/x86_64-linux-gnu is also in the linker search path. Thus it should work and if it does not, then it seems like a distro issue (as was hinted to in one of the comments in the linked bug).

@maiphi
Copy link

maiphi commented May 27, 2020

Indeed, /etc/ld.so.conf.d/x86_64-linux-gnu.conf lists /usr/lib/x86_64-linux-gnu as well as /usr/local/lib/x86_64-linux-gnu. But in reality, only libraries in /usr/lib/x86_64-linux-gnu are found, but not those in /usr/local/lib/x86_64-linux-gnu. If we set prefix=/usr, everything works fine, but the default is prefix=/usr/local. I agree that this is a distro issue, but if Meson doesn't provide a workaround, the users will blame Meson.

Also, I don't think that it is a good idea to use libdir=/lib/x86_64-linux-gnu for user-defined prefixes. Users expect the libraries to end up in $prefix/lib or $prefix/lib64, e.g. when they set LD_LIBRARY_PATH. Actually, from my experience, this is assumed everywhere where module is used to set up environments, which is very common on HPC clusters.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants