cmake: modules: Add zephyr_dt_import
Extract the part of `dts.cmake` that invokes `gen_dts_cmake.py`, then generalize it into a CMake extension, which can be reused by sysbuild. The Python script itself is also updated, so that the generated CMake file can accept an input variable DEVICETREE_TARGET, which comes from the `zephyr_dt_import(TARGET ...)` argument. Signed-off-by: Grzegorz Swiderski <grzegorz.swiderski@nordicsemi.no>
This commit is contained in:
parent
438ed6d74a
commit
468db18389
3 changed files with 51 additions and 42 deletions
|
@ -122,12 +122,6 @@ set(GEN_DRIVER_KCONFIG_SCRIPT ${DT_SCRIPTS}/gen_driver_kconfig_dts.py)
|
||||||
# Generated Kconfig symbols go here.
|
# Generated Kconfig symbols go here.
|
||||||
set(DTS_KCONFIG ${KCONFIG_BINARY_DIR}/Kconfig.dts)
|
set(DTS_KCONFIG ${KCONFIG_BINARY_DIR}/Kconfig.dts)
|
||||||
|
|
||||||
# This generates DT information needed by the CMake APIs.
|
|
||||||
set(GEN_DTS_CMAKE_SCRIPT ${DT_SCRIPTS}/gen_dts_cmake.py)
|
|
||||||
# The generated information itself, which we include() after
|
|
||||||
# creating it.
|
|
||||||
set(DTS_CMAKE ${PROJECT_BINARY_DIR}/dts.cmake)
|
|
||||||
|
|
||||||
# The location of a file containing known vendor prefixes, relative to
|
# The location of a file containing known vendor prefixes, relative to
|
||||||
# each element of DTS_ROOT. Users can define their own in their own
|
# each element of DTS_ROOT. Users can define their own in their own
|
||||||
# modules.
|
# modules.
|
||||||
|
@ -283,7 +277,6 @@ set_property(DIRECTORY APPEND PROPERTY
|
||||||
${GEN_EDT_SCRIPT}
|
${GEN_EDT_SCRIPT}
|
||||||
${GEN_DEFINES_SCRIPT}
|
${GEN_DEFINES_SCRIPT}
|
||||||
${GEN_DRIVER_KCONFIG_SCRIPT}
|
${GEN_DRIVER_KCONFIG_SCRIPT}
|
||||||
${GEN_DTS_CMAKE_SCRIPT}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -356,31 +349,12 @@ if(NOT "${ret}" STREQUAL "0")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#
|
#
|
||||||
# Run GEN_DTS_CMAKE_SCRIPT.
|
# Import devicetree contents into CMake.
|
||||||
|
# This enables the CMake dt_* API.
|
||||||
#
|
#
|
||||||
# A temporary file is copied to the original file if it differs. This prevents issue such as a
|
|
||||||
# cycle when sysbuild is used of configuring and building multiple times due to the dts.cmake file
|
|
||||||
# of images having a newer modification time than the sysbuild build.ninja file, despite the
|
|
||||||
# output having not changed
|
|
||||||
#
|
|
||||||
set(dts_cmake_tmp ${DTS_CMAKE}.new)
|
|
||||||
|
|
||||||
execute_process(
|
add_custom_target(devicetree_target)
|
||||||
COMMAND ${PYTHON_EXECUTABLE} ${GEN_DTS_CMAKE_SCRIPT}
|
zephyr_dt_import(EDT_PICKLE_FILE ${EDT_PICKLE} TARGET devicetree_target)
|
||||||
--edt-pickle ${EDT_PICKLE}
|
|
||||||
--cmake-out ${dts_cmake_tmp}
|
|
||||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
|
||||||
RESULT_VARIABLE ret
|
|
||||||
)
|
|
||||||
if(NOT "${ret}" STREQUAL "0")
|
|
||||||
message(FATAL_ERROR "gen_dts_cmake.py failed with return code: ${ret}")
|
|
||||||
else()
|
|
||||||
zephyr_file_copy(${dts_cmake_tmp} ${DTS_CMAKE} ONLY_IF_DIFFERENT)
|
|
||||||
file(REMOVE ${dts_cmake_tmp})
|
|
||||||
set(dts_cmake_tmp)
|
|
||||||
message(STATUS "Including generated dts.cmake file: ${DTS_CMAKE}")
|
|
||||||
include(${DTS_CMAKE})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Run dtc if it was found.
|
# Run dtc if it was found.
|
||||||
|
|
|
@ -4625,6 +4625,45 @@ function(zephyr_dt_preprocess)
|
||||||
endif()
|
endif()
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
|
# Usage:
|
||||||
|
# zephyr_dt_import(EDT_PICKLE_FILE <file> TARGET <target>)
|
||||||
|
#
|
||||||
|
# Parse devicetree information and make it available to CMake, so that
|
||||||
|
# it can be accessed by the dt_* CMake extensions from section 4.1.
|
||||||
|
#
|
||||||
|
# This requires running a Python script, which can take the output of
|
||||||
|
# edtlib and generate a CMake source file from it. If that script fails,
|
||||||
|
# a fatal error occurs.
|
||||||
|
#
|
||||||
|
# EDT_PICKLE_FILE <file> : Input edtlib.EDT object in pickle format
|
||||||
|
# TARGET <target> : Target to populate with devicetree properties
|
||||||
|
#
|
||||||
|
function(zephyr_dt_import)
|
||||||
|
set(req_single_args "EDT_PICKLE_FILE;TARGET")
|
||||||
|
cmake_parse_arguments(arg "" "${req_single_args}" "" ${ARGN})
|
||||||
|
zephyr_check_arguments_required_all(${CMAKE_CURRENT_FUNCTION} arg ${req_single_args})
|
||||||
|
|
||||||
|
set(gen_dts_cmake_script ${ZEPHYR_BASE}/scripts/dts/gen_dts_cmake.py)
|
||||||
|
set(gen_dts_cmake_output ${arg_EDT_PICKLE_FILE}.cmake)
|
||||||
|
|
||||||
|
if((${arg_EDT_PICKLE_FILE} IS_NEWER_THAN ${gen_dts_cmake_output}) OR
|
||||||
|
(${gen_dts_cmake_script} IS_NEWER_THAN ${gen_dts_cmake_output})
|
||||||
|
)
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${PYTHON_EXECUTABLE} ${gen_dts_cmake_script}
|
||||||
|
--edt-pickle ${arg_EDT_PICKLE_FILE}
|
||||||
|
--cmake-out ${gen_dts_cmake_output}
|
||||||
|
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||||
|
RESULT_VARIABLE ret
|
||||||
|
COMMAND_ERROR_IS_FATAL ANY
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${gen_dts_cmake_script})
|
||||||
|
|
||||||
|
set(DEVICETREE_TARGET ${arg_TARGET})
|
||||||
|
include(${gen_dts_cmake_output})
|
||||||
|
endfunction()
|
||||||
|
|
||||||
########################################################
|
########################################################
|
||||||
# 5. Zephyr linker functions
|
# 5. Zephyr linker functions
|
||||||
########################################################
|
########################################################
|
||||||
|
|
|
@ -11,13 +11,12 @@ That data can then be used in the rest of the build system.
|
||||||
|
|
||||||
The generated CMake file looks like this:
|
The generated CMake file looks like this:
|
||||||
|
|
||||||
add_custom_target(devicetree_target)
|
set_target_properties(${DEVICETREE_TARGET} PROPERTIES
|
||||||
set_target_properties(devicetree_target PROPERTIES
|
|
||||||
"DT_PROP|/soc|compatible" "vnd,soc;")
|
"DT_PROP|/soc|compatible" "vnd,soc;")
|
||||||
...
|
...
|
||||||
|
|
||||||
It defines a special CMake target, and saves various values in the
|
It takes an input variable - DEVICETREE_TARGET - and saves various
|
||||||
devicetree as CMake target properties.
|
values in the devicetree as properties of this CMake target.
|
||||||
|
|
||||||
Be careful:
|
Be careful:
|
||||||
|
|
||||||
|
@ -170,15 +169,12 @@ def main():
|
||||||
cmake_comp = f'DT_COMP|{comp}'
|
cmake_comp = f'DT_COMP|{comp}'
|
||||||
cmake_props.append(f'"{cmake_comp}" "{cmake_path}"')
|
cmake_props.append(f'"{cmake_comp}" "{cmake_path}"')
|
||||||
|
|
||||||
with open(args.cmake_out, "w", encoding="utf-8") as cmake_file:
|
cmake_props = map(
|
||||||
print('add_custom_target(devicetree_target)', file=cmake_file)
|
'set_target_properties(${{DEVICETREE_TARGET}} PROPERTIES {})'.format,
|
||||||
print(file=cmake_file)
|
cmake_props
|
||||||
|
|
||||||
for prop in cmake_props:
|
|
||||||
print(
|
|
||||||
f'set_target_properties(devicetree_target PROPERTIES {prop})',
|
|
||||||
file=cmake_file
|
|
||||||
)
|
)
|
||||||
|
with open(args.cmake_out, "w", encoding="utf-8") as cmake_file:
|
||||||
|
print("\n".join(cmake_props), file=cmake_file)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue