Experiment: C++17 support (#9874)

* Add C++17 support

* Add C++17 runtime probes and update build configurations for STM32 and Portduino

* Remove unflags

* Update C++ standard flags across the platforms

* Convert a couple of instances to structured bindings

* NRF52 platform.txt to add C++17 support

* Still need the unflags apparently

* Remove C++17 runtime probe tests from test_main.cpp

* Reconfigured doesnt need a nodiscard

* Remove nodiscard attribute from init() method in RadioInterface

* Remove mbedtls/error.h from build flags

Removed include directive for mbedtls/error.h from build flags.

* Fix IRAM overflow

* Fix IRAM overflow

* Add build flag to exclude MQTT from rak11200

* Update C++ standard from gnu17 to gnu++17
This commit is contained in:
Ben Meadors
2026-03-11 06:28:24 -05:00
committed by GitHub
co-authored by GitHub
parent d7d08a4725
commit d9e2b12097
12 changed files with 49 additions and 32 deletions
+4
View File
@@ -97,7 +97,11 @@ lib_deps =
${env.lib_deps} ${env.lib_deps}
# renovate: datasource=custom.pio depName=NonBlockingRTTTL packageName=end2endzone/library/NonBlockingRTTTL # renovate: datasource=custom.pio depName=NonBlockingRTTTL packageName=end2endzone/library/NonBlockingRTTTL
end2endzone/NonBlockingRTTTL@1.4.0 end2endzone/NonBlockingRTTTL@1.4.0
build_unflags =
-std=c++11
-std=gnu++11
build_flags = ${env.build_flags} -Os build_flags = ${env.build_flags} -Os
-std=gnu++17
build_src_filter = ${env.build_src_filter} -<platform/portduino/> -<graphics/niche/> build_src_filter = ${env.build_src_filter} -<platform/portduino/> -<graphics/niche/>
; Common libs for communicating over TCP/IP networks such as MQTT ; Common libs for communicating over TCP/IP networks such as MQTT
+4 -4
View File
@@ -23,7 +23,7 @@ ErrorCode NextHopRouter::send(meshtastic_MeshPacket *p)
p->relay_node = nodeDB->getLastByteOfNodeNum(getNodeNum()); // First set the relayer to us p->relay_node = nodeDB->getLastByteOfNodeNum(getNodeNum()); // First set the relayer to us
wasSeenRecently(p); // FIXME, move this to a sniffSent method wasSeenRecently(p); // FIXME, move this to a sniffSent method
p->next_hop = getNextHop(p->to, p->relay_node); // set the next hop p->next_hop = getNextHop(p->to, p->relay_node).value_or(NO_NEXT_HOP_PREFERENCE); // set the next hop
LOG_DEBUG("Setting next hop for packet with dest %x to %x", p->to, p->next_hop); LOG_DEBUG("Setting next hop for packet with dest %x to %x", p->to, p->next_hop);
// If it's from us, ReliableRouter already handles retransmissions if want_ack is set. If a next hop is set and hop limit is // If it's from us, ReliableRouter already handles retransmissions if want_ack is set. If a next hop is set and hop limit is
@@ -170,10 +170,10 @@ bool NextHopRouter::perhapsRebroadcast(const meshtastic_MeshPacket *p)
* Get the next hop for a destination, given the relay node * Get the next hop for a destination, given the relay node
* @return the node number of the next hop, 0 if no preference (fallback to FloodingRouter) * @return the node number of the next hop, 0 if no preference (fallback to FloodingRouter)
*/ */
uint8_t NextHopRouter::getNextHop(NodeNum to, uint8_t relay_node) std::optional<uint8_t> NextHopRouter::getNextHop(NodeNum to, uint8_t relay_node)
{ {
if (isBroadcast(to)) if (isBroadcast(to))
return NO_NEXT_HOP_PREFERENCE; return std::nullopt;
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(to); meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(to);
if (node && node->next_hop) { if (node && node->next_hop) {
@@ -184,7 +184,7 @@ uint8_t NextHopRouter::getNextHop(NodeNum to, uint8_t relay_node)
} else } else
LOG_WARN("Next hop for 0x%x is 0x%x, same as relayer; set no pref", to, node->next_hop); LOG_WARN("Next hop for 0x%x is 0x%x, same as relayer; set no pref", to, node->next_hop);
} }
return NO_NEXT_HOP_PREFERENCE; return std::nullopt;
} }
PendingPacket *NextHopRouter::findPendingPacket(GlobalPacketId key) PendingPacket *NextHopRouter::findPendingPacket(GlobalPacketId key)
+2 -1
View File
@@ -1,6 +1,7 @@
#pragma once #pragma once
#include "FloodingRouter.h" #include "FloodingRouter.h"
#include <optional>
#include <unordered_map> #include <unordered_map>
/** /**
@@ -146,7 +147,7 @@ class NextHopRouter : public FloodingRouter
* Get the next hop for a destination, given the relay node * Get the next hop for a destination, given the relay node
* @return the node number of the next hop, 0 if no preference (fallback to FloodingRouter) * @return the node number of the next hop, 0 if no preference (fallback to FloodingRouter)
*/ */
uint8_t getNextHop(NodeNum to, uint8_t relay_node); std::optional<uint8_t> getNextHop(NodeNum to, uint8_t relay_node);
/** Check if we should be rebroadcasting this packet if so, do so. /** Check if we should be rebroadcasting this packet if so, do so.
* @return true if we did rebroadcast */ * @return true if we did rebroadcast */
+12 -12
View File
@@ -156,7 +156,7 @@ class RadioInterface
virtual ErrorCode send(meshtastic_MeshPacket *p) = 0; virtual ErrorCode send(meshtastic_MeshPacket *p) = 0;
/** Return TX queue status */ /** Return TX queue status */
virtual meshtastic_QueueStatus getQueueStatus() [[nodiscard]] virtual meshtastic_QueueStatus getQueueStatus()
{ {
meshtastic_QueueStatus qs; meshtastic_QueueStatus qs;
qs.res = qs.mesh_packet_id = qs.free = qs.maxlen = 0; qs.res = qs.mesh_packet_id = qs.free = qs.maxlen = 0;
@@ -182,22 +182,22 @@ class RadioInterface
virtual bool reconfigure(); virtual bool reconfigure();
/** The delay to use for retransmitting dropped packets */ /** The delay to use for retransmitting dropped packets */
uint32_t getRetransmissionMsec(const meshtastic_MeshPacket *p); [[nodiscard]] uint32_t getRetransmissionMsec(const meshtastic_MeshPacket *p);
/** The delay to use when we want to send something */ /** The delay to use when we want to send something */
uint32_t getTxDelayMsec(); [[nodiscard]] uint32_t getTxDelayMsec();
/** The CW to use when calculating SNR_based delays */ /** The CW to use when calculating SNR_based delays */
uint8_t getCWsize(float snr); [[nodiscard]] uint8_t getCWsize(float snr);
/** The worst-case SNR_based packet delay */ /** The worst-case SNR_based packet delay */
uint32_t getTxDelayMsecWeightedWorst(float snr); [[nodiscard]] uint32_t getTxDelayMsecWeightedWorst(float snr);
/** Returns true if we should rebroadcast early like a ROUTER */ /** Returns true if we should rebroadcast early like a ROUTER */
bool shouldRebroadcastEarlyLikeRouter(meshtastic_MeshPacket *p); [[nodiscard]] bool shouldRebroadcastEarlyLikeRouter(meshtastic_MeshPacket *p);
/** The delay to use when we want to flood a message. Use a weighted scale based on SNR */ /** The delay to use when we want to flood a message. Use a weighted scale based on SNR */
uint32_t getTxDelayMsecWeighted(meshtastic_MeshPacket *p); [[nodiscard]] uint32_t getTxDelayMsecWeighted(meshtastic_MeshPacket *p);
/** If the packet is not already in the late rebroadcast window, move it there */ /** If the packet is not already in the late rebroadcast window, move it there */
virtual void clampToLateRebroadcastWindow(NodeNum from, PacketId id) { return; } virtual void clampToLateRebroadcastWindow(NodeNum from, PacketId id) { return; }
@@ -215,18 +215,18 @@ class RadioInterface
* *
* @return num msecs for the packet * @return num msecs for the packet
*/ */
uint32_t getPacketTime(const meshtastic_MeshPacket *p, bool received = false); [[nodiscard]] uint32_t getPacketTime(const meshtastic_MeshPacket *p, bool received = false);
virtual uint32_t getPacketTime(uint32_t totalPacketLen, bool received = false) = 0; [[nodiscard]] virtual uint32_t getPacketTime(uint32_t totalPacketLen, bool received = false) = 0;
/** /**
* Get the channel we saved. * Get the channel we saved.
*/ */
uint32_t getChannelNum(); [[nodiscard]] uint32_t getChannelNum();
/** /**
* Get the frequency we saved. * Get the frequency we saved.
*/ */
virtual float getFreq(); [[nodiscard]] virtual float getFreq();
/// Some boards (1st gen Pinetab Lora module) have broken IRQ wires, so we need to poll via i2c registers /// Some boards (1st gen Pinetab Lora module) have broken IRQ wires, so we need to poll via i2c registers
virtual bool isIRQPending() { return false; } virtual bool isIRQPending() { return false; }
@@ -246,7 +246,7 @@ class RadioInterface
* *
* Used as the first step of * Used as the first step of
*/ */
size_t beginSending(meshtastic_MeshPacket *p); [[nodiscard]] size_t beginSending(meshtastic_MeshPacket *p);
/** /**
* Some regulatory regions limit xmit power. * Some regulatory regions limit xmit power.
+3 -3
View File
@@ -58,14 +58,14 @@ class Router : protected concurrency::OSThread, protected PacketHistory
/** Allocate and return a meshpacket which defaults as send to broadcast from the current node. /** Allocate and return a meshpacket which defaults as send to broadcast from the current node.
* The returned packet is guaranteed to have a unique packet ID already assigned * The returned packet is guaranteed to have a unique packet ID already assigned
*/ */
meshtastic_MeshPacket *allocForSending(); [[nodiscard]] meshtastic_MeshPacket *allocForSending();
/** Return Underlying interface's TX queue status */ /** Return Underlying interface's TX queue status */
meshtastic_QueueStatus getQueueStatus(); [[nodiscard]] meshtastic_QueueStatus getQueueStatus();
/** /**
* @return our local nodenum */ * @return our local nodenum */
NodeNum getNodeNum(); [[nodiscard]] NodeNum getNodeNum();
/** Wake up the router thread ASAP, because we just queued a message for it. /** Wake up the router thread ASAP, because we just queued a message for it.
* FIXME, this is kinda a hack because we don't have a nice way yet to say 'wake us because we are 'blocked on this queue' * FIXME, this is kinda a hack because we don't have a nice way yet to say 'wake us because we are 'blocked on this queue'
+3 -3
View File
@@ -141,12 +141,12 @@ bool TransmitHistory::saveToDisk()
file.write((uint8_t *)&header, sizeof(header)); file.write((uint8_t *)&header, sizeof(header));
uint8_t written = 0; uint8_t written = 0;
for (auto &pair : history) { for (const auto &[key, epochSeconds] : history) {
if (written >= MAX_ENTRIES) if (written >= MAX_ENTRIES)
break; break;
Entry entry{}; Entry entry{};
entry.key = pair.first; entry.key = key;
entry.epochSeconds = pair.second; entry.epochSeconds = epochSeconds;
file.write((uint8_t *)&entry, sizeof(entry)); file.write((uint8_t *)&entry, sizeof(entry));
written++; written++;
} }
+5 -2
View File
@@ -300,7 +300,9 @@ struct PubSubConfig {
if (config.tls_enabled) { if (config.tls_enabled) {
serverPort = 8883; serverPort = 8883;
} }
std::tie(serverAddr, serverPort) = parseHostAndPort(serverAddr.c_str(), serverPort); auto [parsedServerAddr, parsedServerPort] = parseHostAndPort(serverAddr.c_str(), serverPort);
serverAddr = std::move(parsedServerAddr);
serverPort = parsedServerPort;
} }
// Defaults // Defaults
@@ -441,7 +443,8 @@ MQTT::MQTT() : concurrency::OSThread("mqtt"), mqttQueue(MAX_MQTT_QUEUE)
moduleConfig.mqtt.map_report_settings.publish_interval_secs, default_map_publish_interval_secs); moduleConfig.mqtt.map_report_settings.publish_interval_secs, default_map_publish_interval_secs);
} }
String host = parseHostAndPort(moduleConfig.mqtt.address).first; auto [host, parsedPort] = parseHostAndPort(moduleConfig.mqtt.address);
(void)parsedPort;
isConfiguredForDefaultServer = isDefaultServer(host); isConfiguredForDefaultServer = isDefaultServer(host);
IPAddress ip; IPAddress ip;
isMqttServerAddressPrivate = ip.fromString(host.c_str()) && isPrivateIpAddress(ip); isMqttServerAddressPrivate = ip.fromString(host.c_str()) && isPrivateIpAddress(ip);
+7 -2
View File
@@ -27,7 +27,12 @@ board_build.filesystem = littlefs
# Remove -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL for low level BLE logging. # Remove -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL for low level BLE logging.
# See library directory for BLE logging possible values: .pio/libdeps/tbeam/NimBLE-Arduino/src/log_common/log_common.h # See library directory for BLE logging possible values: .pio/libdeps/tbeam/NimBLE-Arduino/src/log_common/log_common.h
# This overrides the BLE logging default of LOG_LEVEL_INFO (1) from: .pio/libdeps/tbeam/NimBLE-Arduino/src/esp_nimble_cfg.h # This overrides the BLE logging default of LOG_LEVEL_INFO (1) from: .pio/libdeps/tbeam/NimBLE-Arduino/src/esp_nimble_cfg.h
build_unflags = -fno-lto build_unflags =
-fno-lto
# Keep explicit std unflags on ESP32; base-level unflags are not sufficient
# to prevent framework-injected C++11 fallback on this platform.
-std=c++11
-std=gnu++11
build_flags = build_flags =
${arduino_base.build_flags} ${arduino_base.build_flags}
-flto -flto
@@ -35,7 +40,7 @@ build_flags =
-Wextra -Wextra
-Isrc/platform/esp32 -Isrc/platform/esp32
-include mbedtls/error.h -include mbedtls/error.h
-std=c++11 -std=gnu++17
-DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG
-DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
-DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL -DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL
+4
View File
@@ -16,4 +16,8 @@ build_flags =
${esp32_base.build_flags} ${esp32_base.build_flags}
-D RAK_11200 -D RAK_11200
-I variants/esp32/rak11200 -I variants/esp32/rak11200
-DMESHTASTIC_EXCLUDE_WEBSERVER=1
-DMESHTASTIC_EXCLUDE_PAXCOUNTER=1
-DMESHTASTIC_EXCLUDE_RANGETEST=1
-DMESHTASTIC_EXCLUDE_MQTT=1
upload_speed = 115200 upload_speed = 115200
-1
View File
@@ -8,7 +8,6 @@ build_flags =
-Wall -Wall
-Wextra -Wextra
-Isrc/platform/esp32 -Isrc/platform/esp32
-std=c++11
-DESP_OPENSSL_SUPPRESS_LEGACY_WARNING -DESP_OPENSSL_SUPPRESS_LEGACY_WARNING
-DSERIAL_BUFFER_SIZE=4096 -DSERIAL_BUFFER_SIZE=4096
-DLIBPAX_ARDUINO -DLIBPAX_ARDUINO
+1 -2
View File
@@ -55,8 +55,7 @@ build_flags =
-li2c -li2c
-luv -luv
-std=gnu17 -std=gnu17
-std=c++17 -std=gnu++17
lib_ignore = lib_ignore =
Adafruit NeoPixel Adafruit NeoPixel
Adafruit ST7735 and ST7789 Library Adafruit ST7735 and ST7789 Library
+4 -2
View File
@@ -5,9 +5,9 @@ platform =
platformio/nordicnrf52@10.11.0 platformio/nordicnrf52@10.11.0
extends = arduino_base extends = arduino_base
platform_packages = platform_packages =
; our custom Git version until they merge our PR ; our custom Git version with C++17 support in platform.txt
# TODO renovate # TODO renovate
platformio/framework-arduinoadafruitnrf52 @ https://github.com/meshtastic/Adafruit_nRF52_Arduino#74096746e5f167a2ff22e483d8e79bb1aef00591 platformio/framework-arduinoadafruitnrf52 @ https://github.com/meshtastic/Adafruit_nRF52_Arduino#cpp17-platform
; Don't renovate toolchain-gccarmnoneeabi ; Don't renovate toolchain-gccarmnoneeabi
platformio/toolchain-gccarmnoneeabi@~1.90301.0 platformio/toolchain-gccarmnoneeabi@~1.90301.0
@@ -35,6 +35,8 @@ build_unflags =
-g -g
-g1 -g1
-g0 -g0
-std=c++11
-std=gnu++11
build_src_filter = build_src_filter =
${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/wifi/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<platform/rp2xx0> -<mesh/eth/> -<mesh/raspihttp> -<serialization/> ${arduino_base.build_src_filter} -<platform/esp32/> -<platform/stm32wl> -<nimble/> -<mesh/wifi/> -<mesh/api/> -<mesh/http/> -<modules/esp32> -<platform/rp2xx0> -<mesh/eth/> -<mesh/raspihttp> -<serialization/>