hackndev / zinc

The bare metal stack for rust
zinc.rs
Apache License 2.0
1k stars 100 forks source link

Cargo Build System + Nightly Updates #285

Closed mcoffin closed 9 years ago

mcoffin commented 9 years ago

Don't pull this directly as it has a TON of stupidly small commits. I'll squash them when we deem it ready. Done.

This uses cargo to do most of the heavy lifting as far as the compilation of rust (and even the final linking). I tried to make it a lot less of a fully custom build system and more of a small Makefile built on top of cargo to get us the last few steps of the way.

I also fixed a lot of the fallout from rust updates on nightly, some of which were easier than others.

Most notably: this also means that people can create their own cargo projects and just list zinc, platformtree, etc as dependencies.

mcoffin commented 9 years ago

@posborne If you could give the blink_pt demo a shot on hardware that would be cool, just to make sure it works and doesn't just build something really broken.

I'll work on getting travis working again.

mcoffin commented 9 years ago

Ok, I'm done screwing around with travis, it should work now but is being prevented from passing due to an upstream bug in Cargo rust-lang/cargo#1612. alexcrichton made a fix for it that works, so we'll just have to wait for that to get pulled in. If you actually go examine the travis builds though, all of the tests do pass, for what it's worth.

posborne commented 9 years ago

@mcoffin, blink_pt is working on my device. A few notes:

$ arm-none-eabi-gcc --version 
arm-none-eabi-gcc (4.8.2-14ubuntu1+6) 4.8.2
...
$ PLATFORM=lpc17xx EXAMPLE_NAME=blink_pt make build
...
     Running `rustc examples/app_blink_pt.rs --crate-name blink_pt --crate-type bin -C opt-level=3 -C link-args=-mthumb -mcpu=cortex-m3 -Tsrc/hal/lpc17xx/layout.ld -lm -lgcc target/thumbv7m-none-eabi/release/isr.o --out-dir /home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/examples --emit=dep-info,link --target thumbv7m-none-eabi -L dependency=/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release -L dependency=/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/deps --extern rlibc=/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/deps/librlibc-3bf401f130e6242e.rlib --extern macro_platformtree=/home/posborne/Projects/rust-playground/zinc/target/release/deps/libmacro_platformtree-910568f0144e0a0e.so --extern ioreg=/home/posborne/Projects/rust-playground/zinc/target/release/deps/libioreg-96ac4d6d8a63fad3.so --extern platformtree=/home/posborne/Projects/rust-playground/zinc/target/release/deps/libplatformtree-71e21833f185c068.so --extern zinc=/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/libzinc.rlib`
error: linking with `arm-none-eabi-gcc` failed: exit code: 1
note: "arm-none-eabi-gcc" "-L" "/usr/local/lib/rustlib/thumbv7m-none-eabi/lib" "-o" "/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/examples/blink_pt" "/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/examples/blink_pt.o" "-Wl,--gc-sections" "-Wl,-O1" "-nodefaultlibs" "/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/libzinc.rlib" "/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/deps/librlibc-3bf401f130e6242e.rlib" "/usr/local/lib/rustlib/thumbv7m-none-eabi/lib/libcore.rlib" "-L" "/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release" "-L" "/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/deps" "-L" "/usr/local/lib/rustlib/thumbv7m-none-eabi/lib" "-L" "/home/posborne/Projects/rust-playground/zinc/.rust/lib/thumbv7m-none-eabi" "-L" "/home/posborne/Projects/rust-playground/zinc/lib/thumbv7m-none-eabi" "-Wl,--whole-archive" "-Wl,-Bstatic" "-Wl,--no-whole-archive" "-Wl,-Bdynamic" "-mthumb" "-mcpu=cortex-m3" "-Tsrc/hal/lpc17xx/layout.ld" "-lm" "-lgcc" "target/thumbv7m-none-eabi/release/isr.o"
note: /usr/lib/gcc/arm-none-eabi/4.8.2/armv7-m/libgcc.a(unwind-arm.o): In function `__aeabi_unwind_cpp_pr0':
/build/buildd/gcc-arm-none-eabi-6/build/arm-none-eabi/armv7-m/libgcc/../../../../gcc-4.8.2/libgcc/config/arm/unwind-arm.c:494: multiple definition of `__aeabi_unwind_cpp_pr0'
/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/libzinc.rlib(zinc.o):zinc.0.rs:(.text.__aeabi_unwind_cpp_pr0+0x0): first defined here
collect2: error: ld returned 1 exit status

