-
Notifications
You must be signed in to change notification settings - Fork 6.5k
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
llext-edk: rework, add Python export and more optional information #78727
base: main
Are you sure you want to change the base?
llext-edk: rework, add Python export and more optional information #78727
Conversation
a9c0788
to
c5a5830
Compare
4c9878b
to
b77ad56
Compare
v2:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not convinced of two things:
- Why should we suddenly start exporting a bunch of extra variables ?
No detailed explanation is given, and the closest I can see seems to be because of informational use. So where does this end ?
Are we going to maintain a list in top-level CMakeLists of all Zephyr build settings. - Exporting to bash.
Starting to export to specific shells seems like setting a bad precendence.
We provide CMake and Makefiles, and any downstream build system should be able to cope with those or easily wrap them to set them in their favorite shell instead.
CMakeLists.txt
Outdated
# Define variables for the cmake sub-process | ||
foreach(exported_var | ||
APPLICATION_SOURCE_DIR | ||
CONFIG_LLEXT_EDK_NAME | ||
CONFIG_LLEXT_EDK_USERSPACE_ONLY | ||
llext_edk_cflags | ||
llext_edk_file | ||
PROJECT_BINARY_DIR | ||
WEST_TOPDIR | ||
ZEPHYR_BASE | ||
CONFIG_LLEXT_EDK_TARGET_INFO # uses: | ||
ARCH | ||
BOARD | ||
BOARD_REVISION | ||
BOARD_QUALIFIERS | ||
NORMALIZED_BOARD_QUALIFIERS | ||
NORMALIZED_BOARD_TARGET | ||
SOC_NAME | ||
SOC_SERIES | ||
SOC_FAMILY | ||
CONFIG_LLEXT_EDK_TOOLCHAIN_INFO # uses: | ||
CROSS_COMPILE_TARGET | ||
COMPILER | ||
LINKER | ||
) | ||
list(APPEND llext_edk_var_args -D${exported_var}="${${exported_var}}") | ||
endforeach() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is growing out of hands and easily becomes unmaintainable, not to mention putting undesired restrictions on Zephyr build system internals.
For the first part, starting to have a long list of settings being maintained at the toplevel CMakeLsts.txt is not ok.
What started as a small and maintainable list which is called at a time where things are known to be defined, such as: ZEPHYR_BASE
, WEST_TOPDIR
was acceptable, but a constant growing list for llext is not.
Secondly, exporting Zephyr internals as-is start to mean that Zephyr cannot control this.
Are we starting to promise that we will never rename those variables because they are being exported ?
Although there is no intention of renaming SOC_NAME, SOC_SERIES, BOARD_REVISION, etc. then if this change is accepted, then it sets a precedence that any variable might enter this list.
I know there is a wish for a more controlled and well-defined way of exporting Zephyr internals where names are promised to be stable, especially for CI and IDE integration.
And for that reason work is ongoing to try and establish a common output file for build info.
Perhaps this can be useful for llext to avoid above bloat in CMakeLists.txt.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair points, I will revert this change and simply add the few missing variables I'd like to have exported to the EDK command line.
work is ongoing to try and establish a common output file for build info.
I am also very interested in this. Any pointer is appreciated 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure, it's now opened: #79118
CMakeLists.txt
Outdated
BOARD | ||
BOARD_REVISION | ||
BOARD_QUALIFIERS | ||
NORMALIZED_BOARD_QUALIFIERS | ||
NORMALIZED_BOARD_TARGET | ||
SOC_NAME | ||
SOC_SERIES | ||
SOC_FAMILY |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
exactly why are all those details needed ?
Shouldn't it be sufficient to have the board target ?
Or are you starting to replicate the Zephyr build system outside of Zephyr ?
If that's the case, then perhaps integrate to sysbuild is a better choice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In order of importance, I'd say:
NORMALIZED_BOARD_TARGET
is the really interesting bit, as it is extremely specific to each EDK build. Otherwise, the EDK exports no metadata that can correlate itself with a board target.CROSS_COMPILE_TARGET
is very useful as well, as it identifies the specific compiler used and whose CFLAGS are exported by the EDK.- I have also used
ARCH
,BOARD
, and to a lesser extentSOC_NAME
, to logically group different EDKs.
The other variables were added only for "completeness"; sorry for not thinking about the maintenance burden.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- CROSS_COMPILE_TARGET is very useful as well, as it identifies the specific compiler used and whose CFLAGS are exported by the EDK.
and this exactly proves my worries of exporting those fields like this, because not all toolchains set this variable and we make no promises. But suddenly we could need to fix "bugs" because something which is intended for internal use is being exported.
An example of a toolchain where this variable is not defined is LLVM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- I have also used ARCH, BOARD, and to a lesser extent SOC_NAME, to logically group different EDKs.
Be careful on using arch for grouping, because a board could have multiple SoCs of different archs or a multi-core SoC where the cores are of different arch. Of course this depends on which level the arch is place, but Zephyr has just gone through a rework to avoid arch on high level organization 😉
cmake/llext-edk.cmake
Outdated
elseif(target STREQUAL "BASH") | ||
# Bash: export array variables of the form: | ||
# | ||
# var=("value1" "value2" ...) | ||
# | ||
# TIP: use the "${var[@]}" syntax, including quotes, to pass all the | ||
# elements as single arguments to a command in scripts. | ||
set(DASHIMACROS "-imacros\${${install_dir_var}}/") | ||
set(DASHI "-I\${${install_dir_var}}/") | ||
string(CONFIGURE "${var_value}" exp_var_value @ONLY) | ||
# Embedded quotes and backslashes are escaped. Each element of the | ||
# list is wrapped in quotes and is separated by a space. | ||
edk_escape("${exp_var_value}" exp_var_value) | ||
list(JOIN exp_var_value "\" \"" exp_var_value_str) | ||
file(APPEND ${edk_file_${target}} "${var_name}=(\"${exp_var_value_str}\")\n") | ||
endif() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we should start exporting to specific shells.
This is a build system, and thus exporting CMake and Makefiles seems ok, but starting to export to bash is going to just bloat our interface.
What about bat
files ? fish
? or the favorite shell of some other user ?
If an external build tool is not satisfied with CMake or Makefiles then I would leave it for that tool to have a tool which can read the file and convert to its favorite shell.
Only additional file format I consider acceptable is yaml, because that is a file format Zephyr build system already uses for dumping data, for example in the Zephyr meta file creation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And to think I was about to add Python export as well... 😅 I'm surprised this would be considered "bloat" - it's only for the EDK, it's a few lines of code and it just makes the life easier for simple downstream projects - but I understand.
I'll remove this and use the current CMake export to generate the same script in my project.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm surprised this would be considered "bloat"
when I'm saying bloat then i'm thinking in terms of what we promise externally.
If we provide bash here, should we then also provide this elsewhere, and what about xyz.
And to think I was about to add Python export as well...
had you done it the other way, then a Python might have made it through 😆
because we already use Python a lot, and Python is cross-platform (Linux, Windows, MacOS, etc.), but with Python then a yaml file would have been just as easy / nice to use 😉
Only additional file format I consider acceptable is yaml
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The objective of this PR is to add metadata to an EDK build so that the target board / SOC / CPU can be retrieved and checked by downstream projects. In my case I will require building several different EDKs, and I realized there's no way to avoid mistaking one for another.
I understand your concerns, and will amend the proposal accordingly.
CMakeLists.txt
Outdated
BOARD | ||
BOARD_REVISION | ||
BOARD_QUALIFIERS | ||
NORMALIZED_BOARD_QUALIFIERS | ||
NORMALIZED_BOARD_TARGET | ||
SOC_NAME | ||
SOC_SERIES | ||
SOC_FAMILY |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In order of importance, I'd say:
NORMALIZED_BOARD_TARGET
is the really interesting bit, as it is extremely specific to each EDK build. Otherwise, the EDK exports no metadata that can correlate itself with a board target.CROSS_COMPILE_TARGET
is very useful as well, as it identifies the specific compiler used and whose CFLAGS are exported by the EDK.- I have also used
ARCH
,BOARD
, and to a lesser extentSOC_NAME
, to logically group different EDKs.
The other variables were added only for "completeness"; sorry for not thinking about the maintenance burden.
CMakeLists.txt
Outdated
# Define variables for the cmake sub-process | ||
foreach(exported_var | ||
APPLICATION_SOURCE_DIR | ||
CONFIG_LLEXT_EDK_NAME | ||
CONFIG_LLEXT_EDK_USERSPACE_ONLY | ||
llext_edk_cflags | ||
llext_edk_file | ||
PROJECT_BINARY_DIR | ||
WEST_TOPDIR | ||
ZEPHYR_BASE | ||
CONFIG_LLEXT_EDK_TARGET_INFO # uses: | ||
ARCH | ||
BOARD | ||
BOARD_REVISION | ||
BOARD_QUALIFIERS | ||
NORMALIZED_BOARD_QUALIFIERS | ||
NORMALIZED_BOARD_TARGET | ||
SOC_NAME | ||
SOC_SERIES | ||
SOC_FAMILY | ||
CONFIG_LLEXT_EDK_TOOLCHAIN_INFO # uses: | ||
CROSS_COMPILE_TARGET | ||
COMPILER | ||
LINKER | ||
) | ||
list(APPEND llext_edk_var_args -D${exported_var}="${${exported_var}}") | ||
endforeach() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair points, I will revert this change and simply add the few missing variables I'd like to have exported to the EDK command line.
work is ongoing to try and establish a common output file for build info.
I am also very interested in this. Any pointer is appreciated 🙂
cmake/llext-edk.cmake
Outdated
elseif(target STREQUAL "BASH") | ||
# Bash: export array variables of the form: | ||
# | ||
# var=("value1" "value2" ...) | ||
# | ||
# TIP: use the "${var[@]}" syntax, including quotes, to pass all the | ||
# elements as single arguments to a command in scripts. | ||
set(DASHIMACROS "-imacros\${${install_dir_var}}/") | ||
set(DASHI "-I\${${install_dir_var}}/") | ||
string(CONFIGURE "${var_value}" exp_var_value @ONLY) | ||
# Embedded quotes and backslashes are escaped. Each element of the | ||
# list is wrapped in quotes and is separated by a space. | ||
edk_escape("${exp_var_value}" exp_var_value) | ||
list(JOIN exp_var_value "\" \"" exp_var_value_str) | ||
file(APPEND ${edk_file_${target}} "${var_name}=(\"${exp_var_value_str}\")\n") | ||
endif() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And to think I was about to add Python export as well... 😅 I'm surprised this would be considered "bloat" - it's only for the EDK, it's a few lines of code and it just makes the life easier for simple downstream projects - but I understand.
I'll remove this and use the current CMake export to generate the same script in my project.
This commit refactors the code that generates the Makefile and CMake EDK files into functions that accept the file type as an argument. No functional changes are introduced in this commit. Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All seems very reasonable, nice!
This commit removes all CMake- or Makefile-specific variables from the code and instead uses a single list for each type of flag. Where a difference is needed between the two, a special marker is used. These markers are replaced later in the target-specific area of the write functions. Escaping of problematic characters is also added to the write functions, to ensure that quotes and backslashes in the flags are properly handled. Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
This patch adds several variables related to the Zephyr build to the files generated by the EDK. The exported information is intended to provide additional context to the external projects that use the EDK; however since they are Zephyr internals, there is no guarantee of stability for these variables or their contents. Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
This commit adds a new export target for Python code. The exported variables are formatted as lists of f-strings so the embedded paths is implicitly expanded at definition time. Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
Extend the documentation for the LLEXT EDK to include information about the target and toolchain information that is now exported by the EDK and the new output format. Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
b77ad56
to
8111bad
Compare
v3, incorporating @tejlmand notes:
|
@tejlmand can you please revisit this? Thanks! |
list(JOIN exp_var_value "\", f\"" exp_var_value_str) | ||
file(APPEND ${edk_file_${target}} "${var_name} = [f\"${exp_var_value_str}\"]\n") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this doesn't look like yaml to me 😉
ref: #78727 (comment)
then a yaml file would have been just as easy / nice to use 😉
Only additional file format I consider acceptable is yaml
remember, yaml can be read directly into Python dict and is much nicer to work with.
We actually have a yaml module in Zephyr CMake now 😄
CMakeLists.txt
Outdated
# Define variables for the cmake sub-process | ||
foreach(exported_var | ||
APPLICATION_SOURCE_DIR | ||
CONFIG_LLEXT_EDK_NAME | ||
CONFIG_LLEXT_EDK_USERSPACE_ONLY | ||
llext_edk_cflags | ||
llext_edk_file | ||
PROJECT_BINARY_DIR | ||
WEST_TOPDIR | ||
ZEPHYR_BASE | ||
CONFIG_LLEXT_EDK_TARGET_INFO # uses: | ||
ARCH | ||
BOARD | ||
BOARD_REVISION | ||
BOARD_QUALIFIERS | ||
NORMALIZED_BOARD_QUALIFIERS | ||
NORMALIZED_BOARD_TARGET | ||
SOC_NAME | ||
SOC_SERIES | ||
SOC_FAMILY | ||
CONFIG_LLEXT_EDK_TOOLCHAIN_INFO # uses: | ||
CROSS_COMPILE_TARGET | ||
COMPILER | ||
LINKER | ||
) | ||
list(APPEND llext_edk_var_args -D${exported_var}="${${exported_var}}") | ||
endforeach() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure, it's now opened: #79118
Thanks, but before going into details again on this one, then I have opened #79118 as promised. I know we currently still have the CMake and Makefile export, but I was thinking that it could be beneficial to cover the Python export functionality you need by expanding the schema with the extra info by using the according Later we can then update CMake / makefile generation to actually use the information from the build info infrastructure instead of having to keep track of this manually, but that I would take ast a later stage. Please take a look at #79118 in relation to this PR and give your initial thoughts. |
When building several different EDKs, there's currently no way to avoid mistaking one for another. The goal of this PR is to add metadata to a generated EDK so that the target board / SOC / CPU can be retrieved and checked by downstream projects.
An additional Python-compatible output format is provided for projects that do not use CMake or make.
To implement the above, a number of internal refactors with minimal visible effect have been implemented, with the goal of having more maintainable and extendable code:
LLEXT EDK documentation has been updated accordingly.
EDIT: updated after review notes.