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