Dylib ok at link time but not at runtime - macos

I have a problem linking correctly my project. The project is built with CMAKE. Linking seems fine, but at run time an error is thrown.
Here is the command that was used for linking:
$ /usr/bin/clang -Wl,-search_paths_first -Wl,-headerpad_max_install_names \
CMakeFiles/project.dir/src/conf.c.o CMakeFiles/project.dir/src/tun-compat.c.o \
CMakeFiles/project.dir/src/compress.c.o CMakeFiles/project.dir/src/mc.c.o \
CMakeFiles/project.dir/src/hexdump.c.o CMakeFiles/project.dir/src/server.c.o \
CMakeFiles/project.dir/sys/unix/log.c.o CMakeFiles/project.dir/sys/unix/imsg.c.o \
CMakeFiles/project.dir/ sys/unix/imsg-buffer.c.o CMakeFiles/project.dir/sys/unix/toto.c.o \
CMakeFiles/project.dir/sys/unix/toto.c.o CMakeFiles/project.dir/sys/unix/util.c.o \
CMakeFiles/project.dir/sys/unix/conf.c.o CMakeFiles/project.dir/sys/unix/tntsocket.c.o \
-o bin/project/opt/local/lib/libevent_openssl.dylib /opt/local/lib/libevent_core.dylib \
/usr/lib/libz.dylib /opt/local/lib/libyajl.dylib /opt/local/lib/libtapcfg.dylib
The error I get:
$ ./bin/project
dyld: Library not loaded: build/libtapcfg.dylib
Referenced from: /Users/Antoine/project/./bin/project
Reason: image not found
zsh: trace trap ./bin/project
Additional infos:
$ dyldinfo -dylibs bin/projectattributes
dependent dylibs
/opt/local/lib/libevent_openssl-2.0.5.dylib
/opt/local/lib/libevent_core-2.0.5.dylib
/usr/lib/libz.1.dylib
/opt/local/lib/libyajl.2.dylib
build/libtapcfg.dylib
/usr/lib/libSystem.B.dylib
It looks like black magic to me. The linker is able to find the symbols, but end up by changing the path of the library even if I can't see any difference in the way it is handled in the linking command...
The lib location is /opt/local/lib/libtapcfg.dylib
$ ls -lhF /opt/local/lib/libtapcfg.dylib
-rwxr-xr-x 1 root admin 20K 14 jui 18:05 /opt/local/lib/libtapcfg.dylib*
Does the problem maybe come from the lib I am linking to?

The issue is with how you built and installed libtapcfg.
You seem to have copied it from your local directory to /opt/local/lib and thus its file system path does not match what is stored in the library.
Either leave the lib in your local path or when building it tell the linker where it will end up or copy to /usr/local/lib which is hard coded in the linker. See Apple developer's note on dynamic libraries
You should only put things in /opt/local when using macports by means of a port. In this case create a local portfile which does not have to do much and macports standard work will put the correct information in the library to make it work from /opt/local/lib

Related

Homebrew linking fails with incompatible i386 files already on machine

I'm hitting this error with anything I have tried to install.
The machine is running redhat and devops has installed newer versions of programs/components in non-standard locations. I only have user level access.
I have forced homebrew to use non-standard locations of curl and git, but I do not know how to point to a newer version of gcc or tell it to add options to the linker to handle the older (glibc?) files.
ld: i386 architecture of input file '/lib/crti.o' is incompatible with i386:x86-64 output
ld: i386 architecture of input file '/lib/crtn.o' is incompatible with i386:x86-64 output
Thanks for any help.
First adjust LD_LIBRARY_PATH and LIBRARY_PATH variables so that multiarch lib-dirs take lead of other ones. For example, /lib/x86_64-linux-gnu stands before /usr/lib64 and /lib. Now, make this link:
ln -s /lib64 /lib/x86_64-linux-gnu
The above linking assumes you do not have /lib/x86_64-linux-gnu directory. If you have that directory but it is empty, please first remove it then make link. If that directory is not empty, make individual library linking:
ln -s /lib64/crti.o /lib/x86_64-linux-gnu/crti.o
ln -s /lib64/crtn.o /lib/x86_64-linux-gnu/crtn.o
Overall, to overcome this type of error, the compiler should find correct library (regarding 32bit or 64bit architecture) and necessarily in multiarch lib-dirs, which are:
/usr/lib/i386-linux-gnu
/usr/lib/x86_64-linux-gnu
/lib/i386-linux-gnu
/lib/x86_64-linux-gnu
Also take a look at my answer to similar (though opposite) error here.

Spurious ld error on macOS (M1 processor)

