The ocamldsort command scans a set of OCaml source files (.ml and .mli
files), sorts them according to their dependencies and prints the sorted
files in order to link their corresponding .cmo files.

For ocamldsort to work it must get a list of dependencies generated by
ocamldep, if the standard input to ocamldsort has been redirected
then ocamldsort assumes that this is a dependency file generated by
ocamldep. Otherwise ocamldsort calls ocamldep to generate the dependency
list itself. In either case the source files to be sorted should be
given as arguments to the ocamldsort command.

ocamldsort can be used to compile and link simple projects with one 
command, such as: 

ocamlc $(ocamldsort *.ml)

if your project doesn't contain .mli files or:

ocamlc -c $(ocamldsort -mli *.ml *.mli) && ocamlc $(ocamldsort -byte *.ml)

if it contains .mli files.

However for larger projects where separate compilation is desirable,
ocamldsort can also be used from within a makefile. Here is a typical
Makefile example.

TARGET=my_program
OCAMLC=ocamlc
OCAMLOPT=ocamlopt
OCAMLDEP=ocamldep
OCAMLDSORT=ocamldsort

PPFLAGS=-pp camlp4o

MLY=$(shell echo *.mly)
MLL=$(shell echo *.mll)
GENERATED_ML=$(MLY:.mly=.ml) $(MLL:.mll=.ml)

include .generated .depend .ocamldsort

$(TARGET): $(CMO_FILES)
	$(OCAMLC) $(COMPFLAGS) $(LIBS) $^ -o $@

$(TARGET).opt: $(CMX_FILES)
	$(OCAMLOPT) $(COMPFLAGS) $(LIBS_OPT) $^ -o $@

.generated: $(GENERATED_ML)
	@touch .generated

.depend: .generated
	$(OCAMLDEP) *.ml *.mli > $@

.ocamldsort: .depend
	echo CMO_FILES=`< .depend $(OCAMLDSORT) -byte *.ml` > .ocamldsort
	echo CMX_FILES=`< .depend $(OCAMLDSORT) -opt *.ml` >> .ocamldsort

distclean: clean
	rm -f .generated .depend .ocamldsort
	rm -f $(GENERATED_ML)
	rm -f *~
	rm -f $(TARGET) 

clean:
	rm -f *.cmo *.cmi *.cmx *.o 

.SUFFIXES: .mli .ml .cmi .cmo .cmx .mll .mly

%.cmi:%.mli
	$(OCAMLC) $(PPFLAGS) $(COMPFLAGS) -c $<

%.cmo:%.ml
	$(OCAMLC) $(PPFLAGS) $(COMPFLAGS) -c $<

%.cmi %.cmo:%.ml
	$(OCAMLC) $(PPFLAGS) $(COMPFLAGS) -c $<

%.cmx %.o:%.ml
	$(OCAMLOPT) $(PPFLAGS) $(COMPFLAGS)  -c $<

%.ml:%.mll
	$(OCAMLLEX) $<

%.mli %.ml:%.mly
        $(OCAMLYACC) -v $<
