meson: Meson outputs incorrectly-named shared libraries on OpenBSD
Meson can’t find shared libraries like /usr/lib/libm.so.10.1
in OpenBSD, but uses static libraries like /usr/lib/libm.a
. OpenBSD uses ELF shared libraries but (unlike other ELF systems) has no symbolic link named libm.so
. I have OpenBSD/amd64 6.3 and meson 0.47.0.dev1 (8a9f7cf).
Sometimes the compiler still uses the shared library, but sometimes it doesn’t. For example, OpenBSD’s package of libiconv installs /usr/local/lib/libiconv.a
and /usr/local/lib/libiconv.so.6.0
. The compiler and Meson don’t look in /usr/local by default, and libiconv doesn’t use pkg-config, so I will tell Meson to look for libiconv in /usr/local if the system is OpenBSD.
I have this C program iopen.c
#include <iconv.h>
#include <stdio.h>
int main(int argc, char **argv) {
iconv_t cd = iconv_open("UTF-8", "EUC-JP");
printf("got %lld", (long long)cd);
}
and its meson.build
project('cbrt', 'c')
cc = meson.get_compiler('c')
dirs = []
if host_machine.system() == 'openbsd'
dirs += '/usr/local/lib'
add_global_arguments('-I/usr/local/include', language: 'c')
endif
libiconv = cc.find_library('iconv', dirs: dirs, required: false)
executable('iopen', 'iopen.c', dependencies: libiconv)
Now I build it:
$ meson build
The Meson build system
Version: 0.47.0.dev1
Source dir: /home/kernigh/park/example
Build dir: /home/kernigh/park/example/build
Build type: native build
Project name: cbrt
Native C compiler: cc (clang 5.0.1 "OpenBSD clang version 5.0.1 (tags/RELEASE_50
1/final) (based on LLVM 5.0.1)")
Build machine cpu family: x86_64
Build machine cpu: x86_64
Library iconv found: YES
Build targets in project: 1
Found ninja-1.8.2 at /usr/local/bin/ninja
$ ninja -vC build
ninja: Entering directory `build'
[1/2] cc -Iiopen@exe -I. -I.. -I/usr/local/include -Xclang -fcolor-diagnostics -
pipe -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -O0 -g -MD -MQ 'iopen@exe/iopen
.c.o' -MF 'iopen@exe/iopen.c.o.d' -o 'iopen@exe/iopen.c.o' -c ../iopen.c
[2/2] cc -o iopen 'iopen@exe/iopen.c.o' -Wl,--no-undefined -Wl,--as-needed -Wl,
--start-group /usr/local/lib/libiconv.a -Wl,--end-group
Meson used /usr/local/lib/libiconv.a, not /usr/local/lib/libiconv.so.6.0.
Meson might need to look for libraries named libiconv.so.X.Y, and pick the one with the highest version; see “Understanding shared libraries number rules”.
About this issue
- Original URL
- State: open
- Created 6 years ago
- Reactions: 1
- Comments: 22 (22 by maintainers)
Commits related to this issue
- find_library: Validate and sort globbed shared library files We need to pick the library with the highest version, which is what the OpenBSD linker also does. https://github.com/mesonbuild/meson/iss... — committed to mesonbuild/meson by nirbheek 6 years ago
- find_library: Validate and sort globbed shared library files We need to pick the library with the highest version, which is what the OpenBSD linker also does. https://github.com/mesonbuild/meson/iss... — committed to mesonbuild/meson by nirbheek 6 years ago
- find_library: Validate and sort globbed shared library files We need to pick the library with the highest version, which is what the OpenBSD linker also does. https://github.com/mesonbuild/meson/iss... — committed to mesonbuild/meson by nirbheek 6 years ago
- Makefile: Disable b_lundef or b_asneeded on OpenBSD Both of these default to True but they don't currently work on OpenBSD: https://github.com/mesonbuild/meson/issues/3570 https://github.com/mesonbui... — committed to nomis/dtee by nomis 6 years ago
Meson’s master, having merged #3851, can now find shared libraries like
libiconv.so.6.0
.I found a problem: if there are multiple versions of the same library, Meson picks any one of them. Meson might pick a version that is too old, then the build might be wrong. I had deleted most of my old libraries, so my builds are working for now. To demonstrate the problem on OpenBSD,
I build 5 major versions of the library, then build the program.
Meson picked version 3.0 instead of version 5.0. If the program needs some feature that wasn’t in 3.0, or some struct changed between 3.0 and 5.0, then the program might not work now.
I want Meson to pick the highest version. In my draft code, I tried to pick the highest version using a regexp ending in
'\.([0-9]+)\.([0-9]+)\Z'
to captureversion = tuple(map(int, match.group(1, 2)))
to compareversion > best_v
. The code by @nirbheek uses a glob pattern to get the correct filenames; perhaps the pattern should come with a function that turnslibduck.so.5.0
into(5, 0)
, so one can use Python’smax()
.