Re: SCons misses a dependency which results in incorrect output.
Bill Deegan <[email protected]> Wed, 16 Jul 2025 21:13:04 -0700
| Newsgroups | gmane.comp.programming.tools.scons.user |
|---|---|
| Message-ID | <CAEyG4CEYUJd3eomr2_m2YbC33=s6pRxabg9smwbjB1AfJioTtw@mail.gmail.com> |
--===============3892122861446999038==
Content-Type: multipart/alternative; boundary="0000000000008d5bca063a183ab8"
--0000000000008d5bca063a183ab8
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
If you patch your SCons sources like this, it should remove any failed
actions targets.
(This is just a quick hack, working on a proper fix with option to control
it)
diff --git a/SCons/Script/Main.py b/SCons/Script/Main.py
index 98f1f345a..f0152a383 100644
--- a/SCons/Script/Main.py
+++ b/SCons/Script/Main.py
@@ -317,6 +317,10 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask):
node =3D [node]
nodename =3D ', '.join(map(str, node))
+ for n in node:
+ print(f"removing {n}")
+ n.remove()
+
errfmt =3D "scons: *** [%s] %s\n"
sys.stderr.write(errfmt % (nodename, buildError))
On Wed, Jul 16, 2025 at 5:15=E2=80=AFPM Tal Dayan <[email protected]> wrote:
> Our system is based on Python plugin classes that provide scons Builders
> so I wonder if we can just define our own subclass of Builder that
> automatically adds the deletion on errors functionality.
>
>
> https://github.com/FPGAwars/apio/blob/008b090e92246414353776ef5df4c0dd3e2=
74fab/apio/scons/plugin_ice40.py#L62C16-L62C23
>
> On Wed, Jul 16, 2025 at 5:02=E2=80=AFPM Bill Deegan <bill@baddogconsultin=
g.com>
> wrote:
>
>> Tai,
>>
>> If you have a program you're running as the action in a command which is
>> erroring out but writing the file, you can work around this issue for th=
e
>> time being by wrapping that program with a script which checks the exit
>> value of your program, and removing the target files if it exits with an
>> error status.
>>
>> That should be sufficient to get you going again.
>>
>> -Bill
>>
>> On Wed, Jul 16, 2025 at 3:18=E2=80=AFPM Bill Deegan <bill@baddogconsulti=
ng.com>
>> wrote:
>>
>>> Did you read my explanation and how to fix it in your environment
>>> assuming command.sh is similar to what's really happening in your build=
?
>>>
>>>
>>> On Wed, Jul 16, 2025 at 3:16=E2=80=AFPM Bill Deegan <bill@baddogconsult=
ing.com>
>>> wrote:
>>>
>>>> It's an enhancement request.
>>>>
>>>> The bug is in your command.sh script.
>>>> I'll change the description and text.
>>>>
>>>>
>>>>
>>>> On Wed, Jul 16, 2025 at 12:56=E2=80=AFPM Tal Dayan <[email protected]> wro=
te:
>>>>
>>>>> Hi Bill, I will file an issue.
>>>>>
>>>>> I don't think it's safe for SCons to assume that once a program write=
s
>>>>> an output file it can't crash.
>>>>>
>>>>> On Wed, Jul 16, 2025 at 12:45=E2=80=AFPM Bill Deegan <
>>>>> [email protected]> wrote:
>>>>>
>>>>>> Arguably your command.sh is incorrectly written.
>>>>>>
>>>>>> It copies the file and then checks it's contents and exits with
>>>>>> error status if there improper.
>>>>>>
>>>>>> So a quick fix would be to check the input before copying the file.
>>>>>>
>>>>>> From the URL you posted in other email here's the command.sh
>>>>>> #!/bin/bash
>>>>>> # Usage: ./command input > output
>>>>>>
>>>>>> # Copy source to destination
>>>>>> cp "$1" "$2"
>>>>>>
>>>>>> # If the input file stats with 'bad' inject an error AFTER creating
>>>>>> the output file.
>>>>>>
>>>>>> first_line=3D$(head -n 1 "$1")
>>>>>>
>>>>>> if [[ "$first_line" =3D=3D bad* ]]; then
>>>>>> exit 1
>>>>>> fi
>>>>>>
>>>>>> exit 0
>>>>>>
>>>>>> Change it to this:
>>>>>> #!/bin/bash
>>>>>> # Usage: ./command input > output
>>>>>>
>>>>>> # If the input file stats with 'bad' inject an error AFTER creating
>>>>>> the output file.
>>>>>>
>>>>>> first_line=3D$(head -n 1 "$1")
>>>>>>
>>>>>> if [[ "$first_line" =3D=3D bad* ]]; then
>>>>>> exit 1
>>>>>> fi
>>>>>>
>>>>>> # Copy source to destination
>>>>>> cp "$1" "$2"
>>>>>>
>>>>>> exit 0
>>>>>>
>>>>>> Results:
>>>>>>
>>>>>> % ./run.sh
>>>>>>
>>>>>> ----- Iteration 1: file1 =3D 'good' -----
>>>>>>
>>>>>> scons: Reading SConscript files ...
>>>>>> scons: done reading SConscript files.
>>>>>> scons: Building targets ...
>>>>>> scons: building `file2' because it doesn't exist
>>>>>> ./command.sh file1 file2
>>>>>> +-file2
>>>>>> +-file1
>>>>>> scons: done building targets.
>>>>>>
>>>>>> File1
>>>>>> MD5 (file1) =3D d7f986677d9f563bd1794b09d82206a3
>>>>>> 1 good
>>>>>>
>>>>>> File2
>>>>>> MD5 (file2) =3D d7f986677d9f563bd1794b09d82206a3
>>>>>> 1 good
>>>>>>
>>>>>> DBlite:
>>>>>> =3D=3D=3D .:
>>>>>> file1: d7f986677d9f563bd1794b09d82206a3 1752694898 5
>>>>>> file2: d7f986677d9f563bd1794b09d82206a3 1752694898 5
>>>>>> file1: d7f986677d9f563bd1794b09d82206a3 1752694898 5
>>>>>> 2dbc2dce125a753309a27b7d5157aaaa [./command.sh $SOURCE
>>>>>> $TARGET]
>>>>>>
>>>>>> ----- Iteration 2: file1 =3D 'bad' -----
>>>>>>
>>>>>> scons: Reading SConscript files ...
>>>>>> scons: done reading SConscript files.
>>>>>> scons: Building targets ...
>>>>>> scons: rebuilding `file2' because `file1' changed
>>>>>> ./command.sh file1 file2
>>>>>> scons: *** [file2] Error 1
>>>>>> +-file2
>>>>>> +-file1
>>>>>> scons: building terminated because of errors.
>>>>>>
>>>>>> File1
>>>>>> MD5 (file1) =3D df207dc9143c6fabf60b69b9c3035103
>>>>>> 1 bad
>>>>>>
>>>>>> File2
>>>>>> md5: file2: No such file or directory
>>>>>> cat: file2: No such file or directory
>>>>>>
>>>>>> DBlite:
>>>>>> =3D=3D=3D .:
>>>>>> file1: df207dc9143c6fabf60b69b9c3035103 1752694898 4
>>>>>> file2: d7f986677d9f563bd1794b09d82206a3 1752694898 5
>>>>>> file1: d7f986677d9f563bd1794b09d82206a3 1752694898 5
>>>>>> 2dbc2dce125a753309a27b7d5157aaaa [./command.sh $SOURCE
>>>>>> $TARGET]
>>>>>>
>>>>>> ----- Iteration 3: file1 =3D 'good' -----
>>>>>>
>>>>>> scons: Reading SConscript files ...
>>>>>> scons: done reading SConscript files.
>>>>>> scons: Building targets ...
>>>>>> scons: building `file2' because it doesn't exist
>>>>>> ./command.sh file1 file2
>>>>>> +-file2
>>>>>> +-file1
>>>>>> scons: done building targets.
>>>>>>
>>>>>> File1
>>>>>> MD5 (file1) =3D d7f986677d9f563bd1794b09d82206a3
>>>>>> 1 good
>>>>>>
>>>>>> File2
>>>>>> MD5 (file2) =3D d7f986677d9f563bd1794b09d82206a3
>>>>>> 1 good
>>>>>>
>>>>>> DBlite:
>>>>>> =3D=3D=3D .:
>>>>>> file1: d7f986677d9f563bd1794b09d82206a3 1752694899 5
>>>>>> file2: d7f986677d9f563bd1794b09d82206a3 1752694899 5
>>>>>> file1: d7f986677d9f563bd1794b09d82206a3 1752694899 5
>>>>>> 2dbc2dce125a753309a27b7d5157aaaa [./command.sh $SOURCE
>>>>>> $TARGET]
>>>>>>
>>>>>> There's not presently logic in SCons to delete target files if the
>>>>>> associated action yields an error.
>>>>>>
>>>>>> I think what you want is equivalent to makes .DELETE_ON_FAILURE,
>>>>>> there's actually a SO question on this:
>>>>>>
>>>>>> https://stackoverflow.com/questions/29546276/scons-delete-target-on-=
failure-of-any-action
>>>>>>
>>>>>> Please go ahead and file an enhancement request to add equivalent
>>>>>> to DELETE_ON_FAILURE, please include your reproducer scripts.
>>>>>>
>>>>>> -Bill
>>>>>>
>>>>>> On Wed, Jul 16, 2025 at 10:44=E2=80=AFAM Tal Dayan <[email protected]> w=
rote:
>>>>>>
>>>>>>> Looking at the end state of scons after invocation #3, the actual
>>>>>>> md5 of file2 doesn't match its md5 in the dblite.
>>>>>>>
>>>>>>> https://i.imgur.com/NGco3yQ.png
>>>>>>>
>>>>>>> On Wed, Jul 16, 2025 at 10:33=E2=80=AFAM Tal Dayan <[email protected]> =
wrote:
>>>>>>>
>>>>>>>> Hi Keith, I updated the example files here
>>>>>>>> https://github.com/FPGAwars/apio/issues/676
>>>>>>>>
>>>>>>>> They now include the md5 of the files and a dump of
>>>>>>>> .sconsign.dblite
>>>>>>>>
>>>>>>>> On Wed, Jul 16, 2025 at 10:08=E2=80=AFAM Keith Prussing <
>>>>>>>> [email protected]> wrote:
>>>>>>>>
>>>>>>>>> I suspect it's because `file1` has the same hash in the
>>>>>>>>> .sconsign.dblite as the last "good" build (i.e. the first one).
>>>>>>>>> Thus
>>>>>>>>> you get the line "scons: `file2' is up to date." on the third run=
.
>>>>>>>>> However, I am not an expert in the specifics of SCons' hashing
>>>>>>>>> methods.
>>>>>>>>>
>>>>>>>>> On Wed, Jul 16, 2025 at 12:38=E2=80=AFPM Tal Dayan <[email protected]=
> wrote:
>>>>>>>>> >
>>>>>>>>> > Hi all,
>>>>>>>>> >
>>>>>>>>> > We encountered this problem with the nextpnr tool and created
>>>>>>>>> here a small and independent example that demonstrates it.
>>>>>>>>> >
>>>>>>>>> > In the example below, a shell script 'command.sh' reads the
>>>>>>>>> source file 'file1' and writes it to the target file 'file2'. How=
ever, if
>>>>>>>>> the
>>>>>>>>> > source file starts with 'bad' it exits with an error code,
>>>>>>>>> *after* creating the target file.
>>>>>>>>> >
>>>>>>>>> > The script `run.sh', runs scons three times with these values o=
f
>>>>>>>>> the source file file1 'good', 'bad', and 'good'. The expectation=
is that
>>>>>>>>> after the third scons run, file2 should contain the value 'good' =
but it
>>>>>>>>> contains the value 'bad'.
>>>>>>>>> >
>>>>>>>>> > Do we miss anything or is it simply a bug?
>>>>>>>>> >
>>>>>>>>> > SConstruct:
>>>>>>>>> >
>>>>>>>>> > ----------------------------------------------
>>>>>>>>> >
>>>>>>>>> > # SCons environment
>>>>>>>>> >
>>>>>>>>> > env =3D Environment()
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> > # Copy file1 =E2=86=92 file2 using command.sh
>>>>>>>>> >
>>>>>>>>> > # Inject an error if file1 starts with 'bad"
>>>>>>>>> >
>>>>>>>>> > file2 =3D env.Command(
>>>>>>>>> >
>>>>>>>>> > target=3D'file2',
>>>>>>>>> >
>>>>>>>>> > source=3D'file1',
>>>>>>>>> >
>>>>>>>>> > action=3D'./command.sh $SOURCE > $TARGET'
>>>>>>>>> >
>>>>>>>>> > )
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> > # Make 'file2' the default target
>>>>>>>>> >
>>>>>>>>> > Default(file2)
>>>>>>>>> >
>>>>>>>>> > ----------------------------------------------
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> > command.sh:
>>>>>>>>> >
>>>>>>>>> > ----------------------------------------------
>>>>>>>>> >
>>>>>>>>> > #!/bin/bash
>>>>>>>>> >
>>>>>>>>> > # Usage: ./command input > output
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> > # Read from the first argument and copy to stdout
>>>>>>>>> >
>>>>>>>>> > cat "$1"
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> > # If the input file starts with 'bad', inject an error AFTER
>>>>>>>>> creating the output file.
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> > first_line=3D$(head -n 1 "$1")
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> > if [[ "$first_line" =3D=3D bad* ]]; then
>>>>>>>>> >
>>>>>>>>> > exit 1
>>>>>>>>> >
>>>>>>>>> > fi
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> > exit 0
>>>>>>>>> >
>>>>>>>>> > ----------------------------------------------
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> > run.sh
>>>>>>>>> >
>>>>>>>>> > ----------------------------------------------
>>>>>>>>> >
>>>>>>>>> > #!/bin/bash
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> > # Clean up.
>>>>>>>>> >
>>>>>>>>> > rm -f .sconsign.dblite
>>>>>>>>> >
>>>>>>>>> > rm -f file[12]
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> > echo
>>>>>>>>> >
>>>>>>>>> > echo "---- Iteration 1: file1 =3D 'good'"
>>>>>>>>> >
>>>>>>>>> > echo "good" > file1
>>>>>>>>> >
>>>>>>>>> > scons
>>>>>>>>> >
>>>>>>>>> > echo
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> > echo "File1"
>>>>>>>>> >
>>>>>>>>> > cat -n file1
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> > echo "File2"
>>>>>>>>> >
>>>>>>>>> > cat -n file2
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> > echo
>>>>>>>>> >
>>>>>>>>> > echo "---- Iteration 2: file1 =3D 'bad'"
>>>>>>>>> >
>>>>>>>>> > echo "bad" > file1
>>>>>>>>> >
>>>>>>>>> > cat -n file1
>>>>>>>>> >
>>>>>>>>> > scons
>>>>>>>>> >
>>>>>>>>> > echo
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> > echo "File1"
>>>>>>>>> >
>>>>>>>>> > cat -n file1
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> > echo "File2"
>>>>>>>>> >
>>>>>>>>> > cat -n file2
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> > echo
>>>>>>>>> >
>>>>>>>>> > echo "---- Iteration 3: file1 =3D 'good'"
>>>>>>>>> >
>>>>>>>>> > echo "good" > file1
>>>>>>>>> >
>>>>>>>>> > cat -n file1
>>>>>>>>> >
>>>>>>>>> > scons
>>>>>>>>> >
>>>>>>>>> > echo
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> > echo "File1"
>>>>>>>>> >
>>>>>>>>> > cat -n file1
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> > echo "File2"
>>>>>>>>> >
>>>>>>>>> > cat -n file2
>>>>>>>>> >
>>>>>>>>> > ----------------------------------------------
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> > Run log:
>>>>>>>>> >
>>>>>>>>> > ----------------------------------------------
>>>>>>>>> >
>>>>>>>>> > $ ./run.sh
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> > ---- Iteration 1: file1 =3D 'good'
>>>>>>>>> >
>>>>>>>>> > scons: Reading SConscript files ...
>>>>>>>>> >
>>>>>>>>> > scons: done reading SConscript files.
>>>>>>>>> >
>>>>>>>>> > scons: Building targets ...
>>>>>>>>> >
>>>>>>>>> > ./command.sh file1 > file2
>>>>>>>>> >
>>>>>>>>> > scons: done building targets.
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> > File1
>>>>>>>>> >
>>>>>>>>> > 1 good
>>>>>>>>> >
>>>>>>>>> > File2
>>>>>>>>> >
>>>>>>>>> > 1 good
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> > ---- Iteration 2: file1 =3D 'bad'
>>>>>>>>> >
>>>>>>>>> > 1 bad
>>>>>>>>> >
>>>>>>>>> > scons: Reading SConscript files ...
>>>>>>>>> >
>>>>>>>>> > scons: done reading SConscript files.
>>>>>>>>> >
>>>>>>>>> > scons: Building targets ...
>>>>>>>>> >
>>>>>>>>> > ./command.sh file1 > file2
>>>>>>>>> >
>>>>>>>>> > scons: *** [file2] Error 1
>>>>>>>>> >
>>>>>>>>> > scons: building terminated because of errors.
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> > File1
>>>>>>>>> >
>>>>>>>>> > 1 bad
>>>>>>>>> >
>>>>>>>>> > File2
>>>>>>>>> >
>>>>>>>>> > 1 bad
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> > ---- Iteration 1: file1 =3D 'good'
>>>>>>>>> >
>>>>>>>>> > 1 good
>>>>>>>>> >
>>>>>>>>> > scons: Reading SConscript files ...
>>>>>>>>> >
>>>>>>>>> > scons: done reading SConscript files.
>>>>>>>>> >
>>>>>>>>> > scons: Building targets ...
>>>>>>>>> >
>>>>>>>>> > scons: `file2' is up to date.
>>>>>>>>> >
>>>>>>>>> > scons: done building targets.
>>>>>>>>> >
>>>>>>>>> >
>>>>>>>>> > File1
>>>>>>>>> >
>>>>>>>>> > 1 good
>>>>>>>>> >
>>>>>>>>> > File2
>>>>>>>>> >
>>>>>>>>> > 1 bad
>>>>>>>>> >
>>>>>>>>> > ----------------------------------------------
>>>>>>>>> >
>>>>>>>>> > _______________________________________________
>>>>>>>>> > Scons-users mailing list
>>>>>>>>> > [email protected]
>>>>>>>>> > https://pairlist4.pair.net/mailman/listinfo/scons-users
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> Keith Prussing
>>>>>>>>> _______________________________________________
>>>>>>>>> Scons-users mailing list
>>>>>>>>> [email protected]
>>>>>>>>> https://pairlist4.pair.net/mailman/listinfo/scons-users
>>>>>>>>>
>>>>>>>> _______________________________________________
>>>>>>> Scons-users mailing list
>>>>>>> [email protected]
>>>>>>> https://pairlist4.pair.net/mailman/listinfo/scons-users
>>>>>>>
>>>>>> _______________________________________________
>>>>>> Scons-users mailing list
>>>>>> [email protected]
>>>>>> https://pairlist4.pair.net/mailman/listinfo/scons-users
>>>>>>
>>>>> _______________________________________________
>>>>> Scons-users mailing list
>>>>> [email protected]
>>>>> https://pairlist4.pair.net/mailman/listinfo/scons-users
>>>>>
>>>> _______________________________________________
>> Scons-users mailing list
>> [email protected]
>> https://pairlist4.pair.net/mailman/listinfo/scons-users
>>
> _______________________________________________
> Scons-users mailing list
> [email protected]
> https://pairlist4.pair.net/mailman/listinfo/scons-users
>
--0000000000008d5bca063a183ab8
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>If you patch your SCons sources like this, it should =
remove any failed actions targets.</div><div>(This is just a quick hack, wo=
rking on a proper fix with option to control it)</div><div><br></div><div>d=
iff --git a/SCons/Script/Main.py b/SCons/Script/Main.py<br>index 98f1f345a.=
.f0152a383 100644<br>--- a/SCons/Script/Main.py<br>+++ b/SCons/Script/Main.=
py<br>@@ -317,6 +317,10 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask):=
<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0node =3D [node]<br>=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0nodename =3D ', '.join(map(str, node=
))<br><br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0for n in node:<br>+ =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0print(f"removing {n}")<br>+ =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0n.remove()<br>+<br>=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0errfmt =3D "scons: *** [%s] %s\n"<br>=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0sys.stderr.write(errfmt % (nodename, buildError))</div><di=
v><br></div><div><br></div><div><br></div></div><br><div class=3D"gmail_quo=
te gmail_quote_container"><div dir=3D"ltr" class=3D"gmail_attr">On Wed, Jul=
16, 2025 at 5:15=E2=80=AFPM Tal Dayan <<a href=3D"mailto:[email protected]"=
>[email protected]</a>> wrote:<br></div><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padd=
ing-left:1ex"><div dir=3D"ltr">Our system is based on Python plugin classes=
that provide scons Builders so I wonder if we can just define our own subc=
lass of Builder that automatically adds=C2=A0the=C2=A0deletion on errors fu=
nctionality.<div><br></div><div><a href=3D"https://github.com/FPGAwars/apio=
/blob/008b090e92246414353776ef5df4c0dd3e274fab/apio/scons/plugin_ice40.py#L=
62C16-L62C23" target=3D"_blank">https://github.com/FPGAwars/apio/blob/008b0=
90e92246414353776ef5df4c0dd3e274fab/apio/scons/plugin_ice40.py#L62C16-L62C2=
3</a></div></div><br><div class=3D"gmail_quote"><div dir=3D"ltr" class=3D"g=
mail_attr">On Wed, Jul 16, 2025 at 5:02=E2=80=AFPM Bill Deegan <<a href=
=3D"mailto:[email protected]" target=3D"_blank">bill@baddogconsulti=
ng.com</a>> wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"m=
argin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left=
:1ex"><div dir=3D"ltr"><div>Tai,</div><div><br></div><div>If you have a pro=
gram you're running as the action in a command which is erroring out bu=
t writing the file, you can work around this issue for the time being by wr=
apping that program with a script which checks the exit value of your progr=
am, and removing the target files if it exits with an error status.</div><d=
iv><br></div><div>That should be sufficient to get you going again.</div><d=
iv><br></div><div>-Bill</div></div><br><div class=3D"gmail_quote"><div dir=
=3D"ltr" class=3D"gmail_attr">On Wed, Jul 16, 2025 at 3:18=E2=80=AFPM Bill =
Deegan <<a href=3D"mailto:[email protected]" target=3D"_blank">b=
[email protected]</a>> wrote:<br></div><blockquote class=3D"gmail=
_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204=
,204);padding-left:1ex"><div dir=3D"ltr"><div>Did you read my explanation a=
nd how to fix it in your environment assuming command.sh is similar to what=
's really happening in your build?</div><div><br></div></div><br><div c=
lass=3D"gmail_quote"><div dir=3D"ltr" class=3D"gmail_attr">On Wed, Jul 16, =
2025 at 3:16=E2=80=AFPM Bill Deegan <<a href=3D"mailto:bill@baddogconsul=
ting.com" target=3D"_blank">[email protected]</a>> wrote:<br></d=
iv><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bord=
er-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>=
It's an enhancement request.</div><div><br></div><div>The bug is in you=
r=C2=A0command.sh script.</div><div>I'll change the description and tex=
t.</div><div><br></div><div><br></div></div><br><div class=3D"gmail_quote">=
<div dir=3D"ltr" class=3D"gmail_attr">On Wed, Jul 16, 2025 at 12:56=E2=80=
=AFPM Tal Dayan <<a href=3D"mailto:[email protected]" target=3D"_blank">tal@=
zapta.com</a>> wrote:<br></div><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding=
-left:1ex"><div dir=3D"ltr">Hi Bill, I will file an issue.<div><br></div><d=
iv>I don't think it's safe for SCons to assume that once a program =
writes an output file it can't crash.=C2=A0</div></div><br><div class=
=3D"gmail_quote"><div dir=3D"ltr" class=3D"gmail_attr">On Wed, Jul 16, 2025=
at 12:45=E2=80=AFPM Bill Deegan <<a href=3D"mailto:bill@baddogconsultin=
g.com" target=3D"_blank">[email protected]</a>> wrote:<br></div>=
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>Arg=
uably your command.sh is incorrectly written.</div><div><br></div><div>=C2=
=A0It copies the file and then checks it's contents and exits with erro=
r status if there improper.</div><div><br></div><div>So a quick fix would b=
e to check the input before copying the file.</div><div><br></div><div>From=
the URL you posted in other email here's the command.sh</div><div><spa=
n style=3D"font-family:monospace">#!/bin/bash<br># Usage: ./command input &=
gt; output<br><br># Copy source to destination<br>cp "$1" "$=
2"<br><br># If the input file stats with 'bad' inject an error=
AFTER creating the output file.<br><br>first_line=3D$(head -n 1 "$1&q=
uot;)<br><br>if [[ "$first_line" =3D=3D bad* ]]; then<br>=C2=A0 e=
xit 1<br>fi<br><br>exit 0</span></div><div><span style=3D"font-family:monos=
pace"><br></span></div><div><span style=3D"font-family:monospace">Change it=
to this:</span></div><div><span style=3D"font-family:monospace">#!/bin/bas=
h<br># Usage: ./command input > output<br><br># If the input file stats =
with 'bad' inject an error AFTER creating the output file.<br><br>f=
irst_line=3D$(head -n 1 "$1")<br><br>if [[ "$first_line"=
; =3D=3D bad* ]]; then<br>=C2=A0 exit 1<br>fi<br><br># Copy source to desti=
nation<br>cp "$1" "$2"<br><br>exit 0</span><br><br></di=
v><div>Results:</div><div><br></div><div><span style=3D"font-family:monospa=
ce">% ./run.sh<br><br>----- Iteration 1: file1 =3D 'good' -----<br>=
<br>scons: Reading SConscript files ...<br>scons: done reading SConscript f=
iles.<br>scons: Building targets ...<br>scons: building `file2' because=
it doesn't exist<br>./command.sh file1 file2<br>+-file2<br>=C2=A0 +-fi=
le1<br>scons: done building targets.<br><br>File1<br>MD5 (file1) =3D d7f986=
677d9f563bd1794b09d82206a3<br>=C2=A0 =C2=A0 =C2=A01 good<br><br>File2<br>MD=
5 (file2) =3D d7f986677d9f563bd1794b09d82206a3<br>=C2=A0 =C2=A0 =C2=A01 goo=
d<br><br>DBlite:<br>=3D=3D=3D .:<br>file1: d7f986677d9f563bd1794b09d82206a3=
1752694898 5<br>file2: d7f986677d9f563bd1794b09d82206a3 1752694898 5<br>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 file1: d7f986677d9f563bd1794b09d82206a3 1752694=
898 5<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 2dbc2dce125a753309a27b7d5157aaaa [./co=
mmand.sh $SOURCE $TARGET]<br><br>----- Iteration 2: file1 =3D 'bad'=
-----<br><br>scons: Reading SConscript files ...<br>scons: done reading SC=
onscript files.<br>scons: Building targets ...<br>scons: rebuilding `file2&=
#39; because `file1' changed<br>./command.sh file1 file2<br>scons: *** =
[file2] Error 1<br>+-file2<br>=C2=A0 +-file1<br>scons: building terminated =
because of errors.<br><br>File1<br>MD5 (file1) =3D df207dc9143c6fabf60b69b9=
c3035103<br>=C2=A0 =C2=A0 =C2=A01 bad<br><br>File2<br>md5: file2: No such f=
ile or directory<br>cat: file2: No such file or directory<br><br>DBlite:<br=
>=3D=3D=3D .:<br>file1: df207dc9143c6fabf60b69b9c3035103 1752694898 4<br>fi=
le2: d7f986677d9f563bd1794b09d82206a3 1752694898 5<br>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 file1: d7f986677d9f563bd1794b09d82206a3 1752694898 5<br>=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 2dbc2dce125a753309a27b7d5157aaaa [./command.sh $SOURCE $T=
ARGET]<br><br>----- Iteration 3: file1 =3D 'good' -----<br><br>scon=
s: Reading SConscript files ...<br>scons: done reading SConscript files.<br=
>scons: Building targets ...<br>scons: building `file2' because it does=
n't exist<br>./command.sh file1 file2<br>+-file2<br>=C2=A0 +-file1<br>s=
cons: done building targets.<br><br>File1<br>MD5 (file1) =3D d7f986677d9f56=
3bd1794b09d82206a3<br>=C2=A0 =C2=A0 =C2=A01 good<br><br>File2<br>MD5 (file2=
) =3D d7f986677d9f563bd1794b09d82206a3<br>=C2=A0 =C2=A0 =C2=A01 good<br><br=
>DBlite:<br>=3D=3D=3D .:<br>file1: d7f986677d9f563bd1794b09d82206a3 1752694=
899 5<br>file2: d7f986677d9f563bd1794b09d82206a3 1752694899 5<br>=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 file1: d7f986677d9f563bd1794b09d82206a3 1752694899 5<br>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 2dbc2dce125a753309a27b7d5157aaaa [./command.sh =
$SOURCE $TARGET]</span></div><div><br></div><div>There's not presently =
logic in SCons to delete target files if the associated action yields an er=
ror.</div><div><br></div><div>I think what you want is equivalent to makes =
.DELETE_ON_FAILURE, there's actually a SO question on this:</div><div><=
a href=3D"https://stackoverflow.com/questions/29546276/scons-delete-target-=
on-failure-of-any-action" target=3D"_blank">https://stackoverflow.com/quest=
ions/29546276/scons-delete-target-on-failure-of-any-action</a></div><div><b=
r></div><div>Please go ahead and file an enhancement request to add equival=
ent to=C2=A0DELETE_ON_FAILURE, please include your reproducer scripts.</div=
><div><br></div><div>-Bill</div></div><br><div class=3D"gmail_quote"><div d=
ir=3D"ltr" class=3D"gmail_attr">On Wed, Jul 16, 2025 at 10:44=E2=80=AFAM Ta=
l Dayan <<a href=3D"mailto:[email protected]" target=3D"_blank">[email protected]=
m</a>> wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin=
:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"=
><div dir=3D"ltr">Looking at the end state of scons after invocation #3, th=
e actual md5 of file2 doesn't match its md5 in the dblite.<div><br></di=
v><div><a href=3D"https://i.imgur.com/NGco3yQ.png" target=3D"_blank">https:=
//i.imgur.com/NGco3yQ.png</a></div></div><br><div class=3D"gmail_quote"><di=
v dir=3D"ltr" class=3D"gmail_attr">On Wed, Jul 16, 2025 at 10:33=E2=80=AFAM=
Tal Dayan <<a href=3D"mailto:[email protected]" target=3D"_blank">tal@zapta=
.com</a>> wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1=
ex"><div dir=3D"ltr">Hi Keith, I updated the example files here=C2=A0<a hre=
f=3D"https://github.com/FPGAwars/apio/issues/676" target=3D"_blank">https:/=
/github.com/FPGAwars/apio/issues/676</a><div><br></div><div>They now includ=
e the md5 of the files and a dump of=C2=A0<span style=3D"font-variant-ligat=
ures:no-common-ligatures;color:rgb(0,0,0);font-family:Menlo;font-size:12px"=
>.sconsign.dblite</span></div>
</div><br><div class=3D"gmail_quote"><div dir=3D"ltr" class=3D"gmail_attr">=
On Wed, Jul 16, 2025 at 10:08=E2=80=AFAM Keith Prussing <<a href=3D"mail=
to:[email protected]" target=3D"_blank">[email protected]</a>> w=
rote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0p=
x 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">I suspect =
it's because `file1` has the same hash in the<br>
.sconsign.dblite as the last "good" build (i.e. the first one). T=
hus<br>
you get the line "scons: `file2' is up to date." on the third=
run.<br>
However, I am not an expert in the specifics of SCons' hashing<br>
methods.<br>
<br>
On Wed, Jul 16, 2025 at 12:38=E2=80=AFPM Tal Dayan <<a href=3D"mailto:ta=
[email protected]" target=3D"_blank">[email protected]</a>> wrote:<br>
><br>
> Hi all,<br>
><br>
> We encountered this problem with the nextpnr tool and created here a s=
mall and independent example that demonstrates it.<br>
><br>
> In the example below, a shell script 'command.sh' reads the so=
urce file 'file1' and writes it to the target file 'file2'.=
However, if the<br>
> source file starts with 'bad' it exits with an error code, *af=
ter* creating the target file.<br>
><br>
> The script `run.sh', runs scons three times with these values of t=
he source file file1 'good', 'bad', and 'good'.=C2=
=A0 The expectation is that after the third scons run, file2 should contain=
the value 'good' but it contains the value 'bad'.<br>
><br>
> Do we miss anything or is it simply a bug?<br>
><br>
> SConstruct:<br>
><br>
> ----------------------------------------------<br>
><br>
> # SCons environment<br>
><br>
> env =3D Environment()<br>
><br>
><br>
> # Copy file1 =E2=86=92 file2 using command.sh<br>
><br>
> # Inject an error if file1 starts with 'bad"<br>
><br>
> file2 =3D env.Command(<br>
><br>
>=C2=A0 =C2=A0 =C2=A0target=3D'file2',<br>
><br>
>=C2=A0 =C2=A0 =C2=A0source=3D'file1',<br>
><br>
>=C2=A0 =C2=A0 =C2=A0action=3D'./command.sh $SOURCE > $TARGET'=
;<br>
><br>
> )<br>
><br>
><br>
> # Make 'file2' the default target<br>
><br>
> Default(file2)<br>
><br>
> ----------------------------------------------<br>
><br>
><br>
> command.sh:<br>
><br>
> ----------------------------------------------<br>
><br>
> #!/bin/bash<br>
><br>
> # Usage: ./command input > output<br>
><br>
><br>
> # Read from the first argument and copy to stdout<br>
><br>
> cat "$1"<br>
><br>
><br>
> # If the input file starts with 'bad', inject an error AFTER c=
reating the output file.<br>
><br>
><br>
> first_line=3D$(head -n 1 "$1")<br>
><br>
><br>
> if [[ "$first_line" =3D=3D bad* ]]; then<br>
><br>
>=C2=A0 =C2=A0exit 1<br>
><br>
> fi<br>
><br>
><br>
> exit 0<br>
><br>
> ----------------------------------------------<br>
><br>
><br>
><br>
> run.sh<br>
><br>
> ----------------------------------------------<br>
><br>
> #!/bin/bash<br>
><br>
><br>
> # Clean up.<br>
><br>
> rm -f .sconsign.dblite<br>
><br>
> rm -f file[12]<br>
><br>
><br>
> echo<br>
><br>
> echo "---- Iteration 1: file1 =3D 'good'"<br>
><br>
> echo "good" > file1<br>
><br>
> scons<br>
><br>
> echo<br>
><br>
><br>
> echo "File1"<br>
><br>
> cat -n file1<br>
><br>
><br>
> echo "File2"<br>
><br>
> cat -n file2<br>
><br>
><br>
><br>
> echo<br>
><br>
> echo "---- Iteration 2: file1 =3D 'bad'"<br>
><br>
> echo "bad" > file1<br>
><br>
> cat -n file1<br>
><br>
> scons<br>
><br>
> echo<br>
><br>
><br>
> echo "File1"<br>
><br>
> cat -n file1<br>
><br>
><br>
> echo "File2"<br>
><br>
> cat -n file2<br>
><br>
><br>
> echo<br>
><br>
> echo "---- Iteration 3: file1 =3D 'good'"<br>
><br>
> echo "good" > file1<br>
><br>
> cat -n file1<br>
><br>
> scons<br>
><br>
> echo<br>
><br>
><br>
> echo "File1"<br>
><br>
> cat -n file1<br>
><br>
><br>
> echo "File2"<br>
><br>
> cat -n file2<br>
><br>
> ----------------------------------------------<br>
><br>
><br>
><br>
> Run log:<br>
><br>
> ----------------------------------------------<br>
><br>
> $ ./run.sh<br>
><br>
><br>
> ---- Iteration 1: file1 =3D 'good'<br>
><br>
> scons: Reading SConscript files ...<br>
><br>
> scons: done reading SConscript files.<br>
><br>
> scons: Building targets ...<br>
><br>
> ./command.sh file1 > file2<br>
><br>
> scons: done building targets.<br>
><br>
><br>
> File1<br>
><br>
>=C2=A0 =C2=A0 =C2=A0 1 good<br>
><br>
> File2<br>
><br>
>=C2=A0 =C2=A0 =C2=A0 1 good<br>
><br>
><br>
> ---- Iteration 2: file1 =3D 'bad'<br>
><br>
>=C2=A0 =C2=A0 =C2=A0 1 bad<br>
><br>
> scons: Reading SConscript files ...<br>
><br>
> scons: done reading SConscript files.<br>
><br>
> scons: Building targets ...<br>
><br>
> ./command.sh file1 > file2<br>
><br>
> scons: *** [file2] Error 1<br>
><br>
> scons: building terminated because of errors.<br>
><br>
><br>
> File1<br>
><br>
>=C2=A0 =C2=A0 =C2=A0 1 bad<br>
><br>
> File2<br>
><br>
>=C2=A0 =C2=A0 =C2=A0 1 bad<br>
><br>
><br>
> ---- Iteration 1: file1 =3D 'good'<br>
><br>
>=C2=A0 =C2=A0 =C2=A0 1 good<br>
><br>
> scons: Reading SConscript files ...<br>
><br>
> scons: done reading SConscript files.<br>
><br>
> scons: Building targets ...<br>
><br>
> scons: `file2' is up to date.<br>
><br>
> scons: done building targets.<br>
><br>
><br>
> File1<br>
><br>
>=C2=A0 =C2=A0 =C2=A0 1 good<br>
><br>
> File2<br>
><br>
>=C2=A0 =C2=A0 =C2=A0 1 bad<br>
><br>
> ----------------------------------------------<br>
><br>
> _______________________________________________<br>
> Scons-users mailing list<br>
> <a href=3D"mailto:[email protected]" target=3D"_blank">Scons-users=
@scons.org</a><br>
> <a href=3D"https://pairlist4.pair.net/mailman/listinfo/scons-users" re=
l=3D"noreferrer" target=3D"_blank">https://pairlist4.pair.net/mailman/listi=
nfo/scons-users</a><br>
<br>
<br>
<br>
-- <br>
Keith Prussing<br>
_______________________________________________<br>
Scons-users mailing list<br>
<a href=3D"mailto:[email protected]" target=3D"_blank">Scons-users@scon=
s.org</a><br>
<a href=3D"https://pairlist4.pair.net/mailman/listinfo/scons-users" rel=3D"=
noreferrer" target=3D"_blank">https://pairlist4.pair.net/mailman/listinfo/s=
cons-users</a><br>
</blockquote></div>
</blockquote></div>
_______________________________________________<br>
Scons-users mailing list<br>
<a href=3D"mailto:[email protected]" target=3D"_blank">Scons-users@scon=
s.org</a><br>
<a href=3D"https://pairlist4.pair.net/mailman/listinfo/scons-users" rel=3D"=
noreferrer" target=3D"_blank">https://pairlist4.pair.net/mailman/listinfo/s=
cons-users</a><br>
</blockquote></div>
_______________________________________________<br>
Scons-users mailing list<br>
<a href=3D"mailto:[email protected]" target=3D"_blank">Scons-users@scon=
s.org</a><br>
<a href=3D"https://pairlist4.pair.net/mailman/listinfo/scons-users" rel=3D"=
noreferrer" target=3D"_blank">https://pairlist4.pair.net/mailman/listinfo/s=
cons-users</a><br>
</blockquote></div>
_______________________________________________<br>
Scons-users mailing list<br>
<a href=3D"mailto:[email protected]" target=3D"_blank">Scons-users@scon=
s.org</a><br>
<a href=3D"https://pairlist4.pair.net/mailman/listinfo/scons-users" rel=3D"=
noreferrer" target=3D"_blank">https://pairlist4.pair.net/mailman/listinfo/s=
cons-users</a><br>
</blockquote></div>
</blockquote></div>
</blockquote></div>
_______________________________________________<br>
Scons-users mailing list<br>
<a href=3D"mailto:[email protected]" target=3D"_blank">Scons-users@scon=
s.org</a><br>
<a href=3D"https://pairlist4.pair.net/mailman/listinfo/scons-users" rel=3D"=
noreferrer" target=3D"_blank">https://pairlist4.pair.net/mailman/listinfo/s=
cons-users</a><br>
</blockquote></div>
_______________________________________________<br>
Scons-users mailing list<br>
<a href=3D"mailto:[email protected]" target=3D"_blank">Scons-users@scon=
s.org</a><br>
<a href=3D"https://pairlist4.pair.net/mailman/listinfo/scons-users" rel=3D"=
noreferrer" target=3D"_blank">https://pairlist4.pair.net/mailman/listinfo/s=
cons-users</a><br>
</blockquote></div>
--0000000000008d5bca063a183ab8--
--===============3892122861446999038==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
_______________________________________________
Scons-users mailing list
[email protected]
https://pairlist4.pair.net/mailman/listinfo/scons-users
--===============3892122861446999038==--