Closed dirkbaechle closed 10 years ago
Thanks for these, I'll review them later today.
Thanks very much, I've merged them. I've raised #16 to turn these tests on for Travis.
I'm a little unsure about the Monad examples. The test is deliberately trying to exercise a type of dependency I don't think SCons has, so I would have expected them to not be expressible. I'll have to learn a bit more about SCons so I can properly figure out what is going. These monad style examples are all engineered from real examples - once you start having generated files those dependencies become a lot more common.
Thanks for the merge. I kind of understand your concerns about the Monad examples, that's why I said they look a little wild. SCons has the concept of Scanners, which is what normally gets used to find "#include"s in C files for example, and then adds implicit dependencies while building stuff. Unfortunately this functionality is linked to file extensions, like use ScannerA for all ".c" files and use ScannerB for all ".idl" files. Since your example files don't carry any extension, I had to be a bit more creative when hooking into the processing of the single build tasks. ;) I'm currently watching the vimeo video of your talk at ICFP 2012, and from what I got so far the basic ideas behind shake and SCons are very similar. We don't build a dependency graph "a priori" either, but make it up on the go. If you need any help getting SCons up and running, or have further questions, feel free to ask please.
I've built projects which used SCons before, so I've got it installed previously, shouldn't be too hard. I wasn't aware of the scanners concept, so I guess that's the additional power. How much cleaner would monad3 look with different extensions? If it makes it clearer, I'd be happy to add monad3-ext - the test is really aimed at clarifying the dependency power, and if SCons has the power nicely, but fitting it into the test framework is obscuring that, it might be useful.
I should also add a digest/hash checking example (#1), which I SCons should do nicely on.
I looked at this some more, and it's not so much about file extensions actually. If one changes the log file check to:
diff --git a/Main.hs b/Main.hs
index 8e2ff95..a3a6d24 100755
--- a/Main.hs
+++ b/Main.hs
@@ -111,8 +111,8 @@ monad3 run = do
writeBinary "source" "output1\noutput2\n"
writeFile "input1" "test"
writeFile "input2" "again"
- run [Target "output", Contents "output" "testagain", Log "run"]
- run [Target "output", NoChange, Log "run", Missing "gen"]
+ run [Target "output", Contents "output" "testagain", Log "run run"]
+ run [Target "output", NoChange, Log "run run", Missing "gen"]
writeBinary "source" "gen\noutput2\n"
run [Target "output", Contents "output" "Generated\nagain"]
run [Target "output", NoChange]
then the "monad3-scons" can be written as
import os
# Builder starts here
import re
import SCons.Script
import SCons.Builder
include_re = re.compile(r'^\s*(\S+)$', re.M)
def infile_scan(node, env, path, arg):
if not os.path.isfile(str(node)):
return []
contents = node.get_contents()
return include_re.findall(contents)
in_scanner = SCons.Script.Scanner(function = infile_scan,
argument = None)
list_builder = SCons.Builder.Builder(
action = 'cat $SOURCE | xargs cat > $TARGET',
source_scanner = in_scanner)
# Builder ends here
env = Environment(ENV = os.environ)
env.AppendENVPath('PATH','.')
env.Append(BUILDERS = {'ListBuild' : list_builder})
env.Command('gen', [], 'sh monad3-gen -- $TARGET')
env.Command('output1', 'input1', 'sh monad3-run $SOURCE -- $TARGET')
env.Command('output2', 'input2', 'sh monad3-run $SOURCE -- $TARGET')
env.ListBuild('output','source')
which is not only simpler, but also more "SCons"ish. Note how the Builder part between "start/end" comments would usually be hidden away into its own Tool module "monad3" ( http://www.scons.org/wiki/ToolsForFools ), such that it can be reused by anyone as follows:
import os
env = Environment(ENV = os.environ, tools=['default','monad3'])
env.AppendENVPath('PATH','.')
env.Command('gen', [], 'sh monad3-gen -- $TARGET')
env.Command('output1', 'input1', 'sh monad3-run $SOURCE -- $TARGET')
env.Command('output2', 'input2', 'sh monad3-run $SOURCE -- $TARGET')
env.ListBuild('output','source')
. Along the same lines, one could even wrap the "monad3-run" call into its own builder, let's call it ReplaceBuild(), and then process an arbitrary number of inputs with:
import os
env = Environment(ENV = os.environ, tools=['default','monad3'])
env.AppendENVPath('PATH','.')
env.Command('gen', [], 'sh monad3-gen -- $TARGET')
env.ReplaceBuild(Glob('input*'))
env.ListBuild('output','source')
which would handle auto-generated "input*" files without any further ado. By the way, there is also an external repo for Haskell support in our http://www.scons.org/wiki/ToolsIndex . Maybe you care to have a quick glance at it...
Hi,
this patch adds SCons examples to the "Shootout". All problems pass with "success" on my side (SCons 2.3.1, Python 2.7.3, Ubuntu LTS 12.04)... There is no script for "pool", it's not really applicable since SCons knows only one "stage"...building at full throttle. ;) Also the "monad" examples look a little wild, but it really needs a lot of trickery to force a completely different dependency handling onto SCons...only to satisfy the given test setup (one wouldn't actually model the build like this).
Best regards,
Dirk