PlatformIO Community

One platformio.ini for multiple projects

So lets say I have a repository. And this repository contains multiple platformio projects inside of it which share modules (ie. files) common to all projects. For example, projectA and projectB both use a common Button module, so I will nest that Button module in the root folder and require it from there within each projects main.c or whatever.

Something like this.


How would I structure my platformio.ini file? I believe I would need multiple builds - one build for each project, but I am extremely confused with how to do that. My PATH knowledge is very limited.

IMO, the best way is to organize common modules (e.g. Button) as separate libraries and then let the LDF find them automatically.

Sure, sounds like something I am trying to do. Do you have an example I could look at?

You just need to specify path to your libraries using the lib_extra_dirs option in your platformio.ini


Is there any way to have the same functionality for include directories?
I need to create a multi-target abstraction, where each target has its own include files and own libraries.

For me it is rather one project with multiple targets.

Also the lib_ignore part for me sadly doesn’t work, as I put target specific source files in a library directory, without doing anything that identifies it as a library.
Some kind of lib_ignore_dir to ignore the whole library folder and add a target specific library/directory with a command like lib_add_dir would be nice.

What I find weird is that when I for example create a new directory that I call target, that is supposed to be used like the lib directory, but in a way that not all of the libraries are added automatically.

I want to use the directory in a way, that I declare for every target a library directory, that should
be built and linked to the binary file.

platform = nxplpc
board = lpc1768

; Needs to stay for every probe
build_flags = -D MCB1700, -D LPC1768, -Wl,-T"./scripts/target/LPC1768/LPC1768.ld", -D DEBUG
extra_scripts = scripts/target/LPC1768/

; ignore everythin in lib folder and only add the platform specific library
lib_extra_dirs = target/LPC1768

;J-Link Probe
upload_protocol = jlink-jtag
debug_tool = jlink

platform = atmelavr
board = atmega328p

; atmega328p specific binary files, e.g. board init etc.
lib_extra_dirs = target/ATmega328p

; build and debugging flags
build_flags = -D ATMEGA328P, -D DEBUG

; upload port.
upload_port = /dev/cu.SLAB_USBtoUART

The behavior of the lib_extra_dirs seems to be different from the lib directory, as header files seem not to be found properly.

this is the current repository’s revision, that I want to get working properly.

Thanks for your time and effort.

Please provide a minimal example project that reproduces the problem to, this is very interesting

Again there is the way through an extra script, the documentation describes a library which includes different source and include folders depending on the target, while excluding source foldes not meant for the target. In the example it’s done by looking at the value of a compile-time flag and adding to CPPPATH and modifying SRC_FILTER.

1 Like

the linked repository revision is the example.
Firstly I tried adding those two libraries, that are currently in the target directory into the lib directory.
In the lib directory, the wrong files are being linked, as lib_ignore lib combined with lib_extra_dirs = lib/ATmega328p sadly doesn’t do the job, because no library identification there.

And at the current revision, the header files in the specific extra directories lib_extra_dirs = target/ATmega328p and in lib_extra_dirs = target/LPC1768 are not being recognized by neither the compiler/linker nor by the IntelliSense, when I try to build it at the current revision.

Edit: opened an issue in the core project.

Well, I literals wrote lib_ignore libwhich was supposed to ignore the whole lib folder contents, but doesn’t as the actual lib folder is not a library, as mentioned above by the approved answer, thus the full library folder was not ignored(just an attempt at stuff that is not supposed to work that way at all).

You can also try src_filter setting instead, which will include different source files for each environment corresponding to different projects.

1 Like

I think the src_filter is the way to go without writing actual python scripts for extending the behavior.

It would be pretty awesome if there was some kind of inheritance syntax/mechanism, in order to have your default [env] contain your basic src_filter stuff

src_filter =

and derived environments [env:lpc1768] just adding stuff to the filter.


src_filter += +<target/LPC1768>

As ini files don’t seem to support the +=syntax, one could differentiate between an explicitly declared global [env] with a explicitly declared src_filter versus the default hidden global environment, where an explicitly declared [env] without an explicitly declared src_filter is considered as the not existing default value.

Where the default one would cause src_filter = +<xyz> to actually replace the whole src_filter and an explicitly declared

src_filter = +<xyz>

would cause the derived environments to actually append to the src_filter


I find it rather weird, that when I use this src_filter and some header files contain
includes with the pointy brackets, that the gpio.h is not being found with #include <gpio.h>, but is found with #include "gpio.h". Including header and gpio.h are in the same directory.

But #include <> is an instruction of ‘look in the standard include paths’ and ‘#include “”’’ is an instruction to look in the relative path specified, then fall back to the standard include paths, no?

And yes, being able to add to environments would be nice… which is why you can do it… :stuck_out_tongue: Have a look at the [common] environment block used in this post, and see how the src_filter is manipulated between environments from a single common one.

1 Like

That’ts pretty awesome :D.

1 Like

Yeah, I thought it was pretty neat that I could start reducing the length of my platformio.ini when the ability to have sub environments inherit from env for stuff that merely duplicates… then Ivan pointed out I could also stack the configuration values … like… cooolll! :smiley:

@scottc11 How did this work out for you? Can you share what worked for you?

to be honest, I think this thread got a touch off-track ahah. I essentially was looking for a way to house a monorepo with platformio. I am very novice when it comes to the compilation process of C/C++ programs.

However, I think the initial solution @valeros suggested about using lib_extra_dirs might work for now until I learn a bit more about make files or something. With this approach I will create a git repo to house all my common modules/libraries and just make sure to put it in an easily found directory for other projects. :man_shrugging:

Still would be nice to see a platformio monorepo example in the docs somewhere! :ok_hand::wink: