[Omake] .PHONY rules in subdirs

Aleksey Nogin anogin at hrl.com
Thu Mar 29 10:50:44 PDT 2007


Hi Tom,

Thanks a lot for a very good question. Let me first go over some of the 
details before answering it.

On 28.03.2007 18:44, Tom Murray wrote:

> I'm trying to define a set of default (phony) targets to be active in 
> every subdirectory of my project, a la automake. For example, I want 
> "omake clean" to execute some general cleaning code, and I want to be 
> able to define this once in the root, and not have to copy the 
> definition to subdirectories.

Note that is it easy to define a set of phony _targets_ that would then 
exist in every project directory - this is what the hierarchy of the 
.PHONY targets is supposed to give you if you use ".PHONY: clean" in 
your top-level OMakefile (or OMakeroot) before any of the .SUBDIRS lines.

What is harder, as you found out, is to define some "universal" _rules_ 
for those targets.

> I find 
> the current implementation of this a bit strange: When I type "omake 
> clean" in a subdirectory, it is clearly using the top-level clean rule 
> in some way, because the invocation does not fail.

Here, the "clean" target in the subdirectory is known to be phony, but 
there are no rules for it (As I understand what you are trying to do, 
you only have a "clean: ..." rule for the clean target in the project 
root, but no rules in the subdirectory). In general, OMake is happy to 
accept any number of rules for phony targets, including not doing 
anything in case there are no rules at all. So this is what happens - 
the target is known to be phony, there are no rules for it, it has no 
dependencies, so OMake does not do anything.

> Is there some other mechanism I should be using to achieve what I want 
> to do? 
[...]
> Must I call an "installMySpecialTargets()" 
> function at the end of each OMakefile? Please say it ain't so!

While using some sort of "InstallMyGlobalRules()" call in every 
subdirectory is indeed an option, I completely agree that it is not a 
very good one.

The best approach would probably be to use an implicit rule that would 
then propagate to every subdirectory:

--------
.PHONY: clean

clean%:
   rm -f *$(EXT_OBJ) *$(EXT_LIB)

.SUBDIRS: ...
--------

In current OMake, there are two imperfections w.r.t. this approach:

- You can not define an implicit rule without having a pattern with a 
wildcard in it, so you end up having to use "clean%" (or "%clean", or 
some other variation), which might accidentally match something you did 
not intend to match. I've filed 
http://bugzilla.metaprl.org/show_bug.cgi?id=658 about this.

- If a subdirectory defines its own clean rule (whether implicit or 
not), the existing one will get shadowed and not executed for that 
subdirectory. Depending on the situation, you might be interested in 
keeping both. I've filed http://bugzilla.metaprl.org/show_bug.cgi?id=659 
discussing this.

P.S. One suggestion would be to use something like

--------
.PHONY: clean

EXTRA_CLEANING =

clean%:
   rm -f *$(EXT_OBJ) *$(EXT_LIB) $(EXTRA_CLEANING)

.SUBDIRS: ...
--------

This way any subdirectories can add their own stuff to the 
EXTRA_CLEANING variable.

Aleksey

-- 
Aleksey Nogin, Research Staff Member
Advanced Technologies Department, Information & System Sciences Lab
HRL Laboratories, LLC, Malibu, CA


More information about the Omake mailing list