Running Ubuntu 12.04 compiled C++ Programs on a CentOS5 Box - linux

I have a bunch of software developed on Linux in C++ using g++. The code compiles and runs on both Ubuntu 12.04 and CentOS 5. We have a few older servers still running CentOS 5. Currently I compile for both OSes. I want to start using some C++11 features. These are supported on Ubuntu 12.04 but not CentOS 5.
I am trying to produce executables on Ubuntu for CentOS. Toward that end I have linked all the executables with
-Wl,-rpath,/home/arcamax/lib
That should tell it to look in /home/arcamax/lib for shared libs before the standard locations. I then used 'ldd' on the Ubuntu box to build a list of needed libraries and copied those libs to /home/arcamax/lib on the CentOS box. When I try to run the programs on the CentOS box I get:
When I run ldd on the CentOS5 box I get output like this:
libcrypto.so.1.0.0 => /home/arcamax/lib/libcrypto.so.1.0.0 (0x00002b3557f54000)
libpq.so.5 => /home/arcamax/lib/libpq.so.5 (0x00002b355831c000)
libstdc++.so.6 => /home/arcamax/lib/libstdc++.so.6 (0x00002b3558548000)
libm.so.6 => /home/arcamax/lib/libm.so.6 (0x00002b3558849000)
libgcc_s.so.1 => /home/arcamax/lib/libgcc_s.so.1 (0x00002b3558b43000)
libc.so.6 => /home/arcamax/lib/libc.so.6 (0x00002b3558d59000)
libpthread.so.0 => /home/arcamax/lib/libpthread.so.0 (0x00002b3559117000)
libdl.so.2 => /home/arcamax/lib/libdl.so.2 (0x00002b3559334000)
libz.so.1 => /home/arcamax/lib/libz.so.1 (0x00002b3559538000)
libssl.so.1.0.0 => /home/arcamax/lib/libssl.so.1.0.0 (0x00002b3559750000)
libkrb5.so.3 => /home/arcamax/lib/libkrb5.so.3 (0x00002b35599ac000)
libcom_err.so.2 => /home/arcamax/lib/libcom_err.so.2 (0x00002b3559c7a000)
libgssapi_krb5.so.2 => /home/arcamax/lib/libgssapi_krb5.so.2 (0x00002b3559e7f000)
libldap_r-2.4.so.2 => /home/arcamax/lib/libldap_r-2.4.so.2 (0x00002b355a0bd000)
/lib64/ld-linux-x86-64.so.2 (0x00000035aa800000)
libk5crypto.so.3 => /home/arcamax/lib/libk5crypto.so.3 (0x00002b355a30d000)
libkrb5support.so.0 => /home/arcamax/lib/libkrb5support.so.0 (0x00002b355a535000)
libkeyutils.so.1 => /home/arcamax/lib/libkeyutils.so.1 (0x00002b355a73d000)
libresolv.so.2 => /home/arcamax/lib/libresolv.so.2 (0x00002b355a942000)
liblber-2.4.so.2 => /home/arcamax/lib/liblber-2.4.so.2 (0x00002b355ab5e000)
libsasl2.so.2 => /home/arcamax/lib/libsasl2.so.2 (0x00002b355ad6c000)
libgssapi.so.3 => /home/arcamax/lib/libgssapi.so.3 (0x00002b355af88000)
libgnutls.so.26 => /home/arcamax/lib/libgnutls.so.26 (0x00002b355b1c6000)
libgcrypt.so.11 => /home/arcamax/lib/libgcrypt.so.11 (0x00002b355b482000)
libheimntlm.so.0 => /home/arcamax/lib/libheimntlm.so.0 (0x00002b355b701000)
libkrb5.so.26 => /home/arcamax/lib/libkrb5.so.26 (0x00002b355b908000)
libasn1.so.8 => /home/arcamax/lib/libasn1.so.8 (0x00002b355bb8e000)
libhcrypto.so.4 => /home/arcamax/lib/libhcrypto.so.4 (0x00002b355be2f000)
libroken.so.18 => /home/arcamax/lib/libroken.so.18 (0x00002b355c063000)
libtasn1.so.3 => /home/arcamax/lib/libtasn1.so.3 (0x00002b355c278000)
libp11-kit.so.0 => /home/arcamax/lib/libp11-kit.so.0 (0x00002b355c48a000)
libgpg-error.so.0 => /home/arcamax/lib/libgpg-error.so.0 (0x00002b355c69c000)
libwind.so.0 => /home/arcamax/lib/libwind.so.0 (0x00002b355c8a0000)
libheimbase.so.1 => /home/arcamax/lib/libheimbase.so.1 (0x00002b355caca000)
libhx509.so.5 => /home/arcamax/lib/libhx509.so.5 (0x00002b355ccd9000)
libsqlite3.so.0 => /home/arcamax/lib/libsqlite3.so.0 (0x00002b355cf23000)
libcrypt.so.1 => /home/arcamax/lib/libcrypt.so.1 (0x00002b355d1c7000)
Note there is one lib, /lib64/ld-linux-x86-64.so.2, that is still being pulled from a system location. I don't know why that is. When I try to run the program I get:
relocation error: /home/arcamax/lib/libgnutls.so.26: symbol time, version GLIBC_2.2.5 not defined in file libc.so.6 with link time reference
A few of the programs fail ldd with the message:
not a dynamic executable
Those programs report the same error as the others when I try to run them.

