PlatformIO Community

Library with nested directory structure

Hi,
I have problem with project compilation using library with nested directory struture.
Library I used and which causes problem is https://developer.mbed.org/users/nxp_ip/code/PCAL955x/ which has this structure after imported to PIO:
.piolibdeps\PCAL955x\PCAL9554\PCAL9554.cpp
.piolibdeps\PCAL955x\PCAL9554\PCAL9554.h
.piolibdeps\PCAL955x\PCAL9555\PCAL9555.cpp
.piolibdeps\PCAL955x\PCAL9555\PCAL9555.h
.piolibdeps\PCAL955x\base_classes\PCAL955x.cpp
.piolibdeps\PCAL955x\base_classes\PCAL955x.h
.piolibdeps\PCAL955x\base_classes\CompGpioExp\CompGpioExp.cpp
.piolibdeps\PCAL955x\base_classes\CompGpioExp\CompGpioExp.h
.piolibdeps\PCAL955x\base_classes\CompGpioExp\CompGpioExpAPI.h
.piolibdeps\PCAL955x\base_classes\CompGpioExp\GpioBus\GpioBusIn.cpp
.piolibdeps\PCAL955x\base_classes\CompGpioExp\GpioBus\GpioBusIn.h
.piolibdeps\PCAL955x\base_classes\CompGpioExp\GpioBus\GpioBusInOut.cpp
.piolibdeps\PCAL955x\base_classes\CompGpioExp\GpioBus\GpioBusInOut.h
.piolibdeps\PCAL955x\base_classes\CompGpioExp\GpioBus\GpioBusOut.cpp
.piolibdeps\PCAL955x\base_classes\CompGpioExp\GpioBus\GpioBusOut.h
.piolibdeps\PCAL955x\base_classes\CompGpioExp\GpioDigital\GpioDigitalIn.cpp
.piolibdeps\PCAL955x\base_classes\CompGpioExp\GpioDigital\GpioDigitalIn.h
.piolibdeps\PCAL955x\base_classes\CompGpioExp\GpioDigital\GpioDigitalInOut.cpp
.piolibdeps\PCAL955x\base_classes\CompGpioExp\GpioDigital\GpioDigitalInOut.h
.piolibdeps\PCAL955x\base_classes\CompGpioExp\GpioDigital\GpioDigitalOut.cpp
.piolibdeps\PCAL955x\base_classes\CompGpioExp\GpioDigital\GpioDigitalOut.h

Main code is as simple as this:

#include "mbed.h"
#include "PCAL9554.h"

PCAL9554 i2c_gpio(I2C_SDA, I2C_SCL, 0x40);

int main()
{
    i2c_gpio.configure(0x00);
    for (int i=0; i<=256; i++)
    {
        i2c_gpio.write(i);
        wait_ms(100);
    }
}

platformio.ini has following:

[env:nucleo_l476rg]
platform = ststm32
board = nucleo_l476rg
framework = mbed
upload_port = G:
lib_deps = https://developer.mbed.org/users/nxp_ip/code/PCAL955x/

Compiler result is:

Collected 9 compatible libraries
Looking for dependencies...
Project does not have dependencies
Compiling .pioenvs\nucleo_l476rg\src\main.o

src\main.cpp:2:22: fatal error: PCAL9554.h: No such file or directory
#include "PCAL9554.h"
^
compilation terminated.
*** [.pioenvs\nucleo_l476rg\src\main.o] Error 1
 [ERROR] Took 4.12 seconds

It looks like it has some issue with library with nested directory structure to find given file. PIO also reports no dependencies.
If I change #include line like this
#include "PCAL9554/PCAL9554.h"
compiler finds file PCAL9554.h but other references/includes inside library still not work. Compiler gives:

Looking for dependencies...
Library Dependency Graph
|-- <PCAL955x>

Compiling .pioenvs\nucleo_l476rg\src\main.o
Compiling .pioenvs\nucleo_l476rg\lib\PCAL955x\PCAL9554\PCAL9554.o
Compiling .pioenvs\nucleo_l476rg\lib\PCAL955x\PCAL9555\PCAL9555.o
Compiling .pioenvs\nucleo_l476rg\lib\PCAL955x\base_classes\CompGpioExp\CompGpioExp.o
In file included from src\main.cpp:2:0:
.piolibdeps\PCAL955x/PCAL9554/PCAL9554.h:21:25: fatal error: PCAL955x.h: No such file or directory
#include    "PCAL955x.h"
^
compilation terminated.
*** [.pioenvs\nucleo_l476rg\src\main.o] Error 1
In file included from .piolibdeps\PCAL955x\PCAL9554\PCAL9554.cpp:2:0:
.piolibdeps\PCAL955x\PCAL9554\PCAL9554.h:21:25: fatal error: PCAL955x.h: No such file or directory
#include    "PCAL955x.h"
^
compilation terminated.
*** [.pioenvs\nucleo_l476rg\lib\PCAL955x\PCAL9554\PCAL9554.o] Error 1
In file included from .piolibdeps\PCAL955x\PCAL9555\PCAL9555.cpp:2:0:
.piolibdeps\PCAL955x\PCAL9555\PCAL9555.h:21:25: fatal error: PCAL955x.h: No such file or directory
#include    "PCAL955x.h"
^
compilation terminated.
*** [.pioenvs\nucleo_l476rg\lib\PCAL955x\PCAL9555\PCAL9555.o] Error 1
 [ERROR] Took 4.55 seconds

