Automating merged.hex Patching After Build

Hello Nordic team,

I would like to automatically patch the merged.hex file each time I build my project. I’ve attempted to use extra_post_build in CMakeLists.txt, but my patching script still runs before the merged.hex file is generated.

From what I’ve read here https://devzone.nordicsemi.com/f/nordic-q-a/102010/adding-extra_post_build-step-from-out-of-tree-application, this behavior might be due to the CONFIG_BOOTLOADER_MCUBOOT macro.
Is there an alternative solution or recommended approach to ensure that my patching logic runs after merged.hex is fully created? i am using nrf 5340 and sdk 2.9.0

Thank you in advance!

Best regards,
kelk

Parents
  • Add a condition in your CMakeLists.txt using POST_BUILD for your execution something like below

    if (DEFINED CONFIG_BOOTLOADER_MCUBOOT)
      add_custom_command(
        TARGET mergehex
        POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${CMAKE_CURRENT_SOURCE_DIR}
                python ${CMAKE_CURRENT_SOURCE_DIR}/scripts/patch_hex.py
                ${CMAKE_BINARY_DIR}/merged.hex
      )
    endif()
    

  • Hi,

    I tested the provided code, but encountered the following error:

    CMake Error at CMakeLists.txt:119 (add_custom_command):
      No TARGET 'mergehex' has been created in this directory.
    

    To work around this, I manually added the target using:

    add_custom_target(mergehex
    --input ${CMAKE_BINARY_DIR}/../merged.hex
    )

    However, after doing so, the Python script does not get executed.

  • Sorry for that experience.

    Can you please make sure that you have enabled the MCUBoot since this triggers the merged output via imgtool . I tested with this below 

    my testing scripts/patch_hex.py contains (you might have different patch_hex.py)

    import sys
    print(f"Patching {sys.argv[1]} ...")
    with open(sys.argv[1], "a") as f:
        f.write("\n# Patched!\n")
    

    Adding below to the CMakeLists.txt

    # Run patching script after merged.hex is fully generated
    if(CONFIG_BOOTLOADER_MCUBOOT)
      add_custom_command(
        TARGET app
        POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E echo "Running post-build patch on merged.hex..."
        COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/scripts/patch_hex.py
                ${CMAKE_BINARY_DIR}/zephyr/merged.hex
        COMMENT "Post-build: patch_hex.py running after merged.hex is created"
        VERBATIM
      )
    endif()
    


    Make sure you do not have any typos. and make sure that CMAKE_CURRENT_SOURCE_DIR and  ${CMAKE_BINARY_DIR}/zephyr/merged.hex exists or replace them with the right directory.

    west build -b nrf5340dk/nrf5340/cpuapp -p

    should give something like 

    Running post-build patch on merged.hex...
    Patching build/zephyr/merged.hex ...

  • Hi,

    The commad  is still being executed before the merged files are generated.

    [0/24] Performing build step for 'ipc_radio'
    ninja: no work to do.
    [2/7] Linking C static library app\libapp.a
    Running post-build patch on merged.hex...
    [7/7] Linking C executable zephyr\zephyr.elf
    Memory region Used Size Region Size %age Used
    FLASH: 516152 B 916992 B 56.29%
    RAM: 243496 B 450544 B 54.04%
    IDT_LIST: 0 GB 32 KB 0.00%
    Generating files from C:/projects/sw_b/build/sw_b/zephyr/zephyr.elf for board: cpn0003
    image.py: sign the digest
    image.py: sign the digest
    [5/20] Performing build step for 'mcuboot'
    ninja: no work to do.
    [8/20] Performing build step for 'b0n'
    ninja: no work to do.
    [18/18] Generating ../merged.hex
    * Terminal will be reused by tasks, press any key to close it.

  • You can copy path/to/ncs/version/zephyr/share/sysbuild/template/CMakeLists.txt to your project's sysbuild directory and then add your custom command and target there. For example:

    $ cp ~/ncs/v2.8.0/zephyr/share/sysbuild/template/CMakeLists.txt myapp/sysbuild/
    $ nvim myapp/sysbuild/CMakeLists.txt
    $ cat myapp/sysbuild/CMakeLists.txt
    find_package(Sysbuild REQUIRED HINTS $ENV{ZEPHYR_BASE})
    project(sysbuild LANGUAGES)
    add_custom_command(OUTPUT dummy.out COMMAND cmake -E touch dummy.out)
    add_custom_target(did-it-work ALL DEPENDS dummy.out merged_hex)
    $
    [19/21] Generating ../dfu_application.zip
    [20/21] Generating ../merged.hex
    [21/21] Generating dummy.out
  • The "work around" by creating a dummy.out and depending merged_hex on this dummy.out doesn't seem to be necessary.

    The key solution (at least for me) seems that the custom commands, that need to run after merged.hex are created, are now located in sysbuild/CmakeLists.txt instead of in the projects CmakeLists.txt.

    My sysbuild/CmakeList has some more project specific names, but this should do the trick:


    find_package(Sysbuild REQUIRED HINTS $ENV{ZEPHYR_BASE})
    project(sysbuild LANGUAGES)
    
    set(DIR ${CMAKE_CURRENT_SOURCE_DIR}/../)
    set(BUILD_DIR ${DIR}/build)
    
    add_custom_command(OUTPUT ${BUILD_DIR}/changed_merged.hex
        WORKING_DIRECTORY ${DIR}
        DEPENDS merged_hex
        COMMAND python ${DIR}/foo/bar.py ${BUILD_DIR}/merged.hex)

  • Right, it was just a trivial example that shows how to create a target that depends on merged_hex.

Reply Children
No Data
Related