Don't compile on the system with the newer glibc. It will be very difficult or impossible to run them on the machine with the older glibc.
Instead you should compile on the older CentOS system and the binaries will happily run on the newer system.
I want to start using some C++11 features. These are supported on Ubuntu 12.04 but not CentOS 5.
No, they're supported by the GCC version that happens to be installed on Ubuntu 12.04, they're not supported by "Ubuntu". Install the same GCC version on the CentOS host and you can use C++11 features when you compile there.
Installing GCC is easy, just read that wiki page, and don't try to replace your system compiler i.e. install to /usr/local or /opt or $HOME or somewhere other than /usr

Related

Are dependences backwards compatible for a given compiler or does this result in some sort of undefined behavior?

I have code that was compiled with Intel version 2020.4.304 on Linux SLES 12. Over time various other versions have been added and I switched to default to OneAPI version 2021.1.1. On Windows when I update MSVS I need to update the C++ redistributable installed on any client systems.
I can switch between the loaded versions readily enough using module. When I run ldd against my executable I see that all the dependencies are fulfilled with either compiler loaded. Running the application results in the same output. This seems like undefined behavior that is just happening to work out in my favor. Here is the output from ldd (2020):
linux-vdso.so.1 (0x00007ffc17b9a000)
libifport.so.5 => /ots/sw/INTEL/2020.4/compilers_and_libraries_2020.4.304/linux/compiler/lib/intel64_lin/libifport.so.5 (0x0000150982a82000)
libifcoremt.so.5 => /ots/sw/INTEL/2020.4/compilers_and_libraries_2020.4.304/linux/compiler/lib/intel64_lin/libifcoremt.so.5 (0x0000150982d3a000)
libimf.so => /ots/sw/INTEL/2020.4/compilers_and_libraries_2020.4.304/linux/compiler/lib/intel64_lin/libimf.so (0x00001509823ff000)
libsvml.so => /ots/sw/INTEL/2020.4/compilers_and_libraries_2020.4.304/linux/compiler/lib/intel64_lin/libsvml.so (0x00001509808b5000)
libm.so.6 => /lib64/libm.so.6 (0x000015098056a000)
libintlc.so.5 => /ots/sw/INTEL/2020.4/compilers_and_libraries_2020.4.304/linux/compiler/lib/intel64_lin/libintlc.so.5 (0x00001509802f2000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00001509800cf000)
libdl.so.2 => /lib64/libdl.so.2 (0x000015097fecb000)
libc.so.6 => /lib64/libc.so.6 (0x000015097fad6000)
libgcc_s.so.1 => /ots/sw/GCC/10.2.0/lib64/libgcc_s.so.1 (0x000015097f8be000)
/lib64/ld-linux-x86-64.so.2 (0x0000150982cb0000)
And OneAPI 2021:
linux-vdso.so.1 (0x00007ffd4f2a7000)
libifport.so.5 => /ots/sw/INTEL/oneapi/2021.1/compiler/2021.1.1/linux/compiler/lib/intel64_lin/libifport.so.5 (0x00001529c1c4c000)
libifcoremt.so.5 => /ots/sw/INTEL/oneapi/2021.1/compiler/2021.1.1/linux/compiler/lib/intel64_lin/libifcoremt.so.5 (0x00001529c1f02000)
libimf.so => /ots/sw/INTEL/oneapi/2021.1/compiler/2021.1.1/linux/compiler/lib/intel64_lin/libimf.so (0x00001529c15c4000)
libsvml.so => /ots/sw/INTEL/oneapi/2021.1/compiler/2021.1.1/linux/compiler/lib/intel64_lin/libsvml.so (0x00001529bfa4b000)
libm.so.6 => /lib64/libm.so.6 (0x00001529bf700000)
libintlc.so.5 => /ots/sw/INTEL/oneapi/2021.1/compiler/2021.1.1/linux/compiler/lib/intel64_lin/libintlc.so.5 (0x00001529bf488000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00001529bf265000)
libdl.so.2 => /lib64/libdl.so.2 (0x00001529bf061000)
libc.so.6 => /lib64/libc.so.6 (0x00001529bec6c000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00001529bea53000)
/lib64/ld-linux-x86-64.so.2 (0x00001529c1e7a000)
In general are Linux libraries backwards compatible across compiler versions? Various answers and comments are somewhat contradictory. Question 1 and Question 2
In Linux, library versions are distinguished by a soname. The redistrubutable libraries from Intel should be no different if they follow the suit. If a compatibility breaking change is made, the so version number is increased so that the versions can be distinguished.
Therefore, libifport.so.5 is not compatible with libifport.so.4, but if a program requires libifport.so.5, it should be satisfied with one coming from any version of the compiler that provides it.
The changes that break backward comparibility come only in some compiler versions, certainly not every year. And since Intel has introduced new LLVM compilers and the old ones are becoming legacy, such changes may stop altogether for ifort, but that is my speculation.
Also, such change is made to a specific library or specific set of libraries, whose soname numbers are increased. Not all redistributable libraries coming with a compiler collection will be affected.

