Skip to content

Commit 35b29a1

Browse files
committed
Refactor processing of IDF linker fragments
The helper function extracts fragments directly from Ninja build script
1 parent 09056b0 commit 35b29a1

File tree

1 file changed

+53
-4
lines changed

1 file changed

+53
-4
lines changed

builder/frameworks/espidf.py

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import sys
2727
import shutil
2828
import os
29+
import re
2930
import platform as sys_platform
3031

3132
import click
@@ -494,7 +495,7 @@ def _scan_components_from_framework():
494495
return components or _scan_components_from_framework()
495496

496497

497-
def extract_linker_script_fragments(framework_components_dir, sdk_config):
498+
def extract_linker_script_fragments_backup(framework_components_dir, sdk_config):
498499
# Hardware-specific components are excluded from search and added manually below
499500
project_components = load_component_paths(
500501
framework_components_dir, ignored_component_prefixes=("esp32", "riscv")
@@ -542,6 +543,52 @@ def extract_linker_script_fragments(framework_components_dir, sdk_config):
542543
return result
543544

544545

546+
def extract_linker_script_fragments(
547+
ninja_buildfile, framework_components_dir, sdk_config
548+
):
549+
def _normalize_fragment_path(base_dir, fragment_path):
550+
if not os.path.isabs(fragment_path):
551+
fragment_path = os.path.abspath(
552+
os.path.join(base_dir, fragment_path)
553+
)
554+
if not os.path.isfile(fragment_path):
555+
print("Warning! The `%s` fragment is not found!" % fragment_path)
556+
557+
return fragment_path
558+
559+
assert os.path.isfile(
560+
ninja_buildfile
561+
), "Cannot extract linker fragments! Ninja build file is missing!"
562+
563+
result = []
564+
with open(ninja_buildfile, encoding="utf8") as fp:
565+
for line in fp.readlines():
566+
if "sections.ld: CUSTOM_COMMAND" not in line:
567+
continue
568+
for fragment_match in re.finditer(r"(\S+\.lf\b)+", line):
569+
result.append(_normalize_fragment_path(
570+
BUILD_DIR, fragment_match.group(0).replace("$:", ":")
571+
))
572+
573+
break
574+
575+
# Fall back option if the new algorithm didn't work
576+
if not result:
577+
result = extract_linker_script_fragments_backup(
578+
framework_components_dir, sdk_config
579+
)
580+
581+
if board.get("build.esp-idf.extra_lf_files", ""):
582+
for fragment_path in board.get(
583+
"build.esp-idf.extra_lf_files"
584+
).splitlines():
585+
if not fragment_path.strip():
586+
continue
587+
result.append(_normalize_fragment_path(PROJECT_DIR, fragment_path))
588+
589+
return result
590+
591+
545592
def create_custom_libraries_list(ldgen_libraries_file, ignore_targets):
546593
if not os.path.isfile(ldgen_libraries_file):
547594
sys.stderr.write("Error: Couldn't find the list of framework libraries\n")
@@ -570,11 +617,13 @@ def create_custom_libraries_list(ldgen_libraries_file, ignore_targets):
570617
def generate_project_ld_script(sdk_config, ignore_targets=None):
571618
ignore_targets = ignore_targets or []
572619
linker_script_fragments = extract_linker_script_fragments(
573-
os.path.join(FRAMEWORK_DIR, "components"), sdk_config
620+
os.path.join(BUILD_DIR, "build.ninja"),
621+
os.path.join(FRAMEWORK_DIR, "components"),
622+
sdk_config
574623
)
575624

576-
# Create a new file to avoid automatically generated library entry as files from
577-
# this library are built internally by PlatformIO
625+
# Create a new file to avoid automatically generated library entry as files
626+
# from this library are built internally by PlatformIO
578627
libraries_list = create_custom_libraries_list(
579628
os.path.join(BUILD_DIR, "ldgen_libraries"), ignore_targets
580629
)

0 commit comments

Comments
 (0)