Can't link with shared library - macos

I can't link my program with shared library located in non-standart OSX lib directory. I've got this library from MacPorts and it's located in /opt/local/lib:
$ ls /opt/local/lib/libgmp*
/opt/local/lib/libgmp.10.dylib /opt/local/lib/libgmpxx.4.dylib
/opt/local/lib/libgmp.a /opt/local/lib/libgmpxx.a
/opt/local/lib/libgmp.dylib /opt/local/lib/libgmpxx.dylib
/opt/local/lib/libgmp.la /opt/local/lib/libgmpxx.la
I've found that one can use DYLD_FALLBACK_LIBRARY_PATH, but it not works for me:
$ DYLD_LIBRARY_PATH=/opt/local/lib gcc ab.c -lgmp
ld: library not found for -lgmp
collect2: ld returned 1 exit status

At runtime, DYLD_LIBRARY_PATH helps dynamic linker to locate libraries from non-standard directories.
In your case, you are still in compilation phase.
For gcc to know about these extra directories to search, you could use -L switch.
e.g.
gcc ab.c -L/opt/local/lib -lgmp

Related

Local install of GNU MP, how to access it from ld?

I have a compiled local install of GMP:
/path/to/gmp
.../lib/gmp.h
.../include/[gmp_binaries.etc]
Now, I export the path, just to test the install; I'll add symlinks in some central location once I get it working:
export LD_LIBRARY_PATH=/path/to/gmp:$LD_LIBRARY_PATH
g++ -lgmp
// error: /usr/bin/ld: cannot find -lgmp
export LD_LIBRARY_PATH=/path/to/gmp/include:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=/path/to/gmp/lib:$LD_LIBRARY_PATH
g++ -lgmp
// error: /usr/bin/ld: cannot find -lgmp
Basically, my question is: how do I connect my local libraries to ld?
(And the point is installing content without sudo, so I can't "just ____," for the most part)
-l requires a -L location to search in g++. Make does not follow your LD_LIBRARY_PATH. Make needs a specific location to search for specific libraries not included in /usr/lib
# define library paths in addition to /usr/lib
# if I wanted to include libraries not in /usr/lib I'd specify
# their path using -Lpath, something like:
LFLAGS = -L/home/newhall/lib -L../lib
From this site
Find your libgmp file, and link as follows:
g++ -L/path/to/libgmp/ -lgmp

how can I fix ld not ignoring bad system libraries in favor of my local libraries?

I'm trying to build the newest gcc on my redhat box. I've downloaded and built the latest gmp, mpfr and mpc, per requirements and installed them in my local libraries. From the config.log file I have the following given below. Clearly the system version of mpfr is broken, and I want the configure to ignore it. I have set LIBRARY_PATH and LD_LIBRARY_PATH to point to my local installation /u/victor/lib. Since I'm running a configure script, it's not reasonable for me to try to change command line options for gcc. How do I fix this?
gcc -o conftest -g -O2 conftest.c -L/u/victor/lib -L/u/victor/lib -L/u/victor/lib -lmpc -lmpfr -lgmp >&5
/usr/bin/ld: warning: libmpfr.so.1, needed by /u/victor/lib/libmpc.so, may conflict with libmpfr.so.4
/usr/bin/ld: __gmpfr_cache_const_euler: TLS definition in /u/victor/lib/libmpfr.so section .tdata mismatches non-TLS definition in /usr/lib64/libmpfr.so.1 section .data
What's even more confusing, is that when I compile conftest.c and then
gcc -o conftest conftest.o -lmpc -lmpfr -lgmp
with export LD_LIBRARY_PATH=/u/victor/lib it gives the errors below. I've check libmfpr.so with nm and the three "undefined" symbols are there.
/u/victor/lib/libmpc.so: undefined reference to `mpfr_min_prec'
/u/victor/lib/libmpc.so: undefined reference to `mpfr_set_zero'
/u/victor/lib/libmpc.so: undefined reference to `mpfr_get_z_2exp'

Static -libgfortran in library build

I am trying to build a library that only has static references to libgfortran (and preferably libgcc also).
However, if I use the linker flags
-static -lgfortran -static-libgfortran -static-libgcc
on OS X I get
ld: library not found for -lcrt0.o
collect2: error: ld returned 1 exit status
and if I try to use
-shared -lgfortran -static-libgfortran
I get
Undefined symbols for architecture x86_64:
"_quadmath_snprintf", referenced from:
_write_float in libgfortran.a(write.o)
"_strtoflt128", referenced from:
__gfortrani_convert_real in libgfortran.a(read.o)
__gfortrani_convert_infnan in libgfortran.a(read.o)
and everything compiles fine (but has a dynamic link to libgfortran and libgcc) if I use -dynamiclib -lgfortran.
It would appear that gcc is not build statically on OS X.
How do I build my library so that end-users don't need to have gfortran or gcc installed?
I'm using the macports version of gcc but I'm prepared to use another distributor of gfortran/gcc if it allows me to do this.
-dynamiclib -lgfortran -static-libgfortran \
/opt/local/lib/gcc47/libquadmath.a -static-libgcc
seems to do the trick!
The bizarre thing was figuring out that I needed to add a full path to the libquadmath.a, which feels like a bug with gcc/gfortran to be honest.

Building a 32-bit app in 64-bit Ubuntu

After hours of googling, I decide to give up and ask you experts. I am trying to build a 32-bit application (xgap if anyone interested) in my 64 Ubuntu 11.10. I added the CFLAGS=-m32 and the LDFLAGS=-L/usr/lib32 in the makefile. The objects are built into 32 bit fine. The last step is to link all the objects and libraries for X windows into this executable---xgap. Somehow it keeps giving me this error:
gcc -o xgap xcmds.o utils.o gapgraph.o gaptext.o pty.o popdial.o xgap.o selfile.o -L/usr/lib32 -lXaw -lXmu -lXt -lXext -lX11 -lSM -lICE
/usr/bin/ld: skipping incompatible /usr/lib32/libXmu.so when searching for -lXmu
...
/usr/bin/ld: i386 architecture of input file `xcmds.o' is incompatible with i386:x86-64 output
...
I have installed ia32-libs and mutilib support. I think I just need to force the linker to generate a i386 output. I tried to put two ld flags in my gcc command as shown above: -melf_i386 and -oformat elf32-i386. But what happens is that gcc doesn't search for the 32 bit library in /usr/lib32 anymore. I wonder if I need to put those flags in some fixed order?
Thanks for any idea and help!
EDIT: when I add the -m32 flag in my last gcc command (the linking stage I believe), even if I have the -L/usr/lib32 flag in place, gcc doesn't search in /usr/lib32 anymore ( really weird...) and generates the following error:
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.6.1/../../../libXaw.so when searching for -lXaw
/usr/bin/ld: skipping incompatible /usr/lib/libXaw.so when searching for -lXaw
/usr/bin/ld: cannot find -lXaw
collect2: ld returned 1 exit status
Any one has any idea why this happens? I am using the auto tool to configure and make. I am really good at modifying those script files.
You need to use link with -m32 as well.
gcc -m32 -o xgap xcmds.o utils.o gapgraph.o gaptext.o pty.o popdial.o xgap.o selfile.o -L/usr/lib32 -lXaw -lXmu -lXt -lXext -lX11 -lSM -lICE
All things considered, I think you should be able to drop the -L/usr/lib32 when using -m32.
I solved the problem. I think that gcc was expecting a static library archive. I used the getlibs script from http://ubuntuforums.org/showthread.php?t=474790 to download all the .a archives needed for linking. Then gcc worked. I think gcc did search in /usr/lib32 directory but didn't find the .a archives so went on to search in the standard directory which is /usr/lib, where it finds the incompatible *.so files.
But then the question is: the *.so files in /usr/lib32/ from package ia32-libs doesn't really have the libraries needed for linking? What are those files in /usr/lib32/ used for?

Linking the static version of a library instead of the dynamic one

I am trying to use libjpeg in my application. Making the project yields a libjpeg.a in .libs folder. What I would like to do is to use this file in the linkage stage. I have tried the following: I copied the libjpeg.a into the folder where my C code resides. Trying to link with
gcc libjpeg.a mycode.c -o executable_name
fails. If I do gcc -ljpeg mycode.c, the compilation is successful when I change my header to point to instead of "libjpeg.h", but this obviously links to the system-wide dynamic version of the library.
Trying to link with relative or absolute path also fails:
gcc ./libjpeg.a mycode.c -o executable_name
I have tried the static option as well:
gcc -static libjpeg.a mycode.c -o executable_name
The linker error is the following:
Linking...
gcc -std=c99 -Wall -Wextra -g -pedantic ./libjpeg.a ./libjpeg.a -lm obj/read_jpeg.o obj/utils.o -o test_jpeg
obj/read_jpeg.o: In function `read_JPEG_file':
/home/ustun/Downloads/jpeg_test/read_jpeg.c:37: undefined reference to `jpeg_std_error'
/home/ustun/Downloads/jpeg_test/read_jpeg.c:45: undefined reference to `jpeg_CreateDecompress'
/home/ustun/Downloads/jpeg_test/read_jpeg.c:46: undefined reference to `jpeg_stdio_src'
/home/ustun/Downloads/jpeg_test/read_jpeg.c:47: undefined reference to `jpeg_read_header'
/home/ustun/Downloads/jpeg_test/read_jpeg.c:48: undefined reference to `jpeg_start_decompress'
/home/ustun/Downloads/jpeg_test/read_jpeg.c:62: undefined reference to `jpeg_read_scanlines'
/home/ustun/Downloads/jpeg_test/read_jpeg.c:74: undefined reference to `jpeg_finish_decompress'
/home/ustun/Downloads/jpeg_test/read_jpeg.c:75: undefined reference to `jpeg_destroy_decompress'
obj/read_jpeg.o: In function `read_JPEG_file_props':
/home/ustun/Downloads/jpeg_test/read_jpeg.c:93: undefined reference to `jpeg_std_error'
/home/ustun/Downloads/jpeg_test/read_jpeg.c:100: undefined reference to `jpeg_CreateDecompress'
/home/ustun/Downloads/jpeg_test/read_jpeg.c:101: undefined reference to `jpeg_stdio_src'
/home/ustun/Downloads/jpeg_test/read_jpeg.c:102: undefined reference to `jpeg_read_header'
/home/ustun/Downloads/jpeg_test/read_jpeg.c:103: undefined reference to `jpeg_start_decompress'
/home/ustun/Downloads/jpeg_test/read_jpeg.c:113: undefined reference to `jpeg_read_scanlines'
/home/ustun/Downloads/jpeg_test/read_jpeg.c:116: undefined reference to `jpeg_finish_decompress'
/home/ustun/Downloads/jpeg_test/read_jpeg.c:117: undefined reference to `jpeg_destroy_decompress'
collect2: ld returned 1 exit status
make: *** [test_jpeg] Error 1
You can download a simple project with a Makefile here.
You'd have to give the full path to libjpeg.a, If you have libjpeg.a in a .libs folder relative to where you compile:
gcc mycode.c -o executable_name .libs/libjpeg.a
If your special libjpeg.a is elsewhere, give a full path to it.
If this fails, you have to tell us what happens. (the details are important, so please copy paste the exact errors and the exact command line that is run).
You need to use -static:
gcc -static -o exec_name mycode.c -ljpeg
No need to copy the archive (.a). You could have found out by reading man ld.
This may help you if you have the same problem as mine. In my system, I have
libjpeg.so.62 -> libjpeg.so.62.0.0
libjpeg.so.62.0.0
After I added symbolic link:
sudo ln -s libjpeg.so.62 libjpeg.so
My problem got solved.

Resources