1#**************************************************************************
2#*                                                                        *
3#*                                 OCaml                                  *
4#*                                                                        *
5#*            Xavier Leroy, projet Cristal, INRIA Rocquencourt            *
6#*                                                                        *
7#*   Copyright 1999 Institut National de Recherche en Informatique et     *
8#*     en Automatique.                                                    *
9#*                                                                        *
10#*   All rights reserved.  This file is distributed under the terms of    *
11#*   the GNU Lesser General Public License version 2.1, with the          *
12#*   special exception on linking described in the file LICENSE.          *
13#*                                                                        *
14#**************************************************************************
15
16MAKEFLAGS := -r -R
17include ../config/Makefile
18INSTALL_BINDIR:=$(DESTDIR)$(BINDIR)
19INSTALL_LIBDIR:=$(DESTDIR)$(LIBDIR)
20INSTALL_COMPLIBDIR:=$(DESTDIR)$(COMPLIBDIR)
21INSTALL_STUBLIBDIR:=$(DESTDIR)$(STUBLIBDIR)
22INSTALL_MANDIR:=$(DESTDIR)$(MANDIR)
23
24ifeq ($(SYSTEM),unix)
25override define shellquote
26$i := $$(subst ",\",$$(subst $$$$,\$$$$,$$(subst `,\`,$i)))#")#
27endef
28$(foreach i,BINDIR LIBDIR COMPLIBDIR STUBLIBDIR MANDIR,$(eval $(shellquote)))
29endif
30
31CAMLRUN ?= ../boot/ocamlrun
32CAMLYACC ?= ../boot/ocamlyacc
33DESTDIR ?=
34# Setup GNU make variables storing per-target source and target,
35# a list of installed tools, and a function to quote a filename for
36# the shell.
37override installed_tools := ocamldep ocamlprof ocamlcp ocamloptp \
38                   ocamlmktop ocamlmklib ocamlobjinfo
39
40install_files :=
41define byte2native
42$(patsubst %.cmo,%.cmx,$(patsubst %.cma,%.cmxa,$1))
43endef
44
45# $1 = target, $2 = OCaml object dependencies, $3 = other dependencies
46# There is a lot of subtle code here.  The multiple layers of expansion
47# are due to `make`'s eval() function, which evaluates the string
48# passed to it as a makefile fragment.  So it is crucial that variables
49# not get expanded too many times.
50define byte_and_opt_
51# This check is defensive programming
52$(and $(filter-out 1,$(words $1)),$(error \
53   cannot build file with whitespace in name))
54$1: $3 $2
55	$$(CAMLC) $$(LINKFLAGS) -I .. -o $$@ $2
56
57$1.opt: $3 $$(call byte2native,$2)
58	$$(CAMLOPT) $$(LINKFLAGS) -I .. -o $$@ $$(call byte2native,$2)
59
60all: $1
61
62opt.opt: $1.opt
63
64ifeq '$(filter $(installed_tools),$1)' '$1'
65install_files += $1
66endif
67clean::
68	rm -f -- $1 $1.opt
69
70endef
71
72# Escape any $ characters in the arguments and eval the result.
73define byte_and_opt
74$(eval $(call \
75 byte_and_opt_,$(subst $$,$$$$,$1),$(subst $$,$$$$,$2),$(subst $$,$$$$,$3)))
76endef
77
78ROOTDIR=..
79
80ifeq "$(wildcard $(ROOTDIR)/flexdll/Makefile)" ""
81export OCAML_FLEXLINK:=
82else
83export OCAML_FLEXLINK:=$(ROOTDIR)/boot/ocamlrun $(ROOTDIR)/flexdll/flexlink.exe
84endif
85
86CAMLC=$(CAMLRUN) ../boot/ocamlc -nostdlib -I ../boot \
87      -use-prims ../byterun/primitives -I ..
88CAMLOPT=$(CAMLRUN) ../ocamlopt -nostdlib -I ../stdlib
89ifeq "$(UNIX_OR_WIN32)" "win32"
90  ifneq "$(wildcard ../flexdll/Makefile)" ""
91    CAMLOPT := OCAML_FLEXLINK="../boot/ocamlrun ../flexdll/flexlink.exe" \
92      $(CAMLOPT)
93  endif
94endif
95CAMLLEX=$(CAMLRUN) ../boot/ocamllex
96INCLUDES=-I ../utils -I ../parsing -I ../typing -I ../bytecomp -I ../asmcomp \
97         -I ../middle_end -I ../middle_end/base_types -I ../driver \
98         -I ../toplevel
99COMPFLAGS= -absname -w +a-4-9-41-42-44-45-48 -strict-sequence -warn-error A \
100 -safe-string -strict-formats -bin-annot $(INCLUDES)
101LINKFLAGS=$(INCLUDES)
102VPATH := $(filter-out -I,$(INCLUDES))
103
104# scrapelabels addlabels
105
106.PHONY: all opt.opt
107
108# The dependency generator
109
110CAMLDEP_OBJ=ocamldep.cmo
111CAMLDEP_IMPORTS= \
112  ../compilerlibs/ocamlcommon.cma \
113  ../compilerlibs/ocamlbytecomp.cma
114ocamldep: LINKFLAGS += -compat-32
115$(call byte_and_opt,ocamldep,$(CAMLDEP_IMPORTS) $(CAMLDEP_OBJ),)
116ocamldep: depend.cmi
117ocamldep.opt: depend.cmi
118
119# ocamldep is precious: sometimes we are stuck in the middle of a
120# bootstrap and we need to remake the dependencies
121clean::
122	if test -f ocamldep; then mv -f ocamldep ocamldep.bak; else :; fi
123	rm -f ocamldep.opt
124
125
126# The profiler
127
128CSLPROF=ocamlprof.cmo
129CSLPROF_IMPORTS=misc.cmo config.cmo identifiable.cmo numbers.cmo \
130  arg_helper.cmo clflags.cmo terminfo.cmo \
131  warnings.cmo location.cmo longident.cmo docstrings.cmo \
132  syntaxerr.cmo ast_helper.cmo parser.cmo lexer.cmo parse.cmo
133
134$(call byte_and_opt,ocamlprof,$(CSLPROF_IMPORTS) profiling.cmo $(CSLPROF),)
135
136ocamlcp_cmos = misc.cmo warnings.cmo config.cmo identifiable.cmo numbers.cmo \
137	       arg_helper.cmo clflags.cmo main_args.cmo
138
139$(call byte_and_opt,ocamlcp,$(ocamlcp_cmos) ocamlcp.cmo,)
140$(call byte_and_opt,ocamloptp,$(ocamlcp_cmos) ocamloptp.cmo,)
141
142opt:: profiling.cmx
143
144install::
145	cp -- profiling.cmi profiling.cmo profiling.cmt profiling.cmti "$(INSTALL_LIBDIR)"
146
147installopt::
148	cp -- profiling.cmx profiling.$(O) "$(INSTALL_LIBDIR)"
149
150# To help building mixed-mode libraries (OCaml + C)
151
152$(call byte_and_opt,ocamlmklib,ocamlmklibconfig.cmo config.cmo misc.cmo \
153	         ocamlmklib.cmo,)
154
155
156ocamlmklibconfig.ml: ../config/Makefile Makefile
157	(echo 'let bindir = "$(BINDIR)"'; \
158         echo 'let supports_shared_libraries = $(SUPPORTS_SHARED_LIBRARIES)';\
159         echo 'let byteccrpath = "$(BYTECCRPATH)"'; \
160         echo 'let nativeccrpath = "$(NATIVECCRPATH)"'; \
161         echo 'let mksharedlibrpath = "$(MKSHAREDLIBRPATH)"'; \
162         echo 'let toolpref = "$(TOOLPREF)"'; \
163         sed -n -e 's/^#ml //p' ../config/Makefile) \
164        > ocamlmklibconfig.ml
165
166beforedepend:: ocamlmklibconfig.ml
167
168clean::
169	rm -f ocamlmklibconfig.ml
170
171# To make custom toplevels
172
173OCAMLMKTOP=ocamlmktop.cmo
174OCAMLMKTOP_IMPORTS=misc.cmo identifiable.cmo numbers.cmo config.cmo \
175		   arg_helper.cmo clflags.cmo ccomp.cmo
176
177$(call byte_and_opt,ocamlmktop,$(OCAMLMKTOP_IMPORTS) $(OCAMLMKTOP),)
178
179# Converter olabl/ocaml 2.99 to ocaml 3
180
181OCAML299TO3= lexer299.cmo ocaml299to3.cmo
182LIBRARY3= misc.cmo warnings.cmo location.cmo
183
184ocaml299to3: $(OCAML299TO3)
185	$(CAMLC) $(LINKFLAGS) -o ocaml299to3 $(LIBRARY3) $(OCAML299TO3)
186
187lexer299.ml: lexer299.mll
188	$(CAMLLEX) lexer299.mll
189
190#install::
191#	cp ocaml299to3 "$(INSTALL_BINDIR)/ocaml299to3$(EXE)"
192
193clean::
194	rm -f ocaml299to3 lexer299.ml
195
196# Label remover for interface files (upgrade 3.02 to 3.03)
197
198SCRAPELABELS= lexer301.cmo scrapelabels.cmo
199
200scrapelabels: $(SCRAPELABELS)
201	$(CAMLC) $(LINKFLAGS) -o scrapelabels $(LIBRARY3) $(SCRAPELABELS)
202
203lexer301.ml: lexer301.mll
204	$(CAMLLEX) lexer301.mll
205
206#install::
207#	cp scrapelabels "$(INSTALL_LIBDIR)"
208
209clean::
210	rm -f scrapelabels lexer301.ml
211
212# Insert labels following an interface file (upgrade 3.02 to 3.03)
213
214ADDLABELS_IMPORTS=misc.cmo config.cmo arg_helper.cmo clflags.cmo \
215  identifiable.cmo numbers.cmo terminfo.cmo \
216  warnings.cmo location.cmo longident.cmo docstrings.cmo \
217  syntaxerr.cmo ast_helper.cmo parser.cmo lexer.cmo parse.cmo
218
219addlabels: addlabels.cmo
220	$(CAMLC) $(LINKFLAGS) -w sl -o addlabels \
221		$(ADDLABELS_IMPORTS) addlabels.cmo
222
223#install::
224#	cp addlabels "$(INSTALL_LIBDIR)"
225
226ifeq ($(UNIX_OR_WIN32),unix)
227LN := ln -sf
228else
229LN := cp -pf
230endif
231
232install::
233	for i in $(install_files); \
234	do \
235	  cp -- "$$i" "$(INSTALL_BINDIR)/$$i.byte$(EXE)" && \
236	  if test -f "$$i".opt; then \
237	    cp -- "$$i.opt" "$(INSTALL_BINDIR)/$$i.opt$(EXE)" && \
238	    (cd "$(INSTALL_BINDIR)/" && $(LN) "$$i.opt$(EXE)" "$$i$(EXE)"); \
239	  else \
240	    (cd "$(INSTALL_BINDIR)/" && $(LN) "$$i.byte$(EXE)" "$$i$(EXE)"); \
241	  fi; \
242	done
243
244clean::
245	rm -f addlabels
246
247# The preprocessor for asm generators
248
249CVT_EMIT=cvt_emit.cmo
250
251cvt_emit: $(CVT_EMIT)
252	$(CAMLC) $(LINKFLAGS) -o cvt_emit $(CVT_EMIT)
253
254# cvt_emit is precious: sometimes we are stuck in the middle of a
255# bootstrap and we need to remake the dependencies
256.PRECIOUS: cvt_emit
257clean::
258	if test -f cvt_emit; then mv -f cvt_emit cvt_emit.bak; else :; fi
259
260cvt_emit.ml: cvt_emit.mll
261	$(CAMLLEX) cvt_emit.mll
262
263clean::
264	rm -f cvt_emit.ml
265
266beforedepend:: cvt_emit.ml
267
268# Reading cmt files
269
270READ_CMT= \
271          ../compilerlibs/ocamlcommon.cma \
272          ../compilerlibs/ocamlbytecomp.cma \
273          \
274          cmt2annot.cmo read_cmt.cmo
275
276# Reading cmt files
277$(call byte_and_opt,read_cmt,$(READ_CMT),)
278
279
280# The bytecode disassembler
281
282DUMPOBJ=opnames.cmo dumpobj.cmo
283
284$(call byte_and_opt,dumpobj,misc.cmo identifiable.cmo numbers.cmo tbl.cmo \
285                    config.cmo ident.cmo opcodes.cmo bytesections.cmo \
286		    $(DUMPOBJ),)
287
288make_opcodes.ml: make_opcodes.mll
289	$(CAMLLEX) make_opcodes.mll
290
291make_opcodes: make_opcodes.ml
292	$(CAMLC) make_opcodes.ml -o $@
293
294opnames.ml: ../byterun/caml/instruct.h make_opcodes
295	$(CAMLRUN) make_opcodes -opnames < $< > $@
296
297clean::
298	rm -f opnames.ml make_opcodes make_opcodes.ml
299
300beforedepend:: opnames.ml
301
302# Display info on compiled files
303
304ifeq "$(SYSTEM)" "macosx"
305DEF_SYMBOL_PREFIX = '-Dsymbol_prefix="_"'
306else
307DEF_SYMBOL_PREFIX = '-Dsymbol_prefix=""'
308endif
309
310ifeq "$(CCOMPTYPE)" "msvc"
311CCOUT = -Fe
312else
313EMPTY =
314CCOUT = -o $(EMPTY)
315endif
316
317objinfo_helper$(EXE): objinfo_helper.c ../config/s.h
318	$(BYTECC) $(CCOUT)objinfo_helper$(EXE) $(BYTECCCOMPOPTS) \
319          $(DEF_SYMBOL_PREFIX) $(LIBBFD_INCLUDE) objinfo_helper.c $(LIBBFD_LINK)
320
321OBJINFO=../compilerlibs/ocamlcommon.cma \
322        ../compilerlibs/ocamlbytecomp.cma \
323        ../compilerlibs/ocamlmiddleend.cma \
324        ../asmcomp/printclambda.cmo \
325        ../asmcomp/export_info.cmo \
326        objinfo.cmo
327
328$(call byte_and_opt,ocamlobjinfo,$(OBJINFO),objinfo_helper$(EXE))
329
330install::
331	cp objinfo_helper$(EXE) "$(INSTALL_LIBDIR)/objinfo_helper$(EXE)"
332
333# Scan object files for required primitives
334$(call byte_and_opt,primreq,config.cmo primreq.cmo,)
335
336LINTAPIDIFF=../compilerlibs/ocamlcommon.cmxa \
337        ../compilerlibs/ocamlbytecomp.cmxa \
338        ../compilerlibs/ocamlmiddleend.cmxa \
339        ../asmcomp/printclambda.cmx \
340        ../asmcomp/export_info.cmx \
341	../otherlibs/str/str.cmxa \
342	lintapidiff.cmx
343
344lintapidiff.opt: INCLUDES+= -I ../otherlibs/str
345lintapidiff.opt: $(LINTAPIDIFF)
346	$(CAMLOPT) $(LINKFLAGS) -I .. -o $@ $(LINTAPIDIFF)
347clean::
348	rm -f -- lintapidiff.opt lintapidiff.cm? lintapidiff.o
349
350
351clean::
352	rm -f "objinfo_helper$(EXE)" "objinfo_helper$(EXE).manifest"
353
354
355# Copy a bytecode executable, stripping debug info
356
357stripdebug=../compilerlibs/ocamlcommon.cma \
358           ../compilerlibs/ocamlbytecomp.cma \
359           stripdebug.cmo
360
361$(call byte_and_opt,stripdebug,$(stripdebug),)
362
363# Compare two bytecode executables
364
365CMPBYT=../compilerlibs/ocamlcommon.cma \
366       ../compilerlibs/ocamlbytecomp.cma \
367       cmpbyt.cmo
368
369$(call byte_and_opt,cmpbyt,$(CMPBYT),)
370
371ifeq "$(RUNTIMEI)" "true"
372install::
373	cp ocaml-instr-graph ocaml-instr-report "$(INSTALL_BINDIR)/"
374endif
375
376# Common stuff
377
378.SUFFIXES:
379
380%.cmo: %.ml
381	$(CAMLC) -c $(COMPFLAGS) - $<
382
383%.cmi: %.mli
384	$(CAMLC) -c $(COMPFLAGS) - $<
385
386%.cmx: %.ml
387	$(CAMLOPT) $(COMPFLAGS) -c - $<
388
389clean::
390	rm -f *.cmo *.cmi *.cma *.dll *.so *.lib *.a
391
392depend: beforedepend
393	$(CAMLRUN) ./ocamldep -slash $(INCLUDES) *.mli *.ml > .depend
394
395.PHONY: clean install beforedepend depend
396
397include .depend
398