I have a C project which uses libcairo. On my intel Mac, compiling Cairo with the attached script produces a x86_64 static library, which can be used without issue.
On a M1 Mac (Mac mini, though I doubt that's a factor), I've made sure to set -arch x86_64 everywhere (the output binary is used on Intel). Cairo builds successfully and produces a static library. When building a program that relies on it however, I get the following error message at link stage:
ld: warning: ignoring file (...)/lib/libcairo.a, building for macOS-x86_64 but attempting to link with file built for macOS-x86_64
Undefined symbols for architecture x86_64:
"_cairo_create", referenced from:
_av_display_new in libavionics.a(display.c.o)
(...)
I've made sure to set the CMAKE_OSX_ARCHITECTURES flag to x86_64 in CMake. I can replicate the problem by creating a dummy project in Xcode and building for x86_64. A dummy project using freetype2 (built using the same method), builds & run without errors. I'm at a bit of a loss here, given that the error message says that the architectures don't match (and yet are both macOS-x86_64.
lipo -info libcairo.a returns Non-fat file: libcairo.a is architecture: x86_64.
My Cairo build script is the following:
CAIRO_CONFOPTS_COMMON="--enable-static --disable-egl --disable-glesv2 \
--disable-glesv3 --disable-glx --disable-gl --disable-valgrind \
--disable-xlib --enable-ft --disable-shared --disable-xlib-xrender \
--disable-xcb --disable-svg --disable-full-testing --disable-interpreter \
--disable-gallium --disable-beos --disable-cogl --disable-directfb \
--disable-fc --disable-ps --disable-glesv2 --disable-win32 \
--disable-win32-font --disable-drm --disable-png --disable-script --disable-quartz \
--disable-wgl --disable-gobject --disable-trace --disable-symbol-lookup --disable-zlib"
ARCH_FLAGS="-arch\\ x86_64\\ -mmacosx-version-min=10.9"
export GNUMAKEFLAGS=--no-print-directory
cd cairo
# Make sure we use the libraries we built, and not the system ones
export pixman_CFLAGS="-I$OUTDIR/include/pixman-1"
export pixman_LIBS="$OUTDIR/lib/libpixman-1.a"
export FREETYPE_CFLAGS="-I$OUTDIR/include/freetype2"
export FREETYPE_LIBS="$OUTDIR/lib/libfreetype.a"
export PKG_CONFIG_PATH="$OUTDIR/lib/pkgconfig"
eval LDFAGS="-fvisibility=hidden\\ $ARCH_FLAGS" \
CFLAGS="-fvisibility=hidden\\ $ARCH_FLAGS" \
CXXFLAGS="-fvisibility=hidden\\ $ARCH_FLAGS" \
./configure --prefix=$OUTDIR $CAIRO_CONFOPTS_COMMON $ADDCONF || exit 1
make -j9 || exit 1
make install || exit 1

Generated binary is linked to use system instead of local library

My build system has libtiff installed in this path:
/usr/lib/x86_64-linux-gnu/libtiff.so.5.2.4
And I have built a custom libtiff in a local path:
/home/user/libtiff/usr/local/lib/libtiff.so.3.8.2
I want to build a binary linked with libtiff installed on my local path. To do that, I use this command:
cc -o binary \
obj1.o ... objn.o \
-L /home/user/libtiff/usr/local/lib/ \
-Wl,-rpath,L/home/user/libtiff/usr/local/lib/ \
-ltiff
The problem is after linking and generating the binary, ldd shows the binary is not using the local libtiff, but the library installed on the build system:
$ ldd binary | grep libtiff
libtiff.so.5 => /usr/lib/x86_64-linux-gnu/libtiff.so.5 (0x00007fbaf9ad6000)
I don't understand why the linker is not using the local library.
I have read some related posts talking about setting LD_LIBRARY_PATH, LD_PRELOAD or LIBRARY_PATH, but none of them works as expected.
Modifiying /etc/ld.so.conf is not a nice option.
Remove the spurious L in front of the root slash:
-Wl,-rpath,L/home/user/libtiff/usr/local/lib/
#yugr, thank you for this -verbose tip. It helped me to fix the issue. The problem was with another library compiled locally (spandsp) that depends on libtiff. The configure script of the spandsp was deciding to use libtiff.so.5 (build system) instead of libtiff.so.3 (compiled locally). That was because LDFLAGS was not properly defined before executing the configure script. Defining LDFLAGS as -L/home/user/usr/local/lib/ -Wl,-rpath-link,/home/user/usr/local/lib/ fixed the issue. Thank you very much for your interest in helping with this issue! :)

Static linked vips (libvips) binary

I have been attempting to create a statically linked version of vips but have been unable to. Is it possible to create a statically linked vips command?
The platform I am compiling on is Ubuntu 16.04.
The make command I am running:
make LDFLAGS=-all-static
I am not configuring it to use python or imagemagick, (those show "no" in the config output). The error I am getting is:
/usr/bin/ld: cannot find -lgdk_pixbuf-2.0
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libgio-2.0.a(libgio_2_0_la-glocalfileinfo.o): In function `lookup_gid_name':
(.text+0x11d7): warning: Using 'getgrgid_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libgio-2.0.a(libgio_2_0_la-glocalvfs.o): In function `g_local_vfs_parse_name':
(.text+0x1cd): warning: Using 'getpwnam' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libglib-2.0.a(libglib_2_0_la-gutils.o): In function `g_get_user_database_entry':
(.text+0x249): warning: Using 'getpwuid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libglib-2.0.a(libglib_2_0_la-gutils.o): In function `g_get_user_database_entry':
(.text+0xcf): warning: Using 'getpwnam_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libgio-2.0.a(libgio_2_0_la-glocalfileinfo.o): In function `lookup_uid_data':
(.text+0x1054): warning: Using 'getpwuid_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libxml2.a(nanohttp.o): In function `xmlNanoHTTPConnectHost':
(.text+0x924): warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libxml2.a(nanohttp.o): In function `xmlNanoHTTPConnectHost':
(.text+0x9f4): warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libgio-2.0.a(libgio_2_0_la-gnetworkaddress.o): In function `g_network_address_parse':
(.text+0xc39): warning: Using 'getservbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libgio-2.0.a(libgio_2_0_la-gnetworkaddress.o): In function `g_network_address_parse':
(.text+0xc4e): warning: Using 'endservent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
collect2: error: ld returned 1 exit status
Makefile:597: recipe for target 'vips' failed
make[2]: *** [vips] Error 1
make[2]: Leaving directory '/usr/local/src/vips-8.4.1/tools'
Makefile:631: recipe for target 'all-recursive' failed
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory '/usr/local/src/vips-8.4.1'
Makefile:536: recipe for target 'all' failed
make: *** [all] Error 2
From what I've found on, for example here:
Create statically-linked binary that uses getaddrinfo?
is that this is an issue with libnss. But in the ./configure --help output there is no --enable-static-flag. Even so I tried that and it didn't fix my problem.
The libraries I am linking against (according to the config output, I've truncated it):
build radiance support: yes
build analyze support: yes
build PPM support: yes
use fftw3 for FFT: yes
accelerate loops with orc: yes
ICC profile support with lcms: yes (lcms2)
SVG import with librsvg-2.0: yes
zlib: yes
file import/export with libwebp: yes
file import/export with libpng: yes (pkg-config libpng >= 1.2.9)
file import/export with libtiff: yes (pkg-config libtiff-4)
file import/export with giflib: yes (found by search)
file import/export with libjpeg: yes
use libexif to load/save JPEG metadata: yes
Is there a particular library I am linking against that is causing the problem?
After failing to convince the build mechanism to statically link, I was able to successfully create a working static vips executable with staticx, after reporting an issue to staticx and seeing that it was fixed. See here for how I'm building.
Just in case that link of mines dies in the future, here are the relevant parts:
RUN curl -sL https://github.com/libvips/libvips/releases/download/v8.9.2/vips-8.9.2.tar.gz | tar -xz -f- --strip-components=1 -C .
# TODO: Add --disable-deprecated
# Blocked by https://github.com/libvips/libvips/pull/1593
# XXX: -static doesn't work here, I'm using staticx to make the final vips binary static.
RUN CFLAGS="-O3 -flto -pipe" CXXFLAGS="-O3 -flto -pipe" \
./configure \
--disable-shared \
--disable-static \
--disable-dependency-tracking
# This is the fastest easiest way I found to compile the
# CLI as fast as possible. You can probably get more optimal,
# but it'd be a lot harder wrestling autotools.
RUN cd libvips \
&& make -j"$(nproc)"
RUN cd tools \
&& make -j"$(nproc)" vips
RUN cd tools \
&& staticx vips ../vips
Since configure automatically feature-detects, here are the Debian 10 (June 22) packages I installed:
libglib2.0-dev \
libexpat1-dev \
libjpeg-dev \
libpng-dev \
libimagequant-dev \
libexif-dev \
liborc-0.4-dev
It weighs 3.3M, which is fairly impressive and a heck of a lot smaller than distribution packages, which is why I set out to do this in the first place.
$ file vips-glibc-gcc
vips-glibc-gcc: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped
$ ls -lah vips-glibc-gcc
-rwxr-xr-x 1 josh josh 3.3M Jun 23 02:51 vips-glibc-gcc
I tried like this:
$ CFLAGS="-static" CXXFLAGS="-static" ./configure --prefix=/home/john/vips --without-python --without-magick
And it seems to work:
$ ls ~/vips/lib
girepository-1.0 libvipsCC.a libvips-cpp.a libvips.la python2.7
libvips.a libvipsCC.la libvips-cpp.la pkgconfig
$ which vips
/home/john/vips/bin/vips
$ ls -l ~/vips/bin/vips
-rwxr-xr-x 1 john john 6373864 Sep 27 13:16 /home/john/vips/bin/vips
$ vips invert /data/john/pics/k2.jpg x.jpg
$ eog x.jpg
I've not tested it much though, and I suspect it's not very static. If you run ldd on the vips binary, for example, you get a long list. True static binaries do not really exist any more.
Why do you want a static binary? If it's to ease distribution, things like flatpack and snappy might be better. You can also sort-of make your own --- for example, vips comes with a simple wrapper script which can make the shared binary relocatable.

Compiling gcc-4.1

Unfortunately I'm forced to use gcc-4.1 and I'm using debian wheezy. Since gcc-4.1 is not in repository I'm trying to build gcc from sources.
But I'm getting compiling error:
/usr/bin/ld: skipping incompatible /usr/lib/x86_64-linux-gnu/libc.so when searching for -lc
/usr/bin/ld: skipping incompatible /usr/lib/x86_64-linux-gnu/libc.a when searching for -lc
/usr/bin/ld: i386:x86-64 architecture of input file `/usr/lib/x86_64-linux-gnu/crti.o' is incompatible with i386 output
/usr/bin/ld: i386:x86-64 architecture of input file `/usr/lib/x86_64-linux-gnu/crtn.o' is incompatible with i386 output
It looks that ld is picking wrong version of libraries, but I checked my /usr/lib32 and /usr/lib/x86_64-linux-gnu/ and it contains those files:
/usr/lib32/libc.a
/usr/lib32/libc.so
/usr/lib32/crtn.o
/usr/lib32/crti.o
/usr/lib/x86_64-linux-gnu/libc.a
/usr/lib/x86_64-linux-gnu/libc.so
/usr/lib/x86_64-linux-gnu/crtn.o
/usr/lib/x86_64-linux-gnu/crti.o
And ld should have access to them
~$ echo $LIBRARY_PATH
/usr/lib/x86_64-linux-gnu:/usr/lib32/
So I have no idea where the problem is.
I managed to work around the problem.
Run configure with:
./configure --disable-multilib ...
But than I encountered another problem with makeinfo, if you have newer version >=4.10 than it might not be found by configure. So simple fix in generated makefile worked for me:
Change this line:
MAKEINFO = /home/lecopivo/Downloads/gcc412/gcc412/gcc-4.1.2/missing makeinfo
To this:
MAKEINFO = makeinfo
I found this helpful.
LD_LIBRARY_PATH is only for running programs already linked.
You probably need to set LDFLAGS when you configure gcc:
./configure LDFLAGS="-L/usr/lib32" .....
It might be LDFLAGS_FOR_HOST or LIBS or something like that though.
I had this problem recently and finally solved it this way:
ln -s /usr/lib32 /usr/lib/i386-linux-gnu
Notes:
I assumed you do not have /usr/lib/i386-linux-gnu directory in your 64bit linux. If this directory exists and is empty, please delete it and make the above link.
If the directory already exists and is not empty, you have to make links inside it for (32bit) libraries which cause build error one by one; e.g.:
ln -s /usr/lib32/crti.o /usr/lib/i386-linux-gnu/crti.o
ln -s /usr/lib32/crtn.o /usr/lib/i386-linux-gnu/crtn.o
...
If 32bit development libraries are not installed, you may have to install them first. I've searched different forums and found that installing following set of packages in ubuntu will provide them:
libc6-dev libc6-dev-i386
gcc-multilib g++-multilib
zlib1g-dev lib32z1-dev
libncurses5-dev lib32ncurses5-dev libncursesw5-dev lib32ncursesw5-dev
Also adjust LD_LIBRARY_PATH and LIBRARY_PATH variables so that they contain /usr/lib/i386-linux-gnu and /usr/lib/x86_64-linux-gnu (i.e. multiarch lib-dirs). I am not sure which one of above variables is effective, so I adjust both of them the same.
If you use ./configure --disable-multilib as it is frequently suggested on web, though gcc will be built, but when you want to use that gcc for compiling e.g. legacy grub, you probably get error of "gcc cannot build executable" (or such).
Optionally, you can make similar linking for these pair of libdirs:
ln -s /lib32 /lib/i386-linux-gnu
Doing so, I managed to compile gcc-3.4.6 in a Ubuntu 16.04.6-amd64 used for compiling old 32bit programs like SDL 1.2 and legacy GRUB4DOS 0.4.4.
Also take a look at my answer to similar (though opposite) error here.
Good luck.

Resources