error: aborting due to previous error
Could not compile `zinc`.

Caused by:
  Process didn't exit successfully: `rustc examples/app_blink_pt.rs --crate-name blink_pt --crate-type bin -C opt-level=3 -C link-args=-mthumb -mcpu=cortex-m3 -Tsrc/hal/lpc17xx/layout.ld -lm -lgcc target/thumbv7m-none-eabi/release/isr.o --out-dir /home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/examples --emit=dep-info,link --target thumbv7m-none-eabi -L dependency=/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release -L dependency=/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/deps --extern rlibc=/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/deps/librlibc-3bf401f130e6242e.rlib --extern macro_platformtree=/home/posborne/Projects/rust-playground/zinc/target/release/deps/libmacro_platformtree-910568f0144e0a0e.so --extern ioreg=/home/posborne/Projects/rust-playground/zinc/target/release/deps/libioreg-96ac4d6d8a63fad3.so --extern platformtree=/home/posborne/Projects/rust-playground/zinc/target/release/deps/libplatformtree-71e21833f185c068.so --extern zinc=/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/libzinc.rlib` (exit code: 101)

I can manually build by reordering the arguments to gcc to have all object files at the end, like this...

"arm-none-eabi-gcc" \
  "-L" "/usr/local/lib/rustlib/thumbv7m-none-eabi/lib" \
  "-o" "/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/examples/blink_pt" \
  "-Wl,--gc-sections" "-Wl,-O1" "-nodefaultlibs" \
  "-L" "/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release" \
  "-L" "/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/deps" \
  "-L" "/usr/local/lib/rustlib/thumbv7m-none-eabi/lib" \
  "-L" "/home/posborne/Projects/rust-playground/zinc/.rust/lib/thumbv7m-none-eabi" \
  "-L" "/home/posborne/Projects/rust-playground/zinc/lib/thumbv7m-none-eabi" \
  "-Wl,--whole-archive" "-Wl,-Bstatic" "-Wl,--no-whole-archive" \
  "-Wl,-Bdynamic" "-mthumb" "-mcpu=cortex-m3" \
  "-Tsrc/hal/lpc17xx/layout.ld" "-lm" "-lgcc" \
  "/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/examples/blink_pt.o" \
  "target/thumbv7m-none-eabi/release/isr.o" \
  "/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/libzinc.rlib" \
  "/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/deps/librlibc-3bf401f130e6242e.rlib" \
  "/usr/local/lib/rustlib/thumbv7m-none-eabi/lib/libcore.rlib"
farcaller commented 9 years ago

Whoa, that's one big diff! I'll take a closer look on Monday, so far it looks a different approach that I tried with multi-crate system and it also looks more manageable.

mcoffin commented 9 years ago

If anybody else is getting that linking error, I can't even reproduce it in a VM yet so it's hard to debug. More info would be appreciated.

EDIT: Travis-CI should report all is good once rust-lang/cargo#1617 lands in cargo-nightly (and therefore in travis builds)

posborne commented 9 years ago

@mcoffin, thanks for taking a look. I'll take a deeper look and see if I can determine the root cause.

posborne commented 9 years ago

Ok, so it appears that I had previously left a key piece of information out of what I had snipped...

note: /usr/bin/../lib/gcc/arm-none-eabi/4.9.3/armv7-m/libgcc.a(unwind-arm.o): In function `__aeabi_unwind_cpp_pr0':
unwind-arm.c:(.text+0x7a4): multiple definition of `__aeabi_unwind_cpp_pr0'
/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/libzinc.rlib(zinc.o):zinc.0.rs:(.text.__aeabi_unwind_cpp_pr0+0x0): first defined here
collect2: error: ld returned 1 exit status

