RazrFalcon / tiny-skia

A tiny Skia subset ported to Rust
BSD 3-Clause "New" or "Revised" License
1.05k stars 67 forks source link

Build fails on aarch64-unknown-uefi #108

Closed RustAndMetal closed 8 months ago

RustAndMetal commented 8 months ago

When building the pattern example for aarch64-unknown-uefi using cargo build --target aarch64-unknown-uefi with tiny-skia = { version = "0.11.2", features = ["no-std-float"] }, the build fails.

Several symbols cannot be found, for example fmodf:


   Compiling tiny-skia v0.11.2
   Compiling tinySkiaTest v0.1.0 (/Users/rustandmetal/Documents/GitHub/tinySkiaTest)
  error: linking with `rust-lld` failed: exit status: 1
    |
[...]
  = note: rust-lld: error: undefined symbol: cosf
          >>> referenced by /rustc/df871fbf053de3a855398964cd05fadbe91cf4fd/library/std/src/f32.rs:643
          >>>               libtiny_skia_path-dcd51ef04542f275.rlib(tiny_skia_path-dcd51ef04542f275.tiny_skia_path.91c1f05610bfd5e9-cgu.6.rcgu.o):(std::f32::_$LT$impl$u20$f32$GT$::cos::h865f83daef2299cb)

          rust-lld: error: undefined symbol: sinf
          >>> referenced by /rustc/df871fbf053de3a855398964cd05fadbe91cf4fd/library/std/src/f32.rs:624
          >>>               libtiny_skia_path-dcd51ef04542f275.rlib(tiny_skia_path-dcd51ef04542f275.tiny_skia_path.91c1f05610bfd5e9-cgu.6.rcgu.o):(std::f32::_$LT$impl$u20$f32$GT$::sin::hec7406167cfd6ca5)

          rust-lld: error: undefined symbol: acosf
          >>> referenced by /rustc/df871fbf053de3a855398964cd05fadbe91cf4fd/library/std/src/f32.rs:707
          >>>               libtiny_skia_path-dcd51ef04542f275.rlib(tiny_skia_path-dcd51ef04542f275.tiny_skia_path.91c1f05610bfd5e9-cgu.6.rcgu.o):(std::f32::_$LT$impl$u20$f32$GT$::acos::hfc029dc77703ea74)

          rust-lld: error: undefined symbol: powf
          >>> referenced by /rustc/df871fbf053de3a855398964cd05fadbe91cf4fd/library/std/src/f32.rs:373
          >>>               libtiny_skia_path-dcd51ef04542f275.rlib(tiny_skia_path-dcd51ef04542f275.tiny_skia_path.91c1f05610bfd5e9-cgu.6.rcgu.o):(std::f32::_$LT$impl$u20$f32$GT$::powf::hb62cf66de4597e41)

          rust-lld: error: undefined symbol: cos
          >>> referenced by /rustc/df871fbf053de3a855398964cd05fadbe91cf4fd/library/std/src/f64.rs:643
          >>>               libtiny_skia-084e6b4221d321e8.rlib(tiny_skia-084e6b4221d321e8.tiny_skia.c75a110ab7d5b9e2-cgu.04.rcgu.o):(std::f64::_$LT$impl$u20$f64$GT$::cos::h78447ebc85b54676)

          rust-lld: error: undefined symbol: acos
          >>> referenced by /rustc/df871fbf053de3a855398964cd05fadbe91cf4fd/library/std/src/f64.rs:707
          >>>               libtiny_skia-084e6b4221d321e8.rlib(tiny_skia-084e6b4221d321e8.tiny_skia.c75a110ab7d5b9e2-cgu.04.rcgu.o):(std::f64::_$LT$impl$u20$f64$GT$::acos::h45e5ad84568f530f)

          rust-lld: error: undefined symbol: fmodf
          >>> referenced by /Users/rustandmetal/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tiny-skia-path-0.11.2/src/dash.rs:135
          >>>               libtiny_skia_path-dcd51ef04542f275.rlib(tiny_skia_path-dcd51ef04542f275.tiny_skia_path.91c1f05610bfd5e9-cgu.1.rcgu.o):(tiny_skia_path::dash::adjust_dash_offset::h6ec9220fa33c58e5)
          >>> referenced by /Users/rustandmetal/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tiny-skia-path-0.11.2/src/dash.rs:121
          >>>               libtiny_skia_path-dcd51ef04542f275.rlib(tiny_skia_path-dcd51ef04542f275.tiny_skia_path.91c1f05610bfd5e9-cgu.1.rcgu.o):(tiny_skia_path::dash::adjust_dash_offset::h6ec9220fa33c58e5)
CryZe commented 8 months ago

It seems like the target has std but apparently no libm? That's... very unusual and probably should be reported upstream (this may or may not be a bug tbf).

frereit commented 8 months ago

You're right, apparently there is no fmodf in aarch64-unknown-uefi.

The issue is with any modulo operation involving f32, for example inside tiny_skia_path::dash::adjust_dash_offset:

https://github.com/RazrFalcon/tiny-skia/blob/f050a90f2dad0d9c0f5c0a231418bae40341921a/path/src/dash.rs#L121

The dependency on std can be removed but the issue persists. A minimal example can be reproduced like this:

#!/usr/bin/env cargo

//! ```cargo
//! [dependencies]
//! log = "0.4.20"
//! uefi = "0.24.0"
//! uefi-services = "0.21.0"
//! ```

#![no_main]
#![no_std]

use log::info;
use uefi::prelude::*;
use tiny_skia;

#[entry]
fn main(_image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
    uefi_services::init(&mut system_table).unwrap();
    let mut count = 0f32;
    loop {
        count += 1f32;
        count %= 10f32;
        info!("{:?}", count);
    }
}

This compiles for x86_64-unknown-uefi but does not compile for aarch64-unknown-uefi. Interestingly, the example compiles for aarch64-unknown-none.

We're not really sure if this is "supposed" to work (i.e. it is a bug in the aarch64-unknown-uefi target), or if modulo operations for f32 in no-std are simply not guaranteed to be available?

We found a PR which removes a lot of dependencies on libm but explicitly keeps fmodf: https://github.com/rust-lang/rust/pull/27823

TL;DR:

Does *-unknown-uefi guarantee that modulo operations with f32 are available? If so, this is a bug in the aarch64-unknown-uefi target. If not, this is a bug in tiny-skia-path because it incorrectly assumes modulo operations are available. Maybe @dvdhrm or @nicholasbishop know more?

nicholasbishop commented 8 months ago

I confirmed I can reproduce this. It's definitely a bug in the target, probably some tweaks are needed in https://github.com/rust-lang/compiler-builtins. I'll take a look at fixing it :)

RazrFalcon commented 8 months ago

I think this is out of scope. tiny-skia supports only x86, aarch64 and wasm32.

RustAndMetal commented 8 months ago

Closed by rust-lang/compiler-builtins/pull/553