Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

no_std support for geo-types #936

Merged
merged 7 commits into from
Feb 2, 2023
Merged

no_std support for geo-types #936

merged 7 commits into from
Feb 2, 2023

Conversation

wetheredge
Copy link
Contributor

@wetheredge wetheredge commented Nov 19, 2022

  • I agree to follow the project's code of conduct.
  • I added an entry to CHANGES.md if knowledge of this change could be valuable to users.

This is my take on no_std support. This adds a new std that behave similarly to serde's.

Rough overview of my changes:

  • For the most part, simply swapping alloc or core in for std.
  • Also added a second doc(hidden) public module (_alloc) to give macros access to Vec and Box even if the crate they are used from does not have extern crate alloc. This could be merged into the existing private_utils. It could also be dropped entirely, but that would require modifying the macros to reference std when that feature is enabled and the cleanest way I found to do that is still somewhat ugly: match on () with cfg'd branches.

I've looked some at #426 and the main difference I see is that it adds core-error for the Error trait, while I've just put that behind the std feature. If that is preferred, I can add the dependency.


I have also started working on no_std support in geo, but it's not quite as straight-forward, so I was keeping it for a second PR.

fixes #422, partially supersedes #426

@michaelkirk
Copy link
Member

michaelkirk commented Nov 23, 2022

Hello! Thanks for taking a pass at this.

Firstly, I'm not sure if we should be trying to support no_std (that is, maybe we should, I'm just not sure.)

The std->core stuff is easy enough and I don't personally think it's controversial.

But I'm a little hesitant about the alloc feature. It seems like trying to support a no-alloc build is a bit disruptive, and also, to me, it seems unlikely to be useful. Do you actually have this use case? Can I ask what you're using it for?

What do people think about going the route that rstar went, which is no_std but requiring alloc outright?

Also, I think to have any hope of not breaking this in the future we'd need to be sure the no_std build is added to CI.

@frewsxcv
Copy link
Member

Agreed we should start out by having alloc be required, since it seems to disrupt the code quite a bit, unless there's a really compelling use-case. I think no_std for geo_types is reasonable, but geo might warrant a discussion since that would likely be difficult.

@urschrei
Copy link
Member

Agreed we should start out by having alloc be required, since it seems to disrupt the code quite a bit, unless there's a really compelling use-case. I think no_std for geo_types is reasonable, but geo might warrant a discussion since that would likely be difficult.

Agreed w/both.

@wetheredge
Copy link
Contributor Author

wetheredge commented Nov 23, 2022

