(Sending this a 2nd time, after I joined the list.)
For the Nettle crypto library:
If the C compiler lacks __builtin_bswap64, then Nettle may call a function named __builtin_bswap64 and get a link error. The problem is that ./configure doesn't check for link errors. I append a small diff to switch from AC_TRY_COMPILE to AC_TRY_LINK.
OpenBSD, on some unusual hardware platforms, still uses GCC 4.2.1, which doesn't have __builtin_bswap64. Manphiz reported to OpenBSD that the build of Nettle 3.5.1 failed on mips64el/longsoon hardware: https://marc.info/?l=openbsd-ports&m=157510504817444&w=2
The error was "undefined reference to `__builtin_bswap64'".
Nettle only uses __builtin_bswap64 (in ctr.c) on little-endian hardware. The error didn't happen when OpenBSD built Nettle with GCC 4.2.1 on big-endian platforms, like powerpc/macppc.
In traditional C, you never needed to declare functions if their return type was int. C code like `whatever(11, "a string")` would implicitly declare `int whatever();`. Likewise, if __builtin_bswap64 isn't a built-in, then `__builtin_bswap64(x)` in ./configure does implicitly declare `int __builtin_bswap64();` as a function. AC_TRY_COMPILE can compile this function call, but AC_TRY_LINK can't link it.
OpenBSD decided to patch ./configure to do a link test: https://cvsweb.openbsd.org/cgi-bin/cvsweb/ports/security/libnettle/patches/p...
The below diff is for configure.ac in Nettle git master cdbbe64. After I made this change, I ran ./.bootstrap and checked the build on my OpenBSD powerpc/macppc machine with GCC 4.2.1:
$ ../configure --disable-documentation \
CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib
$ gmake $ gmake check
(The --disable-documentation prevents an error from makeinfo 4.8, which seems too old. The FLAGS find gmp in /usr/local, because OpenBSD's compilers don't look there by default. gmake is GNU make.)
The build got "All 99 tests passed", then "All 3 tests passed". config.log shows that "checking for __builtin_bswap64" failed with the "undefined reference" error. --George
diff --git a/configure.ac b/configure.ac index 3547cae4..7ac84f2e 100644 --- a/configure.ac +++ b/configure.ac @@ -213,7 +213,7 @@ AC_C_BIGENDIAN([AC_DEFINE([WORDS_BIGENDIAN], 1)
AC_CACHE_CHECK([for __builtin_bswap64], nettle_cv_c_builtin_bswap64, -[AC_TRY_COMPILE([ +[AC_TRY_LINK([ #include <stdint.h> ],[ uint64_t x = 17;
George Koehler kernigh@gmail.com writes:
If the C compiler lacks __builtin_bswap64, then Nettle may call a function named __builtin_bswap64 and get a link error. The problem is that ./configure doesn't check for link errors. I append a small diff to switch from AC_TRY_COMPILE to AC_TRY_LINK.
Thanks, applied!
$ ../configure --disable-documentation \
CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib
$ gmake $ gmake check
(The --disable-documentation prevents an error from makeinfo 4.8, which seems too old. The FLAGS find gmp in /usr/local, because OpenBSD's compilers don't look there by default. gmake is GNU make.)
Does OpenBSBs runtime linker look in /usr/local/lib by default? The configure script also supports --with-lib-path=/usr/local/lib, which will add a -L flag and in addition attempt to guess the proper -R/-Wl,-rpath flags.
Regards, /Niels
On Thu, Dec 5, 2019 at 3:08 AM Niels Möller nisse@lysator.liu.se wrote:
...
Does OpenBSBs runtime linker look in /usr/local/lib by default? The configure script also supports --with-lib-path=/usr/local/lib, which will add a -L flag and in addition attempt to guess the proper -R/-Wl,-rpath flags.
The runtime linker is configured to use /usr/local/lib. However, compile and link requires explicit -I /usr/local/include and -L /usr/local/lib to find things.
(Based on my testing of DragonFly, FreeBSD, OpenBSD and NetBSD. I don't recall what Debian's kFreeBSD does).
Jeff
On Thu, 5 Dec 2019 03:20:19 -0500 Jeffrey Walton noloader@gmail.com wrote:
On Thu, Dec 5, 2019 at 3:08 AM Niels Möller nisse@lysator.liu.se wrote:
...
Does OpenBSBs runtime linker look in /usr/local/lib by default? The configure script also supports --with-lib-path=/usr/local/lib, which will add a -L flag and in addition attempt to guess the proper -R/-Wl,-rpath flags.
The runtime linker is configured to use /usr/local/lib. However, compile and link requires explicit -I /usr/local/include and -L /usr/local/lib to find things.
(Based on my testing of DragonFly, FreeBSD, OpenBSD and NetBSD. I don't recall what Debian's kFreeBSD does).
Jeff
Each BSD has its own runtime linker. I believe that OpenBSD ld.so(1) looks in /usr/local/lib by default, but NetBSD ld.elf_so(1) doesn't look there.
For OpenBSD, ldconfig(8) sets the runtime path. It always looks in /usr/lib, but /etc/rc tells ldconfig to also look in /usr/X11R6/lib and /usr/local/lib. I can get the path from ldconfig:
# OpenBSD $ ldconfig -r | grep directories search directories: /usr/lib:/usr/X11R6/lib:/usr/local/lib
NetBSD allows /etc/ld.so.conf to add directories to the runtime path, but my NetBSD install has no ld.so.conf, so the default path has only /usr/lib. Some executables have RPATH to look in /usr/X11R7/lib or /usr/pkg/lib. (My install has no /usr/local.)
For example, OpenBSD's xterm(1) doesn't need RPATH, but NetBSD's xterm(1) needs RPATH with /usr/X11R7/lib.
# OpenBSD $ readelf -d /usr/X11R6/bin/xterm | grep -E 'NEED|PATH' 0x00000001 (NEEDED) Shared library: [libXaw.so.15.0] 0x00000001 (NEEDED) Shared library: [libXpm.so.9.0] 0x00000001 (NEEDED) Shared library: [libXt.so.11.0] ... 0x00000001 (NEEDED) Shared library: [libc.so.96.0]
# NetBSD $ readelf -d /usr/X11R7/bin/xterm | grep -E 'NEED|PATH' 0x00000001 (NEEDED) Shared library: [libXft.so.3] 0x00000001 (NEEDED) Shared library: [libfontconfig.so.2] 0x00000001 (NEEDED) Shared library: [libfreetype.so.18] ... 0x00000001 (NEEDED) Shared library: [libc.so.12] 0x0000000f (RPATH) Library rpath: [/usr/X11R7/lib]
If I don't set RPATH, I can't use /usr/X11R7/lib in NetBSD:
# OpenBSD $ gcc -o code code.c -L/usr/X11R6/lib -lX11 ... $ ./code It works!
# NetBSD $ gcc -o code code.c -L/usr/X11R7/lib -lX11 $ ./code Shared object "libX11.so.7" not found $ gcc -o code code.c -L/usr/X11R7/lib -lX11 -R/usr/X11R7/lib $ ./code It works!
The NEEDED values on OpenBSD have an extra number: [libc.so.96.0] instead of just [libc.so.96]. This is because OpenBSD has its different version rule.
Other systems require M == X in SONAME libwhat.so.M for NEEDED libwhat.so.X OpenBSD requires M == X && N >= Y in SONAME libwhat.so.M.N for NEEDED libwhat.so.X.Y https://www.openbsd.org/faq/ports/specialtopics.html#SharedLibs
Other systems have symbolic links:
# NetBSD $ cd /usr/X11R7/lib $ ls -l libX11.so* lrwxr-xr-x 1 root wheel 13 Jul 17 2018 libX11.so -> libX11.so.7.0 lrwxr-xr-x 1 root wheel 13 Jul 17 2018 libX11.so.7 -> libX11.so.7.0 -r--r--r-- 1 root wheel 1273908 Jul 17 2018 libX11.so.7.0
OpenBSD doesn't have these links. The compile-time ld(1) and run-time ld.so(1) look for libraries named [libwhat.so.X.Y].
Nettle doesn't know OpenBSD's version rule. My git checkout of Nettle, configured for OpenBSD, wants to install [libnettle.so.7.0] with symlinks from [libnettle.so] and [libnettle.so.7], where the SONAME is [libnettle.so.7]. To obey the version rule, it should install [libnettle.so.7.0] without symlinks, and the SONAME should also be [libnettle.so.7.0]. I didn't fix my git checkout to obey the version rule, because I didn't need to.
I know one other quirk: some build tools (but not Nettle's) use $ORIGIN in the runtime path. DragonFly and OpenBSD need a compiler flag "cc -Wl,-z,origin" to enable $ORIGIN, but other systems don't need this flag. https://github.com/mesonbuild/meson/pull/3530/files
This mail is too long; I stop now. --George
nettle-bugs@lists.lysator.liu.se