Rust在Linux上无法编译成可执行文件

4

在Linux上使用 rustccargo build 编译Rust代码会生成共享库而不是可执行文件。
我的文件管理器(thunar)和 file 命令显示该文件类型为共享库。

编译后的二进制文件只能通过终端运行 $ /path/to/file$ cargo run 来执行。
与其他可执行文件不同,该文件不能通过双击来执行。
file 命令的输出:

$ file rust_bin

rust_bin: ELF 64位 LSB共享目标文件,x86_64,版本1(SYSV),动态链接,解释器/lib64/ld-linux-x86-64.so.2,适用于GNU/Linux3.2.0,BuildID [sha1]=cb8cd...,具有调试信息,未剥离`


4
请展示您正在运行的确切命令以及它们产生的确切消息。 - n. m.
3个回答

12
  1. 你的编译器生成一个可执行文件,共享库和动态链接的可执行文件之间没有太大的区别,它们遵循相同的基本格式。字符串interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0表明这是一个可执行文件而不是库文件。库通常不会设置解释器。尝试对一些已知为可执行文件的文件以及一些已知为库的文件运行file命令,亲自查看。解释器通常是一个加载和执行共享对象的小型系统程序。实际上,一个文件可以同时作为库和可执行文件(最常见的例子是你系统中的libc.so.6或其它名称的文件;尝试运行它)。
  2. 如果你可以从shell中运行该可执行文件但无法从文件管理器中运行,则问题出现在文件管理器上,而不是可执行文件上。你可能需要特别指示文件管理器在终端中运行你的程序。通常可以通过创建一个描述你的程序的.desktop文件来完成此操作。此外,桌面工具可能会错误地将现代可执行文件识别为共享库。是一个常见问题。这也可以通过为你的可执行文件创建一个.desktop文件来解决。这与Rust无关。

归根结底,rustccargo以及您运行它们的方式并没有问题。


1
它是可执行的,可以在终端中执行./file,但不能从文件管理器(thunar xfce4)中执行,似乎文件管理器无法识别共享库并像其他可执行文件一样执行它们,只能从文件管理器中执行并从file命令产生相同的输出。我在launchpad.net上找到了相关内容Shared libraries not being executed by file mamagers - AVX-42
@Amiy "似乎文件管理器没有识别共享库"。不,这里并不是发生了这种情况。该文件是一个可执行文件,而不是共享库。错误报告谈论的是GUI中的错误/配置错误。它认为该文件是共享库,但实际上并不是。与rustc无关。 - n. m.
@Amiy 看起来这是一个常见的 bug。在我的机器上,我无法从文件管理器运行 任何 可执行文件。我从来不使用文件管理器,所以我不会自己发现它。 - n. m.
RUSTFLAGS="-C relocation-model=dynamic-no-pic link-args=-no-pie" cargo build 会生成一个可执行文件。对于gcc,使用 gcc -no-pie src.c。我通常使用vim或nano,但今天我尝试从文件管理器执行它时失败了。我认为如果我将二进制文件交给别人,他们将无法在没有打开终端的情况下执行它。这也发生在使用GCC编译的程序中,无论我是否使用 -no-pie 选项。因此,问题出现在GUI文件管理器中。 - AVX-42
@Amiy 如果你把你的程序交给别人使用,并且期望他们使用GUI界面,那么你应该提供一个.desktop文件和一个图标。 - n. m.

1
当你初始创建项目时,可以简单地使用 cargo new(或 init)来获取正确的类型。
cargo new my_project_name
# OR create a lib project
cargo new --lib my_library_name

使用rustc时,您可以使用命令行选项。
rustc lib.rs
# lib.rs has to contain a main function
# OR to build a lib
rustc --crate-type=lib lib.rs

你对共享对象的发现误导了你的错误查找:https://askubuntu.com/questions/690631/executables-vs-shared-objects - 这不是问题,可执行文件可以是共享对象。
我认为在你的情况下问题是另外一个。你的二进制文件做什么?它只是通过stdout打印一些东西吗?也许这就是为什么在GUI文件浏览器中双击不会显示任何东西的原因,它运行了一毫秒,然后就结束了,你还没来得及看到。
你尝试过在主函数结束时等待输入吗?这样用户就可以阅读输出并按回车键。
use std::io;
fn main() {
    // do and print stuff

    // Wait for return key
    let mut input = String::new();
    match io::stdin().read_line(&mut input);
}

我不确定Thunar将如何处理它,但最终他会打开一个终端并显示结果,在按下回车键时关闭终端。


-1
cargo build

在目标路径 target/debug/rust_bin 中创建一个可执行文件

然后就可以了

./target/debug/hello_cargo # or .\target\debug\hello_cargo.exe on Windows

执行,或者只是

cargo run

PS:你需要创建一个包含适当数据的Cargo.toml文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接