thepowersgang / mrustc

Alternative rust compiler (re-implementation)
MIT License
2.11k stars 106 forks source link

Problem to build with #![no_std] #328

Open Ott-cop opened 3 months ago

Ott-cop commented 3 months ago

Hello everybody!

Recently I was testing mrustc to compile using no_std and then I came across the following error:

$ ./minicargo -L /home/ox4/Development/Software/mrustc/output /home/ox4/Development/Programming/mr-tester
--- BUILDING mr-tester v0.1.0 (0.0% 1r,0w,0b/1t)
> /home/ox4/Development/Software/mrustc/bin/mrustc /home/ox4/Development/Programming/mr-tester/src/main.rs -o output/mr_tester -C emit-depfile=output/mr_tester.d --cfg debug_assertions -O -L /home/ox4/Development/Software/mrustc/output -L output --crate-name mr_tester --crate-type bin --crate-tag 0_1_0 > output/mr_tester_dbg.txt
 (0.0% 1r,0w,0b/1t): mr-tester v0.1.0
/home/ox4/Development/Programming/mr-tester/src/main.rs:11:32-45 error:0:Couldn't find path component 'ffi' of crate::core::ffi::c_int/*?*/
Process was terminated with signal 6
FAILING COMMAND: /home/ox4/Development/Software/mrustc/bin/mrustc /home/ox4/Development/Programming/mr-tester/src/main.rs -o output/mr_tester -C emit-depfile=output/mr_tester.d --cfg debug_assertions -O -L /home/ox4/Development/Software/mrustc/output -L output --crate-name mr_tester --crate-type bin --crate-tag 0_1_0
Env:  OUT_DIR=/home/ox4/Development/Software/mrustc/bin/output/build_mr-tester-0_1_0 CARGO_MANIFEST_DIR=/home/ox4/Development/Programming/mr-tester CARGO_PKG_NAME=mr-tester CARGO_PKG_VERSION=0.1.0 CARGO_PKG_VERSION_MAJOR=0 CARGO_PKG_VERSION_MINOR=1 CARGO_PKG_VERSION_PATCH=0
 (100.0% 0r,0w,0b/1t):
BUILD FAILED


I tested some other possible solutions, but so far nothing. So I would like to report this error, and perhaps receive a possible solution.


Specs:

OS: Debian GNU/Linux 12 (bookworm) x86_64
Kernel: 6.1.0-18-amd64
DE: GNOME 43.9
CPU: 13th Gen Intel i5-13450HX (16) @ 4.600GHz
GPU: Intel Raptor Lake-S UHD Graphics
GPU: NVIDIA GeForce RTX 3050 6GB Laptop GPU
Memory: 15676Mi


Thanks!

bjorn3 commented 3 months ago

core::ffi only exists since rust 1.30 and core::ffi::c_int since rust 1.64. I believe mrustc defaults to rust 1.29 and currently only supports up to rust 1.54. It looks like the rust_1.74 branch has work in progress rust 1.74 support but I don't know how complete it is.

Ott-cop commented 3 months ago

Hello @bjorn3.

Thanks for answering!

For use in no_std, in which it requires the main(int, const char **), what would be the way to make this return? The study test would be for use in powering gcc for a specific embedded target where Rust would not be natively supported. Could you do this using mrustc, or is there another better method?

I appreciate the help!

thepowersgang commented 3 months ago

You could just be lazy and use i32 - or include libc (which has been an internal dependency of std for ages)

Ott-cop commented 3 months ago

Thanks for answering @thepowersgang!

It worked perfectly like here, but then the following error appeared:

minicargo -L ~/Development/Software/mrustc/output --vendor-dir /home/ox4/Development/Programming/mr-tester/vendor/libc .
--- BUILDING mr-tester v0.1.0 (0.0% 1r,0w,0b/1t)
> /home/ox4/Development/Software/mrustc/bin/mrustc ./src/main.rs -o output/mr_tester -C emit-depfile=output/mr_tester.d --cfg debug_assertions -O -L /home/ox4/Development/Software/mrustc/output -L output --crate-name mr_tester --crate-type bin --crate-tag 0_1_0 --extern libc=output/liblibc-0_1_12_H1.rlib > output/mr_tester_dbg.txt
 (0.0% 1r,0w,0b/1t): mr-tester v0.1.0
:0:0 error:0:Conflicting definitions of lang item 'mrustc-alloc_error_handler'. ::"std-0_0_0"::alloc::rust_oom and ::"bin#"::rust_oom
Process was terminated with signal 6
FAILING COMMAND: /home/ox4/Development/Software/mrustc/bin/mrustc ./src/main.rs -o output/mr_tester -C emit-depfile=output/mr_tester.d --cfg debug_assertions -O -L /home/ox4/Development/Software/mrustc/output -L output --crate-name mr_tester --crate-type bin --crate-tag 0_1_0 --extern libc=output/liblibc-0_1_12_H1.rlib
Env:  OUT_DIR=/home/ox4/Development/Programming/mr-tester/output/build_mr-tester-0_1_0 CARGO_MANIFEST_DIR=/home/ox4/Development/Programming/mr-tester CARGO_PKG_NAME=mr-tester CARGO_PKG_VERSION=0.1.0 CARGO_PKG_VERSION_MAJOR=0 CARGO_PKG_VERSION_MINOR=1 CARGO_PKG_VERSION_PATCH=0
 (100.0% 0r,0w,0b/1t):
BUILD FAILED

I carried out other tests on this, but without success either. Is there any material to base myself on for this purpose? If so, it will be of great help!

Thanks!

thepowersgang commented 3 months ago

That looks like you have a function tagged with alloc_error_handler, but std has its own of those - hence the conflict. I don't know about rustc, but mrustc doesn't support overriding the OOM handler.

bjorn3 commented 3 months ago

#![no_std] should prevent libstd from being used.

Ott-cop commented 3 months ago

Thanks for the answers!

So, but then another problem would arise... I removed the panic handlers and alloc errors, and then the specific error disappeared. But then another problem appeared, which I believe is correct in relation to type transformation

Error:

$ minicargo -L ~/Development/Software/mrustc/output --vendor-dir /home/ox4/Development/Programming/mr-tester/vendor/libc .
--- BUILDING mr-tester v0.1.0 (0.0% 1r,0w,0b/1t)
> /home/ox4/Development/Software/mrustc/bin/mrustc ./src/main.rs -o output/mr_tester -C emit-depfile=output/mr_tester.d --cfg debug_assertions -O -L /home/ox4/Development/Software/mrustc/output -L output --crate-name mr_tester --crate-type bin --crate-tag 0_1_0 --extern libc=output/liblibc-0_1_12_H1.rlib > output/mr_tester_dbg.txt
 (0.0% 1r,0w,0b/1t): mr-tester v0.1.0
output/mr_tester.c:161:5: error: conflicting types for ‘main’; have ‘int(int,  const char **)’
  161 | int main(int argc, const char* argv[]) {
      |     ^~~~
output/mr_tester.c:143:27: note: previous definition of ‘main’ with type ‘int32_t(int32_t,  int8_t **)’ {aka ‘int(int,  signed char **)’}
  143 | #define ZRG1cD3bin4main0g main
      |                           ^~~~
output/mr_tester.c:150:10: note: in expansion of macro ‘ZRG1cD3bin4main0g’
  150 | int32_t  ZRG1cD3bin4main0g(
      |          ^~~~~~~~~~~~~~~~~
C Compiler failed to execute - error code 256
Process exited with non-zero exit status 1
FAILING COMMAND: /home/ox4/Development/Software/mrustc/bin/mrustc ./src/main.rs -o output/mr_tester -C emit-depfile=output/mr_tester.d --cfg debug_assertions -O -L /home/ox4/Development/Software/mrustc/output -L output --crate-name mr_tester --crate-type bin --crate-tag 0_1_0 --extern libc=output/liblibc-0_1_12_H1.rlib
Env:  OUT_DIR=/home/ox4/Development/Programming/mr-tester/output/build_mr-tester-0_1_0 CARGO_MANIFEST_DIR=/home/ox4/Development/Programming/mr-tester CARGO_PKG_NAME=mr-tester CARGO_PKG_VERSION=0.1.0 CARGO_PKG_VERSION_MAJOR=0 CARGO_PKG_VERSION_MINOR=1 CARGO_PKG_VERSION_PATCH=0
 (100.0% 0r,0w,0b/1t):
BUILD FAILED

Code:

#![feature(start)]
#![no_std]
#![no_main]

#[start]
#[no_mangle]
pub extern "C" fn main(_: libc::c_int, _: *const *const libc::c_char) -> libc::c_int {
    return 0;
}

This code was supposed to work, correct?

I really appreciate your help, thank you!

thepowersgang commented 3 months ago

That's just a disagreement between mrustc's generated main and your no_mangle main Does that code work without #[no_mangle] with rustc?

Ott-cop commented 3 months ago

Hello @thepowersgang

Thanks for the answer!

Sorry for the delay, I've been very busy these days...

I was able to compile it by removing the #[no_mangle], now it compiles perfectly!

Just one detail, to feed via another gcc, would it be just using the generated .c file? Or would there be some other dependency generated in the output folder?

I thank the help of all you!

thepowersgang commented 2 months ago

The gcc arguments for each .c file is in a _cmd.txt file- this includes all of the dependencies required to compile that file (which, if it's an executable, would include all of the other objects needed)

Ott-cop commented 2 months ago

Thanks for the answer @thepowersgang.

Now it is much clearer about how mrustc works. I would like to congratulate you for your work!

Just one more question, is there any way to generate C code without previously compiling it?

I would compile it with another gcc for another architecture...

Thanks and again, great job!

thepowersgang commented 2 months ago

mrustc has basic support for cross-compiling - or you could set CC=true to just not run a C compiler