From 971dfa6024dfe0896baa0c0e44cce9a215f379e1 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Mon, 18 Nov 2024 15:42:30 +0100 Subject: [PATCH] device: export CMake pre-load from device subsystem enumeration script Extend the device subsystem enumeration script to produce a CMake pre-load script. This allow CMake linker generator scripts to create iterable sections based on output from device subsystem enumeration. This ensures that same functionality is available in both ld linker templates and the linker generator. Update linker generators to support the use of the device subsystem enumeration CMake pre-load script. Signed-off-by: Torsten Rasmussen --- CMakeLists.txt | 13 +++++++++-- cmake/linker/armlink/target.cmake | 2 ++ cmake/linker/ld/target.cmake | 2 ++ cmake/linker/linker_script_common.cmake | 4 ++-- scripts/build/gen_iter_sections.py | 31 ++++++++++++++++++++++--- 5 files changed, 45 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2015626637c..58b30ba7a9a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -889,21 +889,30 @@ set( ${CMAKE_CURRENT_BINARY_DIR}/include/generated/device-api-sections.ld ) +set(DEVICE_API_LINKER_SECTIONS_CMAKE + ${CMAKE_CURRENT_BINARY_DIR}/include/generated/device-api-sections.cmake +) + add_custom_command( - OUTPUT ${DEVICE_API_LD_SECTIONS} + OUTPUT ${DEVICE_API_LD_SECTIONS} ${DEVICE_API_LINKER_SECTIONS_CMAKE} COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/gen_iter_sections.py + --alignment ${CONFIG_LINKER_ITERABLE_SUBALIGN} --input ${struct_tags_json} --tag __subsystem --ld-output ${DEVICE_API_LD_SECTIONS} + --cmake-output ${DEVICE_API_LINKER_SECTIONS_CMAKE} DEPENDS ${ZEPHYR_BASE}/scripts/build/gen_iter_sections.py ${struct_tags_json} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) -add_custom_target(${DEVICE_API_LD_TARGET} DEPENDS ${DEVICE_API_LD_SECTIONS}) +add_custom_target(${DEVICE_API_LD_TARGET} + DEPENDS ${DEVICE_API_LD_SECTIONS} + ${DEVICE_API_LINKER_SECTIONS_CMAKE} +) # Add a pseudo-target that is up-to-date when all generated headers # are up-to-date. diff --git a/cmake/linker/armlink/target.cmake b/cmake/linker/armlink/target.cmake index 17f61eec8ff..be2bb8e8977 100644 --- a/cmake/linker/armlink/target.cmake +++ b/cmake/linker/armlink/target.cmake @@ -44,12 +44,14 @@ macro(configure_linker_script linker_script_gen linker_pass_define) ${STEERING_FILE} ${STEERING_C} COMMAND ${CMAKE_COMMAND} + -C ${DEVICE_API_LINKER_SECTIONS_CMAKE} -C ${cmake_linker_script_settings} -DPASS="${linker_pass_define}" ${STEERING_FILE_ARG} ${STEERING_C_ARG} -DOUT_FILE=${CMAKE_CURRENT_BINARY_DIR}/${linker_script_gen} -P ${ZEPHYR_BASE}/cmake/linker/armlink/scatter_script.cmake + DEPENDS ${DEVICE_API_LD_TARGET} ) if("LINKER_ZEPHYR_FINAL" IN_LIST linker_pass_define_list) diff --git a/cmake/linker/ld/target.cmake b/cmake/linker/ld/target.cmake index 47a605cf1da..bdeecd0b0b3 100644 --- a/cmake/linker/ld/target.cmake +++ b/cmake/linker/ld/target.cmake @@ -36,10 +36,12 @@ macro(configure_linker_script linker_script_gen linker_pass_define) add_custom_command( OUTPUT ${linker_script_gen} COMMAND ${CMAKE_COMMAND} + -C ${DEVICE_API_LINKER_SECTIONS_CMAKE} -C ${cmake_linker_script_settings} -DPASS="${linker_pass_define}" -DOUT_FILE=${CMAKE_CURRENT_BINARY_DIR}/${linker_script_gen} -P ${ZEPHYR_BASE}/cmake/linker/ld/ld_script.cmake + DEPENDS ${DEVICE_API_LD_TARGET} ) else() set(template_script_defines ${linker_pass_define}) diff --git a/cmake/linker/linker_script_common.cmake b/cmake/linker/linker_script_common.cmake index ef5ded66fdd..017de14cf6b 100644 --- a/cmake/linker/linker_script_common.cmake +++ b/cmake/linker/linker_script_common.cmake @@ -132,7 +132,7 @@ function(create_section) set(INDEX 100) set(settings_single "ALIGN;ANY;FIRST;KEEP;OFFSET;PRIO;SECTION;SORT") set(settings_multi "FLAGS;INPUT;PASS;SYMBOLS") - foreach(settings ${SECTION_SETTINGS}) + foreach(settings ${SECTION_SETTINGS} ${DEVICE_API_SECTION_SETTINGS}) if("${settings}" MATCHES "^{(.*)}$") cmake_parse_arguments(SETTINGS "" "${settings_single}" "${settings_multi}" ${CMAKE_MATCH_1}) @@ -652,7 +652,7 @@ foreach(group ${GROUPS}) endif() endforeach() -foreach(section ${SECTIONS}) +foreach(section ${SECTIONS} ${DEVICE_API_SECTIONS}) if("${section}" MATCHES "^{(.*)}$") create_section(${CMAKE_MATCH_1} SYSTEM ${new_system}) endif() diff --git a/scripts/build/gen_iter_sections.py b/scripts/build/gen_iter_sections.py index 98ce5c72d1e..cca0ea11eb9 100644 --- a/scripts/build/gen_iter_sections.py +++ b/scripts/build/gen_iter_sections.py @@ -16,10 +16,30 @@ def get_tagged_items(filepath: str, tag: str) -> list: return json.load(fp)[tag] -def gen_ld(filepath: str, items: list): +def gen_ld(filepath: str, items: list, alignment: int): with open(filepath, "w") as fp: for item in items: - fp.write(f"ITERABLE_SECTION_ROM({item}, Z_LINK_ITERABLE_SUBALIGN)\n") + fp.write(f"ITERABLE_SECTION_ROM({item}, {alignment})\n") + + +def gen_cmake(filepath: str, items: list, alignment: int): + with open(filepath, "w") as fp: + for item in items: + fp.write( + f'list(APPEND sections "{{NAME\\;{item}_area\\;' + + 'GROUP\\;RODATA_REGION\\;' + + f'SUBALIGN\\;{alignment}\\;' + + 'NOINPUT\\;TRUE}")\n' + ) + fp.write( + f'list(APPEND section_settings "{{SECTION\\;{item}_area\\;' + + 'SORT\\;NAME\\;' + + 'KEEP\\;TRUE\\;' + + f'INPUT\\;._{item}.static.*\\;' + + f'SYMBOLS\\;_{item}_list_start\\;_{item}_list_end}}")\n' + ) + fp.write('set(DEVICE_API_SECTIONS "${sections}" CACHE INTERNAL "")\n') + fp.write('set(DEVICE_API_SECTION_SETTINGS "${section_settings}" CACHE INTERNAL "")\n') def parse_args() -> argparse.Namespace: @@ -30,8 +50,12 @@ def parse_args() -> argparse.Namespace: ) parser.add_argument("-i", "--input", required=True, help="Path to input list of tags") + parser.add_argument("-a", "--alignment", required=True, help="Iterable section alignment") parser.add_argument("-t", "--tag", required=True, help="Tag to generate iterable sections for") parser.add_argument("-l", "--ld-output", required=True, help="Path to output linker file") + parser.add_argument( + "-c", "--cmake-output", required=True, help="Path to CMake linker script inclusion file" + ) return parser.parse_args() @@ -41,7 +65,8 @@ def main(): items = get_tagged_items(args.input, args.tag) - gen_ld(args.ld_output, items) + gen_ld(args.ld_output, items, args.alignment) + gen_cmake(args.cmake_output, items, args.alignment) if __name__ == "__main__":