Files
esp-idf/components/esp_libc/project_include.cmake

92 lines
3.6 KiB
CMake

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
if(EXISTS "${modified_specs_path}")
return()
endif()
# Find the original specs file in the toolchain directory
execute_process(
COMMAND ${CMAKE_C_COMPILER} --print-file-name=${specs_filename}
OUTPUT_VARIABLE specs_path
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
if(specs_path AND EXISTS "${specs_path}")
file(READ "${specs_path}" 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()
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 "${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")
else()
idf_toolchain_remove_flags(COMPILE_OPTIONS "-mdisable-hardware-atomics")
endif()
if(CONFIG_LIBC_PICOLIBC)
# TODO GCC-464:
# The original picolibc.specs file cannot be used directly in the build
# system because it contains the --gc-sections linker flag. This flag
# causes CMake's compiler detection checks to incorrectly drop required
# data during configuration.
#
# Workaround: Copy picolibc.specs to the working directory with removed
# --gc-sections option.
get_picolibc_specs_path(picolibc_specs_path)
idf_toolchain_add_flags(COMPILE_OPTIONS "\"-specs=${picolibc_specs_path}\"")
if(LIBC_PICOLIBC_NEWLIB_COMPATIBILITY)
idf_toolchain_add_flags(COMPILE_OPTIONS "-D__STDC_WANT_LIB_EXT1__=0")
endif()
else()
idf_toolchain_remove_flags(COMPILE_OPTIONS "-specs=.*picolibc.*")
endif()
if(CONFIG_LIBC_NEWLIB_NANO_FORMAT)
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.*")
endif()
idf_toolchain_rerun_abi_detection()
else() # TODO IDF-14338
if(CONFIG_STDATOMIC_S32C1I_SPIRAM_WORKAROUND)
idf_build_set_property(COMPILE_OPTIONS "-mdisable-hardware-atomics" APPEND)
endif()
endif()