7
votes

Having some trouble getting Rust to link to the core library on OS X targeting i686-unknown-linux-gnu:

MacBook:rustboot alex$ make
rustc -O --target i686-unknown-linux-gnu --crate-type lib -o main.o --emit obj main.rs
main.rs:5:1: 5:19 error: can't find crate for `core`
main.rs:5 extern crate core;
          ^~~~~~~~~~~~~~~~~~
error: aborting due to previous error
make: *** [main.o] Error 101

main.rs looks like this:

#![no_std]
#![allow(ctypes)]
#![feature(lang_items)]

extern crate core;
use core::prelude::*;

#[no_mangle]
#[no_split_stack]
pub fn main() {
}

I suspect it is because I am trying to link to i686-unknown-linux-gnu but the core library doesn't exist for that platform. How do you install or build the libraries for that platform?

1
To be clear, you are deliberately trying to cross compile from OS X to Linux? - Shepmaster
I'm trying to cross compile to write my own toy kernel, based on the code here: github.com/charliesome/rustboot I'm trying to get libcore to compile. The code above is the minimal code that highlights the problem. I'm going to try building from source with ./configure --target=i686-unknown-linux-gnu - zander

1 Answers

13
votes

This is caused by the core library not existing for the platform you're targeting. There's a few ways one might acquire it:

  • use rustup — rustup target add i686-unknown-gnu-linux should do the trick
  • get cargo to do all the hard work by adding core-nightly to your Cargo.toml, and use cargo build --target=.... Unfortunately it seems it hasn't been updated for a while, but one can make a local package by copying src/libcore out of the Rust repo, adding a Cargo.toml and using a path dependency; in future, it is likely to be provided officially through crates.io too, but I have no idea how far away this is.
  • download a Rust build for your desired target (e.g. the corresponding nightly to the one you have installed), extract the lib/rustlib/ directory somewhere either automatically searched (~/.multirust/toolchains/nightly-2015-01-18/lib/rustlib), or anywhere and pass an -L flag to the compiler (I'm not 100% sure on the precise place the -L flag should point to, though).
  • cross-compile Rust itself: checkout the repo, ./configure --target=$yourtarget and then make should build you a compiler that can run on your current computer, but also create binaries that run on your desired target
  • do manual cross-compilation of the crates you need, e.g. zinc.rs uses a Rakefile that builds everything they want

The cargo route is definitely the easiest at the moment. The cross-compiling story will definitely get easier in future, e.g. making multirust do all the complicated bits for the third possibility. However, both the third and fourth ways rely on being able to build std for your platform, which seems unlikely for kernel work.

(BTW, the rlibc crate is useful/necessary for kernel work too.)