From ce64ba36c1dab1ed5ffa9263fa23cdc2650e0caf Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 14:35:46 +0000 Subject: [PATCH 1/9] Initial plan From 65f24d4eee80b51bda0e790ace4c270808bea155 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 14:46:13 +0000 Subject: [PATCH 2/9] build: make core cmake flow portable for native windows Agent-Logs-Url: https://github.com/choco-technologies/dmod-boot/sessions/a0a9a6d9-14a5-49a2-aac0-96475437aeec Co-authored-by: JohnAmadis <17320783+JohnAmadis@users.noreply.github.com> --- CMakeLists.txt | 21 +++++++++--- README.md | 6 ++++ docs/windows-environment-setup.md | 46 +++++++++++++++++++++++---- modules/CMakeLists.txt | 53 ++++++++++++++++++------------- scripts/create_modules_dmp.cmake | 47 +++++++++++++++++++++++++++ scripts/embed_modules_dmp.cmake | 35 ++++++++++++++++++++ scripts/require_file.cmake | 13 ++++++++ scripts/run_monitor.cmake | 10 +++--- scripts/run_monitor_gdb.cmake | 10 +++--- scripts/targets.cmake | 11 +++---- 10 files changed, 203 insertions(+), 49 deletions(-) create mode 100644 scripts/create_modules_dmp.cmake create mode 100644 scripts/embed_modules_dmp.cmake create mode 100644 scripts/require_file.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index d42f742..c001724 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,6 +51,9 @@ project(dmboot DESCRIPTION "DMOD Bootloader" LANGUAGES C CXX ASM) +# Python interpreter for helper scripts (cross-platform) +find_package(Python3 REQUIRED COMPONENTS Interpreter) + # ====================================================================== # For VS Code # ====================================================================== @@ -115,7 +118,11 @@ set(MODULES_DMP_OBJECT "${CMAKE_BINARY_DIR}/__modules_dmp.o") add_custom_command( OUTPUT "${MODULES_DMP_OBJECT}" COMMAND ${CMAKE_COMMAND} -E echo "Checking for modules.dmp..." - COMMAND bash -c "if [ -f ${MODULES_DMP_FILE} ]; then echo 'Embedding modules.dmp'; ${CMAKE_OBJCOPY} --input-target=binary --output-target=elf32-littlearm --binary-architecture=arm --rename-section .data=.embedded.modules_dmp,alloc,load,readonly,data,contents ${MODULES_DMP_FILE} ${MODULES_DMP_OBJECT}; else echo 'No modules.dmp found, creating empty object'; ${CMAKE_OBJCOPY} --input-target=binary --output-target=elf32-littlearm --binary-architecture=arm --rename-section .data=.embedded.modules_dmp,alloc,load,readonly,data,contents /dev/null ${MODULES_DMP_OBJECT}; fi" + COMMAND ${CMAKE_COMMAND} + -DINPUT_DMP="${MODULES_DMP_FILE}" + -DOUTPUT_OBJECT="${MODULES_DMP_OBJECT}" + -DOBJCOPY_EXECUTABLE="${CMAKE_OBJCOPY}" + -P "${CMAKE_CURRENT_SOURCE_DIR}/scripts/embed_modules_dmp.cmake" DEPENDS prepare_modules_dmp COMMENT "Conditionally embedding modules.dmp if it exists" VERBATIM @@ -184,7 +191,7 @@ target_link_libraries(${MODULE_NAME}.elf add_custom_command( TARGET ${MODULE_NAME}.elf POST_BUILD COMMAND ${CMAKE_COMMAND} -E echo "Generating memory usage report..." - COMMAND python3 ${CMAKE_CURRENT_SOURCE_DIR}/scripts/memory_report.py + COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/scripts/memory_report.py ${CMAKE_BINARY_DIR}/${MODULE_NAME}.map ${CMAKE_BINARY_DIR} --lib-dir ${CMAKE_CURRENT_SOURCE_DIR}/lib @@ -205,7 +212,11 @@ include(scripts/targets.cmake) # Custom target to build dmlog_monitor for host architecture set(DMLOG_HOST_BUILD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib/dmlog/build_host) -set(DMLOG_MONITOR_EXECUTABLE ${DMLOG_HOST_BUILD_DIR}/tools/monitor/dmlog_monitor) +if(WIN32) + set(DMLOG_MONITOR_EXECUTABLE ${DMLOG_HOST_BUILD_DIR}/tools/monitor/dmlog_monitor.exe) +else() + set(DMLOG_MONITOR_EXECUTABLE ${DMLOG_HOST_BUILD_DIR}/tools/monitor/dmlog_monitor) +endif() add_custom_command( OUTPUT ${DMLOG_MONITOR_EXECUTABLE} @@ -224,7 +235,7 @@ add_custom_target(build_dmlog_monitor # Extract ring buffer configuration after building firmware add_custom_command( OUTPUT ${CMAKE_BINARY_DIR}/dmlog_ring_buffer.cmake - COMMAND python3 ${CMAKE_CURRENT_SOURCE_DIR}/scripts/extract_ring_buffer_addr.py + COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/scripts/extract_ring_buffer_addr.py ${CMAKE_BINARY_DIR}/${MODULE_NAME}.map --output ${CMAKE_BINARY_DIR}/dmlog_ring_buffer.cmake --format cmake @@ -261,4 +272,4 @@ add_custom_target(monitor-gdb DEPENDS build_dmlog_monitor extract_ring_buffer_config WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMENT "Monitoring logs from ${TARGET} via GDB server..." -) \ No newline at end of file +) diff --git a/README.md b/README.md index c48b6f6..675b73d 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,12 @@ After running the script, restart your terminal or run: source ~/.bashrc ``` +### Option 3: Native Windows Setup + +Native Windows development/build (without WSL or Docker) is supported. + +See [docs/windows-environment-setup.md](docs/windows-environment-setup.md) for the required toolchain and PowerShell build flow. + ## Building ### Building for Hardware diff --git a/docs/windows-environment-setup.md b/docs/windows-environment-setup.md index 9eea6d9..dd926b3 100644 --- a/docs/windows-environment-setup.md +++ b/docs/windows-environment-setup.md @@ -2,16 +2,50 @@ ## Overview -dmod-boot is Linux-oriented (Bash scripts, Linux toolchain, POSIX paths). On Windows, use one of the supported workflows below: +dmod-boot supports native Windows development and build workflows. -1. **WSL2 + Ubuntu (recommended)** - best for local development in VS Code -2. **Docker Desktop** - fastest way to get a ready-to-use environment +Supported workflows: -> Native (non-WSL) Windows builds are not officially supported by this repository. +1. **Native Windows (PowerShell + CMake)** - recommended when you want to work without WSL/Docker +2. **WSL2 + Ubuntu** - Linux-like workflow on Windows +3. **Docker Desktop** - fastest way to get a ready-to-use environment --- -## Option 1: WSL2 + Ubuntu (Recommended) +## Option 1: Native Windows (Recommended) + +### 1. Install required tools + +Install and make available in `PATH`: + +- **CMake** (3.10+) +- **Ninja** (optional, recommended) +- **GNU Arm Embedded Toolchain** (`arm-none-eabi-*`) +- **Python 3** +- **dmod tools** (`dmf-get`, `todmp`, `dmod_loader`) +- **OpenOCD** (for hardware workflow) +- **Renode** (optional, for emulation workflow) + +### 2. Configure and build (PowerShell) + +From repository root: + +```powershell +cmake -DCMAKE_BUILD_TYPE=Debug -DTARGET=STM32F746xG -S . -B build +cmake --build build --config Debug +``` + +### 3. Optional: Renode emulation mode + +```powershell +cmake -DCMAKE_BUILD_TYPE=Debug -DDMBOOT_EMULATION=ON -S . -B build +cmake --build build --config Debug +cmake --build build --target connect +``` + +--- + +## Option 2: WSL2 + Ubuntu ### 1. Install WSL2 @@ -93,7 +127,7 @@ cmake --build build --target monitor-gdb --- -## Option 2: Docker Desktop (Quick Start) +## Option 3: Docker Desktop (Quick Start) ### 1. Install Docker Desktop on Windows diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index 9934ebf..20e6944 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -88,18 +88,24 @@ macro(append_main_module_download_commands LIST_VAR) list(APPEND _MAIN_MODULE_ARGS ${DMBOOT_MAIN_MODULE_CONFIG}) endif() if(DMBOOT_MANIFEST_URL) - list(APPEND ${LIST_VAR} - COMMAND ${CMAKE_COMMAND} -E echo "Downloading main module ${DMBOOT_MAIN_MODULE} (manifest: ${DMBOOT_MANIFEST_URL})..." - COMMAND ${DMF_GET} ${_MAIN_MODULE_ARGS} -m "${DMBOOT_MANIFEST_URL}" -o "${DMBOOT_MODULES_OUT_DIR}" -t "${DMOD_TOOLS_NAME}" --cpu-family "${DMBOOT_MCU_SERIES}" -y --type dmf --config-dir "${DMBOOT_CONFIG_DIR}" - COMMAND bash -c "test -f '${DMBOOT_MODULES_OUT_DIR}/${DMBOOT_MAIN_MODULE}.dmf' || { echo 'ERROR: Main module ${DMBOOT_MAIN_MODULE}.dmf was not downloaded to ${DMBOOT_MODULES_OUT_DIR}. The manifest may not contain the module entry or dmf-get encountered an error.'; exit 1; }" - ) - else() - list(APPEND ${LIST_VAR} - COMMAND ${CMAKE_COMMAND} -E echo "Downloading main module ${DMBOOT_MAIN_MODULE}..." - COMMAND ${DMF_GET} ${_MAIN_MODULE_ARGS} -o "${DMBOOT_MODULES_OUT_DIR}" -t "${DMOD_TOOLS_NAME}" --cpu-family "${DMBOOT_MCU_SERIES}" -y --type dmf --config-dir "${DMBOOT_CONFIG_DIR}" - COMMAND bash -c "test -f '${DMBOOT_MODULES_OUT_DIR}/${DMBOOT_MAIN_MODULE}.dmf' || { echo 'ERROR: Main module ${DMBOOT_MAIN_MODULE}.dmf was not downloaded to ${DMBOOT_MODULES_OUT_DIR}. Check if dmf-get encountered an error.'; exit 1; }" - ) - endif() + list(APPEND ${LIST_VAR} + COMMAND ${CMAKE_COMMAND} -E echo "Downloading main module ${DMBOOT_MAIN_MODULE} (manifest: ${DMBOOT_MANIFEST_URL})..." + COMMAND ${DMF_GET} ${_MAIN_MODULE_ARGS} -m "${DMBOOT_MANIFEST_URL}" -o "${DMBOOT_MODULES_OUT_DIR}" -t "${DMOD_TOOLS_NAME}" --cpu-family "${DMBOOT_MCU_SERIES}" -y --type dmf --config-dir "${DMBOOT_CONFIG_DIR}" + COMMAND ${CMAKE_COMMAND} + -DREQUIRED_FILE="${DMBOOT_MODULES_OUT_DIR}/${DMBOOT_MAIN_MODULE}.dmf" + -DERROR_MESSAGE="Main module ${DMBOOT_MAIN_MODULE}.dmf was not downloaded to ${DMBOOT_MODULES_OUT_DIR}. The manifest may not contain the module entry or dmf-get encountered an error." + -P "${CMAKE_SOURCE_DIR}/scripts/require_file.cmake" + ) + else() + list(APPEND ${LIST_VAR} + COMMAND ${CMAKE_COMMAND} -E echo "Downloading main module ${DMBOOT_MAIN_MODULE}..." + COMMAND ${DMF_GET} ${_MAIN_MODULE_ARGS} -o "${DMBOOT_MODULES_OUT_DIR}" -t "${DMOD_TOOLS_NAME}" --cpu-family "${DMBOOT_MCU_SERIES}" -y --type dmf --config-dir "${DMBOOT_CONFIG_DIR}" + COMMAND ${CMAKE_COMMAND} + -DREQUIRED_FILE="${DMBOOT_MODULES_OUT_DIR}/${DMBOOT_MAIN_MODULE}.dmf" + -DERROR_MESSAGE="Main module ${DMBOOT_MAIN_MODULE}.dmf was not downloaded to ${DMBOOT_MODULES_OUT_DIR}. Check if dmf-get encountered an error." + -P "${CMAKE_SOURCE_DIR}/scripts/require_file.cmake" + ) + endif() endmacro() if(DMBOOT_FLASH_DMD_FILES) @@ -246,11 +252,13 @@ set(DMBOOT_MODULES_DMP "${CMAKE_BINARY_DIR}/modules.dmp") if(DMBOOT_MAIN_MODULE) add_custom_command( OUTPUT "${DMBOOT_MODULES_DMP}" - WORKING_DIRECTORY ${DMBOOT_MODULES_OUT_DIR} - COMMAND ${CMAKE_COMMAND} -E echo "Checking if modules directory contains files..." - COMMAND ${CMAKE_COMMAND} -E echo "Contents of ${DMBOOT_MODULES_OUT_DIR}:" - COMMAND ls -la ${DMBOOT_MODULES_OUT_DIR} || ${CMAKE_COMMAND} -E echo "Directory is empty or does not exist" - COMMAND bash -c "if ls ${DMBOOT_MODULES_OUT_DIR}/*.dmf 1> /dev/null 2>&1; then ${TODMP} modules ${DMBOOT_MODULES_OUT_DIR} ${DMBOOT_MODULES_DMP} ${DMBOOT_MAIN_MODULE}; ls ${DMBOOT_MODULES_OUT_DIR}/*.dmf; else echo 'ERROR: No .dmf files found in ${DMBOOT_MODULES_OUT_DIR} but main module ${DMBOOT_MAIN_MODULE} was expected. Module download may have failed.'; exit 1; fi" + COMMAND ${CMAKE_COMMAND} + -DMODULES_DIR="${DMBOOT_MODULES_OUT_DIR}" + -DOUTPUT_DMP="${DMBOOT_MODULES_DMP}" + -DTODMP_EXECUTABLE="${TODMP}" + -DMAIN_MODULE="${DMBOOT_MAIN_MODULE}" + -DFAIL_IF_EMPTY=ON + -P "${CMAKE_SOURCE_DIR}/scripts/create_modules_dmp.cmake" DEPENDS download_modules COMMENT "Creating modules dmp file from flash modules (if any exist)..." VERBATIM @@ -258,11 +266,12 @@ if(DMBOOT_MAIN_MODULE) else() add_custom_command( OUTPUT "${DMBOOT_MODULES_DMP}" - WORKING_DIRECTORY ${DMBOOT_MODULES_OUT_DIR} - COMMAND ${CMAKE_COMMAND} -E echo "Checking if modules directory contains files..." - COMMAND ${CMAKE_COMMAND} -E echo "Contents of ${DMBOOT_MODULES_OUT_DIR}:" - COMMAND ls -la ${DMBOOT_MODULES_OUT_DIR} || ${CMAKE_COMMAND} -E echo "Directory is empty or does not exist" - COMMAND bash -c "if ls ${DMBOOT_MODULES_OUT_DIR}/*.dmf 1> /dev/null 2>&1; then ${TODMP} modules ${DMBOOT_MODULES_OUT_DIR} ${DMBOOT_MODULES_DMP}; ls ${DMBOOT_MODULES_OUT_DIR}/*.dmf; else echo 'No .dmf files found, skipping DMP creation'; fi" + COMMAND ${CMAKE_COMMAND} + -DMODULES_DIR="${DMBOOT_MODULES_OUT_DIR}" + -DOUTPUT_DMP="${DMBOOT_MODULES_DMP}" + -DTODMP_EXECUTABLE="${TODMP}" + -DFAIL_IF_EMPTY=OFF + -P "${CMAKE_SOURCE_DIR}/scripts/create_modules_dmp.cmake" DEPENDS download_modules COMMENT "Creating modules dmp file from flash modules (if any exist)..." VERBATIM diff --git a/scripts/create_modules_dmp.cmake b/scripts/create_modules_dmp.cmake new file mode 100644 index 0000000..80d1149 --- /dev/null +++ b/scripts/create_modules_dmp.cmake @@ -0,0 +1,47 @@ +if(NOT DEFINED MODULES_DIR) + message(FATAL_ERROR "MODULES_DIR is not defined") +endif() + +if(NOT DEFINED OUTPUT_DMP) + message(FATAL_ERROR "OUTPUT_DMP is not defined") +endif() + +if(NOT DEFINED TODMP_EXECUTABLE) + message(FATAL_ERROR "TODMP_EXECUTABLE is not defined") +endif() + +if(NOT EXISTS "${MODULES_DIR}") + file(MAKE_DIRECTORY "${MODULES_DIR}") +endif() + +file(GLOB DMF_FILES "${MODULES_DIR}/*.dmf") + +if(DMF_FILES) + message(STATUS "Found DMF files in ${MODULES_DIR}:") + foreach(DMF_FILE IN LISTS DMF_FILES) + message(STATUS " ${DMF_FILE}") + endforeach() + + if(DEFINED MAIN_MODULE AND NOT MAIN_MODULE STREQUAL "") + execute_process( + COMMAND "${TODMP_EXECUTABLE}" modules "${MODULES_DIR}" "${OUTPUT_DMP}" "${MAIN_MODULE}" + RESULT_VARIABLE TODMP_RESULT + ) + else() + execute_process( + COMMAND "${TODMP_EXECUTABLE}" modules "${MODULES_DIR}" "${OUTPUT_DMP}" + RESULT_VARIABLE TODMP_RESULT + ) + endif() + + if(NOT TODMP_RESULT EQUAL 0) + message(FATAL_ERROR "todmp failed while creating ${OUTPUT_DMP} (exit code: ${TODMP_RESULT})") + endif() +else() + if(FAIL_IF_EMPTY) + message(FATAL_ERROR "No .dmf files found in ${MODULES_DIR} but main module '${MAIN_MODULE}' was expected. Module download may have failed.") + endif() + + message(STATUS "No .dmf files found in ${MODULES_DIR}, creating empty modules.dmp placeholder") + file(WRITE "${OUTPUT_DMP}" "") +endif() diff --git a/scripts/embed_modules_dmp.cmake b/scripts/embed_modules_dmp.cmake new file mode 100644 index 0000000..458c7bc --- /dev/null +++ b/scripts/embed_modules_dmp.cmake @@ -0,0 +1,35 @@ +if(NOT DEFINED INPUT_DMP) + message(FATAL_ERROR "INPUT_DMP is not defined") +endif() + +if(NOT DEFINED OUTPUT_OBJECT) + message(FATAL_ERROR "OUTPUT_OBJECT is not defined") +endif() + +if(NOT DEFINED OBJCOPY_EXECUTABLE) + message(FATAL_ERROR "OBJCOPY_EXECUTABLE is not defined") +endif() + +set(EMBED_SOURCE_FILE "${INPUT_DMP}") +if(EXISTS "${INPUT_DMP}") + message(STATUS "Embedding modules.dmp from ${INPUT_DMP}") +else() + set(EMBED_SOURCE_FILE "${CMAKE_BINARY_DIR}/empty_modules_dmp.bin") + file(WRITE "${EMBED_SOURCE_FILE}" "") + message(STATUS "No modules.dmp found, embedding empty placeholder") +endif() + +execute_process( + COMMAND "${OBJCOPY_EXECUTABLE}" + --input-target=binary + --output-target=elf32-littlearm + --binary-architecture=arm + --rename-section .data=.embedded.modules_dmp,alloc,load,readonly,data,contents + "${EMBED_SOURCE_FILE}" + "${OUTPUT_OBJECT}" + RESULT_VARIABLE OBJCOPY_RESULT +) + +if(NOT OBJCOPY_RESULT EQUAL 0) + message(FATAL_ERROR "Failed to create embedded modules object (objcopy exit code: ${OBJCOPY_RESULT})") +endif() diff --git a/scripts/require_file.cmake b/scripts/require_file.cmake new file mode 100644 index 0000000..375b5ac --- /dev/null +++ b/scripts/require_file.cmake @@ -0,0 +1,13 @@ +if(NOT DEFINED REQUIRED_FILE) + message(FATAL_ERROR "REQUIRED_FILE is not defined") +endif() + +if(EXISTS "${REQUIRED_FILE}") + message(STATUS "Verified required file exists: ${REQUIRED_FILE}") +else() + if(DEFINED ERROR_MESSAGE) + message(FATAL_ERROR "${ERROR_MESSAGE}") + else() + message(FATAL_ERROR "Required file does not exist: ${REQUIRED_FILE}") + endif() +endif() diff --git a/scripts/run_monitor.cmake b/scripts/run_monitor.cmake index 9494961..6cdadaa 100644 --- a/scripts/run_monitor.cmake +++ b/scripts/run_monitor.cmake @@ -14,7 +14,11 @@ endif() include(${PROJECT_BINARY_DIR}/dmlog_ring_buffer.cmake) # Set paths -set(DMLOG_MONITOR_EXECUTABLE "${PROJECT_SOURCE_DIR}/lib/dmlog/build_host/tools/monitor/dmlog_monitor") +if(WIN32) + set(DMLOG_MONITOR_EXECUTABLE "${PROJECT_SOURCE_DIR}/lib/dmlog/build_host/tools/monitor/dmlog_monitor.exe") +else() + set(DMLOG_MONITOR_EXECUTABLE "${PROJECT_SOURCE_DIR}/lib/dmlog/build_host/tools/monitor/dmlog_monitor") +endif() # Check if dmlog_monitor exists if(NOT EXISTS ${DMLOG_MONITOR_EXECUTABLE}) @@ -36,10 +40,6 @@ message(STATUS "Ring buffer size: ${DMLOG_RING_BUFFER_SIZE}") execute_process( COMMAND ${DMLOG_MONITOR_EXECUTABLE} --addr ${DMLOG_RING_BUFFER_ADDR} WORKING_DIRECTORY ${PROJECT_BINARY_DIR} - # Don't capture OUTPUT or ERROR - let them pass through to terminal - INPUT_FILE /dev/stdin - OUTPUT_FILE /dev/stdout - ERROR_FILE /dev/stderr ) # Note: We intentionally don't check the exit code because: diff --git a/scripts/run_monitor_gdb.cmake b/scripts/run_monitor_gdb.cmake index 9c9dcc9..98b28a8 100644 --- a/scripts/run_monitor_gdb.cmake +++ b/scripts/run_monitor_gdb.cmake @@ -14,7 +14,11 @@ endif() include(${PROJECT_BINARY_DIR}/dmlog_ring_buffer.cmake) # Set paths -set(DMLOG_MONITOR_EXECUTABLE "${PROJECT_SOURCE_DIR}/lib/dmlog/build_host/tools/monitor/dmlog_monitor") +if(WIN32) + set(DMLOG_MONITOR_EXECUTABLE "${PROJECT_SOURCE_DIR}/lib/dmlog/build_host/tools/monitor/dmlog_monitor.exe") +else() + set(DMLOG_MONITOR_EXECUTABLE "${PROJECT_SOURCE_DIR}/lib/dmlog/build_host/tools/monitor/dmlog_monitor") +endif() # Check if dmlog_monitor exists if(NOT EXISTS ${DMLOG_MONITOR_EXECUTABLE}) @@ -38,10 +42,6 @@ message(STATUS "Connecting to GDB server at localhost:3333 (OpenOCD GDB server)" execute_process( COMMAND ${DMLOG_MONITOR_EXECUTABLE} --gdb --port 3333 --addr ${DMLOG_RING_BUFFER_ADDR} WORKING_DIRECTORY ${PROJECT_BINARY_DIR} - # Don't capture OUTPUT or ERROR - let them pass through to terminal - INPUT_FILE /dev/stdin - OUTPUT_FILE /dev/stdout - ERROR_FILE /dev/stderr ) # Note: We intentionally don't check the exit code because: diff --git a/scripts/targets.cmake b/scripts/targets.cmake index 99e24c3..1b4aa88 100644 --- a/scripts/targets.cmake +++ b/scripts/targets.cmake @@ -37,14 +37,13 @@ configure_file( if(DMBOOT_EMULATION) message(STATUS "Emulation mode enabled - targets will use Renode instead of OpenOCD") message(STATUS "Renode platform: ${DMBOOT_RENODE_PLATFORM}") + find_program(RENODE_EXECUTABLE renode REQUIRED) set(INSTALL_FIRMWARE_COMMAND ${CMAKE_COMMAND} -E copy ${MODULE_NAME}.elf ${CMAKE_BINARY_DIR}/renode_firmware.elf) set(INSTALL_FIRMWARE_COMMENT "Copying firmware for Renode: ${TARGET}...") - set(CONNECT_COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/scripts/renode_connect.sh - ${CMAKE_BINARY_DIR}/renode_firmware.elf - ${TARGET} - ${DMBOOT_RENODE_PLATFORM} - ${DMBOOT_MCU_NAME} - ${RENODE_SCRIPT_PATH}) + set(CONNECT_COMMAND ${RENODE_EXECUTABLE} + --disable-xwt + --hide-monitor + -e "include @${RENODE_SCRIPT_PATH}") set(CONNECT_COMMENT "Starting Renode for ${TARGET}...") else() set(INSTALL_FIRMWARE_COMMAND ${OPENOCD} -f ${OPENOCD_INTERFACE} -f ${OPENOCD_TARGET} From 897342fb179e8c7939be71b26ffc235f8e70ec76 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 14:49:20 +0000 Subject: [PATCH 3/9] docs: polish windows guidance and validation helpers Agent-Logs-Url: https://github.com/choco-technologies/dmod-boot/sessions/a0a9a6d9-14a5-49a2-aac0-96475437aeec Co-authored-by: JohnAmadis <17320783+JohnAmadis@users.noreply.github.com> --- docs/windows-environment-setup.md | 2 +- scripts/create_modules_dmp.cmake | 6 +++++- scripts/embed_modules_dmp.cmake | 9 +++++---- scripts/require_file.cmake | 4 +--- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/docs/windows-environment-setup.md b/docs/windows-environment-setup.md index dd926b3..6faa475 100644 --- a/docs/windows-environment-setup.md +++ b/docs/windows-environment-setup.md @@ -6,7 +6,7 @@ dmod-boot supports native Windows development and build workflows. Supported workflows: -1. **Native Windows (PowerShell + CMake)** - recommended when you want to work without WSL/Docker +1. **Native Windows (PowerShell + CMake)** - Recommended when you want to work without WSL/Docker 2. **WSL2 + Ubuntu** - Linux-like workflow on Windows 3. **Docker Desktop** - fastest way to get a ready-to-use environment diff --git a/scripts/create_modules_dmp.cmake b/scripts/create_modules_dmp.cmake index 80d1149..29f509a 100644 --- a/scripts/create_modules_dmp.cmake +++ b/scripts/create_modules_dmp.cmake @@ -39,7 +39,11 @@ if(DMF_FILES) endif() else() if(FAIL_IF_EMPTY) - message(FATAL_ERROR "No .dmf files found in ${MODULES_DIR} but main module '${MAIN_MODULE}' was expected. Module download may have failed.") + if(DEFINED MAIN_MODULE AND NOT MAIN_MODULE STREQUAL "") + message(FATAL_ERROR "No .dmf files found in ${MODULES_DIR} but main module '${MAIN_MODULE}' was expected. Module download may have failed.") + else() + message(FATAL_ERROR "No .dmf files found in ${MODULES_DIR}. Module download may have failed.") + endif() endif() message(STATUS "No .dmf files found in ${MODULES_DIR}, creating empty modules.dmp placeholder") diff --git a/scripts/embed_modules_dmp.cmake b/scripts/embed_modules_dmp.cmake index 458c7bc..a7a82df 100644 --- a/scripts/embed_modules_dmp.cmake +++ b/scripts/embed_modules_dmp.cmake @@ -10,12 +10,13 @@ if(NOT DEFINED OBJCOPY_EXECUTABLE) message(FATAL_ERROR "OBJCOPY_EXECUTABLE is not defined") endif() -set(EMBED_SOURCE_FILE "${INPUT_DMP}") +set(INPUT_BINARY_FILE "${INPUT_DMP}") if(EXISTS "${INPUT_DMP}") message(STATUS "Embedding modules.dmp from ${INPUT_DMP}") else() - set(EMBED_SOURCE_FILE "${CMAKE_BINARY_DIR}/empty_modules_dmp.bin") - file(WRITE "${EMBED_SOURCE_FILE}" "") + get_filename_component(OUTPUT_DIR "${OUTPUT_OBJECT}" DIRECTORY) + set(INPUT_BINARY_FILE "${OUTPUT_DIR}/empty_modules_dmp.bin") + file(WRITE "${INPUT_BINARY_FILE}" "") message(STATUS "No modules.dmp found, embedding empty placeholder") endif() @@ -25,7 +26,7 @@ execute_process( --output-target=elf32-littlearm --binary-architecture=arm --rename-section .data=.embedded.modules_dmp,alloc,load,readonly,data,contents - "${EMBED_SOURCE_FILE}" + "${INPUT_BINARY_FILE}" "${OUTPUT_OBJECT}" RESULT_VARIABLE OBJCOPY_RESULT ) diff --git a/scripts/require_file.cmake b/scripts/require_file.cmake index 375b5ac..2d38084 100644 --- a/scripts/require_file.cmake +++ b/scripts/require_file.cmake @@ -2,9 +2,7 @@ if(NOT DEFINED REQUIRED_FILE) message(FATAL_ERROR "REQUIRED_FILE is not defined") endif() -if(EXISTS "${REQUIRED_FILE}") - message(STATUS "Verified required file exists: ${REQUIRED_FILE}") -else() +if(NOT EXISTS "${REQUIRED_FILE}") if(DEFINED ERROR_MESSAGE) message(FATAL_ERROR "${ERROR_MESSAGE}") else() From 6582e97b4951e4052d3fc5a8a11f3e627626f55c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 15:05:27 +0000 Subject: [PATCH 4/9] scripts: add native windows setup downloader script Agent-Logs-Url: https://github.com/choco-technologies/dmod-boot/sessions/f4e1137d-9b68-4599-a9a9-5fedc243d753 Co-authored-by: JohnAmadis <17320783+JohnAmadis@users.noreply.github.com> --- README.md | 5 + docs/windows-environment-setup.md | 29 +++++- scripts/setup-windows-env.ps1 | 151 ++++++++++++++++++++++++++++++ 3 files changed, 183 insertions(+), 2 deletions(-) create mode 100644 scripts/setup-windows-env.ps1 diff --git a/README.md b/README.md index 675b73d..b818c2f 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,11 @@ source ~/.bashrc Native Windows development/build (without WSL or Docker) is supported. See [docs/windows-environment-setup.md](docs/windows-environment-setup.md) for the required toolchain and PowerShell build flow. +Quick start: + +```powershell +.\scripts\setup-windows-env.ps1 +``` ## Building diff --git a/docs/windows-environment-setup.md b/docs/windows-environment-setup.md index 6faa475..6cc0cba 100644 --- a/docs/windows-environment-setup.md +++ b/docs/windows-environment-setup.md @@ -16,16 +16,41 @@ Supported workflows: ### 1. Install required tools -Install and make available in `PATH`: +Use the repository helper script (no admin-required package installation; tools are downloaded to user-writable directory): + +```powershell +.\scripts\setup-windows-env.ps1 +``` + +By default this downloads/extracts tools to: + +```powershell +$env:USERPROFILE\tools\dmboot +``` + +Then (for the current shell session): + +```powershell +. "$env:USERPROFILE\tools\dmboot\activate-dmboot-tools.ps1" +``` + +Downloaded tools: - **CMake** (3.10+) - **Ninja** (optional, recommended) - **GNU Arm Embedded Toolchain** (`arm-none-eabi-*`) - **Python 3** -- **dmod tools** (`dmf-get`, `todmp`, `dmod_loader`) +- **dmod tools** (`dmf-get`, `todmp`, `dmod_loader`) - provide separately (this script does not install them globally) - **OpenOCD** (for hardware workflow) - **Renode** (optional, for emulation workflow) +Optional script flags: + +```powershell +.\scripts\setup-windows-env.ps1 -ToolsDir D:\tools\dmboot -SkipRenode +.\scripts\setup-windows-env.ps1 -DryRun +``` + ### 2. Configure and build (PowerShell) From repository root: diff --git a/scripts/setup-windows-env.ps1 b/scripts/setup-windows-env.ps1 new file mode 100644 index 0000000..e8117d3 --- /dev/null +++ b/scripts/setup-windows-env.ps1 @@ -0,0 +1,151 @@ +[CmdletBinding()] +param( + [string]$ToolsDir = "$env:USERPROFILE\tools\dmboot", + [string]$ArmVersion = "10.3-2021.10", + [string]$CMakeVersion = "3.31.3", + [string]$RenodeVersion = "1.15.3", + [switch]$SkipArmToolchain, + [switch]$SkipCMake, + [switch]$SkipRenode, + [switch]$SkipProfileSetup, + [switch]$ForceDownload, + [switch]$DryRun +) + +$ErrorActionPreference = "Stop" + +function New-DirectoryIfMissing { + param([Parameter(Mandatory = $true)][string]$Path) + if ($DryRun) { + Write-Host "[DRY RUN] mkdir $Path" + return + } + if (-not (Test-Path -LiteralPath $Path)) { + New-Item -ItemType Directory -Path $Path | Out-Null + } +} + +function Get-Archive { + param( + [Parameter(Mandatory = $true)][string]$Url, + [Parameter(Mandatory = $true)][string]$ArchivePath + ) + if ((Test-Path -LiteralPath $ArchivePath) -and -not $ForceDownload) { + Write-Host "Using cached archive: $ArchivePath" + return + } + if ($DryRun) { + Write-Host "[DRY RUN] download $Url -> $ArchivePath" + return + } + Write-Host "Downloading: $Url" + Invoke-WebRequest -Uri $Url -OutFile $ArchivePath +} + +function Expand-PortableArchive { + param( + [Parameter(Mandatory = $true)][string]$ArchivePath, + [Parameter(Mandatory = $true)][string]$OutputDir + ) + if (Test-Path -LiteralPath $OutputDir) { + Write-Host "Already extracted: $OutputDir" + return + } + if ($DryRun) { + Write-Host "[DRY RUN] expand $ArchivePath -> $OutputDir" + return + } + Expand-Archive -Path $ArchivePath -DestinationPath $ToolsDir -Force +} + +if (-not $IsWindows -and -not $DryRun) { + throw "setup-windows-env.ps1 is intended for native Windows. Use -DryRun outside Windows." +} + +Write-Host "Preparing native Windows environment for dmod-boot..." +Write-Host "Tools directory: $ToolsDir" + +New-DirectoryIfMissing -Path $ToolsDir + +$archivesDir = Join-Path $ToolsDir "_archives" +New-DirectoryIfMissing -Path $archivesDir + +$armRoot = Join-Path $ToolsDir "arm-gnu-toolchain-$ArmVersion-win32" +$cmakeRoot = Join-Path $ToolsDir "cmake-$CMakeVersion-windows-x86_64" +$renodeRoot = Join-Path $ToolsDir "renode_${RenodeVersion}_portable" + +if (-not $SkipArmToolchain) { + $armArchive = Join-Path $archivesDir "arm-gnu-toolchain-$ArmVersion-win32.zip" + $armUrl = "https://developer.arm.com/-/media/Files/downloads/gnu/$ArmVersion/binrel/arm-gnu-toolchain-$ArmVersion-win32.zip" + Get-Archive -Url $armUrl -ArchivePath $armArchive + Expand-PortableArchive -ArchivePath $armArchive -OutputDir $armRoot +} + +if (-not $SkipCMake) { + $cmakeArchive = Join-Path $archivesDir "cmake-$CMakeVersion-windows-x86_64.zip" + $cmakeUrl = "https://github.com/Kitware/CMake/releases/download/v$CMakeVersion/cmake-$CMakeVersion-windows-x86_64.zip" + Get-Archive -Url $cmakeUrl -ArchivePath $cmakeArchive + Expand-PortableArchive -ArchivePath $cmakeArchive -OutputDir $cmakeRoot +} + +if (-not $SkipRenode) { + $renodeArchive = Join-Path $archivesDir "renode-$RenodeVersion.windows-portable.zip" + $renodeUrl = "https://github.com/renode/renode/releases/download/v$RenodeVersion/renode-$RenodeVersion.windows-portable.zip" + Get-Archive -Url $renodeUrl -ArchivePath $renodeArchive + Expand-PortableArchive -ArchivePath $renodeArchive -OutputDir $renodeRoot +} + +$activateScriptPath = Join-Path $ToolsDir "activate-dmboot-tools.ps1" +$activateScript = @" +`$toolPaths = @( + "$armRoot\bin", + "$cmakeRoot\bin", + "$renodeRoot" +) + +foreach (`$toolPath in `$toolPaths) { + if ((Test-Path -LiteralPath `$toolPath) -and (`$env:PATH -notlike "*`$toolPath*")) { + `$env:PATH = "`$toolPath;`$env:PATH" + } +} + +Write-Host "DMOD Boot tool paths loaded for current PowerShell session." +"@ + +if ($DryRun) { + Write-Host "[DRY RUN] write $activateScriptPath" +} else { + Set-Content -Path $activateScriptPath -Value $activateScript +} + +if (-not $SkipProfileSetup) { + $profilePath = $PROFILE.CurrentUserAllHosts + $profileDir = Split-Path -Parent $profilePath + if (-not $DryRun) { + New-Item -ItemType Directory -Path $profileDir -Force | Out-Null + if (-not (Test-Path -LiteralPath $profilePath)) { + New-Item -ItemType File -Path $profilePath | Out-Null + } + } + + $profileSnippet = @" +# DMOD Boot tools (added by setup-windows-env.ps1) +if (Test-Path "$activateScriptPath") { + . "$activateScriptPath" +} +"@ + + if ($DryRun) { + Write-Host "[DRY RUN] append activation snippet to $profilePath" + } else { + $profileContent = Get-Content -Path $profilePath -Raw + if ($profileContent -notlike "*setup-windows-env.ps1*") { + Add-Content -Path $profilePath -Value "`n$profileSnippet" + } + } +} + +Write-Host "" +Write-Host "Done." +Write-Host "Run this in current shell to activate tools now:" +Write-Host " . `"$activateScriptPath`"" From 2d2169b450105663b35330c5dae17776fe4c74a0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 15:06:31 +0000 Subject: [PATCH 5/9] fix: harden windows setup profile handling Agent-Logs-Url: https://github.com/choco-technologies/dmod-boot/sessions/f4e1137d-9b68-4599-a9a9-5fedc243d753 Co-authored-by: JohnAmadis <17320783+JohnAmadis@users.noreply.github.com> --- docs/windows-environment-setup.md | 2 +- scripts/setup-windows-env.ps1 | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/windows-environment-setup.md b/docs/windows-environment-setup.md index 6cc0cba..27adf8e 100644 --- a/docs/windows-environment-setup.md +++ b/docs/windows-environment-setup.md @@ -40,7 +40,7 @@ Downloaded tools: - **Ninja** (optional, recommended) - **GNU Arm Embedded Toolchain** (`arm-none-eabi-*`) - **Python 3** -- **dmod tools** (`dmf-get`, `todmp`, `dmod_loader`) - provide separately (this script does not install them globally) +- **dmod tools** (`dmf-get`, `todmp`, `dmod_loader`) - install/build separately from the dmod project and add them to `PATH` (this script does not install them globally) - **OpenOCD** (for hardware workflow) - **Renode** (optional, for emulation workflow) diff --git a/scripts/setup-windows-env.ps1 b/scripts/setup-windows-env.ps1 index e8117d3..7e97874 100644 --- a/scripts/setup-windows-env.ps1 +++ b/scripts/setup-windows-env.ps1 @@ -138,7 +138,10 @@ if (Test-Path "$activateScriptPath") { if ($DryRun) { Write-Host "[DRY RUN] append activation snippet to $profilePath" } else { - $profileContent = Get-Content -Path $profilePath -Raw + $profileContent = "" + if (Test-Path -LiteralPath $profilePath) { + $profileContent = Get-Content -Path $profilePath -Raw + } if ($profileContent -notlike "*setup-windows-env.ps1*") { Add-Content -Path $profilePath -Value "`n$profileSnippet" } From b78f148d1d5d1f8ea96a6a86454beeba902e6d1e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 15:07:37 +0000 Subject: [PATCH 6/9] fix: improve windows setup robustness and docs note Agent-Logs-Url: https://github.com/choco-technologies/dmod-boot/sessions/f4e1137d-9b68-4599-a9a9-5fedc243d753 Co-authored-by: JohnAmadis <17320783+JohnAmadis@users.noreply.github.com> --- docs/windows-environment-setup.md | 4 +++- scripts/setup-windows-env.ps1 | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/docs/windows-environment-setup.md b/docs/windows-environment-setup.md index 27adf8e..499c923 100644 --- a/docs/windows-environment-setup.md +++ b/docs/windows-environment-setup.md @@ -40,10 +40,12 @@ Downloaded tools: - **Ninja** (optional, recommended) - **GNU Arm Embedded Toolchain** (`arm-none-eabi-*`) - **Python 3** -- **dmod tools** (`dmf-get`, `todmp`, `dmod_loader`) - install/build separately from the dmod project and add them to `PATH` (this script does not install them globally) +- **dmod tools** (`dmf-get`, `todmp`, `dmod_loader`) - install/build separately from the dmod project and add them to `PATH` - **OpenOCD** (for hardware workflow) - **Renode** (optional, for emulation workflow) +> Note: `setup-windows-env.ps1` downloads portable tools to user space and does not install tools globally. + Optional script flags: ```powershell diff --git a/scripts/setup-windows-env.ps1 b/scripts/setup-windows-env.ps1 index 7e97874..c8b4fcd 100644 --- a/scripts/setup-windows-env.ps1 +++ b/scripts/setup-windows-env.ps1 @@ -95,6 +95,23 @@ if (-not $SkipRenode) { Expand-PortableArchive -ArchivePath $renodeArchive -OutputDir $renodeRoot } +if (-not $DryRun) { + $armDetected = Get-ChildItem -Path $ToolsDir -Directory -Filter "arm-gnu-toolchain-$ArmVersion*" | Select-Object -First 1 + if ($armDetected) { + $armRoot = $armDetected.FullName + } + + $cmakeDetected = Get-ChildItem -Path $ToolsDir -Directory -Filter "cmake-$CMakeVersion-windows*" | Select-Object -First 1 + if ($cmakeDetected) { + $cmakeRoot = $cmakeDetected.FullName + } + + $renodeDetected = Get-ChildItem -Path $ToolsDir -Directory -Filter "renode_${RenodeVersion}*" | Select-Object -First 1 + if ($renodeDetected) { + $renodeRoot = $renodeDetected.FullName + } +} + $activateScriptPath = Join-Path $ToolsDir "activate-dmboot-tools.ps1" $activateScript = @" `$toolPaths = @( @@ -141,6 +158,9 @@ if (Test-Path "$activateScriptPath") { $profileContent = "" if (Test-Path -LiteralPath $profilePath) { $profileContent = Get-Content -Path $profilePath -Raw + if ($null -eq $profileContent) { + $profileContent = "" + } } if ($profileContent -notlike "*setup-windows-env.ps1*") { Add-Content -Path $profilePath -Value "`n$profileSnippet" From 0bcaab368a686dca9485a0e3c124f7f41be6cdce Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 15:08:48 +0000 Subject: [PATCH 7/9] fix: prevent duplicate powershell profile entries Agent-Logs-Url: https://github.com/choco-technologies/dmod-boot/sessions/f4e1137d-9b68-4599-a9a9-5fedc243d753 Co-authored-by: JohnAmadis <17320783+JohnAmadis@users.noreply.github.com> --- scripts/setup-windows-env.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/setup-windows-env.ps1 b/scripts/setup-windows-env.ps1 index c8b4fcd..ebbecc3 100644 --- a/scripts/setup-windows-env.ps1 +++ b/scripts/setup-windows-env.ps1 @@ -162,7 +162,7 @@ if (Test-Path "$activateScriptPath") { $profileContent = "" } } - if ($profileContent -notlike "*setup-windows-env.ps1*") { + if ($profileContent -notlike "*activate-dmboot-tools.ps1*") { Add-Content -Path $profilePath -Value "`n$profileSnippet" } } From 8b509ac5ea2cf36657a72cb02866e248e9c7af28 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 15:09:58 +0000 Subject: [PATCH 8/9] fix: align windows setup docs and archive extraction Agent-Logs-Url: https://github.com/choco-technologies/dmod-boot/sessions/f4e1137d-9b68-4599-a9a9-5fedc243d753 Co-authored-by: JohnAmadis <17320783+JohnAmadis@users.noreply.github.com> --- docs/windows-environment-setup.md | 11 +++++++---- scripts/setup-windows-env.ps1 | 12 ++++++++++-- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/docs/windows-environment-setup.md b/docs/windows-environment-setup.md index 499c923..e46e6d8 100644 --- a/docs/windows-environment-setup.md +++ b/docs/windows-environment-setup.md @@ -34,15 +34,18 @@ Then (for the current shell session): . "$env:USERPROFILE\tools\dmboot\activate-dmboot-tools.ps1" ``` -Downloaded tools: +Downloaded by `setup-windows-env.ps1`: - **CMake** (3.10+) -- **Ninja** (optional, recommended) - **GNU Arm Embedded Toolchain** (`arm-none-eabi-*`) +- **Renode** (optional, for emulation workflow) + +Install separately and add to `PATH`: + - **Python 3** -- **dmod tools** (`dmf-get`, `todmp`, `dmod_loader`) - install/build separately from the dmod project and add them to `PATH` +- **Ninja** (optional, recommended) - **OpenOCD** (for hardware workflow) -- **Renode** (optional, for emulation workflow) +- **dmod tools** (`dmf-get`, `todmp`, `dmod_loader`) - build/install from the dmod project > Note: `setup-windows-env.ps1` downloads portable tools to user space and does not install tools globally. diff --git a/scripts/setup-windows-env.ps1 b/scripts/setup-windows-env.ps1 index ebbecc3..7d36f7d 100644 --- a/scripts/setup-windows-env.ps1 +++ b/scripts/setup-windows-env.ps1 @@ -39,7 +39,11 @@ function Get-Archive { return } Write-Host "Downloading: $Url" - Invoke-WebRequest -Uri $Url -OutFile $ArchivePath + try { + Invoke-WebRequest -Uri $Url -OutFile $ArchivePath + } catch { + throw "Failed to download from $Url. $($_.Exception.Message)" + } } function Expand-PortableArchive { @@ -55,7 +59,11 @@ function Expand-PortableArchive { Write-Host "[DRY RUN] expand $ArchivePath -> $OutputDir" return } - Expand-Archive -Path $ArchivePath -DestinationPath $ToolsDir -Force + $destinationRoot = Split-Path -Parent $OutputDir + if (-not (Test-Path -LiteralPath $destinationRoot)) { + New-Item -ItemType Directory -Path $destinationRoot | Out-Null + } + Expand-Archive -Path $ArchivePath -DestinationPath $destinationRoot -Force } if (-not $IsWindows -and -not $DryRun) { From 4fa5799b7b0ce9a9299b0c90c0ea94dba6567c6f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 15:10:38 +0000 Subject: [PATCH 9/9] chore: standardize setup script project naming Agent-Logs-Url: https://github.com/choco-technologies/dmod-boot/sessions/f4e1137d-9b68-4599-a9a9-5fedc243d753 Co-authored-by: JohnAmadis <17320783+JohnAmadis@users.noreply.github.com> --- scripts/setup-windows-env.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/setup-windows-env.ps1 b/scripts/setup-windows-env.ps1 index 7d36f7d..637bb16 100644 --- a/scripts/setup-windows-env.ps1 +++ b/scripts/setup-windows-env.ps1 @@ -70,7 +70,7 @@ if (-not $IsWindows -and -not $DryRun) { throw "setup-windows-env.ps1 is intended for native Windows. Use -DryRun outside Windows." } -Write-Host "Preparing native Windows environment for dmod-boot..." +Write-Host "Preparing native Windows environment for dmboot..." Write-Host "Tools directory: $ToolsDir" New-DirectoryIfMissing -Path $ToolsDir