So, the link step is failing as __aeabi_unwind_cpp_pr0 is defined in both zinc.rlib (from src/util/support.rs) as well as my libgcc. When I removed -lgcc from the link arguments, the compilation succeeded. I am using gcc 4.9.3.

mcoffin commented 9 years ago

Interestingly enough, my libgcc also defines

000007c4 T __aeabi_unwind_cpp_pr0

So I'll have to see why I'm not getting that error.

What versions of rustc / cargo are you running?

posborne commented 9 years ago

What versions of rustc / cargo are you running?

I'm using rustc 1.0.0 and cargo from Alex's branch to fix the issue you reported. I believe I saw the same problem with cargo nightly, but I can retest this evening. I also tried using gcc 4.8 last night and saw the same results.

I am running Ubuntu 14.04 LTS on that machine. The 4.8 toolchain is from the standard repos and the 4.9 toolchain is from https://launchpad.net/~terry.guo/+archive/ubuntu/gcc-arm-embedded, which is the same PPA used by travis.

mcoffin commented 9 years ago

For reference, here is @posborne 's example of a completely external project using zinc as a dependency (yay cargo!).

mcoffin commented 9 years ago

@farcaller By the way, now that we have an external project working that uses this as a dependency, all the huge changes here should stabilize if you want to start reviewing. I guess I opened a little bit early.

bharrisau commented 9 years ago

@farcaller can you fork bharrisau/rust-libcore into hackndev as part of this PR. Also need a rlib too, @mcoffin is there a reason you forked your own instead of bharrisau/rust-librlibc? I've included libcore in the cargo deps for mine (as it is technically required).

bharrisau commented 9 years ago

Just a suggestion, but can we have a build.sh script instead of having autotools as a dep? That also allows for a build.bat for windows users if need be. At the end of the day, we are only covering 3 things:

Could we even just document these three command invokations and remove the autotools, or am I missing something?

bharrisau commented 9 years ago

LGTM

bharrisau commented 9 years ago

On the #start stuff again - main should be where the end user code goes. All the initialisation should be in #start, so platform tree should eventually be the one to handle it. I have to admit that I haven't looked at PT much, but if that is the unit that says 'for device X, and requested peripherals Y, I will initialise everything and hand them over to user code', then I think it is a great idea.

mcoffin commented 9 years ago

@bharrisau

Autotools

The autotools script is there for two purposes currently:

  1. Mapping between PLATFORMs and their respective rustc targets.
  2. Finding the cross toolchain

We could always remove the autotools script, and move the responsibility for that first purpose into the Makefile, but I didn't do it because then the user would have to patch the Makefile with their toolchain information again, and I think it feels more slick and standard to just run a ./configure. Keep in mind that this only has to be done to build the examples... Any dependents of zinc would define their own way to find a cross toolchain.

Spacing

Agh. I just realized how much this is scattered everywhere. The official rust style guide recommends 4 spaces... maybe we should consider converting the project rather than the commit to follow the standard? If not I can go through and convert my work to 2 space indentation.

Start

I agree that the user shouldn't have to actually write the #[start] method. Fortunately, I think it would be a perfect candidate for being emitted by platformtree, which would allow it to be kept out of the zinc crate and we avoid opening up that whole can of worms.

For non-platformtree consumers, we might want to just provide a dummy zinc_start! macro or something similar to provide the boilerplate code.

rlibc Fork

I did this because I had originally been building libcore out of tree (which meant I was using the crates.io version of rlibc). When I moved libcore building back in to the project, I forgot someone had already done it. It looks like you might be a little bit behind upstream changes too (my fork too, strangely enough).

I really really want to get rid of the manual dependency on libcore, but I just don't see a good way to go about it just yet.

bharrisau commented 9 years ago

