mgeisler / textwrap

An efficient and powerful Rust library for word wrapping text.
MIT License
449 stars 44 forks source link

Unable to compile to WASM with version 0.15.1 #472

Open lpil opened 1 year ago

lpil commented 1 year ago

Hello! I've just upgraded to 0.15.1 and can no longer compile this to WASM.

This versions pulls in terminal_size 0.2.1, which pulls in rustix, which pulls in linux-raw-sys, which does not compile on wasm.

I see the dep is marked as optional in textwrap's Cargo.toml, but I couldn't work out how to stop it from being included. I have this in my Cargo.toml:

textwrap = { version = "0.15.0", default_features = false, features = [] }

How can I resolve this?

Thanks, Louis

mgeisler commented 1 year ago

Hi Louis,

That's strange: the dependencies haven't change in the 0.15.1 version. I can also see that my own demo works fine with the latest commit: https://mgeisler.github.io/textwrap/.

The WASM demo in Textwrap uses a Cargo.toml file which includes the default features. You can see the build job here.

To double-check, I just tried to reproduce this with a Cargo.tom file having

[dependencies]
textwrap = "0.15"

This seems to work fine:

% cargo update
    Updating crates.io index
      Adding textwrap v0.15.1
% wasm-pack build
[INFO]: Checking for the Wasm target...
[INFO]: Compiling to Wasm...
   Compiling textwrap v0.15.1
   Compiling textwrap-wasm-demo v0.1.0
    Finished release [optimized] target(s) in 1.18s
[INFO]: Installing wasm-bindgen...
[INFO]: Optimizing wasm binaries with `wasm-opt`...
[INFO]: :-) Done in 4.61s
[INFO]: :-) Your wasm pkg is ready to publish at src/textwrap/examples/wasm/pkg.

What command do you use and what error do you see?

lpil commented 1 year ago

Spooky!

Here's what it looks like in my project:

louis ~/src/gleam/gleam (main) ✘ $ cargo update -p textwrap
    Updating crates.io index
      Adding errno v0.2.8
      Adding errno-dragonfly v0.1.2
      Adding io-lifetimes v0.7.3
    Updating libc v0.2.132 -> v0.2.133
      Adding linux-raw-sys v0.0.46
      Adding rustix v0.35.10
      Adding terminal_size v0.2.1
    Updating textwrap v0.15.0 -> v0.15.1
louis ~/src/gleam/gleam (main *) $ cd compiler-wasm/
louis ~/src/gleam/gleam/compiler-wasm (main *) $ wasm-pack test --node
[INFO]: 🎯  Checking for the Wasm target...
   Compiling futures-core v0.3.23
   Compiling once_cell v1.13.1
   Compiling percent-encoding v2.1.0
   Compiling unicode-ident v1.0.3
   Compiling futures-channel v0.3.23
   Compiling futures-sink v0.3.23
   Compiling rustix v0.35.10
   Compiling matches v0.1.9
   Compiling futures-io v0.3.23
   Compiling errno v0.2.8
error[E0583]: file not found for module `sys`
  --> /Users/louis/.cargo/registry/src/github.com-1ecc6299db9ec823/errno-0.2.8/src/lib.rs:33:1
   |
33 | mod sys;
   | ^^^^^^^^
   |
   = help: to create the module `sys`, create file "/Users/louis/.cargo/registry/src/github.com-1ecc6299db9ec823/errno-0.2.8/src/sys.rs" or "/Users/louis/.cargo/registry/src/github.com-1ecc6299db9ec823/errno-0.2.8/src/sys/mod.rs"

error[E0425]: cannot find function `errno` in module `sys`
   --> /Users/louis/.cargo/registry/src/github.com-1ecc6299db9ec823/errno-0.2.8/src/lib.rs:101:10
    |
101 |     sys::errno()
    |          ^^^^^ not found in `sys`

error[E0425]: cannot find function `set_errno` in module `sys`
   --> /Users/louis/.cargo/registry/src/github.com-1ecc6299db9ec823/errno-0.2.8/src/lib.rs:106:10
    |
106 |     sys::set_errno(err)
    |          ^^^^^^^^^ not found in `sys`

   Compiling bytes v1.2.1
