From d395719adc4344c44a6ea77348520396fb2cf4fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Tue, 28 Feb 2023 13:07:46 -0800 Subject: [PATCH] cmake: modules: dts: extract preprocessing helper extension MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tighten up the interface boundaries by adding an extension function that separates *how* we preprocess the DTS from *what* DTS files we are preprocessing. This involves a functional change to the pre_dt module. This is useful cleanup but is also groundwork for relying on this helper function when adding system devicetree support. Signed-off-by: Martí Bolívar --- cmake/modules/dts.cmake | 40 +++++-------- cmake/modules/extensions.cmake | 102 +++++++++++++++++++++++++++++++++ cmake/modules/pre_dt.cmake | 7 +-- 3 files changed, 118 insertions(+), 31 deletions(-) diff --git a/cmake/modules/dts.cmake b/cmake/modules/dts.cmake index cd2c2be0718..42413ceca73 100644 --- a/cmake/modules/dts.cmake +++ b/cmake/modules/dts.cmake @@ -159,11 +159,7 @@ if(DTC_OVERLAY_FILE) endif() set(i 0) -unset(DTC_INCLUDE_FLAG_FOR_DTS) foreach(dts_file ${dts_files}) - list(APPEND DTC_INCLUDE_FLAG_FOR_DTS - -include ${dts_file}) - if(i EQUAL 0) message(STATUS "Found BOARD.dts: ${dts_file}") else() @@ -203,29 +199,21 @@ set(CACHED_DTS_ROOT_BINDINGS ${DTS_ROOT_BINDINGS} CACHE INTERNAL # regeneration of devicetree_generated.h on every configure. How # challenging is this? Can we cache the dts dependencies? -# Run the preprocessor on the DTS input files. We are leaving -# linemarker directives enabled on purpose. This tells dtlib where -# each line actually came from, which improves error reporting. -execute_process( - COMMAND ${CMAKE_DTS_PREPROCESSOR} - -x assembler-with-cpp - -nostdinc - ${DTS_ROOT_SYSTEM_INCLUDE_DIRS} - ${DTC_INCLUDE_FLAG_FOR_DTS} # include the DTS source and overlays - ${NOSYSDEF_CFLAG} - -D__DTS__ - ${DTS_EXTRA_CPPFLAGS} - -E # Stop after preprocessing - -MD # Generate a dependency file as a side-effect - -MF ${DTS_DEPS} - -o ${DTS_POST_CPP} - ${ZEPHYR_BASE}/misc/empty_file.c - WORKING_DIRECTORY ${APPLICATION_SOURCE_DIR} - RESULT_VARIABLE ret - ) -if(NOT "${ret}" STREQUAL "0") - message(FATAL_ERROR "command failed with return code: ${ret}") +# Run the preprocessor on the DTS input files. +if(DEFINED CMAKE_DTS_PREPROCESSOR) + set(dts_preprocessor ${CMAKE_DTS_PREPROCESSOR}) +else() + set(dts_preprocessor ${CMAKE_C_COMPILER}) endif() +zephyr_dt_preprocess( + CPP ${dts_preprocessor} + SOURCE_FILES ${dts_files} + OUT_FILE ${DTS_POST_CPP} + DEPS_FILE ${DTS_DEPS} + EXTRA_CPPFLAGS ${DTS_EXTRA_CPPFLAGS} + INCLUDE_DIRECTORIES ${DTS_ROOT_SYSTEM_INCLUDE_DIRS} + WORKING_DIRECTORY ${APPLICATION_SOURCE_DIR} + ) # # Make sure we re-run CMake if any devicetree sources or transitive diff --git a/cmake/modules/extensions.cmake b/cmake/modules/extensions.cmake index bc386c2592a..1261aa935fa 100644 --- a/cmake/modules/extensions.cmake +++ b/cmake/modules/extensions.cmake @@ -30,6 +30,7 @@ include(CheckCXXCompilerFlag) # 4. Devicetree extensions # 4.1 dt_* # 4.2. *_if_dt_node +# 4.3 zephyr_dt_* # 5. Zephyr linker functions # 5.1. zephyr_linker* # 6 Function helper macros @@ -3477,6 +3478,107 @@ function(target_sources_if_dt_node path target scope item) endif() endfunction() +######################################################## +# 4.3 zephyr_dt_* +# +# The following methods are common code for dealing +# with devicetree related files in CMake. +# +# Note that functions related to accessing the +# *contents* of the devicetree belong in section 4.1. +# This section is just for DT file processing at +# configuration time. +######################################################## + +# Usage: +# zephyr_dt_preprocess(CPP +# SOURCE_FILES +# OUT_FILE +# [DEPS_FILE ] +# [EXTRA_CPPFLAGS ] +# [INCLUDE_DIRECTORIES ] +# [WORKING_DIRECTORY ] +# +# Preprocess one or more devicetree source files. The preprocessor +# symbol __DTS__ will be defined. If the preprocessor command fails, a +# fatal error occurs. CMAKE_DTS_PREPROCESSOR is used as the +# preprocessor. +# +# Mandatory arguments: +# +# CPP : path to C preprocessor +# +# SOURCE_FILES : The source files to run the preprocessor on. +# These will, in effect, be concatenated in order +# and used as the preprocessor input. +# +# OUT_FILE : Where to store the preprocessor output. +# +# Optional arguments: +# +# DEPS_FILE : If set, generate a dependency file here. +# +# EXTRA_CPPFLAGS : Additional flags to pass the preprocessor. +# +# INCLUDE_DIRECTORIES : Additional directories containing #included +# files. +# +# WORKING_DIRECTORY : where to run the preprocessor. +function(zephyr_dt_preprocess) + set(req_single_args "CPP;OUT_FILE") + set(single_args "DEPS_FILE;WORKING_DIRECTORY") + set(multi_args "SOURCE_FILES;EXTRA_CPPFLAGS;INCLUDE_DIRECTORIES") + cmake_parse_arguments(DT_PREPROCESS "" "${req_single_args};${single_args}" "${multi_args}" ${ARGN}) + + foreach(arg ${req_single_args} SOURCE_FILES) + if(NOT DEFINED DT_PREPROCESS_${arg}) + message(FATAL_ERROR "dt_preprocess() missing required argument: ${arg}") + endif() + endforeach() + + set(include_opts) + foreach(dir ${DT_PREPROCESS_INCLUDE_DIRECTORIES}) + list(APPEND include_opts -isystem ${dir}) + endforeach() + + set(source_opts) + foreach(file ${DT_PREPROCESS_SOURCE_FILES}) + list(APPEND source_opts -include ${file}) + endforeach() + + set(deps_opts) + if(DEFINED DT_PREPROCESS_DEPS_FILE) + list(APPEND deps_opts -MD -MF ${DT_PREPROCESS_DEPS_FILE}) + endif() + + set(workdir_opts) + if(DEFINED DT_PREPROCESS_WORKING_DIRECTORY) + list(APPEND workdir_opts WORKING_DIRECTORY ${DT_PREPROCESS_WORKING_DIRECTORY}) + endif() + + # We are leaving linemarker directives enabled on purpose. This tells + # dtlib where each line actually came from, which improves error + # reporting. + set(preprocess_cmd ${DT_PREPROCESS_CPP} + -x assembler-with-cpp + -nostdinc + ${include_opts} + ${source_opts} + ${NOSYSDEF_CFLAG} + -D__DTS__ + ${DT_PREPROCESS_EXTRA_CPPFLAGS} + -E # Stop after preprocessing + ${deps_opts} + -o ${DT_PREPROCESS_OUT_FILE} + ${ZEPHYR_BASE}/misc/empty_file.c + ${workdir_opts}) + + execute_process(COMMAND ${preprocess_cmd} RESULT_VARIABLE ret) + if(NOT "${ret}" STREQUAL "0") + message(FATAL_ERROR "failed to preprocess devicetree files (error code ${ret}): ${DT_PREPROCESS_SOURCE_FILES}") + endif() +endfunction() + ######################################################## # 5. Zephyr linker functions ######################################################## diff --git a/cmake/modules/pre_dt.cmake b/cmake/modules/pre_dt.cmake index 38ce53d2b90..b19fd7f7fb5 100644 --- a/cmake/modules/pre_dt.cmake +++ b/cmake/modules/pre_dt.cmake @@ -16,7 +16,7 @@ include(extensions) # - DTS_ROOT: a deduplicated list of places where devicetree # implementation files (like bindings, vendor prefixes, etc.) are # found -# - DTS_ROOT_SYSTEM_INCLUDE_DIRS: set to "-isystem PATH1 -isystem PATH2 ...", +# - DTS_ROOT_SYSTEM_INCLUDE_DIRS: set to "PATH1 PATH2 ...", # with one path per potential location where C preprocessor #includes # may be found for devicetree files # @@ -74,10 +74,7 @@ function(pre_dt_module_run) ) get_filename_component(full_path ${dts_root}/${dts_root_path} REALPATH) if(EXISTS ${full_path}) - list(APPEND - DTS_ROOT_SYSTEM_INCLUDE_DIRS - -isystem ${full_path} - ) + list(APPEND DTS_ROOT_SYSTEM_INCLUDE_DIRS ${full_path}) endif() endforeach() endforeach()