Re: SCons misses a dependency which results in incorrect output.
Bill Deegan <[email protected]> Wed, 16 Jul 2025 15:16:51 -0700
| Newsgroups | gmane.comp.programming.tools.scons.user |
|---|---|
| Message-ID | <CAEyG4CG06eqQHOzRGGnWcxSBCy1vf1D7wUnaTJ-PnjH=O0F0+Q@mail.gmail.com> |
--===============7997596445843198506== Content-Type: multipart/alternative; boundary="0000000000009af08a063a13405a" --0000000000009af08a063a13405a Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable 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]> wrote: > Hi Bill, I will file an issue. > > I don't think it's safe for SCons to assume that once a program writes an > output file it can't crash. > > On Wed, Jul 16, 2025 at 12:45=E2=80=AFPM Bill Deegan <bill@baddogconsulti= ng.com> > 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-fail= ure-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]> wrote= : >> >>> Looking at the end state of scons after invocation #3, the actual md5 o= f >>> 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]> wrot= e: >>> >>>> 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@g= mail.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]> wr= ote: >>>>> > >>>>> > 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 th= e >>>>> > 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 th= e >>>>> source file file1 'good', 'bad', and 'good'. The expectation is that= after >>>>> the third scons run, file2 should contain the value 'good' but it con= tains >>>>> 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 > --0000000000009af08a063a13405a Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr"><div>It's an enhancement request.</div><div><br></div>= <div>The bug is in your=C2=A0command.sh script.</div><div>I'll change t= he description and text.</div><div><br></div><div><br></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 12:56=E2=80=AFPM Tal Dayan <<a href=3D"ma= ilto:[email protected]">[email protected]</a>> wrote:<br></div><blockquote class= =3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rg= b(204,204,204);padding-left:1ex"><div dir=3D"ltr">Hi Bill, I will file an i= ssue.<div><br></div><div>I don't think it's safe for SCons to assum= e 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:= [email protected]" target=3D"_blank">[email protected]</a>&= gt; wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0= px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div = dir=3D"ltr"><div>Arguably 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 error status if there improper.</div><div><br></div><div>So = a quick fix would be to check the input before copying the file.</div><div>= <br></div><div>From the URL you posted in other email here's the comman= d.sh</div><div><span style=3D"font-family:monospace">#!/bin/bash<br># Usage= : ./command input > output<br><br># Copy source to destination<br>cp &qu= ot;$1" "$2"<br><br># If the input file stats with 'bad&#= 39; inject an error AFTER creating the output file.<br><br>first_line=3D$(h= ead -n 1 "$1")<br><br>if [[ "$first_line" =3D=3D bad* ]= ]; then<br>=C2=A0 exit 1<br>fi<br><br>exit 0</span></div><div><span style= =3D"font-family:monospace"><br></span></div><div><span style=3D"font-family= :monospace">Change it to this:</span></div><div><span style=3D"font-family:= monospace">#!/bin/bash<br># Usage: ./command input > output<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")<br><br>if [[ &= quot;$first_line" =3D=3D bad* ]]; then<br>=C2=A0 exit 1<br>fi<br><br>#= Copy source to destination<br>cp "$1" "$2"<br><br>exit= 0</span><br><br></div><div>Results:</div><div><br></div><div><span style= =3D"font-family:monospace">% ./run.sh<br><br>----- Iteration 1: file1 =3D &= #39;good' -----<br><br>scons: Reading SConscript files ...<br>scons: do= ne reading SConscript files.<br>scons: Building targets ...<br>scons: build= ing `file2' because it doesn't exist<br>./command.sh file1 file2<br= >+-file2<br>=C2=A0 +-file1<br>scons: done building targets.<br><br>File1<br= >MD5 (file1) =3D d7f986677d9f563bd1794b09d82206a3<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: d7f9866= 77d9f563bd1794b09d82206a3 1752694898 5<br>file2: d7f986677d9f563bd1794b09d8= 2206a3 1752694898 5<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 file1: d7f986677d9f563bd= 1794b09d82206a3 1752694898 5<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 2dbc2dce125a753= 309a27b7d5157aaaa [./command.sh $SOURCE $TARGET]<br><br>----- Iteration 2: = file1 =3D 'bad' -----<br><br>scons: Reading SConscript files ...<br= >scons: done reading SConscript files.<br>scons: Building targets ...<br>sc= ons: rebuilding `file2' because `file1' changed<br>./command.sh fil= e1 file2<br>scons: *** [file2] Error 1<br>+-file2<br>=C2=A0 +-file1<br>scon= s: building terminated because of errors.<br><br>File1<br>MD5 (file1) =3D d= f207dc9143c6fabf60b69b9c3035103<br>=C2=A0 =C2=A0 =C2=A01 bad<br><br>File2<b= r>md5: file2: No such file or directory<br>cat: file2: No such file or dire= ctory<br><br>DBlite:<br>=3D=3D=3D .:<br>file1: df207dc9143c6fabf60b69b9c303= 5103 1752694898 4<br>file2: d7f986677d9f563bd1794b09d82206a3 1752694898 5<b= r>=C2=A0 =C2=A0 =C2=A0 =C2=A0 file1: d7f986677d9f563bd1794b09d82206a3 17526= 94898 5<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 2dbc2dce125a753309a27b7d5157aaaa [./= command.sh $SOURCE $TARGET]<br><br>----- Iteration 3: file1 =3D 'good&#= 39; -----<br><br>scons: Reading SConscript files ...<br>scons: done reading= SConscript files.<br>scons: Building targets ...<br>scons: building `file2= ' because it doesn't exist<br>./command.sh file1 file2<br>+-file2<b= r>=C2=A0 +-file1<br>scons: done building targets.<br><br>File1<br>MD5 (file= 1) =3D d7f986677d9f563bd1794b09d82206a3<br>=C2=A0 =C2=A0 =C2=A01 good<br><b= r>File2<br>MD5 (file2) =3D d7f986677d9f563bd1794b09d82206a3<br>=C2=A0 =C2= =A0 =C2=A01 good<br><br>DBlite:<br>=3D=3D=3D .:<br>file1: d7f986677d9f563bd= 1794b09d82206a3 1752694899 5<br>file2: d7f986677d9f563bd1794b09d82206a3 175= 2694899 5<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 file1: d7f986677d9f563bd1794b09d82= 206a3 1752694899 5<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 2dbc2dce125a753309a27b7d5= 157aaaa [./command.sh $SOURCE $TARGET]</span></div><div><br></div><div>Ther= e's not presently logic in SCons to delete target files if the associat= ed action yields an error.</div><div><br></div><div>I think what you want i= s equivalent to makes .DELETE_ON_FAILURE, there's actually a SO questio= n on this:</div><div><a href=3D"https://stackoverflow.com/questions/2954627= 6/scons-delete-target-on-failure-of-any-action" target=3D"_blank">https://s= tackoverflow.com/questions/29546276/scons-delete-target-on-failure-of-any-a= ction</a></div><div><br></div><div>Please go ahead and file an enhancement = request to add equivalent to=C2=A0DELETE_ON_FAILURE, please include your re= producer scripts.</div><div><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 10:44=E2=80=AFAM Tal Dayan <<a href=3D"mailto:[email protected]" target= =3D"_blank">[email protected]</a>> wrote:<br></div><blockquote class=3D"gmai= l_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,20= 4,204);padding-left:1ex"><div dir=3D"ltr">Looking at the end state of scons= after invocation #3, the actual md5 of file2 doesn't match its md5 in = the dblite.<div><br></div><div><a href=3D"https://i.imgur.com/NGco3yQ.png" = target=3D"_blank">https://i.imgur.com/NGco3yQ.png</a></div></div><br><div c= lass=3D"gmail_quote"><div 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]" tar= get=3D"_blank">[email protected]</a>> wrote:<br></div><blockquote class=3D"g= mail_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 Keith, I updated the exampl= e files here=C2=A0<a href=3D"https://github.com/FPGAwars/apio/issues/676" t= arget=3D"_blank">https://github.com/FPGAwars/apio/issues/676</a><div><br></= div><div>They now include the md5 of the files and a dump of=C2=A0<span sty= le=3D"font-variant-ligatures:no-common-ligatures;color:rgb(0,0,0);font-fami= ly: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> --0000000000009af08a063a13405a-- --===============7997596445843198506== 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 --===============7997596445843198506==--