Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmake: add scope support to script mode #83045

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

pillo79
Copy link
Collaborator

@pillo79 pillo79 commented Dec 16, 2024

In CMake script mode, "targets" are an undefined concept, therefore no properties can be attached to them; those CMake functions are either silently ignored or result in errors. This means that zephyr_set() and any functionality that depends on it (e.g. the yaml module) is not usable in script mode.

This PR works around this limitation by attaching properties to SOURCE entities instead, which are still available.
Two additional functions are introduced to offer an unified access to the scope functionality:

  • a zephyr_exists_scope macro to check if a scope exists; and
  • a zephyr_get_scoped function to retrieve scoped property values.

These utility functions are then used in the current code to replace direct property retrieval and scope checks.

The current test suite for the zephyr_get API is modified to also run itself in script mode and detect any future issue.

This, along with #80007, is a prerequisite for the LLEXT EDK refactor in #78727.

@pillo79 pillo79 force-pushed the pr-cmake-scope-support branch from 4b914b7 to 9119750 Compare December 16, 2024 14:38
Add two new functions that abstract the implementation details of the
"scoped property" retrieval, in preparation for script mode support.

- zephyr_exists_scope() checks if a scope was defined;
- zephyr_get_scoped() retrieves the value of a variable in a specific
  scope.

Refactor current CMake code to use these new functions.

Signed-off-by: Luca Burelli <[email protected]>
This patch adds support for scopes in CMake script mode, where the
concept of targets is not defined and therefore target properties are
not available.

To work around this limitation, the patch uses the SOURCE specifier to
emulate TARGET functionality in script mode. Since there is no if(SOURCE
...) equivalent in CMake language, a dummy property is created on the
virtual source file to support the zephyr_exists_scope() functionality.

Signed-off-by: Luca Burelli <[email protected]>
@pillo79 pillo79 force-pushed the pr-cmake-scope-support branch from 9119750 to 39cb458 Compare December 16, 2024 16:38
Re-run the zephyr_get() testsuite in script mode after the project
mode testsuite has been executed. This is to ensure that the
zephyr_get() function works correctly in script mode as well.

Signed-off-by: Luca Burelli <[email protected]>
@pillo79 pillo79 force-pushed the pr-cmake-scope-support branch from 39cb458 to 8a6052c Compare December 16, 2024 16:45
@pillo79 pillo79 marked this pull request as ready for review December 17, 2024 08:54
Copy link
Collaborator

@tejlmand tejlmand left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Biggest concern for now is introduction of different implementation for normal vs script mode, as well as if(CMAKE_SCRIPT_MODE_FILE) starting to creep into various places in CMake code.

The script mode possibility was introduced for support package_helper, see #41302.

Of course purpose can be extended if there is a need, but from the PR description it is not exactly clear to me why we need this change.

Even with this PR, then yaml_save() is only called from <zephyr-base>/CMakeLists.txt and thus never called from the package helper.

I see some references to other llext related PRs, but even with those it is not fully clear who / why / when the yaml output is required in script mode, as twister itself doesn't seem to be needing it.

Please provide some more description of what is failing and when, and why this is problematic compared to the initial purpose of script mode, so that PR can be reviewed in that context and the extended script mode purpose is clear.

@@ -3359,7 +3359,12 @@ function(zephyr_get_scoped output scope variable)
message(FATAL_ERROR "zephyr_get_scoped(): scope ${scope} doesn't exists.")
endif()

get_property(value TARGET ${scope}_scope PROPERTY ${variable})
if(CMAKE_SCRIPT_MODE_FILE)
set(kind SOURCE)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a big concern here is the use of SOURCE.

The SOURCE scope in CMake properties is following the current directory, now in the script mode case then add_subdirectory() cannot be used, meaning the will not be different directories and thus probablt will work,m but I still find it a problematic use, especially because the directory detail will not be clear to many users of CMake.

@@ -3359,7 +3359,12 @@ function(zephyr_get_scoped output scope variable)
message(FATAL_ERROR "zephyr_get_scoped(): scope ${scope} doesn't exists.")
endif()

get_property(value TARGET ${scope}_scope PROPERTY ${variable})
if(CMAKE_SCRIPT_MODE_FILE)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should not have CMake script mode testing inside functions / throughout the code.

If the code is needed in script mode (thus cannot be stubbed) then it should be written so that there is only one implementation.

Comment on lines +5937 to +5956
# Script mode version, using SOURCE properties
function(zephyr_create_scope scope)
zephyr_exists_scope(scope_exists ${scope})
if(scope_exists)
message(FATAL_ERROR "zephyr_create_scope(${scope}) already exists.")
endif()

set_property(SOURCE ${scope}_scope PROPERTY ZEPHYR_SCOPE TRUE)
endfunction()

# Script mode version, using SOURCE properties
macro(zephyr_exists_scope output scope)
get_property(zephyr_exists_scope_value SOURCE ${scope}_scope PROPERTY ZEPHYR_SCOPE)
if(DEFINED zephyr_exists_scope_value)
unset(zephyr_exists_scope_value)
set(${output} TRUE)
else()
set(${output} FALSE)
endif()
endmacro()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should not embark on a path where we have different behavior / implementation in script mode and normal mode.

Current stubbing is to silence warnings which are not required in script mode.
The script mode was introduced for package_helper, #41302, for example for twister to do a partial (and faster) run for filtering purposes, and thereby remove the need for a full CMake build generation.

# <output> : Output variable containing the result of the check
# <scope> : Scope to look up
#
macro(zephyr_exists_scope output scope)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this as macro and not a function ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants