-
Notifications
You must be signed in to change notification settings - Fork 126
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
Experimental esp-idf native cmake build #7
Conversation
This is a great start, thank you very much for this contribution! I'll review the patch thoroughly, but let me make some general remarks first:
As for why the build does not run - you are probably not applying these patches to ESP-IDF. All of these that don't start with |
Thank you for the response!
I agree. I only looked at
These are just some utilities that I threw together to get a working example. I intended to contribute them to the
That's good to know, will try to do this. And this first try was just to get an initial working example as fast as possible, without considering all the things (like all OS/esp-idf version/... related things).
That was also my intention (should have stated that more clearly).
I've also considered this (need to try it, though I doubt it will work), but I've dismissed it because I thought if this was the problem the linker would've complained. I think this problem has more to do with the way I'm linking the |
Most of these patches are bugfixes ant not really pollyfils. But you are probably right - it might be the way you are assembling the final static lib, as link order matters a lot with ESP-IDF. For example, they use link order to overwrite some symbols from newlib. What I do is really to take the "native" link arguments from PIO, and pass them - exactly in the same order and exactly as they are - to the linker. |
|
Okay, so I've figured some things out. As I've told you already, I had problems with the link command line length and that is because
But anyhow, to fix this for cmake I'll just have to do more processing of the linker arguments, to also incorporate |
What is still a mystery for me is how come
Yes, we can try this way, but we should bear in mind that any "post-processing" on top of the cmake-generated link arguments we do would be fragile as in that it will be manually implemented effort which makes a lot of ESP-IDF-specific assumptions around what these parameters are. And it might break with a subsequent next release of ESP-IDF. What PlatformIO does is exactly such a workaround - it is interrogating the cmake build system about its linker flags, and then manually pushing these into the Scons build system. At places, it does assumptions (related to linker scripts) and instead of taking those from native cmake, it is just assuming those reside at certain locations inside the ESP-IDF directory tree. This is by the way the reason why I cannot compile ESP-IDF master with PlatformIO ATM - because the PlatformIO python code assumes there are some linker scripts which reside at certain locations in the ESP-IDF and is blindly - without checking if these really exist - putting references to them on the linker command line. Well, these do exist in ESP-IDF V4.3, but no longer exist in ESP-IDF master. Guess what happens. So the above goes to say - can't we explore other paths to solve the "too long list of arguments" problem? For example, if GCC (&LD) do support passing the arguments to them in a file, we can build a temp file, shuffle all cmake-generated link arguments there and then just pass the temp file to the linker? And also as per above - can we get to the root cause of why we are having the "too long list of arguments" problem, and cmake itself - when calling the native linker - doesn't? |
That doesn't work either because even if I pass all the arguments for the |
Got it, great analysis. I'm starting to think of bigger hacks. First of all, you anyway need to pass all the linker args from Another hack: if you take advantage of my |
Didn't even think about symlinks, or if that will even work on windows. But also cargo runs If we change the working directory though, as you said, we need cargo to emit absolute paths, which it does in my case but I don't know if this is portable behavior (ie. that cargo never emits relative paths). If that is so we can just cd into the I've also looked if somehow gcc itself could use response files in its invocations and this is indeed possible. But it seems that gcc has to be configured with |
I think the question to @igrr would then be: how is Espressif compiling their GCC-based toolchains for Windows? With |
Well we can at least try this path. You'll need a linker proxy similar to mine. It will just do a chdir() to a directory passed as a special parameter, then run the GCC linker, and then chdir() back. |
As the commit says, I've implemented a workaround that simply copies the cmake build output to the workspace root. This solution isn't great but it is the simplest right now. Making a symlink instead of copying requires elevated permissions on windows.
I don't like that we have to use an extra tool just to work around this, but if we did this it would require us (at least on windows) to parse the response file that cargo gives the linker which contains its command line. We need to do this to handle quoted arguments and paths with spaces. The current But I think the best solution forward is to make a linker wrapper which handles the above. Even if a new build of That's just my reasoning, please tell me what you think. Also, it compiles and runs fine now. I don't know about the patches though. How should these be applied knowing that using cmake one can specify every version? For which |
I'll look into that later.
I didn't do it because it is still a bit of a hack, and moreover - I don't think ESP-IDF supports paths with whitespaces on it anyway. But yeah, more diligent processing of that file would be necessary. Not a rocket science, though.
In the previous paragraph you say that you kind of don't like the idea of a linker proxy just to workaround the long file paths. Here you say that the best solution forward is to make a linker wrapper. I'm a bit confused. For me, these things (linker proxy & linker wrapper) are one and the same thing. You agree?
Well, I definitely prefer a linker wrapper = linker proxy over spilling out stuff outside of the
I'm surprised that it works for you without you applying the thread-local patch at least. Without that one, it should break right after "joining the threads" in the demo binary crate. The non-master patches are for V4.3. |
Yes they're the same. I don't like this solution as it requires a tool that the user has to install beforehand. But it's the best solution because we don't have to sanitize the linker args if/when gcc is updated (or I guess rebuilt), if that doesn't happen it's the only solution. But that doesn't mean I have to like it ^^. Btw. for me the difference between this linker proxy tool and
|
Except that our linker proxy is a cargo subcommand. This means two things:
|
That is also true. |
@N3xed Sorry for the late notice: there is a meeting this Tuesday of rust-on-esp contributors and some of the Espressif folks. Given that having a cargo-first build story with "native" ESP-IDF is important, you might want to participate? If so, can you contact me privately on the esp-rs chat. I need an email address of yours to forward you the invite. In any case, I'll update the agenda for the meeting with the progress done here by you. |
@ivmarkov (1) (2) (3) I will start with (1) and (2) if you're OK with this plan. I'd also like to know what you think about (3) or alternatives. |
I definitely agree with (1) and (2). (3) seems reasonable too - we could use it for flashing, filesystem creation, and why not for monitoring ( |
As far as I can see, without this, response files don't really do anything to alleviate the command-line length limitation on windows. As I've described in a comment above:
So this option should really always be used on windows (assuming See also this:
|
@N3xed thanks! Do you have some fast test to check the using of response files, and to check that it helps us? If not, I'll try to check on my own soon.
|
@antmak Thank you for the builds. I don't have a quick check currently, but will test if this solves the problem with the command-line length as soon as I make some progress with this PR. |
Move `build.rs` contents to `build_pio.rs` Add feature `native` Add optional dependency `strum`
Indeed. Let's have the first iteration of the native build working, and then we can take one of these paths. By the way, for me the native build fails (after all the issues I've mentioned so far are workarounded) with the following error:
|
Use correct target name for `riscv32`.
That's weird. I can't test it as windows spits out Note: I've tested only |
Are you preserving the order of all linker args that you get from |
I'll try if we have the same issue with the ESP32. |
Well yeah that is what it's doing, I'm getting these arguments from cmake. And my guess is that they are missing a final |
Okay, so my guess was partially correct. But it actually happens because There is a workaround: Not sure what better way there is to prevent that. Maybe we could emit something for |
Argh, we have been looking at the same problem. See esp-rs/embuild#16 |
Not to worry, I didn't spend much time on this; you did go much more in-depth than me, nice work. |
Fix potentially using `:` to split PATH on windows.
That's not really true, don't you have to install
I don't like option 4 as it implies that every time And like you point out in the cons of option 1, we should probably not interfere with any installation the user did themselves, though in the case of If both build variants (i.e. pio and native) have to be consistent with the way they are installing the tools this would imply options 2 and 3. But then it doesn't really make sense that this build script installs tools under a Maybe the way forward would be to roll our own install logic (currently this leverages Leaving this issue aside for now though, I propose that we leave the installed tools under a folder in the workspace dir for now (there is already an environment variable to change the default directory). But we should definitely pick a better name than Other than that I think we should merge this like it is and mention in the README/docs that this is an experimental feature for now (and of course setting the default to pio, since it is experimental). |
Actually, why not? As I mentioned in another comment, ESP-IDF (and Espressif) are big enough to deserve their own little "espidf" module in embuild? I don't consider this necessarily "dirty" given that it will nicely built upon the other modules of embuild. But this can be a next step.
I think that would mean extra maintenance burden for us. Why bother? And then - as per above, IMO no big deal to have something ESP-IDF specific in embuild, in its own module.
OK I can somehow live with that. However you really really don't like
Agreed. |
I mean it is a maintenance burden for us either way if we use Also, we'd need to add some logic in this regard anyway if we'd want to remove the requirement that the user has to install
Yeah, but having some code that depends on some python script inside the
Do you mean you want to change the default of the I picked Or do we want to define now that this will use |
Also, we should probably release a new |
Done. Also created esp-rs/embuild#17 |
Set min python version to 3.7. Set default build feature to pio. Make `native` feature usable.
This is very work-in-progress work to compile the
esp-idf
usingcmake
.Currently, it compiles (tested for esp32 on windows) but doesn't run when it has been flashed.
Please give feedback and/or tell me if you find something wrong.