Can't get extra_script Scons Commands to run at all, must be doing something fundamentally wrong

TLDR: SCons tasks created inside the Action (the third param to env.AddCustomTarget()) don’t get triggered. Instead, the final task in the chain should be added as a dependency for the custom target (i.e. the second parameter). That way, they will be triggered correctly when needed - and only rebuilt as required by a change in an upstream dependency of the tasks.

I think I’ve cracked it, by cutting back until I could replicate @flytrex-vadim’s post here.

I believe the “issue” is that that SCons tasks created within an Action are created too late, and are never triggered. Instead, they should be created and added as a dependency of a target (either a custom one or a built-in one).

So, for example, when you run the my_target target, the code below:

  1. Creates the releases directory and copies the binary into it
  2. Creates an empty file also in that directory

Importantly, it only runs those two steps if an upstream step changes. And Scons is clever enough to track the state too, so if you run pio run and it creates a binary with a different checksum, then it will know that next time you pio run -t run my_target its tasks are stale and should be rebuilt, even though the binary doesn’t change.

import os

Import("env")

release_dir = os.path.join(env.GetLaunchDir(), "releases")


def build_task_chain(upstream_artefact):
    print(">>> Parsing tasks <<<")

    tag = env['PIOENV']

    release_file = env.Command(
        target=os.path.join(release_dir, tag + "_" + os.path.basename(upstream_artefact)),
        source=upstream_artefact,
        action=[
            Mkdir(release_dir),
            Copy("$TARGET", "$SOURCE"),
            sayHi
        ])

    release_descriptor = env.Command(
        target=os.path.join(release_dir, tag + ".json"),
        source=release_file,
        action=[
            Touch("$TARGET"),
            sayHi
        ])

    return release_descriptor


def sayHi(target, source, env):
    print(">>> Hi!  Finished creating %s from %s <<<" % (target[0], source[0]))


last_task_in_chain = build_task_chain("$BUILD_DIR/${PROGNAME}.bin");

script_action = env.AddCustomTarget(
    "my_target",
    [last_task_in_chain],
    []
)

1 Like