Re: spacing. I've always been easy on 2 vs 4, as long as we stick to one type (my vim defaults to 4 spaces, but I just override it for zinc projects). I think last I talked to @farcaller he was amenable to moving to 4 spaces, but only if someone else did it (waiting for a rustfmt like utility). I'm not sure what his current thinking is.

Ok, I'm fine with autotools. If build.sh can map from PLATFORM to target that would be prefered.

Yep, let's keep it simple and deal with #start later.

mcoffin commented 9 years ago

Fixed the spacing issues. I'll squash things in some meaningful way once I get the go-ahead.

posborne commented 9 years ago

On spacing, I too would be interested in seeing the move to 4-spaces. The emacs mode for rust also (and rightly) defaults to 4-space indentation now that this is part of the style guide. I wouldn't gate this PR on it, however but might be nice to merge before we have too many people spun up on Zinc again (I'm ignoring other open PRs as this change will break most of them anyway).

This does seem to be undergoing active development. Might not work for zinc with all of the stuff we do with syntax extensions, but could be worth a shot: https://github.com/nrc/rustfmt

mcoffin commented 9 years ago

Honestly, I'm going to play with it a little bit tomorrow, but there's only a few things that break with just using rust.vim and doing a good old

gg=G

One of them is quoting in syntax extensions... and the other is when you have a newline immediately before the return value of a function. It's enough that I don't want to deal with it though.

farcaller commented 9 years ago

First of all, thanks for keeping up this talk active. I am sorry for not paying much attention, I am stuck with family issues I need to solve.

Autotools

I think it's reasonable to use them here. They are more standard and expected to work fine on all the *nix variants.

Spacing

Now that rust style guide is settling down we can refactor all the code to follow. I don't like project-scale formatting refactoring as git blame becomes useless, but we break enough of zinc now to not care much I guess.

@farcaller can you fork bharrisau/rust-libcore into hackndev as part of this PR. Also need a rlib too

Done

bharrisau commented 9 years ago

Let's deal with spacing in a different PR. @mcoffin can you change the libcore to the hackndev repo instead of mine.

mcoffin commented 9 years ago

The cargo PR that's been holding up the travis builds was just merged. Should be on nightly (and therefore travis) tomorrow.

farcaller commented 9 years ago

Actually got a build host.

PLATFORM=lpc17xx ./configure
EXAMPLE_NAME=blink make build
error: couldn't read "/Users/farcaller/.cargo/git/checkouts/rust-libcore-d19a87fa84e493fc/master/rust/src/libcore/lib.rs": No such file or directory (os error 2)

what's going wrong in there?

Update: nevermind, apparently there's no wget on the box

farcaller commented 9 years ago

Also, default acton for make should bail out if EXAMPLE_NAME is undefined

farcaller commented 9 years ago

Okay, I don't have any other comments at this point, this looks really awesome and well done job. Squash them a bit to make more logical structure?

mcoffin commented 9 years ago

@farcaller Since the build system was so volatile throughout the whole process, there's some edits in some of those commits that don't make 100% since because the build system was different at the time, but that's as close to a logical rollup as we're going to get.

r?

mcoffin commented 9 years ago

@posborne Please rebase your pwm-support branch off of the new-build branch as its history was just re-written. Or you could wait until this is pulled in to master to rebase I guess.

posborne commented 9 years ago

