Re: SCons misses a dependency which results in incorrect output.

Tal Dayan <[email protected]> Wed, 16 Jul 2025 10:33:50 -0700
Newsgroups gmane.comp.programming.tools.scons.user
Message-ID <CAM+zu_6d4Q+=sDXrB1rYmDcYm9BO4dTdYUgp3WXJ4Hmhs7VOgg@mail.gmail.com>
--===============5229094423632623214==
Content-Type: multipart/alternative; boundary="000000000000b869ad063a0f4c65"

--000000000000b869ad063a0f4c65
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

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 <kprussing74@gmail.=
com>
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'. However, 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 of the
> source file file1 'good', 'bad', and 'good'.  The expectation is that aft=
er
> the third scons run, file2 should contain the value 'good' but it contain=
s
> 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
>

--000000000000b869ad063a0f4c65
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hi Keith, I updated the example files here=C2=A0<a href=3D=
"https://github.com/FPGAwars/apio/issues/676">https://github.com/FPGAwars/a=
pio/issues/676</a><div><br></div><div>They now include the md5 of the files=
 and a dump of=C2=A0<span style=3D"font-variant-ligatures:no-common-ligatur=
es;color:rgb(0,0,0);font-family:Menlo;font-size:12px">.sconsign.dblite</spa=
n></div>





</div><br><div class=3D"gmail_quote gmail_quote_container"><div dir=3D"ltr"=
 class=3D"gmail_attr">On Wed, Jul 16, 2025 at 10:08=E2=80=AFAM Keith Prussi=
ng &lt;<a href=3D"mailto:[email protected]">[email protected]</a>&g=
t; wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0p=
x 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">I susp=
ect it&#39;s because `file1` has the same hash in the<br>
.sconsign.dblite as the last &quot;good&quot; build (i.e. the first one). T=
hus<br>
you get the line &quot;scons: `file2&#39; is up to date.&quot; on the third=
 run.<br>
However, I am not an expert in the specifics of SCons&#39; hashing<br>
methods.<br>
<br>
On Wed, Jul 16, 2025 at 12:38=E2=80=AFPM Tal Dayan &lt;<a href=3D"mailto:ta=
[email protected]" target=3D"_blank">[email protected]</a>&gt; wrote:<br>
&gt;<br>
&gt; Hi all,<br>
&gt;<br>
&gt; We encountered this problem with the nextpnr tool and created here a s=
mall and independent example that demonstrates it.<br>
&gt;<br>
&gt; In the example below, a shell script &#39;command.sh&#39; reads the so=
urce file &#39;file1&#39; and writes it to the target file &#39;file2&#39;.=
 However, if the<br>
&gt; source file starts with &#39;bad&#39; it exits with an error code, *af=
ter* creating the target file.<br>
&gt;<br>
&gt; The script `run.sh&#39;, runs scons three times with these values of t=
he source file file1 &#39;good&#39;, &#39;bad&#39;, and &#39;good&#39;.=C2=
=A0 The expectation is that after the third scons run, file2 should contain=
 the value &#39;good&#39; but it contains the value &#39;bad&#39;.<br>
