tags:

views:

218

answers:

2

Hi, I'd like to write an SConstruct file that will convert (e.g.) all the JPEG files in a directory into PNGs.

I think I have the Builder alright:

ConvToPNG = Builder(action = 'convert $SOURCE $TARGET',
        suffix = '.png',
        src_suffix = '.jpg')
env['BUILDERS']['ConvToPNG'] = ConvToPNG

But then I'm not sure how to make a list of all the targets that need to be built. I can do it in a Python-y way like this:

pix_conversions = [env.ConvToPNG(jpg_src) for jpg_src in Glob('pix/img_*.jpg')]

And then maybe I'll use an Alias for those:

env.Alias('convert_all', pix_conversions)

Or else make a Node by hand and have it Depends on the conversions.

The thing is, this seems like it's something that Scanners are sorta made for. But I couldn't get that to work well. I tried making a Builder that would work on a directory and call a Scanner that would add a bunch of targets, but it didn't work because the SCons internals expect a Builder to run on a file. (or at least, that's what I gleaned from the error messages).

Is there a more SCons-y way of doing this?

+1  A: 

Scanners are for implicit dependencies.

e.g. you want to build foo which depends on foo.c which does a #include of bar.c. Thus, when you tell SCons to build foo with dependency foo.c, the C scanner will automatically pick up implicit dependency bar.c based on the explicit dependency foo.c.

Ross Rogers
example would be clearer with bar.h :)
BennyG
+1  A: 

Your steps seems fine, but Alias node you need to pass to the AlwaysBuild function:

env.AlwaysBuild(env.Alias('convert_all', pix_conversions))

So the end result would be:

ConvToPNG = Builder(action = 'convert $SOURCE $TARGET',
        suffix = '.png',
        src_suffix = '.jpg')
env['BUILDERS']['ConvToPNG'] = ConvToPNG
pix_conversions = [env.ConvToPNG(jpg_src) for jpg_src in Glob('pix/img_*.jpg')]
env.AlwaysBuild(env.Alias('convert_all', pix_conversions))

It will work fine without any scanners. SCons will check MD5 hash of your JPEG files and if some file changed since last conversion then builder will be launched again.

bialix
Can you explain a little more what the AlwaysBuild function does in this case?Thank you!!
rescdsk
http://www.scons.org/doc/0.97/HTML/scons-user/x1030.html
Ross Rogers
@Ross Rogers - I saw that page, but it's a little bit too abstract for me---does AlwaysBuild force convert_all to be always out of date? Does that just mean that it will always check that the .png's are up to date, or does it mean that it will always rebuild them?Thanks both of you!!
rescdsk
AlwaysBuild used for non filesystem objects to ensure they will be build when needed. Your Alias() has created virtual target, so you need to ensure that every time you'll run `scons convert_all` your conversion builder will be invoked. You may think about AlwaysBuild as rough equivalent of .PHONY in Makefiles.
bialix