@mcoffin, no problem. Feel free to move things around to your heart's content. I'll rebase the next time I take a look at the PWM stuff (isn't quite working as of yet).

On a side note, I was having link issues once I added some floating point stuff (not necessary but was matching the mbed PWM API). I'll open an issue on that once this is all merged up.

posborne commented 9 years ago

I performed some testing on the hardware I have with the latest code (and rustc nightly). Note that on a couple boards, I make minimal changes in order to flash an LED that exists:

[1] Compilation Problems

  1. error: a #[start] function is an experimental feature whose signature may change over time. I fixed this by adding #![feature(start)]
  2. Floating point link error (as mentioned above)...
error: linking with `arm-none-eabi-gcc` failed: exit code: 1
note: "arm-none-eabi-gcc" "-lm" "-lgcc" "-mcpu=cortex-m3" "-mthumb" "-Tlayout.ld" "-L" "/usr/local/lib/rustlib/thumbv7m-none-eabi/lib" "/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/examples/uart.o" "-o" "/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/examples/uart" "-Wl,--gc-sections" "-nodefaultlibs" "/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/libzinc.rlib" "/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/deps/librlibc-68a115e07ddb7f5c.rlib" "/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/deps/libcore-457ad95defb42ceb.rlib" "-L" "/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release" "-L" "/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/deps" "-L" "/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/build/zinc-456b0486afb7648a/out" "-L" "/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/build/zinc-456b0486afb7648a/out" "-L" "/usr/local/lib/rustlib/thumbv7m-none-eabi/lib" "-L" "/home/posborne/Projects/rust-playground/zinc/.rust/lib/thumbv7m-none-eabi" "-L" "/home/posborne/Projects/rust-playground/zinc/lib/thumbv7m-none-eabi" "-Wl,-Bstatic" "-Wl,-Bdynamic"
note: /home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/libzinc.rlib(zinc.o): In function `hal::lpc17xx::uart::UART::new::h9a26705af0258903YSc':
zinc.0.rs:(.text._ZN3hal7lpc17xx4uart4UART3new20h9a26705af0258903YScE+0xea): undefined reference to `__aeabi_uidivmod'
/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/libzinc.rlib(zinc.o): In function `util::strconv::itoa::h84fa40810a57df60yHD':
zinc.0.rs:(.text._ZN4util7strconv4itoa20h84fa40810a57df60yHDE+0x20): undefined reference to `__aeabi_uidivmod'
collect2: error: ld returned 1 exit status

[2] Some hacks are required to run on the Teensy 3.1

Hack 1: changes to use PortC, pin 5 (LED on teensy 3.1: https://www.pjrc.com/teensy/schematic.html)

diff --git a/examples/app_blink_k20.rs b/examples/app_blink_k20.rs
index 841907f..c7a749f 100644
--- a/examples/app_blink_k20.rs
+++ b/examples/app_blink_k20.rs
@@ -29,8 +29,8 @@ pub fn main() {
   zinc::hal::mem_init::init_data();
   watchdog::init(watchdog::State::Disabled);

-  // Pins for MC HCK (http://www.mchck.org/)
-  let led1 = pin::Pin::new(pin::Port::PortB, 16, pin::Function::Gpio, Some(zinc::hal::pin::Out));
+  // Pin for Teensy 3.1
+  let led1 = pin::Pin::new(pin::Port::PortC, 5, pin::Function::Gpio, Some(zinc::hal::pin::Out));

   systick::setup(systick::ten_ms().unwrap_or(480000));
   systick::enable();
diff --git a/examples/app_blink_k20_isr.rs b/examples/app_blink_k20_isr.rs
index 483a9c5..4406788 100644
--- a/examples/app_blink_k20_isr.rs
+++ b/examples/app_blink_k20_isr.rs
@@ -30,8 +30,8 @@ pub fn main() {
   zinc::hal::mem_init::init_data();
   watchdog::init(watchdog::State::Disabled);

-  // Pins for MC HCK (http://www.mchck.org/)
-  let led1 = pin::Pin::new(pin::Port::PortB, 16, pin::Function::Gpio, Some(zinc::hal::pin::Out));
+  // Pin for Teensy 3.1
+  let led1 = pin::Pin::new(pin::Port::PortC, 5, pin::Function::Gpio, Some(zinc::hal::pin::Out));

   systick::setup(systick::ten_ms().unwrap_or(480000));
   systick::enable();

Generating the hexfile is pretty easy (could be added to Makefile):

arm-none-eabi-objcopy -O ihex target/thumbv7em-none-eabi/release/examples/blink_k20_isr blink_k20_isr.hex
bharrisau commented 9 years ago

FP issues may be because of differences between libgcc and compiler-rt? On 30 May 2015 12:08 pm, "Paul Osborne" notifications@github.com wrote:

I performed some testing on the hardware I had with the latest code. Note that on a couple boards, I make minimal changes in order to flash an LED that exists:

  • MBED LPC1768
    • blink: It blinks at about 2hz. The code current has 10ms delays. I can put together a change to fix this. (PASS)
    • blink_pt: PASS
    • app_uart: FAIL (multiple problems) [1]
    • Teensy 3.1 (K20) [2]
    • blink_k20: PASS
    • blink_k20_isr: PASS

[1] Compilation Problems

  1. error: a #[start] function is an experimental feature whose signature may change over time. I fixed this by adding

    ![feature(start)]

  2. Floating point link error (as mentioned above)...

error: linking with arm-none-eabi-gcc failed: exit code: 1 note: "arm-none-eabi-gcc" "-lm" "-lgcc" "-mcpu=cortex-m3" "-mthumb" "-Tlayout.ld" "-L" "/usr/local/lib/rustlib/thumbv7m-none-eabi/lib" "/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/examples/uart.o" "-o" "/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/examples/uart" "-Wl,--gc-sections" "-nodefaultlibs" "/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/libzinc.rlib" "/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/deps/librlibc-68a115e07ddb7f5c.rlib" "/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/deps/libcore-457ad95defb42ceb.rlib" "-L" "/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release" "-L" "/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/deps" "-L" "/home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/build/zinc-456b0486afb7648a/out" "-L" "/ home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/build/zinc-456b0486afb7648a/out" "-L" "/usr/local/lib/rustlib/thumbv7m-none-eabi/lib" "-L" "/home/posborne/Projects/rust-playground/zinc/.rust/lib/thumbv7m-none-eabi" "-L" "/home/posborne/Projects/rust-playground/zinc/lib/thumbv7m-none-eabi" "-Wl,-Bstatic" "-Wl,-Bdynamic" note: /home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/libzinc.rlib(zinc.o): In function hal::lpc17xx::uart::UART::new::h9a26705af0258903YSc': zinc.0.rs:(.text._ZN3hal7lpc17xx4uart4UART3new20h9a26705af0258903YScE+0xea): undefined reference toaeabi_uidivmod' /home/posborne/Projects/rust-playground/zinc/target/thumbv7m-none-eabi/release/libzinc.rlib(zinc.o): In function util::strconv::itoa::h84fa40810a57df60yHD': zinc.0.rs:(.text._ZN4util7strconv4itoa20h84fa40810a57df60yHDE+0x20): undefined reference toaeabi_uidivmod' collect2: error: ld returned 1 exit status

[2] Some hacks are required to run on the Teensy 3.1

Hack 1: changes to use PortC, pin 5 (LED on teensy 3.1: https://www.pjrc.com/teensy/schematic.html)

diff --git a/examples/app_blink_k20.rs b/examples/app_blink_k20.rs index 841907f..c7a749f 100644--- a/examples/app_blink_k20.rs+++ b/examples/app_blink_k20.rs@@ -29,8 +29,8 @@ pub fn main() { zinc::hal::mem_init::init_data(); watchdog::init(watchdog::State::Disabled);

  • // Pins for MC HCK (http://www.mchck.org/)- let led1 = pin::Pin::new(pin::Port::PortB, 16, pin::Function::Gpio, Some(zinc::hal::pin::Out));+ // Pin for Teensy 3.1+ let led1 = pin::Pin::new(pin::Port::PortC, 5, pin::Function::Gpio, Some(zinc::hal::pin::Out));

    systick::setup(systick::ten_ms().unwrap_or(480000)); systick::enable();diff --git a/examples/app_blink_k20_isr.rs b/examples/app_blink_k20_isr.rs index 483a9c5..4406788 100644--- a/examples/app_blink_k20_isr.rs+++ b/examples/app_blink_k20_isr.rs@@ -30,8 +30,8 @@ pub fn main() { zinc::hal::mem_init::init_data(); watchdog::init(watchdog::State::Disabled);

  • // Pins for MC HCK (http://www.mchck.org/)- let led1 = pin::Pin::new(pin::Port::PortB, 16, pin::Function::Gpio, Some(zinc::hal::pin::Out));+ // Pin for Teensy 3.1+ let led1 = pin::Pin::new(pin::Port::PortC, 5, pin::Function::Gpio, Some(zinc::hal::pin::Out));

    systick::setup(systick::ten_ms().unwrap_or(480000)); systick::enable();

Generating the hexfile is pretty easy (could be added to Makefile):

arm-none-eabi-objcopy -O ihex target/thumbv7em-none-eabi/release/examples/blink_k20_isr blink_k20_isr.hex

— Reply to this email directly or view it on GitHub https://github.com/hackndev/zinc/pull/285#issuecomment-106984501.

mcoffin commented 9 years ago

Well the teensy related problems are board-specific and that'll be resolved when we come up with a way to generalize boards and map between boards and mcu peripherals.

I'll look in to the division problems now. Note that when problems like this arise, we should be adding tests, so we can avoid invisible failures like this in the future.

mcoffin commented 9 years ago

@posborne I can't reproduce the compilation error like you stated. My version of libgcc has __eabi_uidivmod.

$ arm-none-eabi-objdump -D armv7e-m/libgcc.a | grep uidivmod
00000014 <__aeabi_uidivmod>:
bharrisau commented 9 years ago

Does your armv7m have it defined? On 30 May 2015 12:28 pm, "Matt Coffin" notifications@github.com wrote:

@posborne https://github.com/posborne I can't reproduce the compilation error like you stated. My version of libgcc has __eabi_uidivmod.

$ arm-none-eabi-objdump -D armv7e-m/libgcc.a | grep uidivmod 00000014 <__aeabi_uidivmod>:

— Reply to this email directly or view it on GitHub https://github.com/hackndev/zinc/pull/285#issuecomment-106986696.

mcoffin commented 9 years ago

Yes.

mcoffin commented 9 years ago

Actually, I can reproduce it even though it's clearly defined in the library.

posborne commented 9 years ago

@mcoffin Ditto for me on the symbol being in libgcc.a.

On the teensy, I agree that that isn't really a problem. Just figured I would not the customization I made for the benefit of anyone else that bumps into this in the near future (maybe me in a week).

posborne commented 9 years ago

I have also confirmed that the version of libgcc.a that I believe is being used also has the undefined symbols...

$ "arm-none-eabi-gcc" "-v" ...
<...>
LIBRARY_PATH=/usr/bin/../lib/gcc/arm-none-eabi/4.9.3/armv7-m/:/usr/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7-m/:/usr/bin/../arm-none-eabi/lib/armv7-m/:/usr/bin/../lib/gcc/arm-none-eabi/4.9.3/:/usr/bin/../lib/gcc/:/usr/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/:/usr/bin/../arm-none-eabi/lib/
<...>
$ arm-none-eabi-objdump -D /usr/lib/gcc/arm-none-eabi/4.9.3/armv7-m//libgcc.a | grep uidivmod
00000014 <__aeabi_uidivmod>:
mcoffin commented 9 years ago

This is because the link arguments were passed in a strange order. I've got it fixed right now, but I have to either feature-gate or weak-link the libgcc emulating symbols from src/util/support.rs to get it to link properly. Actually, they might not even be necessary... let me check to see if they're defined in libcompiler-rt.

bharrisau commented 9 years ago

Did the platform json have the option for a pre/post args, and would moving that around help? On 30 May 2015 12:48 pm, "Matt Coffin" notifications@github.com wrote:

This is because the link arguments were passed in a strange order. I've got it fixed right now, but I have to either feature-gate or weak-link the libgcc emulating symbols from src/util/support.rs to get it to link properly. Actually, they might not even be necessary... let me check to see if they're defined in libcompiler-rt.

— Reply to this email directly or view it on GitHub https://github.com/hackndev/zinc/pull/285#issuecomment-106989295.

mcoffin commented 9 years ago

Yes. Move "-lm" and "-lgcc" to post-link-args to fix this problem, but that generates the problem of zinc having defined the stack unwinding functions internally to support compiler-rt. To work with both, we'll either have to feature-gate those symbols, or, preferably, make them weak.

bharrisau commented 9 years ago

I'm not sure how much of that is legacy from when the custom json feature was more opinionated vs how much is needed today. We would ideally not define any symbols. Well, ideally we would have a cargo package to build compiler-rt. On 30 May 2015 12:52 pm, "Matt Coffin" notifications@github.com wrote:

Yes. Move "-lm" and "-lgcc" to post-link-args to fix this problem, but that generates the problem of zinc having defined the stack unwinding functions internally to support compiler-rt. To work with both, we'll either have to feature-gate those symbols, or, preferably, make them weak.

— Reply to this email directly or view it on GitHub https://github.com/hackndev/zinc/pull/285#issuecomment-106989445.

mcoffin commented 9 years ago

@posborne @bharrisau Ok so this is a whole big can of worms that really boils down to the fact that libgcc is compiled with exceptions (and therefore unwinding) enabled. Integer division by 0 can produce an exception. Since we're not supporting unwinding, we don't have any unwinding tables in the binary (in fact we explicitly discard them in the linker script). So, one could do as I've done and

  1. Remove __aeabi_unwind_cpp* from src/util/support.rs
  2. Add PROVIDE(__aeabi_unwind_cpp* = abort) for each function to src/hal/layout_common.ld
  3. Recompile libgcc with no exceptions enabled.

Looking through the old build system to see how we ordered the arguments to get our versions of the unwinding functions to override those in libgcc (which would fix the problem by effectively soft-disabling unwinding by overriding all the unwinding entry points).

bharrisau commented 9 years ago

Does adding --specs=nano.specs change anything? Probably depends on the toolchains whether the nano build is included. On 30 May 2015 1:13 pm, "Matt Coffin" notifications@github.com wrote:

@posborne https://github.com/posborne @bharrisau https://github.com/bharrisau Ok so this is a whole big can of worms that really boils down to the fact that libgcc is compiled with exceptions (and therefore unwinding) enabled. Since we're not supporting unwinding, we don't have any unwinding tables in the binary (in fact we explicitly discard them in the linker script). So, one could do as I've done and

  1. Remove __aeabi_unwind_cpp* from src/util/support.rs
  2. Add PROVIDE(__aeabi_unwind_cpp* = abort) for each function to src/hal/layout_common.ld
  3. Recompile libgcc with no exceptions enabled.

— Reply to this email directly or view it on GitHub https://github.com/hackndev/zinc/pull/285#issuecomment-106990707.

mcoffin commented 9 years ago

@bharrisau @posborne that should do it. Eventually we may want to consider allowing for unwinding, but that will drastically increase binary size.

bharrisau commented 9 years ago

Unwinding for us is hitting the fault handler really. Stack overflow will probably end as a memfault, if we run user code in the second stack and have a robust fault handler we should have a good platform. On 30 May 2015 1:39 pm, "Matt Coffin" notifications@github.com wrote:

@bharrisau https://github.com/bharrisau @posborne https://github.com/posborne that should do it. Eventually we may want to consider allowing for unwinding, but that will drastically increase binary size.

— Reply to this email directly or view it on GitHub https://github.com/hackndev/zinc/pull/285#issuecomment-106991840.

mcoffin commented 9 years ago

Well in that case, then what I have above should duplicate what was going on before.

posborne commented 9 years ago

@mcoffin, I tested the fix and the UART app builds and spits out bytes at 115200 on the UART.

farcaller commented 9 years ago

Okay, I'm going to land this and try to fix the build sizes reporting on ci. Once again, thanks for a great job.

farcaller commented 9 years ago

cargo test is apparently broken :smile: