Compile on ubuntu and run on RHEL?

What is the portability of the compiled file across linux distros? I am building on Ubuntu currently. If my target is the Amazon Linux AMI (redhat based) will my ubuntu run on that platform?

I found in this link Is linux binary universal to all kinds of distributions? - Ask Ubuntu that a staticly compiled binary will work if the kernel support exists. I didn't see a cargo build option for static linking though. My binary does look to be dynamic:

dan@dan-VirtualBox:~/Downloads/csvreaders/rustcsvreader/target/release$ ldd rustcsvreader
	linux-vdso.so.1 =>  (0x00007ffeb83f0000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fcd06fb2000)
	librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fcd06daa000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fcd06b8c000)
	libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fcd06976000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fcd065ac000)
	/lib64/ld-linux-x86-64.so.2 (0x0000557c7a2d2000)

If you use musl the produced binary is statically linked on most targets with something like

cargo build --target=x86_64-unknown-linux-musl

1 Like

The usual issue is libc, which is dynamically linked. If you rely on C code, that may be statically or dynamically linked; it depends on how you bind to the C code.

Dynamically linked glibc can be compatible between Ubuntu and RHEL and any others, but you'll usually get bitten by picking up newer symbol versions on one and trying to run that on the older. That's why the usual advice is to compile and link using the oldest glibc you need to be compatible with.

You can see a file's version requirements like: readelf -V your-file | grep "Name: GLIBC" -- and to a lesser extent, you may also need to check the same for GCC symbols (linked to libgcc_s.so). You can also try nm your-file | grep @ to see all versioned symbols you're linked to.

(Weak versioned symbols should be OK, e.g. w __cxa_thread_atexit_impl@@GLIBC_2.18)

5 Likes