You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
139 lines
4.9 KiB
139 lines
4.9 KiB
# SPDX-License-Identifier: Apache-2.0 |
|
# |
|
# Copyright (c) 2021, Nordic Semiconductor ASA |
|
|
|
# Snippets support |
|
# |
|
# This module: |
|
# |
|
# - searches for snippets in zephyr and any modules |
|
# - validates the SNIPPET input variable, if any |
|
# |
|
# If SNIPPET contains a snippet name that is not found, an error |
|
# will be raised, and the list of valid snippets will be printed. |
|
# |
|
# Outcome: |
|
# The following variables will be defined when this module completes: |
|
# |
|
# - SNIPPET_AS_LIST: CMake list of snippet names, created from the |
|
# SNIPPET variable |
|
# - SNIPPET_ROOT: CMake list of snippet roots, deduplicated and with |
|
# ZEPHYR_BASE appended at the end |
|
# |
|
# The following variables may be updated when this module completes: |
|
# - DTC_OVERLAY_FILE |
|
# - OVERLAY_CONFIG |
|
# |
|
# The following targets will be defined when this CMake module completes: |
|
# - snippets: when invoked, a list of valid snippets will be printed |
|
# |
|
# Optional variables: |
|
# - SNIPPET_ROOT: input CMake list of snippet roots (directories containing |
|
# additional snippet implementations); this should not include ZEPHYR_BASE, |
|
# as that will be added by this module |
|
|
|
include_guard(GLOBAL) |
|
|
|
include(extensions) |
|
|
|
# Warn the user if SNIPPET changes later. Such changes are ignored. |
|
zephyr_check_cache(SNIPPET WATCH) |
|
|
|
# Putting the body into a function prevents us from polluting the |
|
# parent scope. We'll set our outcome variables in the parent scope of |
|
# the function to ensure the outcome of the module. |
|
function(zephyr_process_snippets) |
|
set(snippets_py ${ZEPHYR_BASE}/scripts/snippets.py) |
|
set(snippets_generated ${CMAKE_BINARY_DIR}/zephyr/snippets_generated.cmake) |
|
set_ifndef(SNIPPET_NAMESPACE SNIPPET) |
|
set_ifndef(SNIPPET_PYTHON_EXTRA_ARGS "") |
|
set_ifndef(SNIPPET_APP_DIR "${APPLICATION_SOURCE_DIR}") |
|
|
|
# Set SNIPPET_AS_LIST, removing snippets_generated.cmake if we are |
|
# running cmake again and snippets are no longer requested. |
|
if(NOT DEFINED SNIPPET) |
|
set(SNIPPET_AS_LIST "" PARENT_SCOPE) |
|
file(REMOVE ${snippets_generated}) |
|
else() |
|
string(REPLACE " " ";" SNIPPET_AS_LIST "${${SNIPPET_NAMESPACE}}") |
|
set(SNIPPET_AS_LIST "${SNIPPET_AS_LIST}" PARENT_SCOPE) |
|
endif() |
|
|
|
# Set SNIPPET_ROOT. |
|
zephyr_get(SNIPPET_ROOT MERGE SYSBUILD GLOBAL) |
|
list(APPEND SNIPPET_ROOT ${SNIPPET_APP_DIR}) |
|
list(APPEND SNIPPET_ROOT ${ZEPHYR_BASE}) |
|
unset(real_snippet_root) |
|
foreach(snippet_dir ${SNIPPET_ROOT}) |
|
# The user might have put a symbolic link in here, for example. |
|
file(REAL_PATH ${snippet_dir} real_snippet_dir) |
|
list(APPEND real_snippet_root ${real_snippet_dir}) |
|
endforeach() |
|
set(SNIPPET_ROOT ${real_snippet_root}) |
|
list(REMOVE_DUPLICATES SNIPPET_ROOT) |
|
set(SNIPPET_ROOT "${SNIPPET_ROOT}" PARENT_SCOPE) |
|
|
|
# Generate and include snippets_generated.cmake. |
|
# The Python script is responsible for checking for unknown |
|
# snippets. |
|
set(snippet_root_args) |
|
foreach(root IN LISTS SNIPPET_ROOT) |
|
list(APPEND snippet_root_args --snippet-root "${root}") |
|
endforeach() |
|
set(requested_snippet_args) |
|
foreach(snippet_name ${SNIPPET_AS_LIST}) |
|
list(APPEND requested_snippet_args --snippet "${snippet_name}") |
|
endforeach() |
|
execute_process(COMMAND ${PYTHON_EXECUTABLE} |
|
${snippets_py} |
|
${snippet_root_args} |
|
${requested_snippet_args} |
|
--cmake-out ${snippets_generated} |
|
${SNIPPET_PYTHON_EXTRA_ARGS} |
|
OUTPUT_VARIABLE output |
|
ERROR_VARIABLE output |
|
RESULT_VARIABLE ret) |
|
if(${ret}) |
|
list(JOIN SNIPPET_ROOT "\n " snippet_root_paths) |
|
set(snippet_root_paths "\n ${snippet_root_paths}") |
|
|
|
if(SYSBUILD) |
|
zephyr_get(SYSBUILD_NAME SYSBUILD GLOBAL) |
|
set(extra_output "Snippet roots for image ${SYSBUILD_NAME}:${snippet_root_paths}\n" |
|
"Note that snippets will be applied to all images unless prefixed with the image name " |
|
"e.g. `-D${SYSBUILD_NAME}_SNIPPET=...`, local snippet roots for one image are not set " |
|
"for other images in a build") |
|
else() |
|
set(extra_output "Snippet roots for application:${snippet_root_paths}") |
|
endif() |
|
|
|
message(FATAL_ERROR "${output}" ${extra_output}) |
|
endif() |
|
include(${snippets_generated}) |
|
|
|
# Create the 'snippets' target. Each snippet is printed in a |
|
# separate command because build system files are not fond of |
|
# newlines. |
|
list(TRANSFORM SNIPPET_NAMES PREPEND "COMMAND;${CMAKE_COMMAND};-E;echo;" |
|
OUTPUT_VARIABLE snippets_target_cmd) |
|
add_custom_target(snippets ${snippets_target_cmd} USES_TERMINAL) |
|
|
|
# If snippets were requested, print messages for each one. |
|
if(SNIPPET_AS_LIST) |
|
# Print the requested snippets. |
|
set(snippet_names "Snippet(s):") |
|
foreach(snippet IN LISTS SNIPPET_AS_LIST) |
|
string(APPEND snippet_names " ${snippet}") |
|
endforeach() |
|
message(STATUS "${snippet_names}") |
|
endif() |
|
|
|
# Re-run cmake if any files we depend on changed. |
|
set_property(DIRECTORY APPEND PROPERTY |
|
CMAKE_CONFIGURE_DEPENDS |
|
${snippets_py} |
|
${SNIPPET_PATHS} # generated variable |
|
) |
|
endfunction() |
|
|
|
zephyr_process_snippets()
|
|
|