[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