Executable not linking to the my desired dynamic library - dynamic-linking

I have built and installed mpich from source (mpich-3.4.1.tar.gz), using the steps given in 'https://www.mpich.org/static/downloads/3.4.1/mpich-3.4.1-README.txt'. I want the resultant executables to be dynamically linked to libraries specified in the path '/home/myname/mylibs'. So, before calling ./configure, I have set my LD_LIBRARY_PATH as:
setenv LD_LIBRARY_PATH /home/myname/mylibs:$LD_LIBRARY_PATH
Inside the directory '/home/myname/mylibs' I have soft linked 'libc.so.6' and 'libstdc++.so.6' to my desired libraries, as I do not want the resultant executables to link to dynamic libraries from path /lib64/. I was able to build and install mpich in my machine. However, when I call 'ldd' on one of the executables (hydra_pmi_proxy) that were generated, I see the following:
$ ldd /home/myname/mpich-3.4.1_install/bin/hydra_pmi_proxy
libc.so.6 => /lib64/libc.so.6 (0x00007f32f9eef000)
libstdc++.so.6 => /home/myname/mylibs/libstdc++.so.6 (0x00007f32f9542000)
The rpath seems to be set to my desired path '/home/myname/mylibs' as shown below:
$ readelf -d /home/myname/mpich-3.4.1_install/bin/hydra_pmi_proxy | egrep "RPATH|RUNPATH"
0x000000000000000f (RPATH) Library rpath: [/home/myname/mylibs]
As shown above, libstdc++.so.6 is pointing to my desired library, but libc.so.6 is still pointing to /lib64/libc.so.6. I want libc.so.6 to point to /home/myname/mylibs/libc.so.6
Is there anything I can do to make this possible?
I do not want my exe to be dynamically linked to libraries in /lib64/ because when I launch my MPI program on multiple machines it seems 'hydra_pmi_proxy' is trying to dynamically link to the /lib64/libc.so.6 of the machine on which a certain process is running. (Most likely, it spawns a child process on the new machine which in turn dynamically links to /lib64/libc.so.6 of that machine). I have seen that I am getting an error when one of the mpi processes tries to run on any machine in which /lib64/libc.so.6 is pointing to an older version. The error is:
/home/myname/mpich-3.4.1_install/bin/hydra_pmi_proxy: /lib64/libc.so.6: version `GLIBC_2.17' not found (required by /home/myname/mpich-3.4.1_install/bin/hydra_pmi_proxy).
When I login to this machine, in which it is failing, and do strings /lib64/libc.so.6 | grep GLIBC_2, I do not see GLIBC_2.17 listed. Whereas, on all other machines, on which the mpi processes are running successfully, I see GLIBC_2.17 listed on running 'strings'. So, my intention is to make all executables to dynamically link to only libraries at "/home/myname/mylibs/". Is this the right way?

I do not want the resultant executables to link to dynamic libraries from path /lib64/
libc.so.6 is a special case. See this answer to understand why.
If you really want to isolate your binaries from libraries in /lib64/..., you must:
configure build and install into /home/myname/mylibs/ a new version of GLIBC (symlinking isn't sufficient) and
set your --dynamic-linker and --rpath to point into mylibs.
That said, you didn't explain why you don't want to link libraries from /lib64. http://xyproblem.info might be relevant here.

Related

How to bundle third party .exe in stanadlone Python executable

I'm writing scripts to automate some task to be executed from windows machine to remote ubuntu server, which uses putty-tools like plink.exe, pscp.exe and psftp.exe.
My python program is able to run successfully but I'm trying to build a single independent standalone file which can be run in another PC even if that PC do not have these putty tools available.
I'm using below commands
python -m nuitka --enable-plugin=tk-inter --windows-disable-console --onefile --standalone my_program.py
I'also found related question here but it was not answered
Bundle third party .exe in Python code and produce another portable .exe
Can someone please help me on this.
Fortunately I found answer for my question by reading the nuitka user manual, we need to use one of the below format based on the requirement. In my case I used second one.
# This will find a file near your onefile.exe
open(os.path.join(os.path.dirname(sys.argv[0]), "user-provided-file.txt"))
# This will find a file inside your onefile.exe
open(os.path.join(os.path.dirname(__file__), "user-provided-file.txt"))
And while packing my command become something like below,here it will include all the files available in source directory to target directory in "onefile.exe"
python -m nuitka --enable-plugin=tk-inter --windows-disable-console --onefile
--include-data-dir=<source>=<target> --standalone my_program.py

Ada path query -- this time with gnatmake

Trying to build the example code in ada-util. So i'm running
gnatmake json.adb inside the ada-util/samples/ directory.
However I get the following error:
gnatmake json.adb
gcc -c json.adb
json.adb:21:06: file "util.ads" not found
json.adb:23:06: file "util.ads" not found
json.adb:23:06: "Json (body)" depends on "Mapping (spec)"
json.adb:23:06: "Mapping (spec)" depends on "Util (spec)"
json.adb:24:06: file "util.ads" not found
json.adb:25:06: file "util.ads" not found
json.adb:26:06: file "util.ads" not found
gnatmake: "json.adb" compilation error
So there's clearly something wrong with my path because I've installed ada-util and I can confirm that util.ads is in the install directory. Now, clearly there's something going wrong here as this isn't the first PATH issue I've had with Ada recently. Where is it supposed to be installed? As currently it's under /opt/GNAT/2020/include/utilada_core.static/util.ads where the GNAT install lives.
Questions:
Where should it be if not here?
Do I have to tell gnatmake where it is and if so how - couldn't see in the docs
If so, why do I have to tell gnatmake where it is given I followed the install instructions -- is that a bug in the install process or is something else going on?
Looks for me, like the library is in proper place.
As you guess properly, you have to tell it where the library is located. As far I see, in the root directory of the project, there is the file samples.gpr. Thus, if you want to build samples, you have to execute in the root directory of the project:
gnatmake -P samples.gpr
Or, if you are in samples directory (like in your example):
gnatmake -P ../samples.gpr
This should build all samples.
By default, gnatmake can't find needed libraries, same as GCC can't find extra libraries for C/C++ projects. It is generally done by GNAT Project files (these one with .gpr extension, easy way) or via compilation flags (hard way) or Makefiles. The Ada compilation process is similar to the C/C++. It also needs a lot of flags, settings and sometimes, for a bigger project not working out of the box. :)

ld skips shared library

I am trying to deploy a Qt application by providing the Qt libraries as shared libraries in a directory and pointing ld to them using LD_LIBRARY_PATH. This works for all Qt libraries such as libQt5Network or libQt5Gui, but not for libQt5Core which is somehow not found and the system version is used instead.
Using LD_DEBUG=all I can see that ld tries the file which exists, but skips it
3705: file=libQt5Core.so.5 [0]; needed by ./app.bin [0]
3705: find library=libQt5Core.so.5 [0]; searching
3705: search path=/home/user/app/lib:/usr/lib64/tls/x86_64/x86_64:/usr/lib64/tls/x86_64:/usr/lib64/tls/x86_64:/usr/lib64/tls:/usr/lib64/x86_64/x86_64:/usr/lib64/x86_64:/usr/lib64/x86_64:/usr/lib64 (LD_LIBRARY_PATH)
3705: trying file=/home/user/app/lib/libQt5Core.so.5 <- this file exists
3705: trying file=/usr/lib64/tls/x86_64/x86_64/libQt5Core.so.5
3705: trying file=/usr/lib64/tls/x86_64/libQt5Core.so.5
3705: trying file=/usr/lib64/tls/x86_64/libQt5Core.so.5
3705: trying file=/usr/lib64/tls/libQt5Core.so.5
3705: trying file=/usr/lib64/x86_64/x86_64/libQt5Core.so.5
3705: trying file=/usr/lib64/x86_64/libQt5Core.so.5
3705: trying file=/usr/lib64/x86_64/libQt5Core.so.5
3705: trying file=/usr/lib64/libQt5Core.so.5
Both libQt5Core.so.5 and app.bin are 64 bit elf.
Is there any way to find out why ld rejects the file?
Solution is here: https://github.com/Microsoft/WSL/issues/3023
The library contains an ABI note which can be removed using strip to make ld accept the library.
The other answer is correct. Just in case the link there gets broken, here's what happened in my case and how I fixed it.
I was running an older kernel, version 3.10, on a system where Qt5 was installed. One of the libraries – namely, libQt5Core.so.5.11.0, has an ELF section .note.ABI-tag, which specifies that the library was compiled for kernel 3.17.0. Presence of this section can be seen via e.g.
objdump -sj .note.ABI-tag /path/to/library.so
And the fact that it's compiled for a newer kernel is revealed by file, with the hard to notice note, "for GNU/Linux 3.17.0", near the end of its output. In my case it was:
/opt/qt511/lib/libQt5Core.so.5.11.0: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 3.17.0, BuildID[sha1]=df5f7e933899d1ff629145ab7ca35b2f9bc41843, stripped
So the fix in my case was to run
strip --remove-section=.note.ABI-tag /path/to/library.so
which removed this section and allowed the library to load.
Beware though, that if you do this, you explicitly break the assumptions the library build system may have used, so things may break. In my case they didn't, though.

libm.so.6: cannot open shared object file: No such file or directory

I've install a program in Centos 6.8, While running the program, I receive error
"error while loading shared libraries: libm.so.6: cannot open shared object file: No such file or directory"
when I checked the linked library to the program using ldd command, I can see libm.so.6 with correct 64bit
"libm.so.6 => /lib64/libm.so.6 (0x0000003a19000000)"
That means, library is installed and already added in environment variable, LD_LIBRARY_PATH
Another program, which uses libm.so.6, works fine.
Can anyone help to solve this problem ?
Thanks
In programming, details matter.
Lets say, The program which I am trying to run is ABC and install
This is not details, this is a hypothetical. If you want useful answers, you should supply actual details that you are asked for. In particular, edit your question (instead of commenting on a different useless answer), and do this: "show the ldd command you actually ran, and its actual output."
That said, if ldd /usr/local/ABC/bin/ABC really does show libm.so.6 => /lib64/libm.so.6, then there is no way for ABC to not find libm.so.6.
Therefore we must conclude that ABC invokes some other program, and that program fails to find libm.so.6. You can confirm this guess by running:
LD_DEBUG=files,libs /usr/local/ABC/bin/ABC
This will show that ABC does find libm.so.6, what other program it invokes, and where that other program looks for libm.so.6.
It is likely that the other program is 32-bit, and looks for /lib/libm.so.6, and that you don't have 32-bit runtime libraries installed.
You can install them with yum install glibc.i686 or some such.

Shared library present with different name

I compiled my program with gcc using openssl crypto library.
I moved the executable to an other system, and after installing openssl tried to run it. I got the following error:
error while loading shared libraries: libcrypto.so.1.0.0: cannot open shared object file: No such file or directory
What I understand from the following the library is present, but has another name:
locate libcrypto
/usr/lib64/.libcrypto.so.1.0.2f.hmac
/usr/lib64/.libcrypto.so.10.hmac
/usr/lib64/libcrypto.so
/usr/lib64/libcrypto.so.1.0.2f
/usr/lib64/libcrypto.so.10
/usr/lib64/pkgconfig/libcrypto.pc
Can I somehow tell the binary to use one of the present libraries? Or is there a way to install the one which is required?
The compilation was done on Ubuntu 15.10 64 bit, tried to run on Fedora 4.2.3-300.fc23.x86_64.
Can I somehow tell the binary to use one of the present libraries?
No, you can't: there is a reason these libraries have a different name: they are not ABI-compatible. If you managed to somehow tell the binary to use the other library, the result will be a crash if you are lucky, or a silent corruption if you are not.
(BTW, you can try this by creating a symbolic link: ln -s libcrypto.so.1.0.2f libcrypto.so.1.0.0, but you've been warned not to do this).
is there a way to install the one which is required?
Sure: you should be able to copy libcrypto.so.1.0.0 from Ubuntu machine to Fedora one, assuming you can't find a Fedora package that provides it.

Resources