[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