Experimenting with no_std for capnp-rpc #196
Draft
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Hi there, I'm back! Thanks for adding the changes for
no_std
a while back. I only recently saw those changes land, so I figured I would try my hand again at putting together a sample program for my embedded project. It seemed that I was able to compile my project when I addedcapnp
as a dependency andcapnpc
as a build dependency, but thatcapnp-rpc
was still not compiling forno_std
. I wanted to see if it'd be possible to getcapnp-rpc
compiling forno_std
using justalloc
, so I started playing around with things. I'll describe what I've discovered so far.A quick TLDR
Right now the biggest thing that seems to be blocking this from working is the fact that
capnp-futures/src/write_queue
depends onfutures::channel::mpsc::unbounded()
, which seems truly unavailable onno_std
, even withalloc
present. Any solution to makingcapnp-rpc
no_std
compatible would probably hinge on finding a different channel solution which usesalloc
or less.Features all the way down
When I added
capnp-rpc
as a dependency to my blankno_std
project, the first thing that I noticed is that something seemed to be depending onstd
, causing the build to fail. I looked at the dependencies ofcapnp-rpc
itself and saw this:So,
capnp-rpc
depends on thestd
feature ofcapnp-futures
. So I decided to dig deeper and see if there was any way that we could disable thestd
feature incapnp-futures
and still retain a minimal working base on whichcapnp-rpc
could run using justalloc
. Incapnp-futures
, I made astd
feature and set it on by default. I also turned off default features for thefutures
crate to avoid the std dependency there, but made sure to add backfutures/std
andfutures/executor
as a dependency of thecapnp-futures
std
feature. Basically, I was hoping to create a big chain ofstd
features which would all turn off if the top-level dependency opted out of default-features.AsyncRead and AsyncWrite
At about this point, I realized that AsyncRead and AsyncWrite have a hard dependency on std again because of their functions returning
io::Result
. So I figured I'd take a shot at reproducing the solution you came up with last time forno_std
, creating approximations of those traits which areno_std
compatible and defining blanket impls for the canonical versions of the traits whenstd
is enabled. I dug down this rabbit hole for awhile, eventually coming up withcapnp-futures/async_io
, which has the trait approximations as well as some watered-down versions of theAsyncReadExt
andAsyncWriteExt
traits fromfutures-util
. It turns out that all of the futures you used incapnp-futures
(e.g.Read
,ReadExact
, etc.) are all just basic structs that don't depend on std at all, even though they're not published in ano_std
compatible module. So I reproduced just those helper Futures fromfutures-util
that you were using.futures::channel::mpsc
At this point, my compiler errors basically watered down to just about one problem: that
futures::channel::mpsc
was not available withoutstd
, not even ifalloc
is present. I tried looking for alternative channel solutions which only requiredalloc
, but I was unable to find any. This is pretty much the largest blocking point that I can see right now. I think it might require analloc
-only implementation of ampsc
channel, which would probably need to be made custom for this. I don't know if you're aware of any crates that would meet that need or whether there's an alternative solution where the dependency onmpsc
could be gotten rid of, but that's where this is all stuck at right now.So, I'm not sure where this leaves this issue. I haven't spent way too long thinking of other approaches yet, but I figured I'd share my findings so far in case others have any ideas for how to proceed. I've never worked with concurrency "primitives" before, so while I think the idea of creating an
alloc
-onlympsc
channel is interesting, I'm not sure I would trust myself to come up with a correct or good enough implementation to be upstreamed to this project. I'd love to hear other thoughts on this though!