2

I'm trying to get a binary compiled on Ubuntu to run on CentOS 7 (both 64bit, one host, the other vm).

So far I've copied the binary with all the shared libs. I no longer get the missing library error but a nice ld SIGSEGV

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff5d67681 in ?? ()
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.149.el6.x86_64
(gdb) where
#0  0x00007ffff5d67681 in ?? ()
#1  0x00007fffffffe3f0 in ?? ()
#2  0x00007ffff7decdd4 in _dl_check_map_versions () from /lib64/ld-linux-x86-64.so.2
#3  0x00007ffff7de08a3 in dl_main () from /lib64/ld-linux-x86-64.so.2
#4  0x00007ffff7df2aee in _dl_sysdep_start () from /lib64/ld-linux-x86-64.so.2
#5  0x00007ffff7dde4a4 in _dl_start () from /lib64/ld-linux-x86-64.so.2
#6  0x00007ffff7dddb08 in _start () from /lib64/ld-linux-x86-64.so.2
#7  0x0000000000000001 in ?? ()
#8  0x00007fffffffe8bb in ?? ()
#9  0x0000000000000000 in ?? ()

I have the source but I barely managed to compile and test on ubuntu, as it relies on some libs that are built from source, tryed on the centOS but the g++ version is older and didn't support c++11. After installing the devtools version now I get other errors, but that's a different question I guess.

So is there anything that I can do to get past this error? Will it eventually run this way? What is the easiest way to port something from Ubuntu to CentOS ?

2 Answers2

4

I would suggest not doing this. It's generally easier to build binaries for the different distros within that distro's package building process. On CentOS, that would be making use of rpmbuild.

Since you're dealing with VMs it would be much more trivial to setup a CentOS 7 VM + build tools and then do the package construction there.


Observations from a User of a Source Based Distribution

I don't normally jump on the bandwagon and edit other peoples answer's, but I find myself earning my reputation here slowly but surely, by helping people realize the difference between a source based distribution, of which there are 3 major ones:

  1. Linux from Scratch
  2. Gentoo
  3. Slackware

and a binary based distribution, of which there are 2 major ones:

  1. Debian
  2. Redhat/Fedora

As of now, there is only 1 major hybrid distribution (cross between source, and binary):

  1. Arch Linux

Whether Linux users like it or not, all the other Linux distributions are children to one of these 6 parents. With that being said, we move on to the next point that:

It is Impossible to Mix Software From a Source Based Distribution with Software in a Binary Distribution


Knowing this also means, unless you know what you're doing, you should not compile a single package from source on a binary distro. There are exceptions to this rule:

  1. The package you need doesn't exist in your distributions repository/tree/etc (This was the OP's reason for his question).
  2. You cannot find a Newer version of a needed package in your repository/tree/etc - See Bullet 9.

Why the OP is Having an Issue

Technically speaking, there is no difference in using a package and building from source when it comes to the final package, i.e., if you can build the package successfully, and it works, no one will fault you for doing it. You must remember that when you do it though, that the tools you used to build your application on one binary based distribution are greater than the versions of the tools available in another binary distribution. What the OP is seeing is the delta, or change, between the old and new packages. The delta or change is caused by the Package and OS Maintainers of Each OS, be it one of the 6 above, or the children, choosing what package they will mark stable for their OS. Once a package is chosen in a Binary Distribution, most times it's frozen until the next release, unless a Critical Bug is Discovered.

A Source Based Distribution, on the other hand can choose to update items as soon as new sources are available, thus bugfixing on the fly.

This is Why the OP is Having Issues

The release schedule, and the update cycle for Ubuntu chose to adopt new versions of the Build Toolchain, before CentOS adopted them. Since CentOS is built on stability, the Build Toolchain may not be updated until their next major release. As such the OP was experiencing an issue similar to this, because Ubuntu's Build Toolchain supports C++11, and CentOS's does not until all the version mismatches are repaired, and will later run into issues with using multiple Package Managers.

What the OP Should Have Done

  1. Determined the Build Tools Available for the system on which the Package will reside. In this case that would be CentOS. Here is a page on how to install them Properly. According to the list in the previous link, that compiler supports C++11. As a very experienced hunch the OP's version mismatch is occurring in either binutils or libtool Binutils depends on glibc, and libtool depends on binutils, therefore libtool indirectly depends on glibc I won't explain why nearly every package on any system indirectly depends on glibc just know that it does.
  2. If the Build Toolchain, after proper installation, had not supported C++11, the OP would be forced to use C++98 to alleviate the issue he is facing now.
  3. Having updated the Build Toolchain in Step 1 above, the OP should now compile his source code in the CentOS VM, and repair/fix as needed. If the OP requires a package, he should use rpmbuild, as this post suggests, as that is the native package manager to the VM where the package resides. Yum is NOT a package manager. Yum IS A Dependency Resolver

References

  1. List of Linux Distributions
  2. C++0x/C++11 Support in GCC
  3. News, Status & Discussion about Standard C++
