From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail4-relais-sop.national.inria.fr (mail4-relais-sop.national.inria.fr [192.134.164.105]) by yquem.inria.fr (Postfix) with ESMTP id 1C439BBAF for ; Fri, 21 May 2010 10:28:15 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: ArYCAHbg9UvZSMDdi2dsb2JhbACeIBUBAQEKCwoHDwUfvQuFEgSPPw X-IronPort-AV: E=Sophos;i="4.53,277,1272837600"; d="scan'208";a="63204693" Received: from fmmailgate01.web.de ([217.72.192.221]) by mail4-smtp-sop.national.inria.fr with ESMTP; 21 May 2010 10:28:14 +0200 Received: from smtp07.web.de ( [172.20.5.215]) by fmmailgate01.web.de (Postfix) with ESMTP id B660515A9E034; Fri, 21 May 2010 10:28:13 +0200 (CEST) Received: from [78.43.204.177] (helo=frosties.localdomain) by smtp07.web.de with asmtp (TLSv1:AES256-SHA:256) (WEB.DE 4.110 #4) id 1OFNaX-0007vL-00; Fri, 21 May 2010 10:28:13 +0200 Received: from mrvn by frosties.localdomain with local (Exim 4.71) (envelope-from ) id 1OFNad-0003Ck-9R; Fri, 21 May 2010 10:28:19 +0200 From: Goswin von Brederlow To: Jeff Shaw Cc: caml-list@inria.fr Subject: Re: [Caml-list] A Tutorial on GNU Make with OCaml References: <4BF603AA.4030703@msu.edu> Date: Fri, 21 May 2010 10:28:19 +0200 In-Reply-To: <4BF603AA.4030703@msu.edu> (Jeff Shaw's message of "Thu, 20 May 2010 23:53:14 -0400") Message-ID: <87k4qxveu4.fsf@frosties.localdomain> User-Agent: Gnus/5.110009 (No Gnus v0.9) XEmacs/21.4.22 (linux, no MULE) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Sender: goswin-v-b@web.de X-Sender: goswin-v-b@web.de X-Provags-ID: V01U2FsdGVkX1+Cft5jWQjFYySMg7CpmH2DW1wWImzchV0Ndn1t wVQwpi1lvFwM2K6k7KWmQGARsSEt5jMW+lRuucRYzN7JkGEy/6 IJKVK8xvU= X-Spam: no; 0.00; ocaml:01 dependencies:01 cmi:01 mli:01 ocamldep:01 ocamldep:01 makefile:01 syntax:01 lacks:01 makefile:01 trivial:01 merging:01 libs:01 foo:01 baz:01 Jeff Shaw 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