Skip to content

Commit 6295224

Browse files
committed
Refactor processing of IDF linker fragments
Resolve platformio#760
1 parent 20e866c commit 6295224

File tree

1 file changed

+71
-32
lines changed

1 file changed

+71
-32
lines changed

builder/frameworks/espidf.py

Lines changed: 71 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -429,57 +429,92 @@ def get_sdk_configuration():
429429
return {}
430430

431431

432-
def find_framework_service_files(search_path, sdk_config):
433-
result = {}
434-
result["lf_files"] = list()
435-
result["kconfig_files"] = list()
436-
result["kconfig_build_files"] = list()
437-
for d in os.listdir(search_path):
438-
path = os.path.join(search_path, d)
439-
if not os.path.isdir(path):
440-
continue
441-
for f in os.listdir(path):
442-
# Skip hardware specific files as they will be added later
443-
if f == "linker.lf" and not os.path.basename(path).startswith(
444-
("esp32", "riscv")
432+
def load_component_paths(framework_components_dir, ignored_component_prefixes=None):
433+
def _scan_components_from_framework():
434+
result = []
435+
for component in os.listdir(framework_components_dir):
436+
component_path = os.path.join(framework_components_dir, component)
437+
if component.startswith(ignored_component_prefixes) or not os.path.isdir(
438+
component_path
445439
):
446-
result["lf_files"].append(os.path.join(path, f))
447-
elif f == "Kconfig.projbuild":
448-
result["kconfig_build_files"].append(os.path.join(path, f))
449-
elif f == "Kconfig":
450-
result["kconfig_files"].append(os.path.join(path, f))
440+
continue
441+
result.append(component_path)
442+
443+
return result
444+
445+
# First of all, try to load the list of used components from the project description
446+
components = []
447+
ignored_component_prefixes = ignored_component_prefixes or []
448+
project_description_file = os.path.join(BUILD_DIR, "project_description.json")
449+
if os.path.isfile(project_description_file):
450+
with open(project_description_file) as fp:
451+
try:
452+
data = json.load(fp)
453+
for path in data.get("build_component_paths", []):
454+
if not os.path.basename(path).startswith(
455+
ignored_component_prefixes
456+
):
457+
components.append(path)
458+
except:
459+
print(
460+
"Warning: Could not find load components from project description!\n"
461+
)
462+
463+
return components or _scan_components_from_framework()
464+
465+
466+
def extract_linker_script_fragments(framework_components_dir, sdk_config):
467+
# Hardware-specific components are excluded from search and added manually below
468+
project_components = load_component_paths(
469+
framework_components_dir, ignored_component_prefixes=("esp32", "riscv")
470+
)
471+
472+
result = []
473+
for component_path in project_components:
474+
linker_fragment = os.path.join(component_path, "linker.lf")
475+
if os.path.isfile(linker_fragment):
476+
result.append(linker_fragment)
477+
478+
if not result:
479+
sys.stderr.write("Error: Failed to extract paths to linker script fragments\n")
480+
env.Exit(1)
451481

452482
if mcu == "esp32c3":
453-
result["lf_files"].append(
454-
os.path.join(FRAMEWORK_DIR, "components", "riscv", "linker.lf")
455-
)
483+
result.append(os.path.join(framework_components_dir, "riscv", "linker.lf"))
456484

457-
result["lf_files"].extend(
485+
result.extend(
458486
[
459487
os.path.join(
460-
FRAMEWORK_DIR,
461-
"components",
488+
framework_components_dir,
462489
idf_variant,
463490
"ld",
464491
"%s_fragments.lf" % idf_variant,
465492
),
466493
os.path.join(
467-
FRAMEWORK_DIR,
468-
"components",
494+
framework_components_dir,
469495
idf_variant,
470496
"linker.lf",
471497
),
472-
os.path.join(FRAMEWORK_DIR, "components", "newlib", "newlib.lf"),
498+
os.path.join(framework_components_dir, "newlib", "newlib.lf"),
473499
]
474500
)
475501

476502
if sdk_config.get("SPIRAM_CACHE_WORKAROUND", False):
477-
result["lf_files"].append(
503+
result.append(
478504
os.path.join(
479-
FRAMEWORK_DIR, "components", "newlib", "esp32-spiram-rom-functions-c.lf"
505+
framework_components_dir, "newlib", "esp32-spiram-rom-functions-c.lf"
480506
)
481507
)
482508

509+
if board.get("build.esp-idf.extra_lf_files", ""):
510+
result.extend(
511+
[
512+
lf if os.path.isabs(lf) else os.path.join(PROJECT_DIR, lf)
513+
for lf in board.get("build.esp-idf.extra_lf_files").splitlines()
514+
if lf.strip()
515+
]
516+
)
517+
483518
return result
484519

485520

@@ -510,7 +545,7 @@ def create_custom_libraries_list(ldgen_libraries_file, ignore_targets):
510545

511546
def generate_project_ld_script(sdk_config, ignore_targets=None):
512547
ignore_targets = ignore_targets or []
513-
project_files = find_framework_service_files(
548+
linker_script_fragments = extract_linker_script_fragments(
514549
os.path.join(FRAMEWORK_DIR, "components"), sdk_config
515550
)
516551

@@ -523,7 +558,9 @@ def generate_project_ld_script(sdk_config, ignore_targets=None):
523558
args = {
524559
"script": os.path.join(FRAMEWORK_DIR, "tools", "ldgen", "ldgen.py"),
525560
"config": SDKCONFIG_PATH,
526-
"fragments": " ".join(['"%s"' % f for f in project_files.get("lf_files")]),
561+
"fragments": " ".join(
562+
['"%s"' % fs.to_unix_path(f) for f in linker_script_fragments]
563+
),
527564
"kconfig": os.path.join(FRAMEWORK_DIR, "Kconfig"),
528565
"env_file": os.path.join("$BUILD_DIR", "config.env"),
529566
"libraries_list": libraries_list,
@@ -589,7 +626,9 @@ def prepare_build_envs(config, default_env, debug_allowed=True):
589626
return build_envs
590627

591628

592-
def compile_source_files(config, default_env, project_src_dir, prepend_dir=None, debug_allowed=True):
629+
def compile_source_files(
630+
config, default_env, project_src_dir, prepend_dir=None, debug_allowed=True
631+
):
593632
build_envs = prepare_build_envs(config, default_env, debug_allowed)
594633
objects = []
595634
components_dir = fs.to_unix_path(os.path.join(FRAMEWORK_DIR, "components"))

0 commit comments

Comments
 (0)