diff --git a/components/esp_libc/project_include.cmake b/components/esp_libc/project_include.cmake index 42c0c49af10..998b5c968ca 100644 --- a/components/esp_libc/project_include.cmake +++ b/components/esp_libc/project_include.cmake @@ -1,6 +1,5 @@ -# Get picolibc specs option with --gc-sections flag removed -function(get_picolibc_specs_path out_var) - set(modified_specs_path "${CMAKE_CURRENT_BINARY_DIR}/specs/picolibc.specs") +function(_get_modified_specs_path out_var specs_filename modification) + set(modified_specs_path "${CMAKE_CURRENT_BINARY_DIR}/specs/${specs_filename}") set(${out_var} "${modified_specs_path}" PARENT_SCOPE) # Return if modified specs file already exists to avoid regeneration @@ -8,30 +7,50 @@ function(get_picolibc_specs_path out_var) return() endif() - # Find the original picolibc.specs file in the toolchain directory + # Find the original specs file in the toolchain directory execute_process( - COMMAND ${CMAKE_C_COMPILER} --print-file-name=picolibc.specs - OUTPUT_VARIABLE picolibc_specs_path + COMMAND ${CMAKE_C_COMPILER} --print-file-name=${specs_filename} + OUTPUT_VARIABLE specs_path OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET ) - if(picolibc_specs_path AND EXISTS "${picolibc_specs_path}") - # Read the original specs file - file(READ "${picolibc_specs_path}" specs_content) + if(specs_path AND EXISTS "${specs_path}") + file(READ "${specs_path}" specs_content) - # Remove --gc-sections flag from the content - string(REGEX REPLACE "--gc-sections" "" specs_content "${specs_content}") + if(modification STREQUAL "remove_gc_sections") + string(REGEX REPLACE "--gc-sections" "" specs_content "${specs_content}") + elseif(modification STREQUAL "add_nosys_to_lib") + set(original_lib_specs [=[ +%{!shared:%{g*:-lg_nano} %{!p:%{!pg:-lc_nano}}%{p:-lc_p}%{pg:-lc_p}} +]=]) + set(modified_lib_specs [=[ +%{!shared:%{g*:-lg_nano} %{!p:%{!pg:-lc_nano -lnosys -lc_nano}}%{p:-lc_p}%{pg:-lc_p}} +]=]) + string(REPLACE "${original_lib_specs}" "${modified_lib_specs}" specs_content "${specs_content}") + endif() - # Write the modified specs file + file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/specs") file(WRITE "${modified_specs_path}" "${specs_content}") else() # Fallback: use original specs if not found - message(WARNING "picolibc.specs not found in toolchain, using default") - set(${out_var} "picolibc.specs" PARENT_SCOPE) + message(WARNING "${specs_filename} not found in toolchain, using default") + set(${out_var} "${specs_filename}" PARENT_SCOPE) endif() endfunction() +# Get picolibc specs option with --gc-sections flag removed +function(get_picolibc_specs_path out_var) + _get_modified_specs_path(specs_path picolibc.specs remove_gc_sections) + set(${out_var} "${specs_path}" PARENT_SCOPE) +endfunction() + +# Get nano specs option with nosys included between libc nano references +function(get_newlib_nano_specs_path out_var) + _get_modified_specs_path(specs_path nano.specs add_nosys_to_lib) + set(${out_var} "${specs_path}" PARENT_SCOPE) +endfunction() + if(CONFIG_IDF_TOOLCHAIN_GCC) if(CONFIG_STDATOMIC_S32C1I_SPIRAM_WORKAROUND) idf_toolchain_add_flags(COMPILE_OPTIONS "-mdisable-hardware-atomics") @@ -55,9 +74,10 @@ if(CONFIG_IDF_TOOLCHAIN_GCC) endif() if(CONFIG_LIBC_NEWLIB_NANO_FORMAT) - idf_toolchain_add_flags(LINK_OPTIONS "--specs=nano.specs") + get_newlib_nano_specs_path(nano_specs_path) + idf_toolchain_add_flags(LINK_OPTIONS "\"--specs=${nano_specs_path}\"") else() - idf_toolchain_remove_flags(LINK_OPTIONS "--specs=nano.specs") + idf_toolchain_remove_flags(LINK_OPTIONS "--specs=.*nano.*") endif() idf_toolchain_rerun_abi_detection()