-
Notifications
You must be signed in to change notification settings - Fork 125
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
External components discussion #72
Comments
I think you are right in that the only option to pass info to downstream crates is by using environment variables, or the In fact, they closed the original issue referenced above and another one which was spawned from it once the As for Option 1 vs 2 - I'm fine with both, and both should probably be implemented:
Perhaps you can start with Option 2, and then I or @N3xed can look into Option 1? |
Yup, that's right. I think there are two types of components (as I see them):
And two use cases:
I don't think there is a general way to compile the extra components separately (i.e. in the build script of a separate crate). If such a component uses esp-idf's kconfig configuration system then there is really no nice way to do this. Additionally, I think we'd have to hack on the esp-idf build system quite a bit to emulate its component registration and building to make this work. But then the only thing a separate crate for such a component can do is generate the bindings, which I guess would only be worth it for really big components if at all. External libraries, that don't use esp-idf's component mechanism or are trivial to convert to normal cmake library targets, are much easier to build in a build script of a separate crate. This is actually what I'm referring to with my response here, which in hindsight may not be that obvious. But again for simple libraries, I think that approach is pretty straightforward and also uses a separate crate. With that said:
I think this is our only option for esp-idf extra components.
But this can very easily be prevented, by checking in the build script of such a wrapper crate that this component exists. (For example by checking that environment variable.) We could even export all the extra (or even all) component names/paths that were built in
We could do this too, but I think this approach should only be used for very select components that most users need. So that we don't end up with 20 features for different components.
Sure, let me come up with something for Option 1, if you think my reasoning here is sound. |
Thanks for the input folks, I agree that we should probably implement both and for rainmaker I will submit a PR to esp-idf-sys soon. Maybe one day we'll get the ability to pass env variables through esp-idf-sys = { version = "x.y.z", env = [{name = "EXTRA_COMPONENTS", value = "/path/to/extra/components"}]} |
Okay, an update for this issue (and sorry for the delay), especially regarding building extra components configured by the user in Getting
The second approach is also the one @MabezDev suggested, and really the only one we need right now, so I'll go with that. The bigger problem is with bindings generation. Here the question is whether How do we specify the headers used for bindings generation though? I see three approaches:
(1) is bad because we would need to somehow turn bindings generation off for some packages if we want users to have custom bindings crates for their components (to reduce compilation overhead). And the user probably doesn't want bindings for all headers in the directory. [package.metadata.esp-idf-sys.extra-components.foo]
headers = ["header1.h"] (3) is the simplest approach and easiest to implement. If the file does not exist and we have extra components we could print a warning? This is the approach I think I'll implement. If there are no issues, I'll start implementing this. |
I think the only problem with option 3 is that we have to make invasive changes upstream, i.e for Rust support we need to add a Take rainmaker as an example, if we add this external component into esp-idf-sys I expect the following changes. [features]
rainmaker = []
rainmaker_with_custom_bindings = ["rainmaker"] When |
Yes, I thought of that too, but I think if we only have one For example: #include "test.h"
[env]
ESP_IDF_EXTRA_COMPONENTS = "./components"
# relative to workspace dir, (i.e. `test/`)
# all subfolders of `./components` that are components are automatically added
Since rainmaker is really multiple components and supplement to the esp-idf I think it makes sense to add a custom feature to |
Excuse my ignorance, but I do not understand how package metadata in a crate Please explain. |
Nope, sorry for the confusion. This metadata section would then be in the |
I don't think even that would work. The top-level crate still falls in the category of "crate IMO the only way forward (as per my original assessment) is to use either plain environment variables, or the It is just a way to set a bunch of environment variables before calling Also: the fact that we put |
Perhaps getting obvious here, but the only way for "crate foo that depends on |
It would work though, because the location of Also, and I've just figured this out, just calling |
Calling
I agree that if we constrain the user to only specify the meta-data at the top-level binary crate (or workspace), the approach might work, as we already have a hack to figure out the workspace directory, so we can load and parse the What I don't like very much is that with this approach we would be introducing asymmetry:
And in the end, you still don't have the perfect setup, which would be a separate-crate-per-custom-component for which you need If we take this route (and btw I also much more prefer So why don't we:
? |
It seems like this indeed works, though with the same caveat that we have to know the Cargo.toml location of the top-level crate (i.e. the workspace directory). And I was partially wrong in saying that its location is deterministic from the target directory point-of-view because the location of the target directory can be changed. With that said, I agree, we can look into migrating to the metadata section.
I think I'll make a PR using the |
OK so to make sure I understand, we are implementing this bullet: What this means, is that we CAN have separate crates representing ESP-IDF components, right? As in e.g.
Right? |
It's possible though this has some (possibly severe) limitations:
With the above in mind:
It's probably more worth it that The [package.metadata.esp-idf-sys]
# Paths relative to the dir that `Cargo.toml` contains.
extra_components_dirs = { "components" }
extra_components_bindings_headers = { "components/bindings.h" }
extra_components_generate_bindings = true
# defaults to true In that example, the folder Not sure if it should be called But again this approach does only seamlessly work if the component crate vendors the sources.
Both work.
Yes, and when calling
I think, especially at the beginning, this logic can just live inside the |
Getting esp-idf-sys to build external components is relatively simple, I have PoC locally building esp-rainmaker. The hard part is how we tell esp-idf-sys where these external components are and what includes we need. Essentially the inter-crate communication.
It seems there is no way (unless I'm missing something, and I hope I am because it would make this really easy) in cargo to set environment variables for dependent crates; therefore a separate crate that depends on
esp-idf-sys
is out of the question because we can't give esp-idf-sys the information it needs to build these external components.Option 1 - env variables in the final application
We already set custom variables to dictate the build, added something like
ESP_IDF_EXTRA_COMPONENT_PATHS
could work. The downside to this is that its yet another thing a user has to remember to include, and if its the case we have a separate wrapper crate for some external components we will get weird missing item errors when we try and build that crate if we forget to add our extra component variableOption 2 -
esp-idf-sys
becomes monolithicInstead of being able to customize the build process, the way to add new components would be to add them at the source level in
esp-idf-sys
.esp-idf-sys
will then take care of downloading the external component and adding it into its normal build process. To save build time, it might be a good idea to put these external components behind feature flags.There may be better options I haven't considered, I won't lie I'm not an expert in
esp-idf-sys
's build system hence why I am opening this 😅.The text was updated successfully, but these errors were encountered: