Skip to content

Commit 08a860e

Browse files
authored
HybridCompile: add Option to enable LTO for Arduino part (#338)
* add lto handling to component manager * lto handling for Arduino HybridCompile * Enable LTO for example Tasmota
1 parent 23c0c5b commit 08a860e

File tree

3 files changed

+119
-0
lines changed

3 files changed

+119
-0
lines changed

builder/frameworks/arduino.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,7 @@ def safe_remove_sdkconfig_files():
532532
flag_custom_component_remove = False
533533
flag_custom_component_add = False
534534
flag_lib_ignore = False
535+
flag_lto = False
535536

536537
if mcu == "esp32c2":
537538
flag_custom_sdkconfig = True
@@ -598,6 +599,10 @@ def has_psram_config():
598599
if has_unicore_flags():
599600
build_unflags += " -ustart_app_other_cores"
600601

602+
# Check for enabling LTO for Arduino HybridCompile part by unflagging -fno-lto
603+
if '-fno-lto' in build_unflags:
604+
flag_lto = True
605+
601606
new_build_unflags = build_unflags.split()
602607
env.Replace(BUILD_UNFLAGS=new_build_unflags)
603608

@@ -916,6 +921,13 @@ def get_frameworks_in_current_env():
916921
from component_manager import ComponentManager
917922
component_manager = ComponentManager(env)
918923
component_manager.handle_component_settings()
924+
925+
# Handle LTO flags if flag_lto is set
926+
if flag_lto:
927+
# First remove existing -fno-lto flags, then add LTO flags
928+
component_manager.remove_no_lto_flags()
929+
component_manager.add_lto_flags()
930+
919931
silent_action = env.Action(component_manager.restore_pioarduino_build_py)
920932
# silence scons command output
921933
silent_action.strfunction = lambda target, source, env: ''

builder/frameworks/component_manager.py

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,3 +1271,109 @@ def print_changes_summary(self) -> None:
12711271
session, useful for build reporting and debugging.
12721272
"""
12731273
self.logger.print_changes_summary()
1274+
1275+
def remove_no_lto_flags(self) -> bool:
1276+
"""
1277+
Remove all -fno-lto flags from pioarduino-build.py.
1278+
1279+
Removes all occurrences of -fno-lto from CCFLAGS, CFLAGS, CXXFLAGS,
1280+
and LINKFLAGS in the Arduino build script.
1281+
1282+
Returns:
1283+
bool: True if successful, False otherwise
1284+
"""
1285+
build_py_path = str(Path(self.config.arduino_libs_mcu) / "pioarduino-build.py")
1286+
1287+
if not os.path.exists(build_py_path):
1288+
print(f"Warning: pioarduino-build.py not found at {build_py_path}")
1289+
return False
1290+
1291+
try:
1292+
with open(build_py_path, 'r', encoding='utf-8') as f:
1293+
content = f.read()
1294+
1295+
# Remove all -fno-lto flags
1296+
modified_content = re.sub(r'["\']?-fno-lto["\']?,?\s*', '', content)
1297+
1298+
# Clean up any resulting empty strings or double commas
1299+
modified_content = re.sub(r',\s*,', ',', modified_content)
1300+
modified_content = re.sub(r'\[\s*,', '[', modified_content)
1301+
modified_content = re.sub(r',\s*\]', ']', modified_content)
1302+
1303+
with open(build_py_path, 'w', encoding='utf-8') as f:
1304+
f.write(modified_content)
1305+
1306+
return True
1307+
1308+
except (IOError, OSError) as e:
1309+
print(f"Error removing -fno-lto flags: {e}")
1310+
return False
1311+
1312+
def add_lto_flags(self) -> bool:
1313+
"""
1314+
Add LTO flags to pioarduino-build.py.
1315+
1316+
Adds -flto=auto to CCFLAGS, CFLAGS, CXXFLAGS and -flto to LINKFLAGS
1317+
in the Arduino build script. Flags are inserted right after the opening bracket.
1318+
1319+
Returns:
1320+
bool: True if successful, False otherwise
1321+
"""
1322+
build_py_path = str(Path(self.config.arduino_libs_mcu) / "pioarduino-build.py")
1323+
1324+
if not os.path.exists(build_py_path):
1325+
print(f"Warning: pioarduino-build.py not found at {build_py_path}")
1326+
return False
1327+
1328+
try:
1329+
with open(build_py_path, 'r', encoding='utf-8') as f:
1330+
content = f.read()
1331+
1332+
modified = False
1333+
1334+
# Add -flto=auto to CCFLAGS right after the opening bracket
1335+
if 'CCFLAGS=[' in content:
1336+
ccflags_start = content.find('CCFLAGS=[')
1337+
ccflags_section_start = ccflags_start + len('CCFLAGS=[')
1338+
content = (content[:ccflags_section_start] +
1339+
'\n "-flto=auto",' +
1340+
content[ccflags_section_start:])
1341+
modified = True
1342+
1343+
# Add -flto=auto to CFLAGS right after the opening bracket
1344+
if 'CFLAGS=[' in content:
1345+
cflags_start = content.find('CFLAGS=[')
1346+
cflags_section_start = cflags_start + len('CFLAGS=[')
1347+
content = (content[:cflags_section_start] +
1348+
'\n "-flto=auto",' +
1349+
content[cflags_section_start:])
1350+
modified = True
1351+
1352+
# Add -flto=auto to CXXFLAGS right after the opening bracket
1353+
if 'CXXFLAGS=[' in content:
1354+
cxxflags_start = content.find('CXXFLAGS=[')
1355+
cxxflags_section_start = cxxflags_start + len('CXXFLAGS=[')
1356+
content = (content[:cxxflags_section_start] +
1357+
'\n "-flto=auto",' +
1358+
content[cxxflags_section_start:])
1359+
modified = True
1360+
1361+
# Add -flto to LINKFLAGS right after the opening bracket
1362+
if 'LINKFLAGS=[' in content:
1363+
linkflags_start = content.find('LINKFLAGS=[')
1364+
linkflags_section_start = linkflags_start + len('LINKFLAGS=[')
1365+
content = (content[:linkflags_section_start] +
1366+
'\n "-flto",' +
1367+
content[linkflags_section_start:])
1368+
modified = True
1369+
1370+
if modified:
1371+
with open(build_py_path, 'w', encoding='utf-8') as f:
1372+
f.write(content)
1373+
1374+
print("*** Added LTO flags for Arduino compile ***")
1375+
return True
1376+
1377+
except (IOError, OSError) as e:
1378+
print(f"Error adding LTO flags: {e}")
1379+
return False

examples/tasmota_platformio_override.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ board = esp32
1010
build_flags = ${env:tasmota32_base.build_flags}
1111
-DHTTPCLIENT_NOSECURE
1212
-DUPDATE_NOCRYPT
13+
build_unflags = -fno-lto
1314
lib_ignore = ${env:tasmota32_base.lib_ignore}
1415
Micro-RTSP
1516
epdiy

0 commit comments

Comments
 (0)