[Omake] Compiling files in different directories

Hugo Ferreira hmf at inescporto.pt
Thu May 31 01:20:49 PDT 2007


Hi Aleksey,

Aleksey Nogin wrote:
> On 30.05.2007 07:41, Hugo Ferreira wrote:
> 
>> The set-up you show is basically what I have. Unfortunately the "camlp4"
>> project is set-up to create a test "application" by default and library.
>> My "resolv" project also has the same set-up. Both these projects
>> share certain targets (libraries of other projects). I have therefore
>> two problems:
>>
>> 1. Avoiding an error from omake complaining about multiple ways to
>> build targets.
>>
>> 2. Use only certain source files files from "camlp4" project.
>>
>> From your example I think my real problem is (1). I cannot seem to find
>> a way to mix and match source files because the default target of the
>> sub-projects use shared targets.
> 
> Hugo,
> 
> There are many ways of eliminating the most obvious problems (such as
> the problem (1) above) by doing things like using .SUBDIRS directives
> with a body (the body then is used in place of the subdir's OMakefile).

I think this solution may not be practical because the sub-project can
be quite large and very different in terms of sources so a OMakefile may
be the better.

> Alternatively, you can move the conflicting stuff from camlp4/OMakefile
> to camlp4/OMakeroot (or just define "CAMLP4_STANDALONE=true" in
> camlp4/OMakeroot, CAMLP4_STANDALONE=false in resolv/OMakefile and then
> in camlp4/OMakefile simply test for $(STANDALONE) before defining common
> targets).
> 

Ok. Lets see if I have this right. Assume I have the following in my
resolve OMakefile (slight change in example):

....................................................................
OCAMLINCLUDES += ../res_stck ../qalist ../term ../symbl_tbl ../compile\
		 ../parser-lexer ../unify ../camlp4 ../db
.SUBDIRS: ../camlp4

# OCaml libraries
OCAML_LIBS = ../qalist/libqalist1 ../res_stck/libres_stck\
	     ../term/libterm2 ../symbl_tbl/libsymbl_tbl3\
	     ../symbl_tbl/liblexeme2 ../compile/libcompile\
	     ../parser-lexer/libllexer ../parser-lexer/liblparser\
	     ../unify/libunify ../camlp4/liblogic

....................................................................

Note that ../camlp4/liblogic depends on all other libraries. Note also
that several of those libraries depend on each other. For example
../qalist/libqalist1 is independent but ../term/libterm2 depends on it.
../symbl_tbl/libsymbl_tbl3 on the other hand depends on
../term/libterm2, which in its turn depends on ../term/libterm2 as
stated above.

How have I dealt with this so far? I simply use a single target in the
.SUBDIR. So you will notice in the above example I have only
.SUBDIRS: ../camlp4. Similarly for all other sub-projects I use a single
.SUBDIRS if common projects exist and simply add only those that are
missing. So far so good.

Now assume I have an additional subproject "db". It has all the same
dependencies as resolve (save maybe for ../unify/libunify). I would
usually simply add all libraries to the "resolv" project and use a
single .SUBDIRS: ../db.

Now what I really want is to use some sources (actually three source
files) from db sub-project only. To do this should I then:

1.) define "DB_STANDALONE=true" in db/OMakeroot
2.) define "DB_STANDALONE=false" in resolv/OMakefile
3.) In the "db" project's OMakefile do:
# OCaml libraries
if $(DB_STANDALONE)
	# Definer all libraries
	OCAML_LIBS = ../qalist/libqalist1 ../res_stck/libres_stck\
		     ../term/libterm2 ../symbl_tbl/libsymbl_tbl3\
		     ../symbl_tbl/liblexeme2 ../compile/libcompile\
		     ../parser-lexer/libllexer \
		     ../parser-lexer/liblparser\
		     ../unify/libunify ../camlp4/liblogic
else
	# Definer local libraries only (empty)
	OCAML_LIBS =
4.) Add ".SUBDIRS: ../camlp4 ../db" to the resolv/OMakefile

> Also, if the camlp4 project already defines the common targets and the
> resolv project includes the camlp4 directory, why not just drop a
> separate definition of the common targets from the resolv project?
> 

I don't know if this makes sense but in each sub-project I have four
targets:
* a 'default' test application,
* launch 'debug' of the test application,
* 'clean' project
* a 'library' version

In the current case I have:
1. "/resolv" that requires "liblogic" (library version of /camlp4)
2. "/resolv" that requires "libdb" (library version of /db)
3. "liblogic" uses a set of libraries call it A
4. "libdb" uses a set of libraries call it B
5. Some libraries in A and B are the same

To have "liblogic" I need ".SUBDIRS: ../camlp4"
To have "libdb" I need ".SUBDIRS: ../db"

The conflict now arises among the projects listed in ".SUBDIRS"
and not with the current "resolv" project. The only way I see to
solve this is by using the suggestion you made above and have all
dependent projects flagged as standalone or not.

> Note, however, you will not be able to eliminate the basic issue of each
> project having a separate build database. Because of that, actions made
> by omake in one project will not be known by omake running for the other
> project, so the other omake instance will not consider the file
> up-to-date (omake does not consider a file to be up-to-date, unless it
> knows that it have built the file before).
> 

This makes sense. However something is amiss here. My real objective is
to have "independent" projects in a sense that I can pick and choose
source files. So in the "resolv" project I simply required:

FILES = ../db/imap ../db/db resolv
PROGRAM = test
OCamlProgram($(PROGRAM), $(FILES))
.DEFAULT: $(PROGRAM).run $(PROGRAM).opt

Notice how I use sources from a different directory other than the
current one. *Now it seems strange to me that this does not work. Omake
complains that is does not know how to "make imap.cmo" and "make
db.cmo". In other words Omake seems to require a ".SUBDIRS" that
contains the build rules for these files. But they are simple Ocaml
sources! Why such requirement?* I mean resolv is is interpreted as
a resolve.ml target and compiles must fine.

> Is there some reason why you can not just create a single _shared_
> project? Note that when you run omake (without arguments) from a
> subdirectory, then by default it only builds the "local" .DEFAULT, not
> the global one, so you can still set things up so that it builds the
> right subset of targets when you run it from a subdirectory.
> 

This is currently my objective. Have each sub-project build by default
locally. Later have a single top level project that builds one or more
specific sub-project targets. However each such local build depends on
other sub-projects, which is a problem due to dependencies.

TIA for your help,
Hugo F.


> Aleksey



More information about the Omake mailing list