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_stda 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 addedcapnpas a dependency andcapnpcas a build dependency, but thatcapnp-rpcwas still not compiling forno_std. I wanted to see if it'd be possible to getcapnp-rpccompiling forno_stdusing 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_queuedepends onfutures::channel::mpsc::unbounded(), which seems truly unavailable onno_std, even withallocpresent. Any solution to makingcapnp-rpcno_stdcompatible would probably hinge on finding a different channel solution which usesallocor less.Features all the way down
When I added
capnp-rpcas a dependency to my blankno_stdproject, 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-rpcitself and saw this:So,
capnp-rpcdepends on thestdfeature ofcapnp-futures. So I decided to dig deeper and see if there was any way that we could disable thestdfeature incapnp-futuresand still retain a minimal working base on whichcapnp-rpccould run using justalloc. Incapnp-futures, I made astdfeature and set it on by default. I also turned off default features for thefuturescrate to avoid the std dependency there, but made sure to add backfutures/stdandfutures/executoras a dependency of thecapnp-futuresstdfeature. Basically, I was hoping to create a big chain ofstdfeatures 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_stdcompatible and defining blanket impls for the canonical versions of the traits whenstdis 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 theAsyncReadExtandAsyncWriteExttraits 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_stdcompatible module. So I reproduced just those helper Futures fromfutures-utilthat you were using.futures::channel::mpsc
At this point, my compiler errors basically watered down to just about one problem: that
futures::channel::mpscwas not available withoutstd, not even ifallocis 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 ampscchannel, 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 onmpsccould 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-onlympscchannel 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!