[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: cons - 2 things to think about
From: |
Steven Knight |
Subject: |
RE: cons - 2 things to think about |
Date: |
Sat, 23 Jun 2001 08:34:45 -0500 (CDT) |
> AfterBuild('foo.in', 'gen_src_list(...)');
>
> sub gen_src_list {
> system("foo -list foo.in >/tmp/srclist"); # or whatever...
> SRCLIST=open('/tmp/srclist');
> while(<SRCLIST>) {
> push @generated_srcs, $env->Objects($_); # Dynamically add rule!
> }
> $env->Program("a.out", @generated_srcs);
> }
>
> The only two catches are:
> - something else must reference your a.out: it cannot be a top-level target
> or cons won't find it and nothing will get built. If you're building an
> installer from it or something this will take care of it. (I have an
> AddTarget patch which does this, but it's not in 2.3.0.)
Actually, there's another caveat here. The string you give to
AfterBuild only gets evaluated after the target was *built* (or
evaluated as up-to-date), as you'd expect. And, as Gary shows above,
you can use it to add additional targets (using Gary's AddTarget patch)
or dependencies (using a method like Program as in Gary's example
above).
But then when you use "cons -r" to remove derived files, the AfterBuild
string does not get evaluated (you're not actually building anything),
so the derived files or targets you added won't get removed by "cons
-r". Having "cons -r" not do a thorough job of cleaning up targets
feels wrong, but that's the current situation. (Similar issues exist
for other options that don't build files; "cons -pa", for example, won't
report actions for any derived files or targets you add in an AfterBuild
string...)
The lack of a good solution for this is what kept AddTarget out of
2.3.0. In retrospect, that was a little short-sighted, because you
can still add new derived files by calling Program, Command, etc., so
it would have been more consistent to have kept AfterBuild out of the
official releases until we had a solution. But that horse has left the
barn, so this caveat needs to be documented, at least.
I did experiment with workarounds like evaluating the AfterBuild string
after every time a target was evaluated, including "cons -{r,p,pa,pw}".
But you run into problems with the evaluated code if, using Gary's
example above, you run "cons -r" on an empty source tree and the
"foo.in" file doesn't exist...
(And things get really hairy if you use something like AddTarget in a
QuickScan routine, to look for in-file dependencies. What if you're
scanning a derived file? Should "cons -r" *build* the derived file just
so it can scan it to find what targets have been added, so it can then
remove them all? That would seem weird...)
If anyone has bright ideas for how to reconcile AfterBuild/AddTarget
things with "cons -r" and the like, I'd love to hear about them. Or
maybe I'm being too much of a perfectionist, and the right answer is to
just document the limitations with a big "user beware" warning.
Comments?
> - there may be some issues with perl packages above. Make sure cons can
> find your $env, and your gen_src_list. I'm not sure how 2.3.0 is handling
> this, but at the very least if you put them both in special named packages
> it'll be sure to find them. The thing to remember is that gen_src_list will
> not get run when the rest of your Conscript does; it'll get run at build
> time, when targets are being built, and the current package then may be
> different.
Cons does AfterBuild evaluations (and executes other things) in the
same package that the Conscript file was read in. The namespace is
manipulated so you have access to all of the routines and variables that
were available in the Conscript file. So this should would work just
fine without rolling your own separate package name; if it doesn't, it's
a bug, and I'd like to hear about it.
--SK