1# SPDX-License-Identifier: Apache-2.0 2 3function(runners_yaml_append content) 4 # Append ${content}\n to a target property which is later evaluated as a 5 # generator expression when writing the flash runner yaml file. 6 # We define this function here to have access to the `flash` target. 7 8 set_property( 9 TARGET runners_yaml_props_target 10 APPEND_STRING 11 PROPERTY yaml_contents 12 "${content}\n" 13 ) 14endfunction() 15 16function(get_runners_prop prop out_var default_value) 17 # Get property 'prop' from runners_yaml_props_target, storing its 18 # value in 'out_var'. If the property is not found (value is 19 # ...-NOTFOUND), 'out_var' is set to 'default_value'. 20 21 get_target_property(out runners_yaml_props_target "${prop}") 22 23 if("${out}" STREQUAL "out-NOTFOUND") 24 set("${out_var}" "${default_value}" PARENT_SCOPE) 25 else() 26 set("${out_var}" "${out}" PARENT_SCOPE) 27 endif() 28endfunction() 29 30function(runners_yaml_append_config) 31 # Append the common configuration values to the relevant property target. 32 33 runners_yaml_append("\n# Common runner configuration values.") 34 runners_yaml_append("config:") 35 runners_yaml_append(" board_dir: ${BOARD_DIR}") 36 get_runners_prop(elf_file elf "${KERNEL_ELF_NAME}") 37 runners_yaml_append(" # Build outputs:") 38 runners_yaml_append(" elf_file: ${elf}") 39 if(CONFIG_BUILD_OUTPUT_EXE) 40 get_runners_prop(exe_file exe "${KERNEL_EXE_NAME}") 41 else() 42 get_runners_prop(exe_file exe "") 43 endif() 44 if(exe) 45 runners_yaml_append(" exe_file: ${exe}") 46 endif() 47 if(CONFIG_BUILD_OUTPUT_HEX) 48 get_runners_prop(hex_file hex "${KERNEL_HEX_NAME}") 49 else() 50 get_runners_prop(hex_file hex "") 51 endif() 52 if(hex) 53 runners_yaml_append(" hex_file: ${hex}") 54 endif() 55 if(CONFIG_BUILD_OUTPUT_BIN) 56 get_runners_prop(bin_file bin "${KERNEL_BIN_NAME}") 57 runners_yaml_append(" bin_file: ${bin}") 58 endif() 59 if(CONFIG_BUILD_OUTPUT_UF2) 60 get_runners_prop(uf2_file uf2 "${KERNEL_UF2_NAME}") 61 runners_yaml_append(" uf2_file: ${uf2}") 62 endif() 63 64 if(CMAKE_GDB OR OPENOCD OR OPENOCD_DEFAULT_PATH) 65 runners_yaml_append(" # Host tools:") 66 endif() 67 if(CMAKE_GDB) 68 runners_yaml_append(" gdb: ${CMAKE_GDB}") 69 endif() 70 if(OPENOCD) 71 runners_yaml_append(" openocd: ${OPENOCD}") 72 runners_yaml_append(" openocd_search:") 73 if(OPENOCD_DEFAULT_PATH) 74 runners_yaml_append(" - ${OPENOCD_DEFAULT_PATH}") 75 endif() 76 endif() 77 runners_yaml_append("") 78endfunction() 79 80# Save runner state in a YAML file, and put that YAML file's location 81# in the cache. 82function(create_runners_yaml) 83 set(runners ${ARGV}) 84 85 set(runners_yaml "${PROJECT_BINARY_DIR}/runners.yaml") 86 87 runners_yaml_append("# Available runners configured by board.cmake.\nrunners:") 88 foreach(runner ${runners}) 89 runners_yaml_append("- ${runner}") 90 endforeach() 91 92 if(DEFINED BOARD_FLASH_RUNNER) 93 runners_yaml_append("\n# Default flash runner if --runner is not given.") 94 runners_yaml_append("flash-runner: ${BOARD_FLASH_RUNNER}") 95 endif() 96 if(DEFINED BOARD_DEBUG_RUNNER) 97 runners_yaml_append("\n# Default debug runner if --runner is not given.") 98 runners_yaml_append("debug-runner: ${BOARD_DEBUG_RUNNER}") 99 endif() 100 101 # Sets up common runner configuration values. 102 runners_yaml_append_config() 103 104 # Get runner-specific arguments set in the board files. 105 runners_yaml_append("# Runner specific arguments") 106 runners_yaml_append("args:") 107 foreach(runner ${runners}) 108 string(MAKE_C_IDENTIFIER ${runner} runner_id) 109 runners_yaml_append(" ${runner}:") 110 get_property(args GLOBAL PROPERTY "BOARD_RUNNER_ARGS_${runner_id}") 111 if(args) 112 # Usually, the runner has arguments. Append them to runners.yaml, 113 # one per line. 114 foreach(arg ${args}) 115 runners_yaml_append(" - ${arg}") 116 endforeach() 117 else() 118 # If the runner doesn't need any arguments, just use an empty list. 119 runners_yaml_append(" []\n") 120 endif() 121 endforeach() 122 123 # Write the final contents and set its location in the cache. 124 file(GENERATE OUTPUT "${runners_yaml}" CONTENT 125 $<TARGET_PROPERTY:runners_yaml_props_target,yaml_contents>) 126 set(ZEPHYR_RUNNERS_YAML "${runners_yaml}" CACHE INTERNAL 127 "a configuration file for the runners Python package") 128endfunction() 129 130get_property(RUNNERS GLOBAL PROPERTY ZEPHYR_RUNNERS) 131 132# Persist the runner-related state. 133# 134# Available runners and their arguments are configured in board.cmake 135# files. 136# 137# Everything is marked with FORCE so that re-running CMake updates the 138# configuration if the board files change. 139if(RUNNERS) 140 create_runners_yaml(${RUNNERS}) 141endif() 142 143zephyr_get(WEST_DIR) 144if(WEST_DIR) 145 set(WEST "PYTHONPATH=${WEST_DIR}/src" "${PYTHON_EXECUTABLE};${WEST_DIR}/src/west/app/main.py;--zephyr-base=${ZEPHYR_BASE} ") 146endif() 147 148# Generate the flash, debug, debugserver, attach targets within the build 149# system itself. 150foreach(target flash debug debugserver attach) 151 if(target STREQUAL flash) 152 set(comment "Flashing ${BOARD}") 153 elseif(target STREQUAL debug) 154 set(comment "Debugging ${BOARD}") 155 elseif(target STREQUAL debugserver) 156 set(comment "Debugging ${BOARD}") 157 if(SUPPORTED_EMU_PLATFORMS) 158 # cmake/qemu/CMakeLists.txt will add a debugserver target for 159 # emulation platforms, so we don't add one here 160 continue() 161 endif() 162 elseif(target STREQUAL attach) 163 set(comment "Debugging ${BOARD}") 164 endif() 165 string(TOUPPER ${target} TARGET_UPPER) 166 167 list(APPEND RUNNERS_DEPS ${logical_target_for_zephyr_elf}) 168 169 # Enable verbose output, if requested. 170 if(CMAKE_VERBOSE_MAKEFILE) 171 set(RUNNER_VERBOSE "--verbose") 172 else() 173 set(RUNNER_VERBOSE) 174 endif() 175 176 if(WEST) 177 add_custom_target(${target} 178 # This script will print an error message and fail if <target> has added 179 # dependencies. This is done using dedicated CMake script, as 180 # `cmake -E {true|false}` is not available until CMake 3.16. 181 COMMAND ${CMAKE_COMMAND} 182 -DTARGET=${target} 183 -DDEPENDENCIES="$<TARGET_PROPERTY:${target},MANUALLY_ADDED_DEPENDENCIES>" 184 -P ${CMAKE_CURRENT_LIST_DIR}/check_runner_dependencies.cmake 185 COMMAND 186 ${CMAKE_COMMAND} -E env 187 ${WEST} 188 ${RUNNER_VERBOSE} 189 ${target} 190 WORKING_DIRECTORY 191 ${APPLICATION_BINARY_DIR} 192 COMMENT 193 ${comment} 194 USES_TERMINAL 195 ) 196 else() 197 add_custom_target(${target} 198 COMMAND ${CMAKE_COMMAND} -E echo \"West was not found in path. To support 199 '${CMAKE_MAKE_PROGRAM} ${target}', please create a west workspace.\" 200 USES_TERMINAL 201 ) 202 endif(WEST) 203endforeach() 204