Skip to content

Commit 8c8971d

Browse files
Fix esp32 32kB path length problem with middleware script
1 parent 3c07f25 commit 8c8971d

File tree

2 files changed

+84
-0
lines changed

2 files changed

+84
-0
lines changed

OATFWGUI/gui_logic.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,13 +326,29 @@ def build_fw(self):
326326
self.main_app.wSpn_build.setState(BusyIndicatorState.BAD)
327327
return
328328

329+
# TODO: should probably refactor the hot patch logic to use ConfigParser...
330+
platformio_ini = configparser.ConfigParser()
331+
platformio_ini.read(Path(self.logic_state.fw_dir, 'platformio.ini'))
332+
ini_extra_scripts = platformio_ini['env']['extra_scripts']
333+
log.info(f'Extra scripts={ini_extra_scripts}')
334+
if not 'iprefix' in ini_extra_scripts and not self.logic_state.env_is_avr_based():
335+
# Make sure base firmware doesn't already have the iprefix script
336+
# AND
337+
# Shouldn't be harmful, but it's a bit weird so we only do this on
338+
# esp32 boards. Assume that anything not AVR based is esp32 :S
339+
pre_script_path = Path(get_install_dir(), 'OATFWGUI', 'pre_script_esp32_iprefix.py')
340+
env_vars = {'PLATFORMIO_EXTRA_SCRIPTS': f'pre:{pre_script_path.absolute()}'}
341+
else:
342+
env_vars = {}
343+
329344
external_processes['platformio'].start(
330345
['run',
331346
'--environment', self.logic_state.pio_env,
332347
'--project-dir', str(self.logic_state.fw_dir),
333348
'--verbose'
334349
],
335350
self.pio_build_finished,
351+
env_vars=env_vars,
336352
)
337353

338354
@Slot()
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import os
2+
3+
Import("env")
4+
5+
6+
def cprint(*args, **kwargs):
7+
print(f'modify_test.py:', *args, **kwargs)
8+
9+
10+
def remove_prefix(text: str, prefix: str) -> str:
11+
if text.startswith(prefix):
12+
return text[len(prefix):]
13+
return text
14+
15+
16+
def use_iprefix_for_esp32_framework(env, node):
17+
"""
18+
The esp32 arduino framework
19+
(https://registry.platformio.org/platforms/platformio/espressif32) has too
20+
many -I includes, which can easily go over the 32kB Windows process command
21+
line limit. I consider this a bug in the framework, but we can fix it with
22+
this platformio middleware by using GCCs
23+
https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html#index-iwithprefixbefore,
24+
which allows us to set a -iprefix once, then reference that prefix when
25+
doing an -I include using -iwithprefixbefore. See
26+
https://github.com/OpenAstroTech/OATFWGUI/issues/62 for more details.
27+
"""
28+
if 'INCPREFIX' in env and env['INCPREFIX'] != '-I':
29+
cprint(f"Warning: ignoring weird prefix for {node.get_abspath()}, {env['INCPREFIX']}")
30+
return node
31+
32+
orig_include_paths = {
33+
'framework': [],
34+
'other': [],
35+
}
36+
for include_path in env['CPPPATH']:
37+
if 'framework-arduinoespressif32' in include_path:
38+
orig_include_paths['framework'].append(include_path)
39+
else:
40+
orig_include_paths['other'].append(include_path)
41+
42+
# Find the common path for the framework, add on the path separator (since commonpath leaves it off)
43+
common_path_prefix = os.path.commonpath(orig_include_paths['framework']) + os.sep
44+
if len(common_path_prefix) < len('iwithprefixbefore'):
45+
# Only continue with replacement if we'll actually see a
46+
# reduction in the command length
47+
return node
48+
49+
new_framework_include_paths = []
50+
for orig_include_path in orig_include_paths['framework']:
51+
new_framework_include_paths.append(remove_prefix(orig_include_path, common_path_prefix))
52+
53+
cprint(f'{node.get_abspath()} prefix is {common_path_prefix}')
54+
55+
# If just a normal list of strings, SCONS will quote the string if it has spaces
56+
# We don't want that, so we use a list of list of strings
57+
iprefix_list = [['-iprefix', common_path_prefix]]
58+
iprefixbefore_list = [['-iwithprefixbefore', f_i] for f_i in new_framework_include_paths]
59+
normal_include_list = [['-I', o_i] for o_i in orig_include_paths['other']]
60+
return env.Object(
61+
node,
62+
CCFLAGS=env['CCFLAGS'] + iprefix_list + iprefixbefore_list + normal_include_list,
63+
INCPREFIX=None,
64+
CPPPATH=None,
65+
)
66+
67+
68+
env.AddBuildMiddleware(use_iprefix_for_esp32_framework)

0 commit comments

Comments
 (0)