cmake: modules: dts: extract preprocessing helper extension

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 <marti.bolivar@nordicsemi.no>
This commit is contained in:
Martí Bolívar 2023-02-28 13:07:46 -08:00 committed by Carles Cufí
commit d395719adc
3 changed files with 118 additions and 31 deletions

View file

@ -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

View file

@ -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 <path>
# SOURCE_FILES <files>
# OUT_FILE <file>
# [DEPS_FILE <file>]
# [EXTRA_CPPFLAGS <flags>]
# [INCLUDE_DIRECTORIES <dirs>]
# [WORKING_DIRECTORY <dir>]
#
# 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>: path to C preprocessor
#
# SOURCE_FILES <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 <file>: Where to store the preprocessor output.
#
# Optional arguments:
#
# DEPS_FILE <file>: If set, generate a dependency file here.
#
# EXTRA_CPPFLAGS <flags>: Additional flags to pass the preprocessor.
#
# INCLUDE_DIRECTORIES <dirs>: Additional directories containing #included
# files.
#
# WORKING_DIRECTORY <dir>: 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
########################################################

View file

@ -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()