From ea082ac2c923d3ce4161bb12f3588dd0c637ffac Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Mon, 7 Feb 2022 12:53:09 +0100 Subject: [PATCH] cmake: only write devicetree files when there are changes. As part of #40167 is was discovered that devicetree headers are always generated when CMake re-runs. This causes all source files that directly or indirectly through included headers to recompile when CMake re-runs, even if there are no changes to devicetree. This commits introduces `zephyr_file_copy(...)` similar to `file(COPY_FILE ...)` from CMake 3.21. However, as CMake 3.20 is supported by Zephyr we need a zephyr variant of this function to allow usage with CMake 3.20. This ensures that only when there are changes to devicetree headers, then source files will recompile. Signed-off-by: Torsten Rasmussen --- CMakeLists.txt | 6 ++-- CODEOWNERS | 1 + cmake/dts.cmake | 15 ++++++---- cmake/extensions.cmake | 36 ++++++++++++++++++++++++ misc/generated/generated_header.template | 1 + 5 files changed, 52 insertions(+), 7 deletions(-) create mode 100644 misc/generated/generated_header.template diff --git a/CMakeLists.txt b/CMakeLists.txt index 017f27289e9e..2684d0e86912 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -471,7 +471,7 @@ set_ifndef(DTS_CAT_OF_FIXUP_FILES ${ZEPHYR_BINARY_DIR}/include/generated/devicet # Concatenate the fixups into a single header file for easy # #include'ing -file(WRITE ${DTS_CAT_OF_FIXUP_FILES} "/* May only be included by devicetree.h */\n\n") +file(WRITE ${DTS_CAT_OF_FIXUP_FILES}.new "/* May only be included by devicetree.h */\n\n") set(DISCOVERED_FIXUP_FILES) foreach(fixup_file ${DTS_BOARD_FIXUP_FILE} @@ -481,10 +481,12 @@ foreach(fixup_file ) if(EXISTS ${fixup_file}) file(READ ${fixup_file} contents) - file(APPEND ${DTS_CAT_OF_FIXUP_FILES} "${contents}") + file(APPEND ${DTS_CAT_OF_FIXUP_FILES}.new "${contents}") string(APPEND DISCOVERED_FIXUP_FILES "- ${fixup_file}\n") endif() endforeach() +zephyr_file_copy(${DTS_CAT_OF_FIXUP_FILES}.new ${DTS_CAT_OF_FIXUP_FILES} ONLY_IF_DIFFERENT) +file(REMOVE ${DTS_CAT_OF_FIXUP_FILES}.new) if (DISCOVERED_FIXUP_FILES) message(WARNING "One or more dts_fixup.h files detected:\n${DISCOVERED_FIXUP_FILES}Use of these files is deprecated; use the devicetree.h API instead.") diff --git a/CODEOWNERS b/CODEOWNERS index a1d4dc3e9fd0..f3bbb504876d 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -613,6 +613,7 @@ /subsys/portability/ @nashif /lib/libc/ @nashif /lib/libc/arcmwdt/ @abrodkin @ruuddw @evgeniy-paltsev +/misc/ @tejlmand /modules/ @nashif /modules/canopennode/ @henrikbrixandersen /modules/mbedtls/ @ceolin @d3zd3z diff --git a/cmake/dts.cmake b/cmake/dts.cmake index 039853a69255..d5a913813e54 100644 --- a/cmake/dts.cmake +++ b/cmake/dts.cmake @@ -189,9 +189,9 @@ if(SUPPORTS_DTS) --dts ${DTS_POST_CPP} --dtc-flags '${EXTRA_DTC_FLAGS_RAW}' --bindings-dirs ${DTS_ROOT_BINDINGS} - --header-out ${DEVICETREE_UNFIXED_H} - --device-header-out ${DEVICE_EXTERN_H} - --dts-out ${ZEPHYR_DTS} # for debugging and dtc + --header-out ${DEVICETREE_UNFIXED_H}.new + --device-header-out ${DEVICE_EXTERN_H}.new + --dts-out ${ZEPHYR_DTS}.new # for debugging and dtc --edt-pickle-out ${EDT_PICKLE} ${EXTRA_GEN_DEFINES_ARGS} ) @@ -204,6 +204,10 @@ if(SUPPORTS_DTS) if(NOT "${ret}" STREQUAL "0") message(FATAL_ERROR "gen_defines.py failed with return code: ${ret}") else() + zephyr_file_copy(${ZEPHYR_DTS}.new ${ZEPHYR_DTS} ONLY_IF_DIFFERENT) + zephyr_file_copy(${DEVICETREE_UNFIXED_H}.new ${DEVICETREE_UNFIXED_H} ONLY_IF_DIFFERENT) + zephyr_file_copy(${DEVICE_EXTERN_H}.new ${DEVICE_EXTERN_H}) + file(REMOVE ${ZEPHYR_DTS}.new ${DEVICETREE_UNFIXED_H}.new ${DEVICE_EXTERN_H}.new) message(STATUS "Generated zephyr.dts: ${ZEPHYR_DTS}") message(STATUS "Generated devicetree_unfixed.h: ${DEVICETREE_UNFIXED_H}") message(STATUS "Generated device_extern.h: ${DEVICE_EXTERN_H}") @@ -267,6 +271,7 @@ if(SUPPORTS_DTS) endif() endif(DTC) else() - file(WRITE ${DEVICETREE_UNFIXED_H} "/* WARNING. THIS FILE IS AUTO-GENERATED. DO NOT MODIFY! */") - file(WRITE ${DEVICE_EXTERN_H} "/* WARNING. THIS FILE IS AUTO-GENERATED. DO NOT MODIFY! */") + set(header_template ${ZEPHYR_BASE}/misc/generated/generated_header.template) + zephyr_file_copy(${header_template} ${DEVICETREE_UNFIXED_H} ONLY_IF_DIFFERENT) + zephyr_file_copy(${header_template} ${DEVICE_EXTERN_H} ONLY_IF_DIFFERENT) endif(SUPPORTS_DTS) diff --git a/cmake/extensions.cmake b/cmake/extensions.cmake index cf2db3c098a4..9746fb14506f 100644 --- a/cmake/extensions.cmake +++ b/cmake/extensions.cmake @@ -2282,6 +2282,42 @@ Relative paths are only allowed with `-D${ARGV1}=`") endif() endfunction() +# Usage: +# zephyr_file_copy( [ONLY_IF_DIFFERENT]) +# +# Zephyr file copy extension. +# This function is similar to CMake function +# 'file(COPY_FILE [ONLY_IF_DIFFERENT])' +# introduced with CMake 3.21. +# +# Because the minimal required CMake version with Zephyr is 3.20, this function +# is not guaranteed to be available. +# +# When using CMake version 3.21 or newer 'zephyr_file_copy()' simply calls +# 'file(COPY_FILE...)' directly. +# When using CMake version 3.20, the implementation will execute using CMake +# for running command line tool in a subprocess for identical functionality. +function(zephyr_file_copy oldname newname) + set(options ONLY_IF_DIFFERENT) + cmake_parse_arguments(ZEPHYR_FILE_COPY "${options}" "" "" ${ARGN}) + + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.21.0) + if(ZEPHYR_FILE_COPY_ONLY_IF_DIFFERENT) + set(copy_file_options ONLY_IF_DIFFERENT) + endif() + file(COPY_FILE ${oldname} ${newname} ${copy_file_options}) + else() + if(ZEPHYR_FILE_COPY_ONLY_IF_DIFFERENT) + set(copy_file_command copy_if_different) + else() + set(copy_file_command copy) + endif() + execute_process( + COMMAND ${CMAKE_COMMAND} -E ${copy_file_command} ${oldname} ${newname} + ) + endif() +endfunction() + # Usage: # zephyr_string( ...) # diff --git a/misc/generated/generated_header.template b/misc/generated/generated_header.template new file mode 100644 index 000000000000..2b323cd20e1c --- /dev/null +++ b/misc/generated/generated_header.template @@ -0,0 +1 @@ +/* WARNING. THIS FILE IS AUTO-GENERATED. DO NOT MODIFY! */