rust-osdev/cargo-xbuild

error: failed to get bitcode from object file for LTO

toku-sa-n opened this issue ยท 23 comments

Hello. I use cargo xbuild to build my OS. Recently build failed with the following error message.

error: failed to get bitcode from object file for LTO (Bitcode section not found in object file)

My repository is this and cargo_settings.json is specified as the target. You can reproduce this by running make on the master branch. I also tried with phil-opp's .json file, but build failed. The only thing which made it possible to build is to disable lto ( lto = false in Cargo.toml) . cargo clean && cargo xbuild did not solve the problem.
This is my CI history. You can see that the same commit succeeds and fails to build.

I never seen this error before, but it sounds more like a rust/cargo problem. Have you tried updating your nightly?

If it still occurs on the current nightly, it might be worth opening an issue in the https://github.com/rust-lang/rust repository.

I'm currently investigating: this looks to be the culprit rust-lang/cargo#8192.

Compiling with rlib enabled in Cargo.toml works, produces the following rustc flags:

-Cembed-bitcode=no

With rlib removed we get:

-C lto

Manually running rustc with -C lto replaced with -C linker-plugin-lto seems to work okay.

I'll look a bit further but that is what I've figured out so far.

@ascjones Thanks for investigating! I think you're right that this pull request caused it. We should definitely open a cargo issue with an example that reproduces this eror.

It seems like the rusty-hermit project has the same issue: hermit-os/hermit-rs#15, so it might make sense to cc the project developers in the issue.

I created a minimal example to reproduce: https://github.com/toku-sa-n/cargo_bug
cargo xbuild should cause the error.

Thanks for the example @toku-sa-n. By bisecting rustc I found out that this error is caused by rust-lang/rust#71528, which in combination with rust-lang/cargo#8066 results in a more aggressive removal/ of bitcode for crates that have lto disabled. Since we compile the sysroot as a separate crate, this means that it gets compiled without bitcode because we don't have lto enabled for it.

I think the most simple fix is to always enable lto for sysroot builds. I will create a PR in a moment.

I created a fix at #70.

Still failing with cargo-xbuild 0.5.30 and rustc 1.45.0-nightly (9912925c2 2020-05-10). I tried cargo clean && cargo xbuild on my minimum example, but build failed with the same error. Is it better to send a issue on cargo project?

Can confirm I also get the same error with the new version 0.5.30

Seems like I messed something upโ€ฆ I can also still reproduce the error. I'll take a look at it again right now.

Still investigating, but it seems like version 0.5.30 only fixed the breakage between nightlies 2020-04-30 and 2020-05-01. There seems to be another breakage between 2020-05-01 and current nightlies. Starting a new bisect run.

Regression is in rust-lang/rust#71925, so it is likely rust-lang/cargo#8192, as @ascjones suspected. I'm still not sure what the best fix is.

I think I will report this to the xargo project too since it also seems to affect them. Maybe they have an idea how to fix this.

I opened a xargo issue at japaric#292.

I also found one possible fix: Set -Clinker-plugin-lto for the sysroot build via RUSTFLAGS. I will create a PR in a moment. Maybe you can help test it then?

@ascjones @toku-sa-n I created a new PR at #71. Maybe you could try whether it fixes the issue. You can install the new version through:

cargo install cargo-xbuild --git https://github.com/rust-osdev/cargo-xbuild.git --branch embed-bitcode  --debug --force

Thank you. Builds of both the minimum example and my OS succeed.

Great to hear that!

Fixed version released as v0.5.31.

Works! Much appreciated :)

Sorry, very sorry, but the problem seems not to be solved. Actually cargo xbuild succeeded, but the output binary seems to have a defect.
Building my OS did not succeed completely, with ld error:

ld: build/libramen_os.a: error adding symbols: file format not recognized

See CI log

@toku-sa-n It seems like this issue is not related to cargo-xbuild. It also occurs when using cargo's -Z build-std flag instead of cargo-xbuild. Try the following diff:

Click to show the diff
diff --git a/Cargo.toml b/Cargo.toml
index 26cf1bb..d9f1861 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -24,6 +24,7 @@ crate-type = ["staticlib"]
 
 [dependencies]
 spin = "0.5.2"
+rlibc = "1.0.0"
 
 [dependencies.lazy_static]
 version = "1.4.0"
diff --git a/Makefile b/Makefile
index 478ffa6..dd58448 100644
--- a/Makefile
+++ b/Makefile
@@ -45,7 +45,7 @@ endif
 
 release:$(KERNEL_FILE) $(HEAD_FILE) $(LD_SRC)|$(BUILD_DIR)
        make clean
-       $(RUSTCC) xbuild --target-dir $(BUILD_DIR) --release
+       $(RUSTCC) build -Zbuild-std=core,alloc --target-dir $(BUILD_DIR) --release
        cp $(BUILD_DIR)/$(CARGO_JSON)/$@/$(shell basename $(LIB_FILE))  $(LIB_FILE)
        make
 
@@ -53,7 +53,7 @@ $(KERNEL_FILE):$(LIB_FILE) $(LD_SRC)|$(BUILD_DIR)
        $(LD) $(LDFLAGS) -o $@ $<
 
 $(LIB_FILE): $(addprefix $(RUST_SRC_DIR)/, $(RUST_SRC))|$(BUILD_DIR)
-       $(RUSTCC) xbuild --target-dir $(BUILD_DIR)
+       $(RUSTCC) build -Zbuild-std=core,alloc --target-dir $(BUILD_DIR)
        cp $(BUILD_DIR)/$(CARGO_JSON)/debug/$(shell basename $(LIB_FILE)) $@
 
 $(HEAD_FILE):$(HEAD_DEPENDS)
diff --git a/src/lib.rs b/src/lib.rs
index c67ceee..f817450 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -3,6 +3,8 @@
 #![feature(start)]
 #![feature(naked_functions)]
 
+extern crate rlibc;
+
 mod asm;
 mod descriptor_table;
 mod interrupt;

So this isn't something that we can fix in the cargo-xbuild tool. I recommend creating a minimal example that uses -Z build-std instead of cargo-xbuild and then report it in the rust-lang/rust or rust-lang/cargo repository directly.

I see. Anyway, thank you for telling me.

I ran a bisect for your project with the above diff applied and the "file format not recognized" also appears with rust-lang/rust@63d0377.

The discussion in japaric#292 showed that rustc bootstrap passes -Cembed-bitcode=yes instead of -Clinker-plugin-lto. I created #73 to switch cargo-xbuild to the same approach.