在另一个发行版中运行 C 可执行文件
我有一个正在使用 Ubuntu 11.10(Linux 版本 3.0.0-12-generic-pae 内核)开发的 C 程序。我需要在安装了 Debian 3.1(Linux 版本 2.4.24-om2)并使用 Intel(R) Pentium(R) 4 CPU 3.20GHz 处理器的集群中运行该程序。
问题是我无法在 Debian 集群中进行编译,因为它没有安装我的程序所需的 GSL 库,并且我不知道如何在没有 root 权限的情况下安装它(或使用它)。
如果我尝试运行在 Ubuntu 中编译的可执行文件(或者一个简单的 hello world 程序,对于这种情况),它不起作用,即使我使用它抛出的所有 gcc 选项进行编译在集群上执行:
gcc --save-temps -fverbose-asm hello_world.c -o hello_world
当我尝试执行在 Ubuntu 中编译的程序时,它会抛出:
floating point exception
更新:当我使用 -static 标志进行编译时,得到的错误是:
FATAL: kernel too old
Segmentation fault.
那么我可以做一些比重新实现所有功能更好的事情吗?我正在使用的 GSL。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我不知道你面临的是什么不起作用,但我能想到的唯一不涉及交叉编译的是添加一个
-static
到您的gcc
行。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 yourgcc
line.如果您的代码实际上正在运行并且在调用 main() 之前没有终止,那么在代码中放置一些调试输出语句以准确了解代码失败的位置将很有用。
为了使您的可执行文件尽可能可移植,您需要使其静态链接。这样它就不会有太多的外部依赖。当然,可执行文件的大小会增加一点。如果仍然不起作用,请确保您正在编译的体系结构与集群正在运行的体系结构相同。也就是说,集群是否运行 64 位 Intel-ish 处理器?或者也许是sparc之类的?
即使使用静态编译,也不是完全可移植的。如果您能找出集群上运行的 glibc 版本并根据该版本构建应用程序,那么您的运气会更好。如果您可以使用集群上相同版本的 gcc 构建应用程序,您会更加安全。基本上,您希望您的工具链与集群系统的工具链尽可能相似。
更新:好的,所以你的问题几乎可以肯定是你正在编译的 glibc 太新,无法运行 2.4 内核。这并不奇怪。可以通过执行我在上一段中所说的操作来解决此问题,但也可以仅使用编译器标志来完成此操作。我发现这个问题谈论关于 gcc 的
--enable-kernel=VERSION
选项。然而,我对此选项的经验为零。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.如果错误
继续。检查主机上运行的linux内核版本以及使用创建的可执行文件所需的支持版本
If the error
continues. check the kernel version of linux running on the host machine and the supporting version required for the executable created using
Linux 中的可移植性存在几个问题。内核 ABI 正在发生变化,库和工具链正在从一个发行版到另一个发行版、从一个版本到另一个版本发生变化。
最可靠的方法是在旧系统(或基于旧版本 Linux 的 chroot 环境)上编译代码,因为 Linux 通常具有相当的向后兼容性。
另外我建议您阅读文章 便携式 Linux 二进制文件
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
最后,我解决了在没有root权限的情况下编译GSL库的问题。
我将源文件解压缩到主目录中的一个文件夹中,创建了一个 _build 目录,然后运行 ../configure,然后 make。
我将在 _build 内创建的 .libs 目录的文件复制到新的 ~/path/lib 目录中,并使用:
复制 GSL 源文件夹中生成的所有头文件(当然有更好的方法来做到这一点) 。
然后我尝试设置 gcc 的环境变量(C_INCLUDE_PATH、LIBRARY_PATH),但由于某种原因我无法保存它们(使用和导出,尝试在 ~/profile 和 ~/.bash_profile 文件中更改它们)。
因此,我使用 -I 和 -L gcc 选项来链接这两个文件夹。它是这样工作的。
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:
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.