I have a C program that I'm developing using Ubuntu 11.10 (Linux version 3.0.0-12-generic-pae kernel). I need to run that program in a cluster that has Debian 3.1 (Linux version 2.4.24-om2) installed, and uses Intel(R) Pentium(R) 4 CPU 3.20GHz processors.
The problem is that I can't compile in the Debian cluster because it doesn't have installed the GSL library that my program needs, and I don't know how to install it (or make use of it) without root privileges.
If I try to run the executable I compiled in Ubuntu (or a simple hello world program, for the case), it doesn't work, even if I compile using all the gcc options that this throws when executed on the cluster:
gcc --save-temps -fverbose-asm hello_world.c -o hello_world
When I try to execute my program compiled in Ubuntu, it throws:
floating point exception
Update: When I compile using the -static flag, the error I get is:
FATAL: kernel too old
Segmentation fault.
So can I do something better than re-implement all the functions of GSL that I'm using.
I have no idea what doesn'twork is that you're facing, but the only thing I can think of it it doesn't involve cross-compilation is adding a -static
to your gcc
line.
If your code is actually running and not dying before main() gets called, it would be useful to put some debug output statements in your code to know exactly where your code fails.
To make your executable as portable as possible you going to want to make it statically link. That way it won't have many external dependencies. Of course, the executable size will grow a bit. If that still doesn't work, be sure the architecture you are compiling for is the same that the cluster is running. That is, is the cluster running 64-bit Intel-ish processors? Or maybe it's sparc or something?
Even with static compilation, you're not completely portable. You'll have better luck if you can figure out what version of glibc is running on the cluster and build your application against that. You'll be even safer if you can build your application with the same version of gcc that is on the cluster. Basically you want your toolchain to be as similar as possible to that of the cluster systems.
UPDATE: Ok, so your problem is almost certainly glibc you are compiling with is too new to run an a 2.4 kernel. That's not surprising. It's possible to fix this by doing what I said in the last paragraph, but it may be possible to do this with just compiler flags. I found this question which talks about the --enable-kernel=VERSION
option to gcc. I have zero experience with this option, however.
If the error
FATAL: kernel too old
Segmentation fault.
continues. check the kernel version of linux running on the host machine and the supporting version required for the executable created using
ldd 'executable'
There are several issues for portability in linux. Kernel ABI is changing, libraries and toolchain are changing from distro to distro and from release to release.
The most reliable approach is to compile your code on an old system (or a chroot environment based on an old version of Linux), since Linux is typically fairly backwards compatible.
Also I recommend you to read the article Portable Linux Binaries
At the end, I solved it compiling the GSL library without root privileges.
I uncompressed the sources in a folder in the home directory, created a _build directory, and ran ../configure, and then make.
I copied the files of the .libs directory that was created inside _build in a new ~/path/lib directory, and used:
find -name "*.h" -type f -exec cp {} ~/path/include/gsl \;
To copy all the header files generated in the GSL source folder (surely there was a better way to do that).
I then tried to set the environment variables for gcc (C_INCLUDE_PATH, LIBRARY_PATH) but for some reason I wasn't able to save them (used and export, tried to change them in the ~/profile and ~/.bash_profile files).
So, I used the -I and -L gcc options to link the two folders. It worked this way.