[Omake] Recursive invocation of omake
Jason Hickey
jyh at cs.caltech.edu
Wed Jun 7 13:59:05 PDT 2006
Benjamin Pierce wrote:
> Looking at the OMakefiles for OMake itself, I discovered that if both
> the root OMakefile and some subdirectory's OMakefile contain clean:
> targets, then
> 1) doing 'make clean' in the root dir will execute them both (in the
> appropriate directories)
> 2) doing 'make clean' in the subdirectory will execute just its
> local one.
>
> This is exactly the behavior I wanted, so that problem is solved.
>
> However, this makes me realize that there is still quite a bit I don't
> understand about OMake's view of a multi-directory project -- I don't
> have a model that would have allowed me to predict both (1) and (2).
> Can someone explain?
Hi Benjamin,
Aleksey explained about .PHONY targets. Let me say a bit more about the
general model.
In general, a project will span multiple directories, and there is a
single "project root" directory that contains an OMakeroot file. Other
directories become part of the project when they are listed as a
.SUBDIRS target. The build (.SUBDIRS) tree doesn't have to conform to
the filesystem tree, but it often does. This is an example tree:
./OMakeroot:
# Configuration stuff
.SUBDIRS: . # Includes the current directory in the project
./OMakefile:
# Rules, etc.
# Include directories a, b/c
# The files ./a/OMakefile and ./b/c/OMakefile must exist
.SUBDIRS: a b/c
OMake performs a global analysis, reading the entire project (see
performance notes later).
Most frequently, you run omake from the project root and it builds all
targets that are declared somewhere in the project with .DEFAULT. If
you run omake from a subdirectory, any targets you list on the command
line are taken relative to that subdirectory. The global analysis is
still performed, so it may be that targets in other directories will
still be built (Aleksey thinks we should have a "sloppy" mode, but I
disagree:) If you run omake in a subdirectory, and you want to pretend
as if you ran it from the root, you can use the -R option.
Some notes:
- By default, each subdirectory must have an OMakefile. Alternately,
you can use a .SUBDIRS body. The body is evaluated instead of
the OMakefile, for each directory dir1, ..., dirn in turn.
.SUBDIRS: dir1 ... dirn
<body>
- The language is functional-- all variables (including environment
variables) are immutable, but dynamically scoped. So what is the
environment that is used to build a particular target, like
foo/boo.exe? Here is the rule:
1. If the target boo.exe is defined explicitly in foo/OMakefile,
then the environment at that point is used when building the
target.
2. Otherwise, the environment as defined at the end
of foo/OMakefile is used.
Functionality is one of the main points. The environment is inherited
down the project build tree, but each subdirectory can make changes
and/or add new definitions without affecting other parts of the project.
About performance. Since omake performs a global analysis, on each run,
all the OMakefiles must be evaluated. This is reasonably cheap; the
language is interpreted, but we do some caching after parsing (saved in
the .omc files). The big cost is that a stat(2) system call must be
performed on each source file in the project. Also, the very first
time, this requires taking MD5 digests too.
The stat cost is more-or-less unavoidable--recursive make winds up doing
much the same. One thing we frequently do is use the -P option. In
this case, omake actively monitors the filesystem for changes, and build
restarts are more-or-less instantaneous when a source file changes.
Jason
--
Jason Hickey http://www.cs.caltech.edu/~jyh
Caltech Computer Science Tel: 626-395-6568 FAX: 626-792-4257
More information about the Omake
mailing list