[Omake] Multiple targets with OMake.

Aleksey Nogin nogin at metaprl.org
Mon Jan 29 10:54:17 PST 2007


On 29.01.2007 08:33, Yves Amalric wrote:

> while managing ocaml modules with omake i need to create
> multiple targets e.g. one for the very 'main' program and the
> other for some 'test' program.

[...]

> Any proposal to get all this clearer, lighter & more efficient ?

I am not sure I understand what exactly was not working right for you, 
but I've added a bunch of comments on your OMakefile below.

> ################################################
> # Configuration.  You may want to modify any of these
> configuration
> # variables.
> #
> OCAMLC = ocamlc
> OCAMLOPT = ocamlopt
> CAMLP4 = camlp4
> OCAMLLEX = ocamllex
> OCAMLYACC = menhir --infer --explain --error-recovery  --trace
> OCAMLDEP = ocamldep
> OCAMLMKTOP = ocamlmktop -I +camlp4
> OCAMLLINK = ocamlc
> OCAMLOPTLINK = ocamlopt

Any reasons for setting the above manually? The default values should 
normally work best, and it is better/cleaner to add any extra flags that 
you want to the corresponding *FLAGS variables. Also, it is probably 
better to leave OCAMLYACC alone and use MENHIR and MENHIR_FLAGS 
variables for menhir.

> #
> # Include path
> #
> # OCAMLINCLUDES +=

May be you should include +camlp4 here, instead of manually adding "-I 
+camlp4" to a bunch of places?

> FILES = timestamp cgi debug util  base mytables  formsyn
> formlex primitives session xhtml testeur

Note that it is probably better to use the "FILES[] =" syntax that would 
make the FILES value be an array.

> CMO_FILES = timestamp.cmo cgi.cmo debug.cmo util.cmo base.cmo
> mytables.cmo formsyn.cmo formlex.cmo primitives.cmo
> session.cmo xhtml.cmo testeur.cmo

CMO_FILES = $(addsuffix .cmo, $(FILES))

> OCAMLPACKS = unix str cgi mysql

Probably cleaner to use "OCAMLPACKS[] = ..." (although it does not 
probably matter in your case).

> OCAMLOPTIONS_ = -package unix -package str -package mysql
> -package cgi

You do not need this - OCaml.om knows how to use OCAMLPACKS. If you do 
need to use the expanded form in your custom rules, just use the 
PREFIXED_OCAMLPACKS variable.

> OCamlProgram($(MAIN_PROGRAM), $(FILES) $(MAIN))
> .DEFAULT: $(MAIN_PROGRAM).run $(MAIN_PROGRAM).opt

OCamlProgram returns the set of targets, so you can use simply

.DEFAULT: $(OCamlProgram $(MAIN_PROGRAM), $(FILES) $(MAIN))

The above has an added bonus of not insisting on .opt if ocamlopt is not 
available (e.g. you are on a bytecode-only platform).

> # cible supplémentaire pour menhir
> .PHONY: clean all install generate_files
> # Pour contourner la stupidité d'ocamldep avec les fichiers
> générés
> generate_files:
>     touch lisp_parser.ml lisp_parser.mli lisp_lexer.ml
> .SCANNER: scan-ocaml%: generate_files

There is a function for doing this -

OCamlGeneratedFiles(lisp_parser.ml lisp_parser.mli lisp_lexer.ml)

Alternatively, try enabling  OCAMLDEP_MODULES_ENABLED (or setting 
"OCAMLDEP_MODULES_ENABLED = $(OCAMLDEP_MODULES_AVAILABLE)" ). This is a 
bit experimental for now, and is known not to work right on OS X (we are 
working on it), but long-term this is the way to go, especially with menhir.

When OCAMLDEP_MODULES_ENABLED is set, OMake will only use ocamldep to 
extract the list of module dependencies (_without_ paths), and then will 
do it's own OCAMLINCLUDES lookup, where it would take into account not 
only files that already exist, but also files that it knows can be 
generated.

> # Faire un scanner de .mly avec menhir
> .SCANNER: %.ml %.mli: %.mly
>     menhir --depend $<

You should not need this - the existing OCaml.om should take care of it. 
Please let us know if the default setup is not doing the right thing for 
you.

> calculs_top: $(CMO_FILES) $(MAIN_CMO)
>     $(OCAMLFIND) $(OCAMLMKTOP) $(OCAMLOPTIONS_) -linkpkg $(OCAML_LIBS)  $(CMO_FILES) $(MAIN_CMO) -o $@

Right, we should probably provide some sort of OCamlMkTop function that 
would be similar to OCamlProgram, but use the OCAMLMKTOP instead. Note 
that you should probably be using OCAML_LINK_FLAGS (which would already 
include the -linkpkg when OCAMLPACKS is non-empty and USE_OCAMLFIND is 
set), and PREFIXED_OCAMLPACKS in place of OCAMLOPTIONS_.

> $(TEST_PROGRAM): $(CMO_FILES)
>         $(OCAMLFIND) $(OCAMLLINK) $(OCAMLOPTIONS_)  -linkpkg $(OCAML_LIBS)  $(CMO_FILES)  -o $@

Is there a problem with using the standard OCamlProgram for this?

> #        $(TEST_PROGRAM) -thexpr '?LETREC factorielle (n) = IF n = 0 THEN 1 ELSE n * factorielle(n - 1) IN factorielle(5)'

> #test: $(TEST_PROGRAM)
> #    ./scriptest

The "test" target should probably be declared as .PHONY.

Aleksey


More information about the Omake mailing list