How can I specify the GLIBC version in cargo build for Rust?

I use rust 1.34 and 1.35. Currently it links to GLIBC_2.18.
How can I limit cargo build to link GLIBC up to version 2.14?
Unfortunately, you can't. Not really, and not consistently. This is a problem with any binary that dynamically links to GLIBC. You can try setting up multiple GLIBC versions and linking to one, or you can try patching the resulting binary, but it's inconsistent and impractical.
So what are some practical options?
Compile Statically
By using MUSL instead of GLIBC we can compile statically.
To install the MUSL target with rustup (assuming x86_64 architecture):
$ rustup component add rust-std-x86_64-unknown-linux-musl
And to use it when compiling:
$ cargo build --target x86_64-unknown-linux-musl
This is the easiest method by far, but won't always work, especially when using native libraries, unless they can also be compiled statically.
Make a VM That Has an Older Version
This is a common approach. By using an OS with an outdated, GLIBC the binary will have GLIBC symbols that are compatible with it.
Use a Docker Container
This is probably the most convenient method, in my opinion. If you have Docker, you can just compile your project with a container that contains an old GLIBC. View the Rust contianer's README for compilation instructions. The command below will compile a project using Rust 1.67 and GLIBC 2.28 (which comes with buster):
$ docker run --rm --user "$(id -u)":"$(id -g)" -v "$PWD":/usr/src/myapp -w /usr/src/myapp rust:1.67-buster cargo build --release
I compiled this on Ubuntu 22.04 and tested it on Ubuntu 20.04.
To test further, I made sure the binary relied on another dynamic library (OpenSSL) and here's the result of ldd ./mybinary after compiling with the Docker container:
$ ldd ./mybinary
linux-vdso.so.1 (0x00007ffd98fdf000)
libcrypto.so.1.1 => /lib/x86_64-linux-gnu/libcrypto.so.1.1 (0x00007fe49e248000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fe49e22d000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fe49e223000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fe49e200000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fe49e0b1000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fe49e0ab000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe49deb7000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe49ea30000)
And this is what it looks like without the container:
$ ldd ./mybinary
linux-vdso.so.1 (0x00007ffd5d7b7000)
libcrypto.so.3 => /lib/x86_64-linux-gnu/libcrypto.so.3 (0x00007fe85564c000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fe85562c000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fe855545000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe85531d000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe855f98000)

How to fix 'Can't open libmsodbcsql-17.3.so.1.1'

