2

我有一个使用 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 的所有功能更好的事情。

4

5 回答 5

1

我不知道你所面临的是什么不起作用,但我能想到的唯一不涉及交叉编译的就是-static在你的gcc行中添加一个。

于 2011-11-14T20:29:21.290 回答
1

如果您的代码在 main() 被调用之前实际上正在运行并且没有死亡,那么在您的代码中放置一些调试输出语句以准确了解您的代码失败的位置会很有用。

为了使您的可执行文件尽可能可移植,您需要使其静态链接。这样它就不会有很多外部依赖。当然,可执行文件的大小会增长一点。如果这仍然不起作用,请确保您正在编译的架构与集群正在运行的架构相同。也就是说,集群是否运行 64 位 Intel 处理器?或者也许它是sparc或其他什么?

即使使用静态编译,您也不是完全可移植的。如果您能弄清楚集群上正在运行什么版本的 glibc 并针对它构建您的应用程序,那么您将会有更好的运气。如果您可以使用集群上相同版本的 gcc 构建应用程序,您将更加安全。基本上,您希望您的工具链与集群系统的工具链尽可能相似。

更新:好的,所以您的问题几乎可以肯定是您正在编译的 glibc 太新而无法运行 2.4 内核。这并不奇怪。可以通过执行我在上一段中所说的来解决此问题,但也可以仅使用编译器标志来解决此问题。我发现这个问题谈到了--enable-kernel=VERSIONgcc 的选项。但是,我对此选项的经验为零。

于 2011-11-14T20:43:39.673 回答
1

如果错误

致命:内核太旧

分段故障。

继续。检查主机上运行的 linux 的内核版本以及使用创建的可执行文件所需的支持版本

ldd'可执行文件'

于 2012-12-09T19:33:23.217 回答
0

linux 的可移植性有几个问题。内核 ABI 正在发生变化,库和工具链正在从发行版到发行版以及从发行版到发行版都在变化。

最可靠的方法是在旧系统(或基于旧版本 Linux 的 chroot 环境)上编译代码,因为 Linux 通常向后兼容。

我还建议您阅读文章Portable Linux Binaries

于 2011-11-14T21:59:54.320 回答
0

最后,我解决了它在没有root权限的情况下编译GSL库。我在主目录的一个文件夹中解压缩了源文件,创建了一个 _build 目录,然后运行 ​​../configure,然后 make。

我将在 _build 中创建的 .libs 目录的文件复制到一个新的 ~/path/lib 目录中,并使用:

find -name "*.h" -type f -exec cp {} ~/path/include/gsl \;

复制 GSL 源文件夹中生成的所有头文件(当然有更好的方法)。

然后我尝试为 gcc (C_INCLUDE_PATH, LIBRARY_PATH) 设置环境变量,但由于某种原因我无法保存它们(使用和导出,试图在 ~/profile 和 ~/.bash_profile 文件中更改它们)。

所以,我使用 -I 和 -L gcc 选项来链接这两个文件夹。它以这种方式工作。

于 2011-11-15T20:46:11.980 回答