Version française
Home     About     Download     Resources     Contact us    
Browse thread
A Tutorial on GNU Make with OCaml
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Goswin von Brederlow <goswin-v-b@w...>
Subject: Re: [Caml-list] A Tutorial on GNU Make with OCaml
Jeff Shaw <shawjef3@msu.edu> writes:

> Dear OCamlers,
> I spent quite a lot of time today getting better acquainted with GNU
> make and decided I to share my experience and results. It's a bit on
> the newbie friendly side of instruction.
>
> http://shawjeff.blogspot.com/2010/05/this-is-storytutorial-about-how-i_20.html
>
> I hope someone finds it helpful!
>
> Jeff Shaw
> shawjef3@msu.edu

Some comments:

- For things you don't want to be deleted even though make sees they
will never be reused on subsequent make calls look up .PRECIOUS

- Targets that have no dependencies and create no file are implicitly
PHONY. No need to specify it as such. A reason for why one might do it
anyway would be to protect against someone doing "touch clean" by
accident:

% touch clean
% make clean
make: `clean' is up to date.

A .PHONY: clean would prevent that and run clean anyway.

- Don't create interface files if there are none

If you start writing a module and haven't decided on the exact interface
it will be a pain to delete the generated interface file every time. It
is also completly useless as you can generate the cmi file from the .ml
file directly. No need to create .mli first.

- Use ocamldep

Ocamldep figures out wich modules depend on other modules and generates
that in Makefile syntax for you. Unfortunately ocamldep lacks an option
to generate a dependency line for the final binary so SOURCES below must
be set by hand and in the right order.

- List source files, not generated files and use pattern substitution to
get the later


Here is my own version of a Makefile for a trivial project. I hardcoded
it for native code but you already know how to use 'TARGET=byte' from
your Makefile. Merging the two is left as an execise.

PROG       := prog
LIBS       := graphics unix
SOURCES    := foo.ml bar.ml baz.ml

# No user servicable parts below
INTERFACES := $(wildcard *.mli)
OBJS       := $(patsubst %.ml,%.cmx,$(SOURCES))
LIBS       := $(patsubst %,%.cmxa,$(LIBS))

# Count number of cores and use them all, no idea how do to that for windows
PARALLEL   := -j$(shell cat /proc/cpuinfo | grep processor | wc -l)

all:
	$(MAKE) $(PARALLEL) $(PROG)

$(PROG): $(OBJS)
        ocamlopt -o $@ $(LIBS) $(OBJS)

clean:
        rm -rf $(PROG) *.o *.cmx *.cmi *~

%.cmx: %.ml
        ocamlopt -c $*.ml

%.cmi: %.mli
        ocamlopt -c $*.mli

.depend: $(SOURCES) $(INTERFACES)
        ocamldep -native $(SOURCES) $(INTERFACES) >.depend

include .depend