What would be correct way using such library with nested directory structure?

Thanks

Have you tried to add into platformio.ini?

[env:...]
build_flags = -I.piolibdeps/PCAL955x/base_classes  -I.piolibdeps/PCAL955x/PCAL9554 -I.piolibdeps/PCAL955x/PCAL9555

I tried to add following into platformio.ini

build_flags =
    -I .piolibdeps/PCAL955x/PCAL9554
    -I .piolibdeps/PCAL955x/PCAL9555
    -I .piolibdeps/PCAL955x/base_classes
    -I .piolibdeps/PCAL955x/base_classes/CompGpioExp
    -I .piolibdeps/PCAL955x/base_classes/CompGpioExp/GpioBus
    -I .piolibdeps/PCAL955x/base_classes/CompGpioExp/GpioDigital

and it works now.

Nevertheless, I was wondering if there is some simpler way instead of listing all subdirectories in library dir. E.g. some option to tell compiler to look recursively in given directory.

Thanks

Sure, see 2-nd example here http://docs.platformio.org/en/latest/librarymanager/config.html#id5

Hello,
I have upgraded pio to 3.4.1a4 and trying same example as before. It seems it is not working again.

I have follownig in platformio.ini:

build_flags =
            -I .piolibdeps/PCAL955x/PCAL9554
            -I .piolibdeps/PCAL955x/PCAL9555
            -I .piolibdeps/PCAL955x/base_classes
            -I .piolibdeps/PCAL955x/base_classes/CompGpioExp
            -I .piolibdeps/PCAL955x/base_classes/CompGpioExp/GpioBus
            -I .piolibdeps/PCAL955x/base_classes/CompGpioExp/GpioDigital

but linker is still having problems to link main code with library:

Linking .pioenvs\nucleo_l476rg\firmware.elf
.pioenvs/nucleo_l476rg/src/main.o: In function `main':
main.cpp:(.text.startup.main+0x6): undefined reference to `PCAL955x::configure(int)'
main.cpp:(.text.startup.main+0x10): undefined reference to `PCAL955x::write(int)'
.pioenvs/nucleo_l476rg/src/main.o: In function `_GLOBAL__sub_I_i2c_gpio':
main.cpp:(.text.startup._GLOBAL__sub_I_i2c_gpio+0xc): undefined reference to `PCAL9554::PCAL9554(PinName, PinName, char)'
main.cpp:(.text.startup._GLOBAL__sub_I_i2c_gpio+0x24): undefined reference to `PCAL9554::~PCAL9554()'
collect2.exe: error: ld returned 1 exit status
*** [.pioenvs\nucleo_l476rg\firmware.elf] Error 1
 [ERROR] Took 4.51 seconds

From co,piler log it looks like PCAL955x library is not compiled even it is in platformio.ini:

lib_deps = https://developer.mbed.org/users/nxp_ip/code/PCAL955x/

Any idea what is wrong?

Thanks

Playing little bit more with example I found difference causing it works/it doesn’t work.

Having this in platformio.ini:

build_flags =
            -I .piolibdeps/PCAL955x/PCAL9554
            -I .piolibdeps/PCAL955x/PCAL9555
            -I .piolibdeps/PCAL955x/base_classes
            -I .piolibdeps/PCAL955x/base_classes/CompGpioExp
            -I .piolibdeps/PCAL955x/base_classes/CompGpioExp/GpioBus
            -I .piolibdeps/PCAL955x/base_classes/CompGpioExp/GpioDigital

I thought above directories are used for header file search and it would be fine to have this in main code:

#include "mbed.h"
#include "PCAL9554.h"

Unfortunatelly above is not working. Adding parent direcotry of header file seems to solve issue:

#include "mbed.h"
#include "PCAL9554/PCAL9554.h"

This works as expected. pio detects library dependency and compile and link code.

Why is needed to specify parent directory (or even some folder hierarchy in case it is deeper) if all these directories are in in build_flags?

Thanks

PlatformIO Library Dependecy Finder ignores global envrinmoment while find depenpdent candidates. You should configure environment directly from library.json. Just create this file, please to libary folder, fill name and version field, declare custom build option and all should work.

Hello,
apologies for reviving this topic, but I’m running into the same exact problem. I placed a very large library in /lib, with many subfolders, and I can’t find the correct way to make the compiler look recursively using library.json.

The link to the post I’m replying is now pointing at the library.json docs, which are comprehensive, but I can’t find the specific example. I tried writing the following library.json:

"export": {
    "include": [
        "*.h",
        "*/*.h",
        "*/*/*.h"
    ]
}

… and variations of it, but it did not work. If I manually add folders in platformio.ini as build_flags -I, then it starts to see them - but it’s absolutely unfeasible for me to do so, there’s dozens of folders. Would you be able to help me?

Also having this problem and in need of a solution

Hi @ivankravets, any help on this?
Same issue here
Any help would be so much appreciated.

Keep up with the good work!

You need to use “build” field from “library.json” https://docs.platformio.org/en/latest/librarymanager/config.html#build

You can explain PlatformIO where source files are located and filter some of them.