zephyr/cmake/package_helper.cmake
Torsten Rasmussen c7779bec8c cmake: stub zephyr_set(... SCOPE ...) function in package helper
Fixes: #63011

Custom targets are not available in script mode, which cause snippet
loading to fail when using package helper.

Lookup of snippets is supported by package helper, thus allowing twister
to filter test cases based on snippets.

However, loading of snippets itself is not supported as snippets make
use of Zephyr scoping, which uses custom targets, something that is not
available in script mode.

Therefore overload the `zephyr_set()` function, so that CMake package
helper can be used together with snippets.

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
2023-10-05 09:43:28 +01:00

127 lines
4.6 KiB
CMake

# SPDX-License-Identifier: Apache-2.0
#
# Copyright (c) 2021, Nordic Semiconductor ASA
# The Zephyr package helper script provides a generic script mode interface
# to the Zephyr CMake package and module structure.
#
# The purpose of this script is to provide a single entry for running any Zephyr
# build tool that is executed during CMake configure time without creating a
# complete build system.
#
# It does so by loading the Zephyr CMake modules specified with the 'MODULES'
# argument.
#
# This script executes the given module identical to Zephyr CMake configure time.
# The application source directory must be specified using
# '-S <path-to-sample>'
#
# The build directory will default to current working directory but can be
# controlled with: '-B <path-to-build>'
#
# For example, if you were invoking CMake for 'hello_world' sample as:
# $ cmake -DBOARD=<board> -B build -S samples/hello_world
#
# you can invoke only dts module (and dependencies) as:
# $ cmake -DBOARD=<board> -B build -S samples/hello_world \
# -DMODULES=dts -P <ZEPHYR_BASE>/cmake/package_helper.cmake
#
# It is also possible to pass additional build settings.
# If you invoke CMake for 'hello_world' as:
#
# $ cmake -DBOARD=<board> -B build -S samples/hello_world -DEXTRA_CONF_FILE=foo.conf
#
# you just add the same argument to the helper like:
# $ cmake -DBOARD=<board> -B build -S samples/hello_world -DEXTRA_CONF_FILE=foo.conf \
# -DMODULES=dts -P <ZEPHYR_BASE>/cmake/package_helper.cmake
#
# Note: the samples CMakeLists.txt file is not processed by package helper, so
# any 'set(<var> <value>)' specified before 'find_package(Zephyr)' must be
# manually applied, for example if the CMakeLists.txt contains:
# set(EXTRA_CONF_FILE foo.conf)
# find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
# the 'foo.conf' must be specified using '-DEXTRA_CONF_FILE=foo.conf'
cmake_minimum_required(VERSION 3.20.5)
# add_custom_target and set_target_properties are not supported in script mode.
# However, several Zephyr CMake modules create custom target for user convenience
# like menuconfig, boards, shields, etc.
# As we are not generating a build system with this tool, only running part of
# the modules, then we simply override those functions to allow running those
# modules.
function(add_custom_target)
# This silence the error: 'add_custom_target command is not scriptable'
endfunction()
function(set_target_properties)
# This silence the error: 'set_target_properties command is not scriptable'
endfunction()
# Find last `-B` and `-S` instances.
foreach(i RANGE ${CMAKE_ARGC})
if(CMAKE_ARGV${i} MATCHES "^-B(.*)")
set(argB ${CMAKE_MATCH_1})
set(argB_index ${i})
elseif()
elseif(CMAKE_ARGV${i} MATCHES "^-S(.*)")
set(argS_index ${i})
set(argS ${CMAKE_MATCH_1})
endif()
endforeach()
if(DEFINED argB_index)
if(DEFINED argB)
set(CMAKE_BINARY_DIR ${argB})
else()
# value of -B follows in next index
math(EXPR argB_value_index "${argB_index} + 1")
set(CMAKE_BINARY_DIR ${CMAKE_ARGV${argB_value_index}})
endif()
endif()
if(DEFINED argS_index)
if(DEFINED argS)
set(APPLICATION_SOURCE_DIR ${argS})
else()
# value of -S follows in next index
math(EXPR argS_value_index "${argS_index} + 1")
set(APPLICATION_SOURCE_DIR ${CMAKE_ARGV${argS_value_index}})
endif()
endif()
if(NOT DEFINED APPLICATION_SOURCE_DIR)
message(FATAL_ERROR
"Source directory not defined, please use '-S <path-to-source>' to the "
"application for which this tool shall run.\n"
"For example: -S ${ZEPHYR_BASE}/samples/hello_world"
)
endif()
if(DEFINED APPLICATION_SOURCE_DIR)
cmake_path(ABSOLUTE_PATH APPLICATION_SOURCE_DIR NORMALIZE)
endif()
cmake_path(ABSOLUTE_PATH CMAKE_BINARY_DIR NORMALIZE)
set(CMAKE_CURRENT_BINARY_DIR ${CMAKE_BINARY_DIR})
if(NOT DEFINED MODULES)
message(FATAL_ERROR
"No MODULES defined, please invoke package helper with minimum one module"
" to execute in script mode."
)
endif()
# Loading Zephyr CMake extension commands, which allows us to overload Zephyr
# scoping rules.
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE} COMPONENTS extensions)
# Zephyr scoping creates custom targets for handling of properties.
# However, custom targets cannot be used in CMake script mode.
# Therefore disable zephyr_set(... SCOPE ...) in package helper as it is not needed.
function(zephyr_set variable)
# This silence the error: zephyr_set(... SCOPE <scope>) doesn't exists.
endfunction()
string(REPLACE ";" "," MODULES "${MODULES}")
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE} COMPONENTS zephyr_default:${MODULES})