diff --git a/cmake/linker/linker_script_common.cmake b/cmake/linker/linker_script_common.cmake index 017de14cf6b..38d6c8307be 100644 --- a/cmake/linker/linker_script_common.cmake +++ b/cmake/linker/linker_script_common.cmake @@ -94,6 +94,25 @@ function(create_group) set(${OBJECT_OBJECT} GROUP_${OBJECT_NAME} PARENT_SCOPE) endfunction() +function(is_active_in_pass ret_ptr current_pass pass_rules) + # by validation in zephyr_linker_* we know that if there is a NOT, + # it is the first, and the other entries are pass names + if(NOT pass_rules) + set(result 1) + elseif("NOT" IN_LIST pass_rules) + set(result 1) + if(current_pass IN_LIST pass_rules) + set(result 0) + endif() + else() + set(result 0) + if(current_pass IN_LIST pass_rules) + set(result 1) + endif() + endif() + set(${ret_ptr} ${result} PARENT_SCOPE) +endfunction() + function(create_section) set(single_args "NAME;ADDRESS;ALIGN_WITH_INPUT;TYPE;ALIGN;ENDALIGN;SUBALIGN;VMA;LMA;NOINPUT;NOINIT;NOSYMBOLS;GROUP;SYSTEM") set(multi_args "PASS") @@ -101,8 +120,8 @@ function(create_section) cmake_parse_arguments(SECTION "" "${single_args}" "${multi_args}" ${ARGN}) if(DEFINED SECTION_PASS) - if(NOT (${SECTION_PASS} IN_LIST PASS)) - # This section is not active in this pass, ignore. + is_active_in_pass(active ${PASS} "${SECTION_PASS}") + if(NOT active) return() endif() endif() @@ -141,8 +160,8 @@ function(create_section) endif() if(DEFINED SETTINGS_PASS) - if(NOT (${SETTINGS_PASS} IN_LIST PASS)) - # This section setting is not active in this pass, ignore. + is_active_in_pass(active ${PASS} "${SETTINGS_PASS}") + if(NOT active) continue() endif() endif() diff --git a/cmake/modules/extensions.cmake b/cmake/modules/extensions.cmake index 209e4878fbc..0ba73a600ab 100644 --- a/cmake/modules/extensions.cmake +++ b/cmake/modules/extensions.cmake @@ -5010,7 +5010,7 @@ endfunction() # [ADDRESS
] [ALIGN ] # [SUBALIGN ] [FLAGS ] # [HIDDEN] [NOINPUT] [NOINIT] -# [PASS [NOT] ] +# [PASS [NOT] []] # ) # # Zephyr linker output section. @@ -5065,15 +5065,13 @@ endfunction() # NOINPUT : No default input sections will be defined, to setup input # sections for section , the corresponding # `zephyr_linker_section_configure()` must be used. -# PASS [NOT] : Linker pass iteration where this section should be active. -# Default a section will be present during all linker passes -# but in cases a section shall only be present at a specific -# pass, this argument can be used. For example to only have -# this section present on the `TEST` linker pass, use `PASS TEST`. -# It is possible to negate , such as `PASS NOT `. -# For example, `PASS NOT TEST` means the call is effective -# on all but the `TEST` linker pass iteration. -# +# PASS [NOT] [ ..]: Linker pass where this section should be active. +# By default a section will be present during all linker +# passes. +# PASS [] [...] makes the section present only in +# the given passes. Empty list means no passes. +# PASS NOT [] [...] makes the section present in +# all but the given passes. Empty list means all passes. # Note: VMA and LMA are mutual exclusive with GROUP # function(zephyr_linker_section) @@ -5110,16 +5108,7 @@ function(zephyr_linker_section) endif() endif() - if(DEFINED SECTION_PASS) - list(LENGTH SECTION_PASS pass_length) - if(${pass_length} GREATER 1) - list(GET SECTION_PASS 0 pass_elem_0) - if((NOT (${pass_elem_0} STREQUAL "NOT")) OR (${pass_length} GREATER 2)) - message(FATAL_ERROR "zephyr_linker_section(PASS takes maximum " - "a single argument of the form: '' or 'NOT '.") - endif() - endif() - endif() + zephyr_linker_check_pass_param("${SECTION_PASS}") set(SECTION) zephyr_linker_arg_val_list(SECTION "${single_args}") @@ -5326,15 +5315,12 @@ endfunction() # you may use `PRIO 50`, `PRIO 20` and so on. # To ensure an input section is at the end, it is advised # to use `PRIO 200` and above. -# PASS [NOT] : The call should only be considered for linker pass where -# is defined. It is possible to negate , such -# as `PASS NOT . -# For example, `PASS TEST` means the call is only effective -# on the `TEST` linker pass iteration. `PASS NOT TEST` on -# all iterations the are not `TEST`. +# PASS [NOT] [..]: Control in which linker passes this piece is present +# See zephyr_linker_section(PASS) for details. # FLAGS : Special section flags such as "+RO", +XO, "+ZI". # ANY : ANY section flag in scatter file. # The FLAGS and ANY arguments only has effect for scatter files. +# INPUT : Input section name or list of input section names. # function(zephyr_linker_section_configure) set(options "ANY;FIRST;KEEP") @@ -5354,16 +5340,7 @@ function(zephyr_linker_section_configure) endif() endif() - if(DEFINED SECTION_PASS) - list(LENGTH SECTION_PASS pass_length) - if(${pass_length} GREATER 1) - list(GET SECTION_PASS 0 pass_elem_0) - if((NOT (${pass_elem_0} STREQUAL "NOT")) OR (${pass_length} GREATER 2)) - message(FATAL_ERROR "zephyr_linker_section_configure(PASS takes maximum " - "a single argument of the form: '' or 'NOT '.") - endif() - endif() - endif() + zephyr_linker_check_pass_param("${SECTION_PASS}") set(SECTION) zephyr_linker_arg_val_list(SECTION "${single_args}") @@ -5432,6 +5409,16 @@ macro(zephyr_linker_arg_val_list list arguments) endforeach() endmacro() + +# Internal helper that checks if we have consistent PASS arguments. +# Allow PASS [NOT] [...] +function(zephyr_linker_check_pass_param PASSES) + list(POP_FRONT PASSES) + if("NOT" IN_LIST PASSES) + message(FATAL_ERROR "NOT only allowed before first value, like this: PASS [NOT] ...") + endif() +endfunction() + ######################################################## # 6. Function helper macros ########################################################