【问题标题】:Run a C executable in another distro在另一个发行版中运行 C 可执行文件
【发布时间】:2011-11-14 20:24:33
【问题描述】:

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

【问题讨论】:

  • 你能详细说明错误输出的“不起作用”吗?此外,您似乎没有完成以“So can I do something...”开头的句子。
  • 你在看什么来查看 Debian 的版本号?您发布的那个数字似乎与当前发布的任何版本都不对应。
  • 感谢您的回答。我编辑了帖子以纠正错误。我正在查看的 Debian 版本是 gcc -v 的输出版本。
  • more /etc/debian_version 输出 3.1。不是那个版本吗?
  • 最轻松的方法是在虚拟机中安装 Debian 3.1 并在其上编译程序。由于您的 Debian 集群版本和最新的 Ubuntu 版本之间存在如此巨大的差距 - 可能只会有麻烦。另一种选择是以非 root 用户身份在集群上编译/安装 GSL 本身,并针对该 GSL 库在集群上编译您的程序。无论哪种情况,您都可能需要将 GSL 静态链接到您的程序。

标签: c linux gcc cross-platform gsl


【解决方案1】:

我不知道您所面临的不起作用是什么,但我能想到的唯一不涉及交叉编译的就是在您的gcc 线。

【讨论】:

  • 它只是输出一些神秘的“浮点异常”。 hello world 程序也是如此。
  • umm.. 也许你的内核太旧了 :)
  • 当您编译的 glibc 对于您要运行的内核来说太新时,我已经看到“内核太旧”。您很可能在 3.0.x 内核上进行开发并在类似 2.4 内核上运行。请参阅我的答案以了解更多详细信息。
  • 是的,@kbyrd,听起来像这样。不过,看不到您的答案有何帮助,因为据我了解,OP 无法在集群环境中编译。
  • 我的回答很有帮助,因为完全有可能从运行更新的库的系统构建 2.4 和相关 glibc 的二进制文件。这有点像在 x86 系统上交叉编译 ARM 二进制文件。
【解决方案2】:

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

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

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

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

【讨论】:

  • 使用 -static 将错误更改为 FATAL: kernel too old,所以我认为它实际上无法执行。集群使用的处理器是 Intel(R) Pentium(R) 4 CPU 3.20GHz。
  • 请更新您的问题以添加您正在编译的内核和您正在运行的内核。对于 Sarge (Debian 3.1),它可能是 2.4 或 2.6 内核,我相信 Ubuntu 11.10 的默认内核是 3.0。您将不得不构建一个与 Debian 环境足够相似的工具链。解决它有点像交叉编译,就像你在你的 Ubuntu 机器上构建 ARM 二进制文件:-)
【解决方案3】:

如果出错

致命:内核太旧

分段错误。

继续。检查主机上运行的 linux 的内核版本以及使用

创建的可执行文件所需的支持版本

ldd '可执行文件'

【讨论】:

    【解决方案4】:

    在 linux 中存在一些可移植性问题。内核 ABI 正在发生变化,库和工具链正在从发行版到发行版以及从发布版到发布版发生变化。

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

    另外我推荐你阅读文章Portable Linux Binaries

    【讨论】:

      【解决方案5】:

      最后,我解决了在没有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 选项来链接这两个文件夹。它是这样工作的。

      【讨论】:

      • 如果你使用configure--prefix参数会更好,例如:./configure --prefix=/full/path/to/home/gsl。然后你可以发出make install 来在~/gsl 目录中安装所有需要的头文件和库,而不是使用这个花哨的find。获得全面帮助问题./configure --help
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-03
      • 1970-01-01
      • 2010-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多