Some errors have detailed explanations: E0425, E0583.
For more information about an error, try `rustc --explain E0425`.
error: could not compile `errno` due to 3 previous errors
warning: build failed, waiting for other jobs to finish...
Error: Compilation of your program failed
Caused by: failed to execute `cargo build`: exited with exit status: 101
  full command: "cargo" "build" "--tests" "--target" "wasm32-unknown-unknown"

Is there anything I can do to help debug?

mgeisler commented 1 year ago

The

   Compiling errno v0.2.8
error[E0583]: file not found for module `sys`
  --> /Users/louis/.cargo/registry/src/github.com-1ecc6299db9ec823/errno-0.2.8/src/lib.rs:33:1
   |
33 | mod sys;
   | ^^^^^^^^
   |
   = help: to create the module `sys`, create file "/Users/louis/.cargo/registry/src/github.com-1ecc6299db9ec823/errno-0.2.8/src/sys.rs" or "/Users/louis/.cargo/registry/src/github.com-1ecc6299db9ec823/errno-0.2.8/src/sys/mod.rs"

output makes me think that the problem is in errno. You could try using cargo tree to see what depends on errno and thus track down where the problem is.

To double-check, you can also specify a strict 0.15.0 dependency on Textwrap:

[dependencies]
textwrap = "=0.15"

The = will make Cargo ignore the 0.15.1 release. I hope that will reproduce the problem, otherwise we need to dig deeper :-)

lpil commented 1 year ago

Sorry, I accidentally skipped errno in my original post. Here's the tree

└── textwrap v0.15.1
     └── terminal_size v0.2.1
         └── rustix v0.35.10
             └── errno v0.2.8

It successfully compiles if textwrap is pinned to 0.15.0.

namse commented 1 year ago

Hi. For me, I failed with unicode-linebreak v0.1.3 of textwrap v0.15.1.

error[E0658]: use of unstable library feature 'iter_zip'
   --> /usr/local/cargo/registry/src/github.com-1ecc6299db9ec823/unicode-linebreak-0.1.3/build.rs:237:20
    |
237 |         .find(|&n| iter::zip(&a[a.len() - n..], b.clone()).all(|(x, y)| x == y.borrow()))
    |                    ^^^^^^^^^
    |
    = note: see issue #83574 <https://github.com/rust-lang/rust/issues/83574> for more information

For more information about this error, try `rustc --explain E0658`.
error: could not compile `unicode-linebreak` due to previous error
warning: build failed, waiting for other jobs to finish...
error: build failed
Error: Compilation of your program failed
Caused by: failed to execute `cargo build`: exited with exit status: 101
  full command: "cargo" "build" "--tests" "--target" "wasm32-unknown-unknown"
test failed
namse commented 1 year ago

Nevermind, my problem was rust version <=1.58.

mgeisler commented 1 year ago

Nevermind, my problem was rust version <=1.58.

Thanks @namse, I now see the same build error in the weekly build. The problem is that unicode-linebreak now requires Rust 1.59 because of the use of std::iter::zip instead of Iterator::zip.

The new code was added in https://github.com/axelf4/unicode-linebreak/commit/4f916faa1fdaf541390bb3e686f0b20042a04ca6.

mgeisler commented 1 year ago

I've now created axelf4/unicode-linebreak#4 to see if we can easily restore compatibility with Rust 1.56 and fix the problem @namse noticed.

mgeisler commented 1 year ago

Sorry, I accidentally skipped errno in my original post. Here's the tree

└── textwrap v0.15.1
     └── terminal_size v0.2.1
         └── rustix v0.35.10
             └── errno v0.2.8

Thanks for this part, that's very useful!

I now finally understand what's going on: Textwrap 0.15.1 updated the dependency on terminal_size to the latest version, and this version pulls in errno. That happened in #461.

Now, terminal_size is an optional dependency, meaning that you should only see the transitive errno dependency if you specify your Textwrap dependency as

[dependencies]
textwrap = { version = "=0.15.1", features = ["terminal_size"] }

Can you double-check the features enabled for Textwrap to check that you don't enable terminal_size in your Wasm program?

namse commented 1 year ago

