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
########################################################