2

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.

John Conde
  • 217,595
  • 99
  • 455
  • 496
Zah
  • 6,394
  • 1
  • 22
  • 34
  • Can you elaborate on "doesn't work" with the error output or something? Also, it doesn't look like you finished the sentence starting with "So can I do something...". – Dan Fego Nov 14 '11 at 20:26
  • What are you looking at to see the version number for Debian? That number you posted doesn't appear to correspond to any of the currently released versions. – Zoredache Nov 14 '11 at 20:33
  • Thanks for your answers. I edited the post to correct the mistakes. The version of Debian that I was looking at was that of the output of gcc -v. – Zah Nov 14 '11 at 20:40
  • `more /etc/debian_version` outputs 3.1. Isn't that the version? – Zah Nov 14 '11 at 20:51
  • you get "kernel too old" when compiling or when running on the cluster? – kbyrd Nov 14 '11 at 20:56
  • When running the executable I compiled in Ubuntu. – Zah Nov 14 '11 at 21:02
  • 7
    The most painless way to go on about this is to install Debian 3.1 in a virtual machine and compile your program on that. With such a huge gap between versions of your Debian cluster and the latest Ubuntu - there will likely be nothing but trouble. The other alternative is to compile/install GSL itself on the cluster as a non-root user and compile your program on the cluster against that GSL library. In either case you likely need to link in GSL statically to your program. – nos Nov 14 '11 at 22:17

5 Answers5

1

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'

Kumar Sukhani
  • 377
  • 2
  • 8
1

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.

Michael Krelin - hacker
  • 138,757
  • 24
  • 193
  • 173
  • It just outputs some cryptic "floating point exception". The same for the hello world program. – Zah Nov 14 '11 at 20:35
  • umm.. Perhaps your kernel is too old :) – Michael Krelin - hacker Nov 14 '11 at 20:58
  • I've seen "kernel too old" when the glibc you compiled against is too new for the kernel you want to run on. It's likely you're doing development on a 3.0.x kernel and running on something like a 2.4 kernel. See my answer for a bit more detail. – kbyrd Nov 14 '11 at 21:01
  • Yes, @kbyrd, sounds like that. Don't see how your answer helps, though, because as I understand the OP can't compile in cluster environment. – Michael Krelin - hacker Nov 14 '11 at 21:05
  • My answer helps because it's entirely possible to build binaries for 2.4 and associated glibc from a system running much newer libraries. It's a bit like cross-compiling ARM binaries on an x86 system. – kbyrd Nov 14 '11 at 21:07
  • Ok, I see that the kernel versions are different. So now how should I proceed? Thank you very much. – Zah Nov 14 '11 at 21:13
1

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.

Community
  • 1
  • 1
kbyrd
  • 3,321
  • 27
  • 41
  • Using -static changes the error to FATAL: kernel too old, so I don't think it actually gets to execute. The processors that the cluster uses are Intel(R) Pentium(R) 4 CPU 3.20GHz. – Zah Nov 14 '11 at 20:59
  • Please update your question to add the kernel you're compiling on and the kernel you're running on. For Sarge (Debian 3.1) it could be a 2.4 or a 2.6 kernel and I believe the default kernel for Ubuntu 11.10 is 3.0. You're going to have to build a toolchain similar enough to the Debian environment. Solve it a bit like cross-compiling, like you are building ARM binaries on your Ubuntu box :-) – kbyrd Nov 14 '11 at 21:03
0

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

Andrii Radyk
  • 394
  • 1
  • 4
0

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.

Zah
  • 6,394
  • 1
  • 22
  • 34
  • 1
    It would be better if you use `configure` with `--prefix` parameter, e.g: `./configure --prefix=/full/path/to/home/gsl`. Then you could issue `make install` to install all needed headers and libraries in `~/gsl` directory instead using this fancy `find`. To get full help issue `./configure --help`. – smbear Nov 15 '11 at 20:55