diff --git a/cmake/linker/linker_script_common.cmake b/cmake/linker/linker_script_common.cmake index 272fe7977779f..e7cdfb9dfa9ca 100644 --- a/cmake/linker/linker_script_common.cmake +++ b/cmake/linker/linker_script_common.cmake @@ -713,27 +713,46 @@ foreach(file IN LISTS PREPROCESSOR_FILES ) endforeach() # To pickup information gathered by the scripts from the previous pass, we use -# the syntax @FOO@ where FOO is a cmake variable name +# the syntax @FOO[,undef:VALUE][,var=VALUE]@ +# The expansion is recursive so if FOO contains @BAR@ it @BAR will also be +# expanded +# Where the undef:VALUE gets picked if we dont find FOO +# and foo=bar defines a (local) variable in the coming expansion +# The variable values are kept in cmake varaiables, MOSTLY with the +# AT_VAR_ prefix to avoid name-clashes function(do_var_replace_in res_ptr src) - string(REGEX MATCHALL "@([^@]*)@" match_res "${src}") + string(REGEX MATCHALL "@[^@]*@" match_res "${src}") foreach(match IN LISTS match_res) - string(REPLACE "@" "" expr ${match}) - # the variable expression is as follows: - # @NAME[,undef:VALUE]@ Where the VALUE gets picked if we dont find NAME - string(REPLACE "," ";" expr ${expr}) - list(GET expr 0 var) + #Drop the leading and closing @ + string(REGEX MATCH "@([^@]*)@" expr ${match}) + + # Turn the , into ; to treat it as a list: + string(REPLACE "," ";" expr ${CMAKE_MATCH_1}) + unset(undef_value) + list(POP_FRONT expr var) + foreach(e IN LISTS expr) + if(e MATCHES "undef:([^,]*)") + set(undef_value ${CMAKE_MATCH_1}) + elseif(e MATCHES "([^=;]+)=([^=;]+)") + set(AT_VAR_${CMAKE_MATCH_1} ${CMAKE_MATCH_2}) + endif() + endforeach() + if(DEFINED "AT_VAR_${var}") set(value "${AT_VAR_${var}}") - elseif(DEFINED ${var}) # set by zephyr_linker_include_generated files + elseif(DEFINED ${var}) set(value "${${var}}") - elseif("${expr}" MATCHES ";undef:([^,]*)") - set(value "${CMAKE_MATCH_1}") + elseif(DEFINED undef_value) + set(value "${undef_value}") else() - set(value "${match}") # can't warn here because we can't check for what is relevant in this pass # message(WARNING "Missing definition for ${match}") + continue() endif() + #Resolve variables inside variables + do_var_replace_in(value "${value}") + if(CMAKE_VERBOSE_MAKEFILE) message("Using variable ${match} with value ${value}") endif() diff --git a/cmake/linker_script/arm/linker.cmake b/cmake/linker_script/arm/linker.cmake index 94c2af6e4c5a2..739a320ec199f 100644 --- a/cmake/linker_script/arm/linker.cmake +++ b/cmake/linker_script/arm/linker.cmake @@ -22,16 +22,15 @@ if((NOT DEFINED CONFIG_CUSTOM_SECTION_ALIGN) AND DEFINED CONFIG_MPU_REQUIRES_PO # . = ALIGN( 1 << LOG2CEIL(region_size)) # Handling this requires us to handle log2ceil() in iar linker since the size # isn't known until then. - set(MPU_ALIGN_BYTES ${region_min_align}) + zephyr_linker_include_var(VAR MPU_ALIGN VALUE "MAX(${region_min_align} , 1 << LOG2CEIL(@region_size@) )") #message(WARNING "We can not handle . = ALIGN( 1 << LOG2CEIL(region_size)) ") else() - set(MPU_ALIGN_BYTES ${region_min_align}) + zephyr_linker_include_var(VAR MPU_ALIGN VALUE "${region_min_align}") endif() -# The APP_SHARED_ALIGN and SMEM_PARTITION_ALIGN macros are defined as -# ". = ALIGN(...)" things. -# the cmake generator stuff needs an align-size in bytes so: -zephyr_linker_include_var(VAR APP_SHARED_ALIGN_BYTES VALUE ${region_min_align}) -zephyr_linker_include_var(VAR SMEM_PARTITION_ALIGN_BYTES VALUE ${MPU_ALIGN_BYTES}) + +zephyr_linker_include_var(VAR APP_SHARED_ALIGN VALUE ${region_min_align}) +# Note that MPU_ALIGN (may) require an argument (region_size +zephyr_linker_include_var(VAR SMEM_PARTITION_ALIGN VALUE "@MPU_ALIGN@") # Note, the `+ 0` in formulas below avoids errors in cases where a Kconfig # variable is undefined and thus expands to nothing. diff --git a/scripts/build/gen_app_partitions.py b/scripts/build/gen_app_partitions.py index 4a178762afcc5..2aecf979e7b22 100755 --- a/scripts/build/gen_app_partitions.py +++ b/scripts/build/gen_app_partitions.py @@ -279,8 +279,9 @@ def zephyr_linker_symbol(symbol, expr) : class CmakeTemplate: section_name = "@_APP_SMEM{SECTION}_SECTION_NAME@" + smem_partition_align = "@SMEM_PARTITION_ALIGN,region_size=z_data_smem_{partition}_bss_end - z_data_smem_{partition}_part_start@" data_template = ( - zephyr_linker_section_configure(section=section_name, align="@SMEM_PARTITION_ALIGN_BYTES@")+ + zephyr_linker_section_configure(section=section_name, align=smem_partition_align)+ zephyr_linker_section_configure(section=section_name, input="data_smem_{partition}_data*", symbols="z_data_smem_{partition}_part_start", keep=True) ) @@ -294,20 +295,20 @@ class CmakeTemplate: footer_template = ( zephyr_linker_section_configure(section=section_name, symbols="z_data_smem_{partition}_bss_end", keep=True) + - zephyr_linker_section_configure(section=section_name, align="@SMEM_PARTITION_ALIGN_BYTES@") + + zephyr_linker_section_configure(section=section_name, align=smem_partition_align) + zephyr_linker_section_configure(section=section_name, symbols="z_data_smem_{partition}_part_end", keep=True) ) linker_start_seq = ( zephyr_linker_section(name=section_name, group="APP_SMEM_GROUP", noinput=True, align_with_input=True) + - zephyr_linker_section_configure(section=section_name, align="@APP_SHARED_ALIGN_BYTES@", symbols="_app_smem{section}_start")) + zephyr_linker_section_configure(section=section_name, align="@APP_SHARED_ALIGN@", symbols="_app_smem{section}_start")) linker_end_seq = ( - zephyr_linker_section_configure(section=section_name, align="@APP_SHARED_ALIGN_BYTES@") + + zephyr_linker_section_configure(section=section_name, align="@APP_SHARED_ALIGN@") + zephyr_linker_section_configure(section=section_name, symbols="_app_smem{section}_end") ) empty_app_smem = ( - zephyr_linker_section(name=section_name, group="APP_SMEM_GROUP", align="@APP_SHARED_ALIGN_BYTES@", noinput=True, align_with_input=True) + + zephyr_linker_section(name=section_name, group="APP_SMEM_GROUP", align="@APP_SHARED_ALIGN@", noinput=True, align_with_input=True) + zephyr_linker_section_configure(section = section_name, symbols="_app_smem{section}_start") + zephyr_linker_section_configure(section = section_name, symbols="_app_smem{section}_end") )