slm
  • 369,824
  • I've never made a package and from what I see, it seems to be like building from source, at which I have a problem on the centOS. Also I didn't use any tools for building, basically the whole build runs with one g++ compile command – Stefan Rogin Nov 25 '14 at 07:23
  • @clickstefan - I've done the above for apps that were internally developed using a similar mixture of libraries (boost, etc.). – slm Nov 25 '14 at 12:34
  • what is the difference between building from source and creating a package? referring to my case, what are the benefits and disadvantages of using one or another. Also I've seen that there are binary packages and source packages, at what type where you referring ? – Stefan Rogin Nov 25 '14 at 14:07
  • @clickstefan Deleted Comments now in Answer – eyoung100 Nov 25 '14 at 17:07
  • wow, thanks... too bad I can't give more than one vote. – Stefan Rogin Nov 26 '14 at 07:55
0

OP solution and conclusions

Based on previous answers here is the solution I ended up doing.


1. Copy the source code

Copy your source code to the VM or other machine. I've used :

scp -R /host/path/to/src/ user@remoteHost:/remote/build/path/

It's like going on a road trip, so pack well, gather all the sources that you require for compile, minus the shared libs and other resources that you can find on the other machine.

2. Install dependencies (libs/build tools)

Reverted VM to basic install (centOS7 min) and updated the tools used to build my app, based on trial and error (yum search, install, try build command)

yum -y update
yum -y install boost-*      #probably could have used only boost-devel
yum -y install glibc-utils
yum -y install gcc-c++
yum -y install git
yum -y install libtool       
yum -y install zlib-devel    
yum -y install ncurses-devel 
yum -y install make          
yum -y install cmake         
yum -y install openssl-devel 
yum -y install libssh2-devel
...

In case your project depends on (newer) libraries not available in the OS repository, install from source:

For example I needed curl built with c-ares, and the updated mysql client library.

#mysqlclient
if [[ -z $(ldconfig -p | grep libmysqlclient) ]]
then
    mkdir -p "${INSTALL_PREQ_PATH}/lib/mysql/";
    cd "${INSTALL_PREQ_PATH}lib/mysql/"
    wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm
    yum -y localinstall mysql-community-release-el7-5.noarch.rpm
    sudo yum install mysql-community-client
    sudo yum install mysql-community-devel
fi


#c-ares
if [[ -z $(ldconfig -p | grep libcares) ]]
then
    mkdir -p "${INSTALL_PREQ_PATH}lib/libcares/"
    cd "${INSTALL_PREQ_PATH}lib/libcares/"
    git clone git://github.com/bagder/c-ares.git
    cd c-ares
    ./buildconf
    ./configure
    make
    sudo make install
    ldconfig
fi

#libcurl
if [[ -z $(ldconfig -p | grep libcares) ]]
then
    mkdir -p "${INSTALL_PREQ_PATH}lib/libcurl/"
    cd "${INSTALL_PREQ_PATH}lib/libcurl/"
    wget http://curl.haxx.se/download/curl-7.39.0.tar.gz
    tar -xvzf curl-7.39.0.tar.gz
    cd curl-7.39.0
    ./configure --enable-ares --with-libidn --with-zlib --disable-ipv6
    make
    sudo make install
    ldconfig
fi

Obs: each build comes with it's own dependencies, and were added to the step above.

3. Foreach dependency installed, verify it's working and check if you broke anything

Check if libraries are loaded by the system:

ldconfig                    # update library cache
ldconfig -p | grep libcurl  # check for library

In my case libraries were installed in /usr/local/lib/ folder, which is not included by default in the link builder search path. To fix this:

echo "/usr/local/lib/">/etc/ld.so.conf.d/local.conf    #add lib search path
ldconfig                                               #reload library cache

Also check if the other programs that use that shared lib are still working. In my case the curl install broke yum as it was missing ssh and ssl, fix:

rm /etc/ld.so.conf.d/local.conf              #remove the new libs search path
ldconfig                                     #reload
yum install openssl-devel                    #install ssl dependency
yum install libssh2-devel                    #install ssh dependency
cd "${INSTALL_PREQ_PATH}lib/libcurl/"        #go to libcurl source path
./configure --enable-ares --with-libidn --with-zlib --disable-ipv6 --with-ssl --with-libssh2   # configure build with ssl and ssh
make                                         #compile
sudo make install                            #install binary, libs and headers
echo "/usr/local/lib/">/etc/ld.so.conf.d/local.conf    #add lib search path
ldconfig                                               #reload library cache

4. Build your program

In my case I used the same compiler I used on ubuntu, gcc-c++ (g++). In case it's not working:

  • See if any dependency is missing, read warnings and errors
  • Check compiler version on both machines, check if there are differences in support for your code and compiler flags, use the internet to find ways to update your compiler for your OS

Other notes:

  • Write down your steps, preferably in a bash script so you can retry or (re)install on another machine.
  • This is not good advice for a production machine, run trials somewhere else.
  • If you're using a VM, take snapshots, otherwise backup, and always be prepared to fail
  • Don't take my advice, this is what worked for me, it might not work for all, and might be a bad choice for other cases. I'm no expert just writing to help out other noobs like me :)