<div dir="ltr"><div>This should be pretty close to what you want:</div><div><br></div><div><a href="https://gist.github.com/bdbaddog/698e0c4fe9922eb24da6a66cd760f8a1">https://gist.github.com/bdbaddog/698e0c4fe9922eb24da6a66cd760f8a1</a></div><div><br></div><div>Give it a try and let us know what you think.</div><div>Also it may be easier to get your solution working if you join our discord server.</div><div><a href="https://discord.gg/bXVpWAy">https://discord.gg/bXVpWAy</a></div><div><br></div><div>-Bill</div><div>SCons Project Manager</div></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Sat, Apr 12, 2025 at 12:26 PM Mats Wichmann <<a href="mailto:mats@wichmann.us">mats@wichmann.us</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 4/12/25 12:13, Oliver Koch via Scons-users wrote:<br>
> Dear SCons experts,<br>
> <br>
> Thank your for your last supporting comments!<br>
> <br>
> I have developed a small SConstruct file (attached) that implements to<br>
> tool calls via Command().<br>
> However, I have a few questions regarding generalization as given in the<br>
> comments of the SConstruct file.<br>
> <br>
> The required input file (MyDeps.puml) is also attached.<br>
> <br>
> The output of the two subsequent runs of "scons" are given in Run1.out<br>
> and Run2.out.<br>
> <br>
> So, the build is executed as intended, but the toy example is not really<br>
> scalable to a real world tool chain.<br>
> <br>
> Could you answer my questions resp. give me some hints, how to make this<br>
> a "real" build chain?<br>
> <br>
> Thank you!<br>
> <br>
> Oliver<br>
<br>
A few comments, out of order.<br>
<br>
# This is not executed. Why?<br>
act = env.Action(PlantUML, cmdstr="Building ${TARGET}")<br>
<br>
The Action method produces an action object, but you never do anything <br>
with that action object. You have to tell something that act is its <br>
action before anything happens with it. It's fine to pass it to Command, <br>
that works in the same way as passing it an action string (which will <br>
anyway be converted to an action object). So like:<br>
<br>
tgt = env.Command(target, source, action=act)<br>
<br>
----<br>
<br>
from SCons.Script import *<br>
<br>
you don't need to do that in an SConstruct/SConscript file, the <br>
execution context causes it to be done for you.  Where you need that <br>
import is in files that are run directly and not executed by the <br>
SConscript() function.<br>
<br>
----<br>
<br>
The classic way to scale when there are many files is to write a <br>
builder.  I think we've previously sent you links on that, please check <br>
the earlier messages.  But you don't have to. You could also take this:<br>
<br>
# I am lloking for something like:<br>
# for svg in SVGs:<br>
#   env.Command(svg.basename + '.svgz', svg, SVGZ)<br>
<br>
and actually enable it, there's no real reason it wouldn't work<br>
<br>
from pathlib import Path<br>
<br>
for svg in SVGs:<br>
     tgtpath = str(Path(svg).name) + '.svgz'<br>
     env.Command(tgtpath, svg, action=SVGZ)<br>
<br>
<br>
That's a bit "hacky", you should properly let SCons compute the path and <br>
there are facilities for doing so. If you write a real Builder, part of <br>
the plumbing it the knowlede of how to transform source to target names <br>
for the type of files that builder handles.-<br>
<br>
There's also a function which can let you find files - read up on Glob <br>
in the manual. The nice thing about Glob() is it "finds" files that <br>
haven't been built yet, as it can compute targets based on the <br>
information in the graph. So you can potentially:<br>
<br>
for svg in env.Glob('*.svg'):   # these will be Nodes, unless you add a <br>
strings=True arg<br>
<br>
----<br>
<br>
def PlantUML(target, source, env):<br>
   import os<br>
   for src in source:<br>
     Cmd = 'java.exe' + \<br>
           ' -jar C:\\Progra~1\\PlantUML\\plantuml.jar' + \<br>
           ' -tsvg ' + str(src)<br>
     print('Calling: ', Cmd)<br>
     os.system(Cmd)<br>
   # target should not be an input, but is given from Cmd output.<br>
   # How to make a list of targets from the just created files?<br>
   for tgt in target:<br>
     print('  Creating: ', str(tgt))<br>
<br>
If you do things this way, you bypass the work SCons does for you. If <br>
you build a command string like Cmd, and include substitutable elements <br>
(like $SOURCE), and pass that to Command (instead of going directly out <br>
via os.system() - and fwiw, using subprocess.run() is preferred if you <br>
*MUST*), then bingo: the return from Command is the list of targets it <br>
computed, and you have your answer to<br>
<br>
   # How to make a list of targets from the just created files?<br>
<br>
<br>
<br>
_______________________________________________<br>
Scons-users mailing list<br>
<a href="mailto:Scons-users@scons.org" target="_blank">Scons-users@scons.org</a><br>
<a href="https://pairlist4.pair.net/mailman/listinfo/scons-users" rel="noreferrer" target="_blank">https://pairlist4.pair.net/mailman/listinfo/scons-users</a><br>
</blockquote></div>