Skip to content

Commit 844b756

Browse files
committed
Improve processing of default flags for ESP-IDF build environment
Add a dummy component with different file extensions so CMake will generate comprehensive code model
1 parent 707ae55 commit 844b756

File tree

1 file changed

+67
-27
lines changed

1 file changed

+67
-27
lines changed

builder/frameworks/espidf.py

Lines changed: 67 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -338,35 +338,36 @@ def filter_args(args, allowed, ignore=None):
338338
return result
339339

340340

341-
def get_app_flags(app_config):
342-
app_flags = {}
343-
for cg in app_config["compileGroups"]:
344-
app_flags[cg["language"]] = []
341+
def get_app_flags(app_config, default_config):
342+
def _extract_flags(config):
343+
flags = {}
344+
for cg in config["compileGroups"]:
345+
flags[cg["language"]] = []
345346
for ccfragment in cg["compileCommandFragments"]:
346347
fragment = ccfragment.get("fragment", "")
347348
if not fragment.strip() or fragment.startswith("-D"):
348349
continue
349-
app_flags[cg["language"]].extend(
350+
flags[cg["language"]].extend(
350351
click.parser.split_arg_string(fragment.strip())
351352
)
352353

353-
cflags = app_flags.get("C", [])
354-
cxx_flags = app_flags.get("CXX", [])
355-
ccflags = set(cflags).intersection(cxx_flags)
354+
return flags
355+
356+
app_flags = _extract_flags(app_config)
357+
default_flags = _extract_flags(default_config)
356358

357359
# Flags are sorted because CMake randomly populates build flags in code model
358360
return {
359-
"ASFLAGS": sorted(app_flags.get("ASM", [])),
360-
"CFLAGS": sorted(list(set(cflags) - ccflags)),
361-
"CCFLAGS": sorted(list(ccflags)),
362-
"CXXFLAGS": sorted(list(set(cxx_flags) - ccflags)),
361+
"ASFLAGS": sorted(app_flags.get("ASM", default_flags.get("ASM"))),
362+
"CFLAGS": sorted(app_flags.get("C", default_flags.get("C"))),
363+
"CXXFLAGS": sorted(app_flags.get("CXX", default_flags.get("CXX"))),
363364
}
364365

365366

366367
def get_sdk_configuration():
367368
config_path = join(env.subst("$BUILD_DIR"), "config", "sdkconfig.json")
368369
if not isfile(config_path):
369-
print("Warning: Could not find \"sdkconfig.json\" file\n")
370+
print('Warning: Could not find "sdkconfig.json" file\n')
370371

371372
try:
372373
with open(config_path, "r") as fp:
@@ -401,36 +402,41 @@ def find_framework_service_files(search_path, sdk_config):
401402
return result
402403

403404

404-
def create_custom_libraries_list(orignial_ldgen_libraries_file, project_target_name):
405-
if not isfile(orignial_ldgen_libraries_file):
405+
def create_custom_libraries_list(ldgen_libraries_file, ignore_targets):
406+
if not isfile(ldgen_libraries_file):
406407
sys.stderr.write("Error: Couldn't find the list of framework libraries\n")
407408
env.Exit(1)
408409

409-
pio_libraries_file = orignial_ldgen_libraries_file + "_pio"
410+
pio_libraries_file = ldgen_libraries_file + "_pio"
410411

411412
if isfile(pio_libraries_file):
412413
return pio_libraries_file
413414

414415
lib_paths = []
415-
with open(orignial_ldgen_libraries_file, "r") as fp:
416+
with open(ldgen_libraries_file, "r") as fp:
416417
lib_paths = fp.readlines()
417418

418419
with open(pio_libraries_file, "w") as fp:
419420
for lib_path in lib_paths:
420-
if "lib%s.a" % project_target_name.replace("__idf_", "") not in lib_path:
421+
if all(
422+
"lib%s.a" % t.replace("__idf_", "") not in lib_path
423+
for t in ignore_targets
424+
):
421425
fp.write(lib_path)
422426

423427
return pio_libraries_file
424428

425429

426-
def generate_project_ld_script(project_target_name, sdk_config):
430+
def generate_project_ld_script(sdk_config, ignore_targets=None):
431+
ignore_targets = ignore_targets or []
427432
project_files = find_framework_service_files(
428-
join(FRAMEWORK_DIR, "components"), sdk_config)
433+
join(FRAMEWORK_DIR, "components"), sdk_config
434+
)
429435