glad to help you :)

lpil commented 1 year ago

Hi @mgeisler

The dep is specified like so:

textwrap = { version = "=0.15.1", default_features = false, features = [] }
mgeisler commented 1 year ago

The dep is specified like so:

textwrap = { version = "=0.15.1", default_features = false, features = [] }

Okay, that should not be able to pull in the terminal_size dependency. I'm not sure where it comes from then... Have you run cargo update after changing the flags? I don't think it should be necessary, but I'm not sure why it's pulled in.

lpil commented 1 year ago

Yes, I have. I've also tried it when just specifying the version.

mgeisler commented 1 year ago

Hi @lpil, have you managed to make this work or do you have new information?

Just to recap, I cannot reproduce this in my CI (please see this build for an example) or on my laptop.

However, if I apply this patch:

modified   examples/wasm/Cargo.toml
@@ -12,7 +12,7 @@ publish = false  # This project should not be uploaded to crates.io
 crate-type = ["cdylib", "rlib"]

 [dependencies]
-textwrap = { path = "../../" }
+textwrap = { path = "../../", features = ["terminal_size"] }

 console_error_panic_hook = "0.1.7"
 js-sys = "0.3.57"

to the examples/wasm/Cargo.toml file, then the output of cargo tree matches your output:

$ % cargo tree -e normal
textwrap-wasm-demo v0.1.0 (.../textwrap/examples/wasm)
├── textwrap v0.16.0 (.../textwrap)
│   ├── smawk v0.3.1
│   ├── terminal_size v0.2.1
│   │   └── rustix v0.35.12
│   │       ├── bitflags v1.3.2
│   │       ├── io-lifetimes v0.7.4
│   │       ├── libc v0.2.137
│   │       └── linux-raw-sys v0.0.46
│   ├── unicode-linebreak v0.1.4
│   └── unicode-width v0.1.10

and I do get a compilation error from wasm-pack build:

% wasm-pack build
[INFO]: Checking for the Wasm target...
[INFO]: Compiling to Wasm...
   Compiling wasm-bindgen-backend v0.2.83
   Compiling regex v1.6.0
   Compiling rustix v0.35.12
   Compiling io-lifetimes v0.7.4
   Compiling bitflags v1.3.2
error[E0432]: unresolved imports `portability::AsFilelike`, `portability::AsSocketlike`, `portability::BorrowedFilelike`, `portability::BorrowedSocketlike`, `portability::FromFilelike`, `portability::FromSocketlike`, `portability::IntoFilelike`, `portability::IntoSocketlike`, `portability::OwnedFilelike`, `portability::OwnedSocketlike`
   --> /home/mg/.cargo/registry/src/github.com-1ecc6299db9ec823/io-lifetimes-0.7.4/src/lib.rs:153:5
    |
153 |     AsFilelike, AsSocketlike, BorrowedFilelike, BorrowedSocketlike, FromFilelike, FromSocketlike,
    |     ^^^^^^^^^^  ^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^  ^^^^^^^^^^^^^^ no `FromSocketlike` in `portability`
    |     |           |             |                 |                   |
    |     |           |             |                 |                   no `FromFilelike` in `portability`
    |     |           |             |                 no `BorrowedSocketlike` in `portability`
    |     |           |             no `BorrowedFilelike` in `portability`
    |     |           no `AsSocketlike` in `portability`
    |     no `AsFilelike` in `portability`
154 |     IntoFilelike, IntoSocketlike, OwnedFilelike, OwnedSocketlike,
    |     ^^^^^^^^^^^^  ^^^^^^^^^^^^^^  ^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^ no `OwnedSocketlike` in `portability`
    |     |             |               |
    |     |             |               no `OwnedFilelike` in `portability`
    |     |             no `IntoSocketlike` in `portability`
    |     no `IntoFilelike` in `portability`

This is with

mgeisler commented 1 year ago

Hi @lpil, did you ever manage to find out what the problem is? Something seems to be enabling the terminal_size feature, but I don't know where it comes from.

lpil commented 1 year ago

I did not unfortunately, I've pinned to an older version and not dug into this since.

mgeisler commented 1 year ago

Strange, but thanks for confirming.