ArduinoIoTCloud: Getting it to work with Heltec WIFI Kit 32

I am having a heck of a time getting a build completed with the ArduinoIoTCloud library as part of my project. I am using a Heltec WiFi Kit 32 board. Seems there are any number of conflicts between various libraries. I have tried a number of lib_ignore in my platformio.ini but still seem to be missing something fundamental. Here are some of the errors:

.pio/libdeps/heltec_wifi_kit_32/WiFi101/src/socket/include/socket.h:1839:15: error: conflicting declaration of C function 'sint8 close(SOCKET)'     NMI_API sint8 close(SOCKET sock);

.pio/libdeps/heltec_wifi_kit_32/WiFi101/src/WiFiUdp.h:35:7: error: redefinition of 'class WiFiUDP'

(those are just the lines in red… I attach the full set of errors below.

Anyone been successful with this library and could give me a few pointers?
Thanks!

CONFIGURATION: https://docs.platformio.org/page/boards/espressif32/heltec_wifi_kit_32.html
PLATFORM: Espressif 32 (5.0.0) > Heltec WiFi Kit 32
HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash
DEBUG: Current (cmsis-dap) External (cmsis-dap, esp-bridge, esp-prog, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd, olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa)
PACKAGES:
 - framework-arduinoespressif32 @ 3.20003.220626 (2.0.3)
 - tool-esptoolpy @ 1.30300.0 (3.3.0)
 - tool-openocd-esp32 @ 2.1100.20220411 (11.0)
 - toolchain-xtensa-esp32 @ 8.4.0+2021r2-patch3
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ deep, Compatibility ~ soft
Found 49 compatible libraries
Scanning dependencies...
Dependency Graph
|-- Sensirion I2C SEN5X @ 0.2.0
|   |-- Sensirion Core @ 0.6.0
|   |   |-- Wire @ 2.0.0
|   |-- Wire @ 2.0.0
|-- GFX Library for Arduino @ 1.2.3
|   |-- SPI @ 2.0.0
|-- Adafruit GFX Library @ 1.11.3
|   |-- Adafruit BusIO @ 1.12.0
|   |   |-- Wire @ 2.0.0
|   |   |-- SPI @ 2.0.0
|   |-- SPI @ 2.0.0
|   |-- Wire @ 2.0.0
|-- Heltec ESP32 Dev-Boards @ 1.1.1
|   |-- Wire @ 2.0.0
|   |-- SPI @ 2.0.0
|-- ArduinoIoTCloud @ 1.6.1
|   |-- ArduinoECCX08 @ 1.3.6
|   |   |-- Wire @ 2.0.0
|   |-- WiFi @ 2.0.0
|   |-- Arduino_DebugUtils @ 1.3.0
|   |-- Adafruit SleepyDog Library @ 1.6.1
|   |-- Arduino_ConnectionHandler @ 0.6.6
|   |   |-- Arduino_DebugUtils @ 1.3.0
|   |   |-- MKRGSM @ 1.5.0
|   |   |-- MKRNB @ 1.5.1
|   |   |-- MKRWAN @ 1.1.0
|   |   |-- WiFi @ 2.0.0
|   |   |-- WiFi101 @ 0.16.1
|   |   |   |-- SPI @ 2.0.0
|   |-- ArduinoMqttClient @ 0.1.5
|   |-- WiFiClientSecure @ 2.0.0
|   |   |-- WiFi @ 2.0.0
|   |-- WiFi101 @ 0.16.1
|   |   |-- SPI @ 2.0.0
|   |-- RTCZero @ 1.6.0
|-- Wire @ 2.0.0
|-- Arduino_ConnectionHandler @ 0.6.6
|   |-- Arduino_DebugUtils @ 1.3.0
|   |-- MKRGSM @ 1.5.0
|   |-- MKRNB @ 1.5.1
|   |-- MKRWAN @ 1.1.0
|   |-- WiFi @ 2.0.0
|   |-- WiFi101 @ 0.16.1
|   |   |-- SPI @ 2.0.0
Building in release mode
Compiling .pio\build\heltec_wifi_kit_32\src\main.cpp.o
Generating partitions .pio\build\heltec_wifi_kit_32\partitions.bin
Compiling .pio\build\heltec_wifi_kit_32\libc00\Wire\Wire.cpp.o
Compiling .pio\build\heltec_wifi_kit_32\libb5a\Sensirion Core\SensirionCrc.cpp.o
Compiling .pio\build\heltec_wifi_kit_32\libb5a\Sensirion Core\SensirionErrors.cpp.o
Compiling .pio\build\heltec_wifi_kit_32\libb5a\Sensirion Core\SensirionI2CCommunication.cpp.o
Compiling .pio\build\heltec_wifi_kit_32\libb5a\Sensirion Core\SensirionI2CTxFrame.cpp.o
In file included from .pio/libdeps/heltec_wifi_kit_32/WiFi101/src/WiFiUdp.h:24,
                 from .pio/libdeps/heltec_wifi_kit_32/Arduino_ConnectionHandler/src/Arduino_ConnectionHandler.h:121,
                 from .pio/libdeps/heltec_wifi_kit_32/ArduinoIoTCloud/src/ArduinoIoTCloud.h:27,
                 from src/thingProperties.h:3,
                 from src/main.cpp:57:
.pio/libdeps/heltec_wifi_kit_32/WiFi101/src/socket/include/socket.h:1839:15: error: conflicting declaration of C function 'sint8 close(SOCKET)'      
 NMI_API sint8 close(SOCKET sock);
               ^~~~~
In file included from C:/Users/peted/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/newlib/platform_include/sys/unistd.h:23,
                 from c:\users\peted\.platformio\packages\toolchain-xtensa-esp32\xtensa-esp32-elf\sys-include\unistd.h:4,
                 from c:\users\peted\.platformio\packages\toolchain-xtensa-esp32\xtensa-esp32-elf\sys-include\pthread.h:25,
                 from C:/Users/peted/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/newlib/platform_include/pthread.h:21, 
                 from c:\users\peted\.platformio\packages\toolchain-xtensa-esp32\xtensa-esp32-elf\include\c++\8.4.0\xtensa-esp32-elf\no-rtti\bits\gthr-default.h:48,
                 from c:\users\peted\.platformio\packages\toolchain-xtensa-esp32\xtensa-esp32-elf\include\c++\8.4.0\xtensa-esp32-elf\no-rtti\bits\gthr.h:151,
                 from c:\users\peted\.platformio\packages\toolchain-xtensa-esp32\xtensa-esp32-elf\include\c++\8.4.0\ext\atomicity.h:35,
                 from c:\users\peted\.platformio\packages\toolchain-xtensa-esp32\xtensa-esp32-elf\include\c++\8.4.0\bits\basic_string.h:39,
                 from c:\users\peted\.platformio\packages\toolchain-xtensa-esp32\xtensa-esp32-elf\include\c++\8.4.0\string:52,
                 from c:\users\peted\.platformio\packages\toolchain-xtensa-esp32\xtensa-esp32-elf\include\c++\8.4.0\stdexcept:39,
                 from c:\users\peted\.platformio\packages\toolchain-xtensa-esp32\xtensa-esp32-elf\include\c++\8.4.0\array:39,
                 from c:\users\peted\.platformio\packages\toolchain-xtensa-esp32\xtensa-esp32-elf\include\c++\8.4.0\tuple:39,
                 from c:\users\peted\.platformio\packages\toolchain-xtensa-esp32\xtensa-esp32-elf\include\c++\8.4.0\functional:54,
                 from C:/Users/peted/.platformio/packages/framework-arduinoespressif32/cores/esp32/HardwareSerial.h:49,
                 from C:/Users/peted/.platformio/packages/framework-arduinoespressif32/cores/esp32/Arduino.h:167,
                 from src/main.cpp:50:
c:\users\peted\.platformio\packages\toolchain-xtensa-esp32\xtensa-esp32-elf\sys-include\sys\unistd.h:30:9: note: previous declaration 'int close(int)'
 int     close (int __fildes);
         ^~~~~
In file included from .pio/libdeps/heltec_wifi_kit_32/Arduino_ConnectionHandler/src/Arduino_ConnectionHandler.h:121,
                 from .pio/libdeps/heltec_wifi_kit_32/ArduinoIoTCloud/src/ArduinoIoTCloud.h:27,
                 from src/thingProperties.h:3,
                 from src/main.cpp:57:
.pio/libdeps/heltec_wifi_kit_32/WiFi101/src/WiFiUdp.h:35:7: error: redefinition of 'class WiFiUDP'
 class WiFiUDP : public UDP {
       ^~~~~~~
In file included from C:/Users/peted/.platformio/packages/framework-arduinoespressif32/libraries/WiFi/src/WiFi.h:39,
                 from .pio/libdeps/heltec_wifi_kit_32/Arduino_ConnectionHandler/src/Arduino_ConnectionHandler.h:120,
                 from .pio/libdeps/heltec_wifi_kit_32/ArduinoIoTCloud/src/ArduinoIoTCloud.h:27,
                 from src/thingProperties.h:3,
                 from src/main.cpp:57:
C:/Users/peted/.platformio/packages/framework-arduinoespressif32/libraries/WiFi/src/WiFiUdp.h:42:7: note: previous definition of 'class WiFiUDP'
 class WiFiUDP : public UDP {
       ^~~~~~~
In file included from src/thingProperties.h:3,
Archiving .pio\build\heltec_wifi_kit_32\libc00\libWire.a
                 from src/main.cpp:57:
src/thingProperties.h: In function 'void initProperties()':
.pio/libdeps/heltec_wifi_kit_32/ArduinoIoTCloud/src/ArduinoIoTCloud.h:113:64: warning: 'void ArduinoIoTCloudClass::addPropertyReal(float&, String, permissionType, long int, void (*)(), float, void (*)(Property&))' is deprecated: Use addProperty(property, Permission::ReadWrite) instead. [-Wdeprecated-declarations]
 #define addProperty( v, ...) addPropertyReal(v, #v, __VA_ARGS__)
                                                                ^
src/thingProperties.h:20:16: note: in expansion of macro 'addProperty'
   ArduinoCloud.addProperty(humidity, READ, 5 * SECONDS, NULL);
                ^~~~~~~~~~~
In file included from src/thingProperties.h:3,
                 from src/main.cpp:57:
.pio/libdeps/heltec_wifi_kit_32/ArduinoIoTCloud/src/ArduinoIoTCloud.h:121:10: note: declared here
     void addPropertyReal(float& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(Property & property) = CLOUD_WINS) __attribute__((deprecated("Use addProperty(property, Permission::ReadWrite) instead.")));
          ^~~~~~~~~~~~~~~
In file included from src/thingProperties.h:3,
                 from src/main.cpp:57:
.pio/libdeps/heltec_wifi_kit_32/ArduinoIoTCloud/src/ArduinoIoTCloud.h:113:64: warning: 'void ArduinoIoTCloudClass::addPropertyReal(Property&, String, permissionType, long int, void (*)(), float, void (*)(Property&))' is deprecated: Use addProperty(property, Permission::ReadWrite) instead. [-Wdeprecated-declarations]
 #define addProperty( v, ...) addPropertyReal(v, #v, __VA_ARGS__)
                                                                ^
src/thingProperties.h:21:16: note: in expansion of macro 'addProperty'
   ArduinoCloud.addProperty(temperature, READ, 5 * SECONDS, NULL);
                ^~~~~~~~~~~
.pio/libdeps/heltec_wifi_kit_32/ArduinoIoTCloud/src/ArduinoIoTCloud.h:119:10: note: declared here
     void addPropertyReal(Property& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(Property & property) = CLOUD_WINS) __attribute__((deprecated("Use addProperty(property, Permission::ReadWrite) instead.")));
          ^~~~~~~~~~~~~~~
*** [.pio\build\heltec_wifi_kit_32\src\main.cpp.o] Error 1
============================================================ [FAILED] Took 20.89 seconds ============================================================

Since the library uses compile-time conditional includes, the LDF mode needs to be turned up to evaluate those. Forther for the WiFiNINA library then, it has to be manually ignored as it uses the same WiFi.h header as the built-in libraries. Besides from that, when using the official example

this causes a compile error because the Heltec board already has a LED_BUILTIN defined, so it is more correct to do

#if defined(ESP32) && !defined(LED_BUILTIN)
static int const LED_BUILTIN = 2;
#endif

As you can see in GitHub - maxgerhardt/pio-arduinoiotcloud-esp32: PIO project for https://github.com/arduino-libraries/ArduinoIoTCloud/tree/master/examples/ArduinoIoTCloud-Basic, this builds perfectly fine.

Thank you Max. Once again your brilliance has saved my project. (I wish I had asked sooner but I had to struggle for a few days first to try to learn). That said, I want to learn… how does one notice that a library is using compile-time conditional includes without going in and reading the library code?

I used lib_ldf_mode = deep+ since chain was not finding some of the Heltec library dependencies such as SPI.

This arduinoIoTCloud library sure throws a lot of warnings about depricated code. I will edit my version of the library code to fix those.

  1. When looking at the dependency graph and you see 5 different libraries for the same functionality and even possible for different MCUs, that’s a sign their header names are the same but may be conditionally included by a higher-level library. Specifically, the smoking gun here is
  1. Through code inspection, the pattern of #ifdef <some macro>#include <lib version 1.h>#elif defined(some other macro)#include <lib version 2.h>.

Got it. Thank you. I had seen that but tried to address it with lib ignore statements. That though has too many permutations…