问题
I got sick of looking up the magic symbols in make and decided to try waf.
I'm trying to use calibre to make ebooks and I'd like to create a wscript that takes in a file, runs a program with some arguments that include that file, and produces an output. Waf should only build if the input file is newer than the output.
In make, I'd write a makefile like this:
%.epub: %.recipe
ebook-convert $ .epub --test -vv --debug-pipeline debug
Where % is a magic symbol for the basename of the file and $ a symbol for the output filename (basename.epub).
I could call make soverflow.epub
and it would run ebook-convert on soverflow.recipe. If the .recipe hadn't changed since the last build, it wouldn't do anything.
How can I do something similar in waf?
(Why waf? Because it uses a real language that I already know. If this is really easy to use in scons, that's a good answer too.)
回答1:
I figured out how to make a basic wscript file, but I don't know how to build targets specified on the command-line.
The Waf Book has a section on Task generators. The Name and extension-based file processing section gives an example for lua that I adapted:
from waflib import TaskGen
TaskGen.declare_chain(
rule = 'ebook-convert ${SRC} .epub --test -vv --debug-pipeline debug',
ext_in = '.recipe',
ext_out = '.epub'
)
top = '.'
out = 'build'
def configure(conf):
pass
def build(bld):
bld(source='soverflow.recipe')
It even automatically provides a clean step that removes the epub.
回答2:
I gave up on waf for a bit and found that it's pretty easy to do in scons. The documentation has a section on Writing Your Own Builders.
# Setup the custom builder
def add_book_builder(env):
rule = 'ebook-convert $SOURCE .epub --test -vv --debug-pipeline debug'
bld = Builder(action = rule,
suffix = '.epub',
src_suffix = '.recipe')
env.Append(BUILDERS = {'Book' : bld})
env = Environment()
add_book_builder(env)
# Define the epubs that can be built
for target in Glob('*.recipe'):
env.Book(target)
Running scons soverflow.epub
builds the epub. I can add Default(env.Book('soverflow.recipe'))
to the end to build it when there are no arguments.
Unlike waf, it doesn't provide a clean step. Instead, you can clean with scons -c
.
来源:https://stackoverflow.com/questions/9445848/how-do-i-write-a-waf-file-for-a-custom-compiler