我正在通过使用 ssh 连接到 Linux 终端来远程工作。我连接的机器是 64 位 x86 Linux 机器。我的电脑也是带有 x86 处理器的 64 位 Ubuntu 机器。
我需要提交使用 gcc 编译并在远程机器上运行的程序作业,否则将不予评分。教授提到,gcc 在不同的机器上编译程序的方式可能不同,并且 C 不像 Java 那样完全可移植。
我的问题是,我可以在 gedit 中编写程序,然后在计算机上使用 gdb 进行调试,然后使用 scp 上传它们吗(如果我通过 ssh 进入远程 unix 终端进行工作,我只能使用 nano/pico/vim)?或者我的计算机的编译方式与远程计算机不同吗?同样,它们都是 x86 64 位 Linux 计算机。
答案1
如果您提交二进制文件(如果您必须这样做我会感到惊讶),它就会起作用(因为您提到两台机器的架构相同),很有可能,除非安装的库存在差异并且您最终实际上使用了其中的一些。
但假设您只需提交源代码,您的代码将在远程服务器上编译。这意味着只要您不使用系统上存在的某些特定库,您的程序就会在远程服务器上编译和运行。但如果您最终使用了这样的库,您可以指定链接标志(在您的 Makefile 中或在提交时明确提及它)。
答案2
正如@rhn-grg 指出的那样,如果两台机器具有相同的处理器架构,那么可能阻止您的二进制文件在另一台机器上运行的唯一区别就是您的二进制文件所链接的库 - 默认情况下二进制文件是链接的,因此它们会动态加载库,这允许保持二进制文件较小并且还允许更有效地使用RAM,因为库只需加载一次但可以被多个进程使用。
但是,在需要确保二进制文件的“可移植性”的情况下,您可以告诉它gcc
静态链接二进制文件 - 即将其使用的所有库都包含到二进制文件中 - 这将产生一个相当大的二进制文件,但它不会依赖于任何外部库。
我从来没有需要这样做,但是,现在当你知道了魔法词(静态链接,可移植二进制)时,你可以在 Google 中找到很多建议,例如这:
通常,当您下载源代码的 tarball 时,您将执行标准的“configure; make; make install”来构建它。如果您想要静态链接的二进制文件,请将普通的“make”替换为:
make SHARED=0 CC='gcc -static'
要查看二进制文件所依赖的库,可以使用ldd
命令:
$ ldd /bin/bash
linux-vdso.so.1 => (0x00007fff6dbff000)
libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007f8e37337000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f8e37133000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8e36d75000)
/lib64/ld-linux-x86-64.so.2 (0x00007f8e37587000)
答案3
您的教授可能暗示的问题是 C 中各种类型的大小与平台相关。例如,long
如果变量是为x86-64
Linux 系统编译的,那么与为 Linux 编译的变量相比,您可以在变量中存储更大的数字i386
。对于正确的程序来说,这不是问题,但是如果您有一个程序交替使用int
和long
,它可能在 64 位系统上运行良好,i386
但在 64 位系统上运行时会失败。
相比之下,Java 在所有平台上对基本类型使用相同的大小,因此避免了这类可移植性问题。
如果您的开发系统和远程系统都是x86-64
Linux,那么您不应该遇到任何此类差异。您在本地编写和调试程序应该不会遇到任何问题。
考虑到这一点,如果根据程序在远程系统上的表现对您进行评分,那么在远程系统上测试您的完成的程序是值得的。