How to produce executable with rustc?

2020-05-07 06:36发布

If I compile this simple program fn main() { println!("Hello"); } with rustc test.rs -o test then I can run it with ./test, but double clicking it in the file manager gives this error: Could not display "test". There is no application installed for "shared library" file. Running file test seems to agree: test: ELF 64-bit LSB shared object....

How can I get rustc, and also tools that use it such as cargo, to produce executables rather than shared objects?

I am using 64-bit Linux (Ubuntu 14.10).

EDIT: I have posted on the Rust forum about this.

EDIT@: So it turns out this is an issue with the file executable.

标签: rust
2条回答
Lonely孤独者°
2楼-- · 2020-05-07 06:55

What you have described is not entirely consistent with what I observe:

$ rustc - -o test <<< 'fn main() { println!("Hello"); }' 
$ ./test
Hello
$ file test
test: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=99e97fcdc41eb2d36c950b8b6794816b05cf854c, not stripped

Unless you tell rustc to produce a library with e.g. #![crate_type = "lib"] or --crate-type lib, it will produce an executable.

It sounds like your file manager may be being too smart for its own good. It should just be trusting the executable bit and executing it.

查看更多
做自己的国王
3楼-- · 2020-05-07 06:56

I don't have the rust compiler and can't find its docs on the internet, but I know how to do shared obkect vs executable in C, so maybe this info will help you out in solving it.

The difference is the -pie option to the linker. With a hello world C program:

$ gcc test.c -ohello -fPIC -pie
$ file hello
hello: ELF 64-bit LSB  shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), not stripped

If we remove the position-independent flags, we get an executable:

$ gcc test.c -ohello
$ file hello
hello: ELF 64-bit LSB  executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), not stripped

Both generated files work the same way from the command line, but I suspect the difference file sees is changing what your GUI does. (Again, I'm not on Ubuntu... I use Slackware without a gui file manager, so I can't confirm myself, but I hope my guesses will help you finish solving the problem yourself.)

So, what I'd try next if I was on your computer would be to check the rustc man page or rustc --help and see if there's an option to turn off that -pie option to the linker. It stands for "position independent executable", so look for those words in the help file too.

If it isn't mentioned, try rustc -v test.rs -o test - or whatever the verbose flag is in the help file. That should print out the command it uses to link at the end. It'll probably be a call to gcc or ld. You can use that to link it yourself (there's probably a flag -c or something that you can pass to rustc to tell it to compile only, do not link, which will leave just the .o file it generates).

Once you have that, just copy/paste the final link command rustc called and remove the -pie option yourself.... if it is there... and see what happens.

Manually copy/pasting isn't fun to do and won't work with tools, but if you can get it to work at least once, you can confirm my hunch and maybe ask a differently worded question to get more rust users' attention.

You might also be able to tell the file manager how to open the shared object files and just use them. If the manager treated them the same as programs file identifies as executables, as the command line does, everything should work without changing the build process. I don't know how to do that though, but maybe asking on the ubuntu stack exchange will find someone who does.

查看更多
登录 后发表回答