To answer my own question, the problem was that the file node created was not set as a dependency of the main target.
Here’s a working example:
extra_script.py
:
Import("env")
c = env.Command('msgs.c', 'msgs.txt', action="cp $SOURCE $TARGET")
env.Depends("$BUILD_DIR/$PROGNAME$PROGSUFFIX", c)