Automatic all and clean targets?

1,120 views
Skip to first unread message

Evan Jones

unread,
Mar 18, 2011, 4:22:22 PM3/18/11
to ninja...@googlegroups.com
I think that ninja's design philosophy probably excludes including "all"
or "clean" targets automatically. However, I have to wonder if these
might be good exceptions. Any thoughts?


Pros:
+ basically every project wants these targets. including support means
that not every project gets polluted with these rules, and .ninja files
don't need to have excess cruft in them.

+ ninja's graph already has all the information required to make them
automatic: simply enumerate all the output targets and build them or
delete them


Cons:
- ninja is supposed to execute build rules in the graph and nothing
else. this is extra stuff.

- if you are generating your .ninja files, you can generate your own
"all" and "clean" rules

- how would you tell ninja to do this, when the names could conflict
with legitimate files? I would argue that the "noargs" operation could
be build all, but clean would probably need something like flags (ninja
-clean), which would then require dash escaping (ninja -- -file_with_dash)

--
http://evanjones.ca/

Evan Martin

unread,
Mar 22, 2011, 6:03:17 PM3/22/11
to ninja...@googlegroups.com, Evan Jones

I haven't responded earlier because I think your pros and cons pretty
much cover it all.

Maybe you could try implementing it and see how much code it ends up being?

I guess the two features are sort of the mirror of each other: "clean"
nodes are all nodes with in-edges, while "all" nodes are all nodes
without out-edges. (I almost wonder if the more general thing is a
way to query for lists of nodes by properties like these and then just
use them in a shell pipeline: "ninja -tool query :in-edge | xargs rm",
which would also work with something like "ninja -tool query
:no-in-edge | xargs git add". It's probably too cute to be useful
though.)

I'm ok with not supporting plain filename targets named "all" or
"clean", as well as not supporting filenames that start with a dash.
I know that means it's not completely general but I don't think that
generality gains you much. (If necessary you could even retrofit an
explicit path interpretation with something like "./all" or "./-foo",
but I doubt it would ever come up...)

Evan Jones

unread,
Mar 22, 2011, 9:03:35 PM3/22/11
to Evan Martin, ninja...@googlegroups.com
On Mar 22, 2011, at 18:03 , Evan Martin wrote:
> Maybe you could try implementing it and see how much code it ends up
> being?

You are right: This would be the best way to figure these things out.
I may make an attempt at it, but no promises.


> I guess the two features are sort of the mirror of each other: "clean"
> nodes are all nodes with in-edges, while "all" nodes are all nodes
> without out-edges.

Well, in my view these are the same things: just build them all, and
don't look at the number of out edges. Although I haven't looked at
the Ninja internals at all, but I guess it is possible that one may be
easier/better than the other based on how the graph is stored /
traversed / whatever.

Evan

--
http://evanjones.ca/

Nicolas Desprès

unread,
Apr 20, 2011, 12:39:41 PM4/20/11
to ninja-build
FYI, I have started to implement a 'clean' tool for Ninja. You can
find the code in my github fork here https://github.com/polrop/ninja/commits/more-options-and-tools

Basically you can:
- clean all the built files using: ninja -t clean
- clean a given target and recursively all the files built for it
using: ninja -t clean <mytarget>
- clean all files generated by a given rule: ninja -t clean rule
<myrule>

The implementation is pretty straight forward, since it just have to
walk throw the graph.

-Nico

Evan Jones

unread,
Apr 21, 2011, 2:43:46 PM4/21/11
to ninja...@googlegroups.com
On Apr 20, 2011, at 12:39 , Nicolas Desprès wrote:
> Basically you can:
> - clean all the built files using: ninja -t clean

Yay! This is basically what I wanted to do. Thanks for getting to it
faster than me. It basically does exactly what I want, although it
*doesn't* clean up the "depfile" output files like it probably should?

Any interest in doing the same sort of treatment for a "build all"
tool? :)

Evan

--
http://evanjones.ca/

Nicolas Desprès

unread,
Apr 25, 2011, 12:35:59 PM4/25/11
to ninja...@googlegroups.com
On Thu, Apr 21, 2011 at 8:43 PM, Evan Jones <ev...@mit.edu> wrote:
> On Apr 20, 2011, at 12:39 , Nicolas Desprès wrote:
>>
>> Basically you can:
>> - clean all the built files using: ninja -t clean
>
> Yay! This is basically what I wanted to do. Thanks for getting to it faster
> than me. It basically does exactly what I want, although it *doesn't* clean
> up the "depfile" output files like it probably should?
>

Actually I was not sure about whether I should clean the "depfile". I
have the beginning of an implementation doing so in a local branch.
Any other opinion?

> Any interest in doing the same sort of treatment for a "build all" tool? :)

Maybe we could just call ninja without giving any specific target and
thus it builds all root nodes of the graph.

--
Nicolas Desprès

Evan Martin

unread,
Apr 29, 2011, 2:00:28 PM4/29/11
to ninja...@googlegroups.com
2011/4/25 Nicolas Desprès <nicolas...@gmail.com>:

> On Thu, Apr 21, 2011 at 8:43 PM, Evan Jones <ev...@mit.edu> wrote:
>> On Apr 20, 2011, at 12:39 , Nicolas Desprès wrote:
>>>
>>> Basically you can:
>>> - clean all the built files using: ninja -t clean
>>
>> Yay! This is basically what I wanted to do. Thanks for getting to it faster
>> than me. It basically does exactly what I want, although it *doesn't* clean
>> up the "depfile" output files like it probably should?
>
> Actually I was not sure about whether I should clean the "depfile". I
> have the beginning of an implementation doing so in a local branch.
> Any other opinion?

I don't have a strong opinion. I try to generate all build output
into a separate build directory, so it's easy enough for me to clean
up a build with 'rm -rf'.

>> Any interest in doing the same sort of treatment for a "build all" tool? :)
>
> Maybe we could just call ninja without giving any specific target and
> thus it builds all root nodes of the graph.

I like this idea. It seems consistent with the 'graph all' change of
yours that I just merged.

Nicolas Desprès

unread,
May 2, 2011, 5:27:23 AM5/2/11
to ninja...@googlegroups.com
On Fri, Apr 29, 2011 at 8:00 PM, Evan Martin <mar...@danga.com> wrote:
> 2011/4/25 Nicolas Desprès <nicolas...@gmail.com>:
>> On Thu, Apr 21, 2011 at 8:43 PM, Evan Jones <ev...@mit.edu> wrote:
>>> On Apr 20, 2011, at 12:39 , Nicolas Desprès wrote:
>>>>
>>>> Basically you can:
>>>> - clean all the built files using: ninja -t clean
>>>
>>> Yay! This is basically what I wanted to do. Thanks for getting to it faster
>>> than me. It basically does exactly what I want, although it *doesn't* clean
>>> up the "depfile" output files like it probably should?
>>
>> Actually I was not sure about whether I should clean the "depfile". I
>> have the beginning of an implementation doing so in a local branch.
>> Any other opinion?
>
> I don't have a strong opinion.  I try to generate all build output
> into a separate build directory, so it's easy enough for me to clean
> up a build with 'rm -rf'.

I have been thinking a bit more about it and actually the 'make clean'
approach belongs to the past when people were doing in-source build.
Nowadays everybody using a decent build system has a build directory
so 'rm -rf' is perfect clean tool and git clean -fdx if you are using
git and doing in-source build.

That is to say, I mainly wrote this tool because it is useful when
debugging in ninja file generator (remove the build directory also
remove your generated .ninja and generally you don't want that when
testing/debugging).

There are other problem to consider:
- Should we remove directories (like the doxygen/ directory) ?
- All side-effect files (not mentioned in the graph won't be cleaned either).

So basically you use the clean tool before to rename/move source files
around or to clean just a partial part of the graph like a sub-library
of your project. But you have to do the clean before to do the rename.
It is a hard problem to solve. Right now I know only tup
(http://gittup.org/tup/index.html) which is able to track file
renaming and dependencies properly. In a ninja/make philosophy, we
should just use a build directory.

Conclusion, I'm not going to remove depfiles because they will be
regenerated anyway since the output has been removed and that I cannot
write the perfect clean tool.

One could add a clean target in its ninja files doing: git clean -fdx
if in-source build is done.

>
>>> Any interest in doing the same sort of treatment for a "build all" tool? :)
>>
>> Maybe we could just call ninja without giving any specific target and
>> thus it builds all root nodes of the graph.
>
> I like this idea.  It seems consistent with the 'graph all' change of
> yours that I just merged.
>

I have seen that you have just checked in this behavior (that's cool
:-) so my reply is a bit late.

I think building every targets can be long for a large project with
code + test suite (larger than code) + benchmark suite +
documentation. Although normally this is enabled at configuration
time. Even with this behavior I think it could be still convenient to
have "shortcut" target like "all" to build all the code "test" to
build all the test, "doc" to build all the documentation, etc... But
that would be the job of the generator to generate them.

Finally, we could have introduce the concept of a default target like
in make (= the first one parsed), but I think this behavior with
shortcut target is better.

--
Nicolas Desprès

Evan Jones

unread,
May 2, 2011, 11:28:00 AM5/2/11
to ninja...@googlegroups.com
On May 2, 2011, at 5:27 , Nicolas Desprès wrote:
> Nowadays everybody using a decent build system has a build directory
> so 'rm -rf' is perfect clean tool and git clean -fdx if you are using
> git and doing in-source build.

I agree with your sentiment, but I think the "clean" tool is still
very useful.

I need to work with pre-existing build systems that build in tree,
despite my personal preference for the separate output directory. This
was my motivation for wanting a "clean" option, even if it is
imperfect. I also fear the "revision control" approach because if I've
forgotten to check something in it is now deleted.

In conclusion: Thanks for writing the clean tool, as it makes my life
better. :)

Evan

--
http://evanjones.ca/

Reply all
Reply to author
Forward
0 new messages