Can't generate hex file using post process

I am new to PlatformIO and TBH have been struggling for several days with this problem.
I have managed to import a project and build it to create a .bin and .elf file, but what I really want is a .hex file.
Reading the support docs has led me to run a post script file but it just bombs out with error 1 and no other explanation.

*** [.pio\build\mks_servo57b\firmware.elf] Error 1

my entry in platformio.ini is : extra_scripts = post:extra_script.py
and extra_script.py contains:

Import("env")
# Custom HEX from ELF
env.AddPostAction(
    "$BUILD_DIR/${PROGNAME}.elf",
    env.VerboseAction(" ".join([
        "$OBJCOPY", "-O", "ihex", "-R", ".eeprom", "-V",
        "$BUILD_DIR/${PROGNAME}.elf", "$BUILD_DIR/${PROGNAME}.hex"
    ]), "Building $BUILD_DIR/${PROGNAME}.hex")
)

I can’t find anything that tells me what the arguments to env.verboseaction() are, or what the arguments to Join() are, so I can’t work out where it’s falling down.

Any pointers appreciated
Thanks

Open a CLI and execute

pio run -e mks_servo57b -v

what are the last few lines of the output?

I get the same output:
*** [.pio\build\mks_servo57b\firmware.elf] Error 1
preceded by the following:

PS C:\Vetronic Services Limited\ShortPath Stepper\MKS-SERVO42B-master\firmware> pio run -e mks_servo57b -v
Processing mks_servo57b (platform: ststm32@~11.0; board: genericSTM32F103CB; framework: stm32cube; upload_protocol: jlink; debug_tool: jlink; build_flags: -fmax-errors=5, -g, -ggdb, -IMKS_SERVO/src/APP, -IMKS_SERVO/src/BSP, -IMKS_SERVO/src/CMSIS, -IMKS_SERVO/src/LIB/inc, -IMKS_SERVO/src/LIB/src, -D STM32F10X_HD, -D USE_STDPERIPH_DRIVER, -D MKS_SERVO57B; extra_scripts: post:extra_script.py)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------CONFIGURATION: https://docs.platformio.org/page/boards/ststm32/genericSTM32F103CB.html
PLATFORM: ST STM32 (11.0.0) > STM32F103CB (20k RAM. 128k Flash)
HARDWARE: STM32F103CBT6 72MHz, 20KB RAM, 128KB Flash
DEBUG: Current (jlink) External (blackmagic, cmsis-dap, jlink, stlink)
PACKAGES:
 - framework-stm32cubef1 1.8.4
 - tool-ldscripts-ststm32 0.1.0
 - toolchain-gccarmnoneeabi 1.70201.0 (7.2.1)
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 28 compatible libraries
Scanning dependencies...
No dependencies
Building in release mode
<SCons.Script.SConscript.SConsEnvironment object at 0x0000021F70EFFE50>
Starting ObjCopy
Finished!
arm-none-eabi-gcc -o .pio\build\mks_servo57b\firmware.elf -T C:\Users\keith.simpson\.platformio\packages\tool-ldscripts-ststm32@0.1.0\stm32f1\STM32F103CBTX_FLASH.ld -Os -Wl,--gc-sections,--relax -mthumb -mcpu=cortex-m3 --specs=nano.specs --specs=nosys.specs .pio\build\mks_servo57b\src\APP\main.o .pio\build\mks_servo57b\src\APP\stm32f10x_it.o .pio\build\mks_servo57b\src\BSP\A1333.o .pio\build\mks_servo57b\src\BSP\A4950.o .pio\build\mks_servo57b\src\BSP\IIC.o .pio\build\mks_servo57b\src\BSP\MKS.o .pio\build\mks_servo57b\src\BSP\board.o .pio\build\mks_servo57b\src\BSP\calibration.o .pio\build\mks_servo57b\src\BSP\delay.o .pio\build\mks_servo57b\src\BSP\display.o .pio\build\mks_servo57b\src\BSP\flash.o .pio\build\mks_servo57b\src\BSP\nonvolatile.o .pio\build\mks_servo57b\src\BSP\oled.o .pio\build\mks_servo57b\src\BSP\sine.o .pio\build\mks_servo57b\src\BSP\spi.o .pio\build\mks_servo57b\src\BSP\stepper_controller.o .pio\build\mks_servo57b\src\BSP\steppin.o .pio\build\mks_servo57b\src\BSP\usart.o .pio\build\mks_servo57b\src\CMSIS\core_cm3.o .pio\build\mks_servo57b\src\CMSIS\system_stm32f10x.o .pio\build\mks_servo57b\src\LIB\src\misc.o .pio\build\mks_servo57b\src\LIB\src\stm32f10x_adc.o .pio\build\mks_servo57b\src\LIB\src\stm32f10x_bkp.o .pio\build\mks_servo57b\src\LIB\src\stm32f10x_can.o .pio\build\mks_servo57b\src\LIB\src\stm32f10x_cec.o .pio\build\mks_servo57b\src\LIB\src\stm32f10x_crc.o .pio\build\mks_servo57b\src\LIB\src\stm32f10x_dac.o .pio\build\mks_servo57b\src\LIB\src\stm32f10x_dbgmcu.o .pio\build\mks_servo57b\src\LIB\src\stm32f10x_dma.o .pio\build\mks_servo57b\src\LIB\src\stm32f10x_exti.o .pio\build\mks_servo57b\src\LIB\src\stm32f10x_flash.o .pio\build\mks_servo57b\src\LIB\src\stm32f10x_fsmc.o .pio\build\mks_servo57b\src\LIB\src\stm32f10x_gpio.o .pio\build\mks_servo57b\src\LIB\src\stm32f10x_i2c.o .pio\build\mks_servo57b\src\LIB\src\stm32f10x_iwdg.o .pio\build\mks_servo57b\src\LIB\src\stm32f10x_pwr.o .pio\build\mks_servo57b\src\LIB\src\stm32f10x_rcc.o .pio\build\mks_servo57b\src\LIB\src\stm32f10x_rtc.o .pio\build\mks_servo57b\src\LIB\src\stm32f10x_sdio.o .pio\build\mks_servo57b\src\LIB\src\stm32f10x_spi.o .pio\build\mks_servo57b\src\LIB\src\stm32f10x_tim.o .pio\build\mks_servo57b\src\LIB\src\stm32f10x_usart.o .pio\build\mks_servo57b\src\LIB\src\stm32f10x_wwdg.o -LC:\Users\keith.simpson\.platformio\platforms\ststm32@11.0.0\ldscripts -L.pio\build\mks_servo57b -LC:\Users\keith.simpson\.platformio\packages\framework-stm32cubef1\Drivers\CMSIS\Lib\GCC -LC:\Users\keith.simpson\.platformio\packages\framework-stm32cubef1\platformio\ldscripts -Wl,--start-group -lc -lgcc -lm -lstdc++ -lnosys .pio\build\mks_servo57b\libFrameworkHALDriver.a .pio\build\mks_servo57b\libFrameworkCMSISDevice.a -Wl,--end-group
arm-none-eabi-objcopy -O ihex -R .eeprom C:\Vetronic Services Limited\ShortPath Stepper\MKS-SERVO42B-master\firmware\.pio\build\mks_servo57b/firmware.elf C:\Vetronic Services Limited\ShortPath Stepper\MKS-SERVO42B-master\firmware\.pio\build\mks_servo57b/firmware.hex
Usage: arm-none-eabi-objcopy [option(s)] in-file [out-file]
 Copies a binary file, possibly transforming it in the process
 The options are:
  -I --input-target <bfdname>      Assume input file is in format <bfdname>
  -O --output-target <bfdname>     Create an output file in format <bfdname>
  -B --binary-architecture <arch>  Set output arch, when input is arch-less
  -F --target <bfdname>            Set both input and output format to <bfdname>
     --debugging                   Convert debugging information, if possible
  -p --preserve-dates              Copy modified/access timestamps to the output
  -D --enable-deterministic-archives
                                   Produce deterministic output when stripping archives
  -U --disable-deterministic-archives
                                   Disable -D behavior (default)
  -j --only-section <name>         Only copy section <name> into the output
     --add-gnu-debuglink=<file>    Add section .gnu_debuglink linking to <file>
  -R --remove-section <name>       Remove section <name> from the output
     --remove-relocations <name>   Remove relocations from section <name>
  -S --strip-all                   Remove all symbol and relocation information
  -g --strip-debug                 Remove all debugging symbols & sections
     --strip-dwo                   Remove all DWO sections
     --strip-unneeded              Remove all symbols not needed by relocations
  -N --strip-symbol <name>         Do not copy symbol <name>
     --strip-unneeded-symbol <name>
                                   Do not copy symbol <name> unless needed by
                                     relocations
     --only-keep-debug             Strip everything but the debug information
     --extract-dwo                 Copy only DWO sections
     --extract-symbol              Remove section contents but keep symbols
  -K --keep-symbol <name>          Do not strip symbol <name>
     --keep-file-symbols           Do not strip file symbol(s)
     --localize-hidden             Turn all ELF hidden symbols into locals
  -L --localize-symbol <name>      Force symbol <name> to be marked as a local
     --globalize-symbol <name>     Force symbol <name> to be marked as a global
  -G --keep-global-symbol <name>   Localize all symbols except <name>
  -W --weaken-symbol <name>        Force symbol <name> to be marked as a weak
     --weaken                      Force all global symbols to be marked as weak
  -w --wildcard                    Permit wildcard in symbol comparison
  -x --discard-all                 Remove all non-global symbols
  -X --discard-locals              Remove any compiler-generated symbols
  -i --interleave[=<number>]       Only copy N out of every <number> bytes
     --interleave-width <number>   Set N for --interleave
  -b --byte <num>                  Select byte <num> in every interleaved block
     --gap-fill <val>              Fill gaps between sections with <val>
     --pad-to <addr>               Pad the last section up to address <addr>
     --set-start <addr>            Set the start address to <addr>
    {--change-start|--adjust-start} <incr>
                                   Add <incr> to the start address
    {--change-addresses|--adjust-vma} <incr>
                                   Add <incr> to LMA, VMA and start addresses
    {--change-section-address|--adjust-section-vma} <name>{=|+|-}<val>
                                   Change LMA and VMA of section <name> by <val>
     --change-section-lma <name>{=|+|-}<val>
                                   Change the LMA of section <name> by <val>
     --change-section-vma <name>{=|+|-}<val>
                                   Change the VMA of section <name> by <val>
    {--[no-]change-warnings|--[no-]adjust-warnings}
                                   Warn if a named section does not exist
     --set-section-flags <name>=<flags>
                                   Set section <name>'s properties to <flags>
     --add-section <name>=<file>   Add section <name> found in <file> to output
     --update-section <name>=<file>
                                   Update contents of section <name> with
                                   contents found in <file>
     --dump-section <name>=<file>  Dump the contents of section <name> into <file>
     --rename-section <old>=<new>[,<flags>] Rename section <old> to <new>
     --long-section-names {enable|disable|keep}
                                   Handle long section names in Coff objects.
     --change-leading-char         Force output format's leading character style
     --remove-leading-char         Remove leading character from global symbols
     --reverse-bytes=<num>         Reverse <num> bytes at a time, in output sections with content
     --redefine-sym <old>=<new>    Redefine symbol name <old> to <new>
     --redefine-syms <file>        --redefine-sym for all symbol pairs
                                     listed in <file>
     --srec-len <number>           Restrict the length of generated Srecords
     --srec-forceS3                Restrict the type of generated Srecords to S3
     --strip-symbols <file>        -N for all symbols listed in <file>
     --strip-unneeded-symbols <file>
                                   --strip-unneeded-symbol for all symbols listed
                                     in <file>
     --keep-symbols <file>         -K for all symbols listed in <file>
     --localize-symbols <file>     -L for all symbols listed in <file>
     --globalize-symbols <file>    --globalize-symbol for all in <file>
     --keep-global-symbols <file>  -G for all symbols listed in <file>
     --weaken-symbols <file>       -W for all symbols listed in <file>
     --add-symbol <name>=[<section>:]<value>[,<flags>]  Add a symbol
     --alt-machine-code <index>    Use the target's <index>'th alternative machine
     --writable-text               Mark the output text as writable
     --readonly-text               Make the output text write protected
     --pure                        Mark the output file as demand paged
     --impure                      Mark the output file as impure
     --prefix-symbols <prefix>     Add <prefix> to start of every symbol name
     --prefix-sections <prefix>    Add <prefix> to start of every section name
     --prefix-alloc-sections <prefix>
                                   Add <prefix> to start of every allocatable
                                     section name
     --file-alignment <num>        Set PE file alignment to <num>
     --heap <reserve>[,<commit>]   Set PE reserve/commit heap to <reserve>/
                                   <commit>
     --image-base <address>        Set PE image base to <address>
     --section-alignment <num>     Set PE section alignment to <num>
     --stack <reserve>[,<commit>]  Set PE reserve/commit stack to <reserve>/
                                   <commit>
     --subsystem <name>[:<version>]
                                   Set PE subsystem to <name> [& <version>]
     --compress-debug-sections[={none|zlib|zlib-gnu|zlib-gabi}]
                                   Compress DWARF debug sections using zlib
     --decompress-debug-sections   Decompress DWARF debug sections using zlib
     --elf-stt-common=[yes|no]     Generate ELF common symbols with STT_COMMON
                                     type
  -M  --merge-notes                Remove redundant entries in note sections
      --no-merge-notes             Do not attempt to remove redundant notes (default)
  -v --verbose                     List all object files modified
  @<file>                          Read options from <file>
  -V --version                     Display this program's version number
  -h --help                        Display this output
     --info                        List object formats & architectures supported
arm-none-eabi-objcopy: supported targets: elf32-littlearm elf32-bigarm elf32-little elf32-big plugin srec symbolsrec verilog tekhex binary ihex
*** [.pio\build\mks_servo57b\firmware.elf] Error 1

Thanks

Due to spaces in the paths with missing quotes the command is not interpreted correctly. You need to quote the filepaths.

Write instead

Import("env")
# Custom HEX from ELF
env.AddPostAction(
    "$BUILD_DIR/${PROGNAME}.elf",
    env.VerboseAction(" ".join([
        "$OBJCOPY", "-O", "ihex", "-R", ".eeprom", 
        '"$BUILD_DIR/${PROGNAME}.elf"', '"$BUILD_DIR/${PROGNAME}.hex"'
    ]), "Building $BUILD_DIR/${PROGNAME}.hex")
)
1 Like

That fixed it!
Thank you for your prompt and helpful response