430436
# Create a new file to avoid automatically generated library entry as files from
431437
# this library are built internally by PlatformIO
432438
libraries_list = create_custom_libraries_list(
433-
join(env.subst("$BUILD_DIR"), "ldgen_libraries"), project_target_name
439+
join(env.subst("$BUILD_DIR"), "ldgen_libraries"), ignore_targets
434440
)
435441

436442
args = {
@@ -698,6 +704,37 @@ def get_project_elf(target_configs):
698704
return exec_targets[0]
699705

700706

707+
def generate_default_component():
708+
# Used to force CMake generate build environments for all supported languages
709+
710+
prj_cmake_tpl = """# Warning! Do not delete this auto-generated file.
711+
file(GLOB component_sources *.c* *.S)
712+
idf_component_register(SRCS ${component_sources})
713+
"""
714+
dummy_component_path = join(BUILD_DIR, "__pio_env")
715+
if not isdir(dummy_component_path):
716+
makedirs(dummy_component_path)
717+
718+
for ext in (".cpp", ".c", ".S"):
719+
dummy_file = join(dummy_component_path, "__dummy" + ext)
720+
if not isfile(dummy_file):
721+
open(dummy_file, "a").close()
722+
723+
component_cmake = join(dummy_component_path, "CMakeLists.txt")
724+
if not isfile(component_cmake):
725+
with open(component_cmake, "w") as fp:
726+
fp.write(prj_cmake_tpl)
727+
728+
return dummy_component_path
729+
730+
731+
def find_default_component(target_configs):
732+
for config in target_configs:
733+
if "__pio_env" in config:
734+
return config
735+
return ""
736+
737+
701738
#
702739
# Generate final linker script
703740
#
@@ -778,10 +815,9 @@ def get_project_elf(target_configs):
778815
# By default 'main' folder is used to store source files. In case when a user has
779816
# default 'src' folder we need to add this as an extra component. If there is no 'main'
780817
# folder CMake won't generate dependencies properly
781-
782-
extra_components = []
818+
extra_components = [generate_default_component()]
783819
if env.subst("$PROJECT_SRC_DIR") != join(env.subst("$PROJECT_DIR"), "main"):
784-
extra_components = [env.subst("$PROJECT_SRC_DIR")]
820+
extra_components.append(env.subst("$PROJECT_SRC_DIR"))
785821
if "arduino" in env.subst("$PIOFRAMEWORK"):
786822
extra_components.append(ARDUINO_FRAMEWORK_DIR)
787823

@@ -819,12 +855,15 @@ def get_project_elf(target_configs):
819855
sys.stderr.write("Error: Couldn't find the main target of the project!\n")
820856
env.Exit(1)
821857

822-
project_ld_scipt = generate_project_ld_script(project_target_name, sdk_config)
858+
project_ld_scipt = generate_project_ld_script(sdk_config, ["__idf_src", "__pio_env"])
823859
env.Depends("$BUILD_DIR/$PROGNAME$PROGSUFFIX", project_ld_scipt)
824860

825861
elf_config = get_project_elf(target_configs)
862+
default_config_name = find_default_component(target_configs)
826863
framework_components_map = get_components_map(
827-
target_configs, ["STATIC_LIBRARY", "OBJECT_LIBRARY"], [project_target_name]
864+
target_configs,
865+
["STATIC_LIBRARY", "OBJECT_LIBRARY"],
866+
[project_target_name, default_config_name],
828867
)
829868

830869
build_components(env, framework_components_map, env.subst("$PROJECT_DIR"))
@@ -838,8 +877,9 @@ def get_project_elf(target_configs):
838877

839878
project_config = target_configs.get(project_target_name, {})
840879
project_includes = get_app_includes(project_config)
880+
default_config = target_configs.get(default_config_name, {})
841881
project_defines = get_app_defines(project_config)
842-
project_flags = get_app_flags(project_config)
882+
project_flags = get_app_flags(project_config, default_config)
843883
link_args = extract_link_args(elf_config)
844884

845885
app_includes = get_app_includes(elf_config)

0 commit comments

Comments
 (0)