I’m working on automatic BLE library detection in ArduinoBleOTA and ArduinoBleChess. Implementation of BleChessDefines.h looks like:
#pragma once
#if __has_include("ArduinoBLE.h")
#include <ArduinoBLE.h>
#define BLE_CHESS_BLE_LIB_ARDUINO_BLE
#define BLE_CHESS_LIB_ARDUINO_BLE
#elif __has_include("NimBLEDevice.h")
#include <NimBLEDevice.h>
#define BLE_CHESS_BLE_LIB_NIM_BLE_ARDUINO
#define BLE_CHESS_LIB_NIM_BLE_ARDUINO
#if !defined(CONFIG_NIMBLE_MAX_CONNECTIONS) && \
!defined(CONFIG_NIMBLE_CPP_DEBUG_ASSERT_ENABLED)
#define BLE_CHESS_BLE_LIB_NIM_BLE_ARDUINO_V1
#else
#define BLE_CHESS_BLE_LIB_NIM_BLE_ARDUINO_V2
#endif
#elif defined(ARDUINO_ARCH_ESP32)
#include <BLEDevice.h>
#define BLE_CHESS_BLE_LIB_ESP32
#define BLE_CHESS_LIB_ESP32
#else
#error "Unsupported BLE library. Consider ArduinoBLE or NimBLE-Arduino."
#endif
Libraries added by:
lib_deps =
vovagorodok/ArduinoBleOTA@^1.2.0
vovagorodok/ArduinoBleChess@^0.6.0
h2zero/NimBLE-Arduino@^1.4.3
At the end, linking error:
undefined reference to `BleChessLib::begin(NimBLEServer*, BleChessPeripheral&, BleChessOfflineCentral&)'
collect2: error: ld returned 1 exit status
Adding at the beginning of .pio/libdeps/ArduinoBleChess/src/BleChessDefines.h
#include <NimBLEDevice.h>
fix an issue
Looks that __has_include("NimBLEDevice.h") doesn’t work if appropriate include isn’t added. It makes impossible to prepare automatic detection.
As I correctly understand PlatformIO somehow check all includes and if NimBLEDevice.h exist than add h2zero/NimBLE-Arduino library to the ArduinoBleChess compilation.
Any idea how to solve this issue?
Thanks. I’m using deep+. It is not lib_ldf_mode issue. Perhaps I should describe issue better.
Idea is to have library that haven’t dependencies but can work with different BLE libraries, depending which is added to lib_deps. In library ArduinoBleChess I have section/include where I check which Bluetooth library is used in main project: ArduinoBLE, NimBLE-Arduino or native ESP32. I’m doing it by __has_include macro:
#elif __has_include("NimBLEDevice.h")
#include <NimBLEDevice.h>
#define BLE_CHESS_LIB_NIM_BLE_ARDUINO
Expected, if NimBLEDevice.h is available in project than ArduinoBleChess will be compiled with BLE_CHESS_LIB_NIM_BLE_ARDUINO flag in order to work with that BLE library.
But when ArduinoBleChess is compiled __has_include("NimBLEDevice.h") return false and BLE_CHESS_LIB_NIM_BLE_ARDUINO is not defined. ArduinoBleChess library compiles without this flag. But main project that has library ArduinoBleChessand NimBLE-Arduino in lib_deps compiles with __has_include("NimBLEDevice.h") equals true, that cause linking error.
If I add hacked #include <NimBLEDevice.h> like
#include <NimBLEDevice.h>
...
#elif __has_include("NimBLEDevice.h")
#include <NimBLEDevice.h>
#define BLE_CHESS_LIB_NIM_BLE_ARDUINO
than __has_include("NimBLEDevice.h") return true on both ArduinoBleChess and main project.
Perhaps it is PlatformIO issue, I think that __has_include("NimBLEDevice.h") should return the same value for main project and for libraries in lib_deps.
Link to library ArduinoBleChess/src/BleChessDefines.h at main · vovagorodok/ArduinoBleChess · GitHub
I can create example of this issue if needed
You was right @maxgerhardt, issue was in lib_ldf_mode. lib_ldf_mode=deep+ in my case.
After checking Library Dependency Finder (LDF) — PlatformIO latest documentation
Looks that + (mean evaluate C/C++ Preprocessor conditional syntax) removes code before compilation. Using deep or chain(default) without + fix an issue and maim project + libraries compile as expected.
Issue exist only when chain+ or deep+. Do You think it is correct behavior or preprocessor should know more about dependent libraries/includes?