&gt;<br>
&gt; Do we miss anything or is it simply a bug?<br>
&gt;<br>
&gt; SConstruct:<br>
&gt;<br>
&gt; ----------------------------------------------<br>
&gt;<br>
&gt; # SCons environment<br>
&gt;<br>
&gt; env =3D Environment()<br>
&gt;<br>
&gt;<br>
&gt; # Copy file1 =E2=86=92 file2 using command.sh<br>
&gt;<br>
&gt; # Inject an error if file1 starts with &#39;bad&quot;<br>
&gt;<br>
&gt; file2 =3D env.Command(<br>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0target=3D&#39;file2&#39;,<br>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0source=3D&#39;file1&#39;,<br>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0action=3D&#39;./command.sh $SOURCE &gt; $TARGET&#39=
;<br>
&gt;<br>
&gt; )<br>
&gt;<br>
&gt;<br>
&gt; # Make &#39;file2&#39; the default target<br>
&gt;<br>
&gt; Default(file2)<br>
&gt;<br>
&gt; ----------------------------------------------<br>
&gt;<br>
&gt;<br>
&gt; command.sh:<br>
&gt;<br>
&gt; ----------------------------------------------<br>
&gt;<br>
&gt; #!/bin/bash<br>
&gt;<br>
&gt; # Usage: ./command input &gt; output<br>
&gt;<br>
&gt;<br>
&gt; # Read from the first argument and copy to stdout<br>
&gt;<br>
&gt; cat &quot;$1&quot;<br>
&gt;<br>
&gt;<br>
&gt; # If the input file starts with &#39;bad&#39;, inject an error AFTER c=
reating the output file.<br>
&gt;<br>
&gt;<br>
&gt; first_line=3D$(head -n 1 &quot;$1&quot;)<br>
&gt;<br>
&gt;<br>
&gt; if [[ &quot;$first_line&quot; =3D=3D bad* ]]; then<br>
&gt;<br>
&gt;=C2=A0 =C2=A0exit 1<br>
&gt;<br>
&gt; fi<br>
&gt;<br>
&gt;<br>
&gt; exit 0<br>
&gt;<br>
&gt; ----------------------------------------------<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt; run.sh<br>
&gt;<br>
&gt; ----------------------------------------------<br>
&gt;<br>
&gt; #!/bin/bash<br>
&gt;<br>
&gt;<br>
&gt; # Clean up.<br>
&gt;<br>
&gt; rm -f .sconsign.dblite<br>
&gt;<br>
&gt; rm -f file[12]<br>
&gt;<br>
&gt;<br>
&gt; echo<br>
&gt;<br>
&gt; echo &quot;---- Iteration 1: file1 =3D &#39;good&#39;&quot;<br>
&gt;<br>
&gt; echo &quot;good&quot; &gt; file1<br>
&gt;<br>
&gt; scons<br>
&gt;<br>
&gt; echo<br>
&gt;<br>
&gt;<br>
&gt; echo &quot;File1&quot;<br>
&gt;<br>
&gt; cat -n file1<br>
&gt;<br>
&gt;<br>
&gt; echo &quot;File2&quot;<br>
&gt;<br>
&gt; cat -n file2<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt; echo<br>
&gt;<br>
&gt; echo &quot;---- Iteration 2: file1 =3D &#39;bad&#39;&quot;<br>
&gt;<br>
&gt; echo &quot;bad&quot; &gt; file1<br>
&gt;<br>
&gt; cat -n file1<br>
&gt;<br>
&gt; scons<br>
&gt;<br>
&gt; echo<br>
&gt;<br>
&gt;<br>
&gt; echo &quot;File1&quot;<br>
&gt;<br>
&gt; cat -n file1<br>
&gt;<br>
&gt;<br>
&gt; echo &quot;File2&quot;<br>
&gt;<br>
&gt; cat -n file2<br>
&gt;<br>
&gt;<br>
&gt; echo<br>
&gt;<br>
&gt; echo &quot;---- Iteration 3: file1 =3D &#39;good&#39;&quot;<br>
&gt;<br>
&gt; echo &quot;good&quot; &gt; file1<br>
&gt;<br>
&gt; cat -n file1<br>
&gt;<br>
&gt; scons<br>
&gt;<br>
&gt; echo<br>
&gt;<br>
&gt;<br>
&gt; echo &quot;File1&quot;<br>
&gt;<br>
&gt; cat -n file1<br>
&gt;<br>
&gt;<br>
&gt; echo &quot;File2&quot;<br>
&gt;<br>
&gt; cat -n file2<br>
&gt;<br>
&gt; ----------------------------------------------<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt; Run log:<br>
&gt;<br>
&gt; ----------------------------------------------<br>
&gt;<br>
&gt; $ ./run.sh<br>
&gt;<br>
&gt;<br>
&gt; ---- Iteration 1: file1 =3D &#39;good&#39;<br>
&gt;<br>
&gt; scons: Reading SConscript files ...<br>
&gt;<br>
&gt; scons: done reading SConscript files.<br>
&gt;<br>
&gt; scons: Building targets ...<br>
&gt;<br>
&gt; ./command.sh file1 &gt; file2<br>
&gt;<br>
&gt; scons: done building targets.<br>
&gt;<br>
&gt;<br>
&gt; File1<br>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0 1 good<br>
&gt;<br>
&gt; File2<br>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0 1 good<br>
&gt;<br>
&gt;<br>
&gt; ---- Iteration 2: file1 =3D &#39;bad&#39;<br>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0 1 bad<br>
&gt;<br>
&gt; scons: Reading SConscript files ...<br>
&gt;<br>
&gt; scons: done reading SConscript files.<br>
&gt;<br>
&gt; scons: Building targets ...<br>
&gt;<br>
&gt; ./command.sh file1 &gt; file2<br>
&gt;<br>
&gt; scons: *** [file2] Error 1<br>
&gt;<br>
&gt; scons: building terminated because of errors.<br>
&gt;<br>
&gt;<br>
&gt; File1<br>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0 1 bad<br>
&gt;<br>
&gt; File2<br>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0 1 bad<br>
&gt;<br>
&gt;<br>
&gt; ---- Iteration 1: file1 =3D &#39;good&#39;<br>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0 1 good<br>
&gt;<br>
&gt; scons: Reading SConscript files ...<br>
&gt;<br>
&gt; scons: done reading SConscript files.<br>
&gt;<br>
&gt; scons: Building targets ...<br>
&gt;<br>
&gt; scons: `file2&#39; is up to date.<br>
&gt;<br>
&gt; scons: done building targets.<br>
&gt;<br>
&gt;<br>
&gt; File1<br>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0 1 good<br>
&gt;<br>
&gt; File2<br>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0 1 bad<br>
&gt;<br>
&gt; ----------------------------------------------<br>
&gt;<br>
&gt; _______________________________________________<br>
&gt; Scons-users mailing list<br>
&gt; <a href=3D"mailto:[email protected]" target=3D"_blank">Scons-users=
@scons.org</a><br>
&gt; <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>

--000000000000b869ad063a0f4c65--

--===============5229094423632623214==
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

--===============5229094423632623214==--