I added the alloc feature because since that was mentioned as a possibility in the last PR (#426 (comment)) (and the issue #422 (comment)). I'm fine with requiring alloc for no_std. The crate I need this for can't go no-alloc anyway.

I'll go ahead and remove the alloc feature, unless you want to leave it in unused (and documented as such) for the possibility of adding support for no-alloc in a non-breaking release in the future.

Also, I think to have any hope of not breaking this in the future we'd need to be sure the no_std build is added to CI.

I'll add a build on a bare metal ARM target that can't provide std to verify that it works, based on advice from this article.

My other question is whether to add core-error as a dependency so that no_std has an Error impl, since core doesn't yet provide it natively. The last PR did, but I don't know if it's worth another dependency.

geo might warrant a discussion since that would likely be difficult.

Agreed, it's not as simple. I'll take another look at it, perhaps after this is complete, and open a PR for that discussion only if it's not too bad.

@michaelkirk
Copy link
Member

My other question is whether to add core-error as a dependency so that no_std has an Error impl, since core doesn't yet provide it natively. The last PR did, but I don't know if it's worth another dependency.

I've done very little with no_std. What is common across the no_std ecosystem? What's the cost? What's the benefit?

@wetheredge
Copy link
Contributor Author

What's the cost?

  • Longer compile time (likely minimal tbf)
  • Another source for bugs
  • Looks to be somewhat dead

What's the benefit?

  • Removes the difference between the std api & the no_std+alloc api

I don't have all that much experience with no_std either, but based on lib.rs/crates.io & GitHub, it looks like the only major crate that uses it is rhai, and only as an optional dependency. Could add it as an optional dep, but that adds yet another feature…. I lean toward not including it at all.

@frewsxcv
Copy link
Member

@wetheredge Are you still working on this? I think the next step is to require alloc for no_std, instead of making it optional

@wetheredge
Copy link
Contributor Author

Looks like the current CI does run with --no-default-features, but that isn't 100% accurate for testing no_std compatibility: https://blog.dbrgn.ch/2019/12/24/testing-for-no-std-compatibility/. Should I add one of those workarounds? I'm using the build for ARM method in my no_std crate.

@frewsxcv
Copy link
Member

I think it makes sense to add a --no-default-features build to our CI, yeah

@frewsxcv
Copy link
Member

Oh disregard my last message, I misread yours. Let me think about this

@michaelkirk
Copy link
Member

https://github.com/hobofan/cargo-nono looks nice. It hasn't been updated very recently, but maybe that's a sign of maturity vs. abandonment.

@frewsxcv
Copy link
Member

My vote would be to try adding a new no-std target (e.g. thumbv6m-none-eabi from the blog post) since that simulates the closest thing to what our goal is with no-std. But if that's not feasible then fallback to cargo-nono.

@wetheredge
Copy link
Contributor Author

I've used thumbv7em-none-eabihf since that's what I've got installed and what's in my CI, but I can change it to thumbv6m-none-eabi to match the blog post if wanted. Any of the Tier 2 targets with an asterisk in the middle column should do.

Most of the features are no_std compatible, except for rstar v0.8 & arbitrary. Looks like there's an open PR to add no_std support to arbitrary. Could wait for that, or just document it as incompatible with no_std until that's merged and updated. no_std in rstar v0.8 would likely be pretty simple, tho I haven't checked. rstar v0.9 does work.

@frewsxcv
Copy link
Member

Let's disable rstar and arbitrary support for now, and if it's something you think you'll need, let's open a follow-up GitHub issue tracking those. No need for this PR to get held up by those dependencies. How does that sound?

@wetheredge
Copy link
Contributor Author

Unless I've missed something, this should be ready.

Copy link
Member

@frewsxcv frewsxcv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm! thank you! will leave it open for another day or two to see if anyone else has feedback

@michaelkirk
Copy link
Member

michaelkirk commented Jan 20, 2023

This LGTM, thanks!

Is this a breaking change that would necessitate bumping semver? In particular, I'm thinking that introducing a default feature and disabling default features for some of our deps might break things for people.

@wetheredge
Copy link
Contributor Author

Re semver:

The cargo docs aren't entirely clear on adding a new default feature that controls existing functionality. I'd be inclined to say it's technically a major change, but since there weren't any default features before, perhaps you could get away with treating it as minor.

Following the same guidelines, disabling features on dependencies only needs to be a minor change since, as RFC 1105 says, any crate relying on those features without enabling them themselves is a bug.

@wetheredge
Copy link
Contributor Author

Is this ready to merge?

@frewsxcv
Copy link
Member

frewsxcv commented Feb 2, 2023

Thanks for your patience!

bors r+

bors bot added a commit that referenced this pull request Feb 2, 2023
936: `no_std` support for `geo-types` r=frewsxcv a=wetheredge

- [x] I agree to follow the project's [code of conduct](https://github.com/georust/geo/blob/main/CODE_OF_CONDUCT.md).
- [x] I added an entry to `CHANGES.md` if knowledge of this change could be valuable to users.
---

This is my take on `no_std` support. This adds a new `std` that behave similarly to `serde`'s.

Rough overview of my changes:
- For the most part, simply swapping `alloc` or `core` in for `std`.
- Also added a second `doc(hidden)` public module (`_alloc`) to give macros access to `Vec` and `Box` even if the crate they are used from does not have `extern crate alloc`. This could be merged into the existing `private_utils`. It could also be dropped entirely, but that would require modifying the macros to reference `std` when that feature is enabled and the cleanest way I found to do that is still somewhat ugly: match on `()` with `cfg`'d branches.

I've looked some at #426 and the main difference I see is that it adds `core-error` for the `Error` trait, while I've just put that behind the `std` feature. If that is preferred, I can add the dependency.

---

I have also started working on `no_std` support in `geo`, but it's not quite as straight-forward, so I was keeping it for a second PR.

fixes #422, partially supersedes #426

Co-authored-by: William Etheredge <[email protected]>
@bors
Copy link
Contributor

bors bot commented Feb 2, 2023

Build failed:

geo-types/src/lib.rs Outdated Show resolved Hide resolved
@frewsxcv
Copy link
Member

frewsxcv commented Feb 2, 2023

It looks like byteorder can't be built on our new target? 🤔

@wetheredge
Copy link
Contributor Author

Oops was installing thumbv6 but building with v7…. Looks like it's fixed.

@frewsxcv
Copy link
Member

frewsxcv commented Feb 2, 2023

bors r+

@bors
Copy link
Contributor

bors bot commented Feb 2, 2023

Build succeeded:

@bors bors bot merged commit d3b07ee into georust:main Feb 2, 2023
@michaelkirk
Copy link
Member

Thanks for seeing this through @wetheredge!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

support no_std
4 participants