Extending PlatformIO

Hi!

I think I want to extend PlatformIO, and I am not sure what is the best way.
Are there any examples of vscode-plugins that does this, or are there other ways?

I am developing a kind of meta framework/toolkit with the goal of making all kinds of boards able to communicate with each other, regardless of framework, for example on an ESP32 or an Arduino. Or STM32 or Raspberry Pico. It is also about having more cross platform code.And in general make it easier to get going. Basically it is about doing all the #if’s so others don’t have, it feels like. :slight_smile:

The thinking is that the same code should be able to run on all of them, and if one would like, even in the same project, something that PlatformIO, impressively and rather elegantly, makes possible.

The first thing that is relevant , I have made scripts that adds KConfig support to all PlatformIO projects (except ESP-IDF, Zephyr or others that already has it, of course), and adds itself in the tasks lists and so on. But they have to be included using “extra scripts”, which either isn’t very general, or very convenient. I have also not found any ways for dependencies to extend PlatformIO itself.

I am also quite certain that you wouldn’t want to add these things to PlatformIO code, at least not in its current state. I wouldn’t, let’s put it that way. :slight_smile:

Any ideas?

You mean to fork https://github.com/platformio/platformio-vscode-ide/?

Hi!

No, I am wondering if there is any way to extend it so that I can add for example KConfig-support to PlatformIO-projects “from the outside”. I am trying to find out how I can extend PlatformIO, basically.

Well the PlatformIO core code is the basis for everything, if it’s supposed to work for all platform (atmelavr, esp32, …) and frameworks, I think that’s the place to add it.

So there is no way to extend platform-io core without committing to it?
It would be nice if there was, that way stuff like this could get to mature on the outside, without having to implement it in the framework.

You can also add certain types of functionalities like new project tasks (such as “open the kconfig”) by using Advanced Scripting. The project you want to use this in though then has to have at least a extra_scripts = <your script.py> line in its platformio.ini.

That is how I am doing it now. However that needs to be added through manipulating platformio.ini, and I am not sure if extra_scripts can easily be pointing to something provided by package.

I would rather have a way to add that functionality either by me plugging in, by being a package, or if there was some other way to extend PlatformIO.

Thanks for your quick reply, BTW!

Could you share your extra scripts? We can review them and add missed API/functionality.

Sure, but be gentle, it is a bit hackish:

You can seen the platform.ini config obviously, and the scripts are in the /scripts folder.

So basically (if it’s not ESP-IDF), it adds a menuconfig task to the menu, which runs menuconfig on the config file it has created in the init_env.py.
At build time, the pre-build script is run, which generates the header with the config and puts it directly into the build folder.

I am not very knowledgeable when it comes to what is the best way of doing things, and it isn’t smart and looks for Kconfig in dependencies and stuff like that.
While that is probably not hard to do, I have no idea if I’d be doing things in the way that is intended in PlatformIO.

Thanks for sharing the project. A few comments:

  1. Tactically, you are doing everything correctly.
  2. Technically, I would recommend making your code more portable between operating systems. Please replace all os.system() calls with native Python functions. See os.remove(), os.makedirs(), shutil — High-level file operations — Python 3.11.3 documentation , etc.
1 Like

Yeah, that would be better.

So there is no way for a library or other construct to hook into PlatformIO and extend it in general then, have I understood this correctly? The only possibility is per-project?

You can do the same with libraries. See extraScript — PlatformIO latest documentation

1 Like

Exactly what I was looking for, or at least I think so! Thank you!
(no idea how didn’t find that before)

1 Like

Hi @ivankravets,

I still seem to have some roblems running the scripts.
Possibly with regards to timing, or possibly with regards to context, I am not sure.

What I did before (above) was this:
extra_scripts =
pre:scripts/pre-build.py
scripts/init_env.py

But as extraScript neither takes two files as parameters or cares about the pre: prefix, I keep failing after trying all kinds of combinations to make it work using AddPre/PostAction instead.

There seem to be two problems:

  1. When I run the Kconfig generation of the config.h-file, I seem to run it a bit too early, as the robconfig.h isn’t found even though I have added it using env.Append(CPPPATH=[build_dir]) and env.BuildSources(build_dir, build_dir)…with one exception; it seems like it is found in main.c. But nowhere else.

  2. And the adding of the menu targets, there I have tried with all combinations of addPre- or -PostAction that seemed relevant.

So my questions are; what actions are appropriate to be pre/post when:

  1. Adding source files that are to be included in the build?
  2. Adding targets that can be clicked in the menu.

The latest attempt, where I, quite desperately, tried to be post “clean”, just to be able to get some output, made absolutely nothing happen: GitHub - nicklasb/robusto-platformio

You missed one important thing. The env which you use in the library extra script is different in comparison to the env which you used in the extra project script. Docs

https://docs.platformio.org/en/latest/scripting/construction_environments.html

See also examples in
https://docs.platformio.org/en/latest/manifests/library-json/fields/build/extrascript.html

If you want to reach the global construction environment (which is a default in project extra scripts), you have to use global_env = DefaultEnvironment().

1 Like

Aha…thanks!
I will try that!

Hi…sorry for keeping on needing help here, but if I succeed, it could be a nice example on how to really extend PlatformIO and its ecosystem.

So I have gotten the hang of the different environments now, the only thing remaining is adding the “Run menuconfig”-target. I can successfully add it by running a build and muck around with triggering a rebuild of the target menu by making small changes of the platform.ini file.

But what one could expect an extension to do, would be to add its functionality when installed, and remove it when uninstalled. Not when a build is run, it might have nothing to do with the build.

For that, the scripts - postinstall and preuninstall would be perfect.
But I can’t for the life of me get access to any of the pio environments from there, like I can from the lib_extra_scripts and the extraScript. I have tried different kinds of hackish calls, the last was to try and run pios virtual env, but that didn’t have any of that, or I was already in it.
Is there any way to get to the environments there? It would be quite natural if it was possible, as the dependencies are per project and environment?

Basically, if I want to extend PlatformIO beyond the build process, I cannot add functionality that depends on it being in place before the build process (or any other) is invoked. And as I do not want to start monkey patching PlatformIO, access to instrumentation at package install time would be great.

@ivankravets
So should I understand it as there is no way to do what I am trying to do?

Do you mean scripts — PlatformIO latest documentation ?