# Zephyr code can configure itself based on a KConfig'uration with the
# header file autoconf.h. There exists an analogous file
# generated_dts_board.h that allows configuration based on information
# encoded in DTS.
#
# Here we call on dtc, the gcc preprocessor, and
# scripts/dts/extract_dts_includes.py to generate this header file at
# CMake configure-time.
#
# See ~/zephyr/doc/dts
set(GENERATED_DTS_BOARD_H    ${PROJECT_BINARY_DIR}/include/generated/generated_dts_board.h)
set(GENERATED_DTS_BOARD_CONF ${PROJECT_BINARY_DIR}/include/generated/generated_dts_board.conf)
set_ifndef(DTS_SOURCE ${BOARD_ROOT}/boards/${ARCH}/${BOARD_FAMILY}/${BOARD_FAMILY}.dts)
set_ifndef(DTS_COMMON_OVERLAYS ${PROJECT_SOURCE_DIR}/dts/common/common.dts)

message(STATUS "Generating zephyr/include/generated/generated_dts_board.h")

if(CONFIG_HAS_DTS)

  if(DTC_OVERLAY_FILE)
    # Convert from space-separated files into file list
    string(REPLACE " " ";" DTC_OVERLAY_FILE_AS_LIST ${DTC_OVERLAY_FILE})
  endif()

  # Prepend common overlays
  set(DTC_OVERLAY_FILE_AS_LIST ${DTS_COMMON_OVERLAYS} ${DTC_OVERLAY_FILE_AS_LIST})

  set(
    dts_files
    ${DTS_SOURCE}
    ${DTC_OVERLAY_FILE_AS_LIST}
  )

  unset(DTC_INCLUDE_FLAG_FOR_DTS)
  foreach(dts_file ${dts_files})
    list(APPEND DTC_INCLUDE_FLAG_FOR_DTS
         -include ${dts_file})
  endforeach()

  # TODO: Cut down on CMake configuration time by avoiding
  # regeneration of generated_dts_board.h on every configure. How
  # challenging is this? What are the dts dependencies? We run the
  # preprocessor, and it seems to be including all kinds of
  # directories with who-knows how many header files.

  # Run the C preprocessor on an empty C source file that has one or
  # more DTS source files -include'd into it to create the
  # intermediary file *.dts.pre.tmp
  execute_process(
    COMMAND ${CMAKE_C_COMPILER}
    -x assembler-with-cpp
    -nostdinc
    -I${PROJECT_SOURCE_DIR}/arch/${ARCH}/soc
    -isystem ${PROJECT_SOURCE_DIR}/include
    -isystem ${PROJECT_SOURCE_DIR}/dts/${ARCH}
    -isystem ${PROJECT_SOURCE_DIR}/dts
    -include ${AUTOCONF_H}
    ${DTC_INCLUDE_FLAG_FOR_DTS}  # include the DTS source and overlays
    -I${PROJECT_SOURCE_DIR}/dts/common
    -I${PROJECT_SOURCE_DIR}/drivers
    -undef -D__DTS__
    -P
    -E ${ZEPHYR_BASE}/misc/empty_file.c
    -o ${BOARD_FAMILY}.dts.pre.tmp
    WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
    RESULT_VARIABLE ret
    )
  if(NOT "${ret}" STREQUAL "0")
    message(FATAL_ERROR "command failed with return code: ${ret}")
  endif()

  # Run the DTC on *.dts.pre.tmp to create the intermediary file *.dts_compiled
  execute_process(
    COMMAND ${DTC}
    -O dts
    -o ${BOARD_FAMILY}.dts_compiled
    -b 0
    ${BOARD_FAMILY}.dts.pre.tmp
    WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
    RESULT_VARIABLE ret
    )
  if(NOT "${ret}" STREQUAL "0")
    message(FATAL_ERROR "command failed with return code: ${ret}")
  endif()

  # Run extract_dts_includes.py for the header file
  # generated_dts_board.h
  set_ifndef(DTS_BOARD_FIXUP_FILE ${BOARD_ROOT}/boards/${ARCH}/${BOARD_FAMILY}/dts.fixup)
  if(EXISTS ${DTS_BOARD_FIXUP_FILE})
    set(DTS_BOARD_FIXUP -f ${DTS_BOARD_FIXUP_FILE})
  endif()
  set_ifndef(DTS_SOC_FIXUP_FILE ${PROJECT_SOURCE_DIR}/arch/${ARCH}/soc/${CONFIG_SOC_FAMILY}/${CONFIG_SOC_SERIES}/dts.fixup)
  if(EXISTS ${DTS_SOC_FIXUP_FILE})
    set(DTS_SOC_FIXUP -f ${DTS_SOC_FIXUP_FILE})
  endif()
  if(EXISTS ${APPLICATION_SOURCE_DIR}/dts.fixup)
    set(DTS_APP_FIXUP -f ${APPLICATION_SOURCE_DIR}/dts.fixup)
  endif()
  set(CMD_EXTRACT_DTS_INCLUDES ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/dts/extract_dts_includes.py
    --dts ${BOARD_FAMILY}.dts_compiled
    --yaml ${PROJECT_SOURCE_DIR}/dts/bindings
    ${DTS_SOC_FIXUP} ${DTS_BOARD_FIXUP} ${DTS_APP_FIXUP}
    )
  execute_process(
    COMMAND ${CMD_EXTRACT_DTS_INCLUDES}
    OUTPUT_VARIABLE STDOUT
    WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
    RESULT_VARIABLE ret
    )
  if(NOT "${ret}" STREQUAL "0")
    message(FATAL_ERROR "command failed with return code: ${ret}")
  endif()

  # extract_dts_includes.py writes the header file contents to stdout,
  # which we capture in the variable STDOUT and then finaly write into
  # the header file.
  file(WRITE ${GENERATED_DTS_BOARD_H} "${STDOUT}" )

  # Run extract_dts_includes.py to create a .conf file that can be
  # included into the CMake namespace
  execute_process(
    COMMAND ${CMD_EXTRACT_DTS_INCLUDES} --keyvalue
    OUTPUT_VARIABLE STDOUT
    WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
    RESULT_VARIABLE ret
    )
  if(NOT "${ret}" STREQUAL "0")
    message(FATAL_ERROR "command failed with return code: ${ret}")
  endif()

  file(WRITE ${GENERATED_DTS_BOARD_CONF} "${STDOUT}" )
  import_kconfig(${GENERATED_DTS_BOARD_CONF})

else()
  file(WRITE ${GENERATED_DTS_BOARD_H} "/* WARNING. THIS FILE IS AUTO-GENERATED. DO NOT MODIFY! */")
endif()
