Мultiple builders in sequence

is there a solution how to run multiple builders in sequence
with different settings and linker scripts


Build Stage 1
    some OBJs, ELF -> BIN
Build Stage 2
    some libraries, some tools
Build Main
    main builder script - use data from upper builders
    main_elf = env.BuildProgram() <-- is only one task
    bin = env.ElfToBin( join("$BUILD_DIR", "${PROGNAME}"), main_elf )
    main_bin = env.HeaderToBin( join("$BUILD_DIR", "${PROGNAME}"), bin )
    AlwaysBuild( ... )

This is exactly how PlatformIO works. You declare dependency tree, PlatformIO via SCons resolve all dependencies.

YEP, but… :slight_smile:

SET COMPILER ( for all builderr is the same )

BOOT BUILDER ( Stage:1 )
1.  INCLUDE = some path, DEFINE some ... etc
2.  LINKER SCRIPT = 'boot.ld'
3.  BUILD bootloader.c -> bootloader.elf
4.  ELF2BIN bootloader.bin
5.  SIGN bootloader.bin -> signed_bootloader.bin
6.  CREATE ASM signed_bootloader.bin -> signed_bootloader.S <--- mus be ready before stage-2

MAIN BUILDER ( Stage:2 )
7.  INCLUDE = other path, DEFINE other ... etc
8.  LINKER SCRIPT = 'main.ld'
9.  env.BuildSources( signed_bootloader.S )
10. env.BuildSources( source_codes )
11. BUILD source_codes -> application.elf
12. ELF2BIN application.bin
13. DONE

Will you advise me how to make this sequence 1…13
( note: there are also more complex “combinations” … as Zephyr from scratch )

Ahh, I see. You mean new_env = env.Clone(). If you clone SCons environment - it will be isolated.

:slight_smile: yep … but not work
I’ve been experimenting for a few days
Stage:2 is normal evb
Stage:1 is cloned evb

#### main.py
env = DefaultEnvironment()
env['BOOT'] = env.Clone()
ENV_BOOT = env['BOOT']
boot_elf = ENV_BOOT.BuildProgram() 
# Error: Nothing to build. Please put your source codes...
# if skip this, next work
# ENV_BOOT.BuildSources( .... ,bootloader.c)  is set for cloned evb
main_elf = env.BuildProgram()

even more interesting is that this is how it compiles everything
but cloned only compiles as an object, no ELF, no BIN … etc
main builder work as is

from os.path import join
from SCons.Script import (AlwaysBuild, DefaultEnvironment)

print('MAIN[BEGIN] ####')

env = DefaultEnvironment()
env['BOOT'] = env.Clone()  # used as global variable
ENV_BOOT = env['BOOT']

# boot_elf = ENV_BOOT.BuildProgram() # Error: Nothing to build. Please put your
# boot_bin = ENV_BOOT.ELF2BIN( join("$BUILD_DIR", "${PROGNAME}"), boot_elf )
# boot_prg = ENV_BOOT.Alias( "buildprog", boot_bin, [ ENV_BOOT.VerboseAction("", "BOOT DONE") ] )
# AlwaysBuild( boot_prg )

main_elf = env.BuildProgram()
main_bin = env.ELF2BIN( join("$BUILD_DIR", "${PROGNAME}"), main_elf )
main_prg = env.Alias( "buildprog", main_bin, [ env.VerboseAction("", "DONE") ] )
AlwaysBuild( main_prg )

print('MAIN[END] ####')

cloned_env = env.Clone() work only for compiler settings CPPPATH, LINKFLAGS etc,
but not for nodes

or I don’t know how to work with Clone()

cloned_env.BuildSources() it does not add files to cloned_env.PIOBUILDFILES

cloned_env.BuildProgram() say: Error: Nothing to build. Please put your… if PIOBUILDFILES is empty

if I add file to cloned_env.PIOBUILDFILES
PIO say: Two environments with different… for (main.c)
but cloned_env not have (main.c) … have only (boot.S) <— not exist in PIOBUILDFILES

BuildProgram() always add PROJECT/src/*.c no matter env