In ubuntu 19.04 when working with Python3 in an anaconda environment with pyodbc 4.0.26 installed I get the Error: ('01000', "[01000] [unixODBC][Driver Manager]Can't open lib '/opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.3.so.1.1' : file not found (0) (SQLDriverConnect)")!
Installed msodbcsql17 in ubuntu 19.04 like described here. I tried all the suggestions from here and here. I did the analysis like described here.
With pyodbc 4.0.26, it is possible to check the driver in the anaconda environment with python3 -c 'import pyodbc; print(pyodbc.drivers())' and got ['ODBC Driver 17 for SQL Server'].
After the analysis and the solutions from the links shown above, I still am not able to get a connection to work with MS-SQL and Python3. Please help me!
Edit:
...:~$ ldd /opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.3.so.1.1
linux-vdso.so.1
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1
libodbcinst.so.2 => /usr/lib/x86_64-linux-gnu/libodbcinst.so.2
libcrypto.so.1.0.0 => not found
libkrb5.so.3 => /usr/lib/x86_64-linux-gnu/libkrb5.so.3
libgssapi_krb5.so.2 => /usr/lib/x86_64-linux-gnu/libgssapi_krb5.so.2
libssl.so.1.0.0 => not found
libuuid.so.1 => /lib/x86_64-linux-gnu/libuuid.so.1
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6
/lib64/ld-linux-x86-64.so.2
libltdl.so.7 => /usr/lib/x86_64-linux-gnu/libltdl.so.7
libk5crypto.so.3 => /usr/lib/x86_64-linux-gnu/libk5crypto.so.3
libcom_err.so.2 => /lib/x86_64-linux-gnu/libcom_err.so.2
libkrb5support.so.0 => /usr/lib/x86_64-linux-gnu/libkrb5support.so.0
libkeyutils.so.1 => /lib/x86_64-linux-gnu/libkeyutils.so.1
libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2
Also:
~$ sudo locate libcrypto.so.1.0.0
/home/xxx/anaconda3/pkgs/openssl-1.0.2o-h20670df_0/lib/libcrypto.so.1.0.0
/home/xxx/anaconda3/pkgs/openssl-1.0.2p-h14c3975_0/lib/libcrypto.so.1.0.0
/home/xxx/anaconda3/pkgs/openssl-1.0.2p-h470a237_1/lib/libcrypto.so.1.0.0
and:
~$ sudo locate libssl.so.1.0.0
/home/xxx/anaconda3/pkgs/openssl-1.0.2o-h20670df_0/lib/libssl.so.1.0.0
/home/xxx/anaconda3/pkgs/openssl-1.0.2p-h14c3975_0/lib/libssl.so.1.0.0
/home/xxx/anaconda3/pkgs/openssl-1.0.2p-h470a237_1/lib/libssl.so.1.0.0
And I am working in Anaconda environment.
Installing libssl1.0.0 manually in Ubuntu 19.04 solves the problem, maybe with some other tuning I have done before - see the links mentioned in my question above. You can install the old lib in ubuntu 19.04 with wget http://archive.ubuntu.com/ubuntu/pool/main/o/openssl1.0/libssl1.0.0_1.0.2n-1ubuntu6.2_amd64.deb && dpkg -i libssl1.0.0_1.0.2n-1ubuntu6.2_amd64.deb. It will be installed parallel to libssl1.1.
As of 2019-05-22 Microsoft's installation instructions have not been updated to include Ubuntu 19.04. Microsoft has added an entry for 19.04 in the repository, i.e.,
https://packages.microsoft.com/config/ubuntu/19.04/prod.list
but it may not be ready for prime-time. It certainly looks like they need to sort out the libssl dependency for 19.04 since libssl1.0.0 is apparently no longer available
gord#VBox-Xubuntu1904:~$ sudo apt install libssl1.0.0
Reading package lists... Done
Building dependency tree
Reading state information... Done
Package libssl1.0.0 is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
E: Package 'libssl1.0.0' has no installation candidate

How to check if my cross compiled executable is dynamic or static?

I used crosstools-ng to compile shadowsocks for my router, on my router, I can just ldd myExecutable to list the dependencies,
$ ssh root#my-router-ip
root#unknown:/tmp/home/root# ldd ./ss-server
libcrypto.so.1.0.0 => /usr/lib/libcrypto.so.1.0.0 (0x2aabf000)
libm.so.0 => /lib/libm.so.0 (0x2ac23000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x2ac37000)
libpthread.so.0 => /lib/libpthread.so.0 (0x2ac56000)
libc.so.0 => /lib/libc.so.0 (0x2ac78000)
libdl.so.0 => /lib/libdl.so.0 (0x2accb000)
ld-uClibc.so.0 => /lib/ld-uClibc.so.0 (0x2aaa8000)
but right now I don't have my router with me, how do I check it?
tried with the tools from crosstools-ng compiled toolchain which used to compile the executable
$ mipsel-unknown-linux-uclibc-ldd /home/oglop/Downloads/ss-install/bin/ss-server
mipsel-unknown-linux-uclibc-ldd: no root given
Try `mipsel-unknown-linux-uclibc-ldd --help' for more information
$ mipsel-unknown-linux-uclibc-readelf -d /home/oglop/Downloads/ss-install/bin/ss-server
There is no dynamic section in this file.
I have already tried methods here in How to list library dependencies of a non-native binary?, none of them works.

Linux module dependency

We have a linux module developed by a 3rd party, now the module runs correctly on a Fedora system but on Ubuntu the same fails. When we do an ldd for the binary the following output is received
linux-gate.so.1 => (0xffffe000)
libdl.so.2 => /lib32/libdl.so.2 (0xf76f5000)
libc.so.6 => /lib32/libc.so.6 (0xf759b000)
/lib/ld-linux.so.2 (0xf7705000)
libutf16.so => not found
I am unable to find the library libutf16 for ubuntu, where can i find this library or is it part of a bigger library.
There is no file that contains libutf16 in its name in any package in Ubuntu 10.04.

Resources