PlatformIO Community

Use two different copies of a library with the same name (SD lib)

I have this platform.ini:
[platformio]
default_envs =
mega2560
esp32
esp8266
native

[env:esp32]
platform = espressif32
board = node32s
framework = espidf
monitor_speed = 115200

[env:mega2560]
platform = atmelavr
board = megaatmega2560
framework = arduino
monitor_speed = 115200

[env:native]
platform = native

[env:esp8266]
board = esp01_1m
platform = espressif8266
framework = arduino
monitor_speed = 115200

The trouble is I need to use a different SD library for the mega2560 and for the esp8266**

**failing that i’d just forgo the arduino framework on the ESP8266 altogether but i can’t get the espressif stuff to work with C++ code, only with C code. That’s an alternative (and preferred) solution but I’ve had no luck

So as far as using two different libraries with the same name, but for different builds, how do I do that without modifying the code for the libraries?

Every environment can have lib_deps declarations for their libraries (docs).

It doesn’t matter if they’re called the same – for a builtin library, that’s even a must. You can e.g. have the lib_deps = Wire (for I2C) in two environments, one for a board = uno and another board = nodemcuv2, and the build process will pull in the correct built in library from the framework.

When using external libraries from e.g. the library registry, they are still distinguishable since they’re published by different owners. So we can reference e.g. adafruit/SD @ ^0.0.0-alpha+sha.041f788250 and arduino-libraries/SD @ ^1.2.4, even though they’re both called “SD”.

Actually in your case, if #include <SD.h> is a line in your main cpp file, PlatformIO’s library dependency finder should pick up the usage of that library without you even needing to declare it in lib_deps, and pull in the correct library accordingly.

That sounds good in theory. In practice I get this:

In file included from lib/SD/src/utility/Sd2Card.h:26:0,
             from lib/SD/src/utility/SdFat.h:29,
             from lib/SD/src/SD.h:20,
             from src/main.cpp:33:

lib/SD/src/utility/Sd2PinMap.h:524:2: error: #error Architecture or board not supported.
#error Architecture or board not supported.
^
In file included from lib/SD/src/utility/Sd2Card.h:26:0,
from lib/SD/src/utility/SdFat.h:29,
from lib/SD/src/SD.h:20,
from lib/SD/src/File.cpp:15:
lib/SD/src/utility/Sd2PinMap.h:524:2: error: #error Architecture or board not supported.
#error Architecture or board not supported.
^
In file included from lib/SD/src/utility/Sd2Card.h:26:0,
from lib/SD/src/utility/SdFat.h:29,
from lib/SD/src/SD.h:20,
from lib/SD/src/SD.cpp:53:
lib/SD/src/utility/Sd2PinMap.h:524:2: error: #error Architecture or board not supported.
#error Architecture or board not supported.
^
*** [.pio/build/esp8266/lib4c8/SD/File.cpp.o] Error 1
*** [.pio/build/esp8266/src/main.cpp.o] Error 1
*** [.pio/build/esp8266/lib4c8/SD/SD.cpp.o] Error 1

So how do I make it do the right thing? It’s trying to use the wrong SD lib

Well putting the SD library for one particular in version / platform in lib/ breaks it of course*. Can you remove that folder and let PlatformIO decide the source? Or is there a particular fix in that library that must be used (which PlatformIO can still do with a lib_deps = SD=file://some/file/path syntax)

** If there is no library.json that declares compatibility with certain platform and framework values, then PlatformIO should correctly ignore that source

Now it won’t build for my Mega either because I removed the library. Whatever automagic thing platformIO is supposed to do with libraries isn’t working, and that’s why I hate automagic things and why I moved away from Arduino IDE. It would be nice to have a platform for this that was just raw C++ and a toolchain, rather than all these “automatic” scripts

So how do I modify library.json because now I apparently need to override all of this dirty magic

Edit: never mind. I figured it out using lib_deps =

I’ve tested this myself and the caveat is that

  1. When using board = megaatmega2560 the framework does not have a builtin SD library as I thought, so it must be declared as being sourced from arduino-libraries
  2. For the ESP8266 environment, the library must be referenced with SD(esp8266)

So my platformio.ini of

[env:megaatmega2560]
platform = atmelavr
board = megaatmega2560
framework = arduino
lib_deps = 
    arduino-libraries/SD @ 1.2.4

[env:esp8266]
board = esp01_1m
platform = espressif8266
framework = arduino
monitor_speed = 115200
lib_deps =
    SD(esp8266)

with src/main.cpp of

#include <Arduino.h>
#include <SD.h>

void setup() {
  /* argument = chip select pin */
  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
}

void loop() { }

works for both environments.

hah, thanks! I figured it out just before you replied but the detail you added will probably help people down the road. I appreciate it, as this was frustrating.