Hello,
I am trying to integrate libamath.so (and libastring.so) in my program. But it seems that libm.so is used instead. I link the shared libraries something like this:
libamath.so
libastring.so
libm.so
$ gfortran -shared -L~/proj/lib -fPIC -lastring -lamath -lm -o ~/proj/lib/libmylib.so ~/data/proj/obj/myobj.o -lmy_archive
Then I run the program:
$ LD_DEBUG=bindings ~/proj/bin/myprog 1>/tmp/foo.txt 2>/tmp/foo.txt
And examining the bindings I get:
$ cat /tmp/foo.txt | grep log10 | grep libgfortran 2465474: binding file ~/proj/lib/libgfortran.so.5 [0] to /lib/aarch64-linux-gnu/libm.so.6 [0]: normal symbol `log10l' [GLIBC_2.17] 2465474: binding file ~/proj/lib/libgfortran.so.5 [0] to /lib/aarch64-linux-gnu/libm.so.6 [0]: normal symbol `log10' [GLIBC_2.17] 2465474: binding file ~/proj/lib/libgfortran.so.5 [0] to /lib/aarch64-linux-gnu/libm.so.6 [0]: normal symbol `log10f' [GLIBC_2.17]
$ cat /tmp/foo.txt | grep log10 | grep libgfortran
2465474: binding file ~/proj/lib/libgfortran.so.5 [0] to /lib/aarch64-linux-gnu/libm.so.6 [0]: normal symbol `log10l' [GLIBC_2.17]
2465474: binding file ~/proj/lib/libgfortran.so.5 [0] to /lib/aarch64-linux-gnu/libm.so.6 [0]: normal symbol `log10' [GLIBC_2.17]
2465474: binding file ~/proj/lib/libgfortran.so.5 [0] to /lib/aarch64-linux-gnu/libm.so.6 [0]: normal symbol `log10f' [GLIBC_2.17]
Why isn't libamath.so used? If I preload it, then it appears to be used:
$ LD_DEBUG=bindings LD_PRELOAD=~/proj/lib/libamath.so ~/proj/bin/myprog 1>/tmp/foo.txt 2>/tmp/foo.txt
$ cat /tmp/foo.txt | grep log10 | grep libgfortran 2463666: binding file ~/proj/lib/libgfortran.so.5 [0] to /lib/aarch64-linux-gnu/libm.so.6 [0]: normal symbol `log10l' [GLIBC_2.17] 2463666: binding file ~/proj/lib/libgfortran.so.5 [0] to ~/proj/lib/libamath.so [0]: normal symbol `log10' [GLIBC_2.17] 2463666: binding file ~/proj/lib/libgfortran.so.5 [0] to ~/proj/lib/libamath.so [0]: normal symbol `log10f' [GLIBC_2.17]
2463666: binding file ~/proj/lib/libgfortran.so.5 [0] to /lib/aarch64-linux-gnu/libm.so.6 [0]: normal symbol `log10l' [GLIBC_2.17]
2463666: binding file ~/proj/lib/libgfortran.so.5 [0] to ~/proj/lib/libamath.so [0]: normal symbol `log10' [GLIBC_2.17]
2463666: binding file ~/proj/lib/libgfortran.so.5 [0] to ~/proj/lib/libamath.so [0]: normal symbol `log10f' [GLIBC_2.17]
What am I doing wrong?
Hello! Your link line looks right.
Maybe the linker is not aware of the path to libamath/libastring.
Is the path to acfl or armpl in your search path? Can you please run ldd on the executable and report output here?
I have libamath/libastring in my lib directory (-L~/proj/lib). If I examine the library with ldd, it definitely depends on these two libraries. I can also see that they get loaded with lsof. If I preload the libraries, I observe a significant performance improvement for a number of workloads. It would be nice to be able to benefit from them without preloading.Could it be that my library uses libamath/libastring but the dependent libraries don't?Can you think of any negative side effects if I would preload libamath/libastring?
lib
-L~/proj/lib
ldd
lsof
> Could it be that my library uses libamath/libastring but the dependent libraries don't?
It looks like it is what is happening. Your report shows that log10 is bound to libm from libgfortran.so.However libgfortran doesn't have a dependency on amath, only the symbols in the executable you're building will.
With preload you might end up picking up symbols from amath that you wish to pick up from libgfortran/libm. But I don't see a major issue with that.
Another (more intrusive) solution, would be to take a copy of libgfortran and use patchelf to add a dependency on libamath, which could help take precedence over libm.
Another solution would be to use armpl_ prefixed symbols for the math routines you wish to pick up from amath, e.g. for log10, use armpl_log10_f64 (it maps to amath's implementation of log10).