forked from ocaml/ocaml
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Makefile.common
443 lines (366 loc) · 15 KB
/
Makefile.common
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
#**************************************************************************
#* *
#* OCaml *
#* *
#* Gabriel Scherer, projet Parsifal, INRIA Saclay *
#* *
#* Copyright 2018 Institut National de Recherche en Informatique et *
#* en Automatique. *
#* *
#* All rights reserved. This file is distributed under the terms of *
#* the GNU Lesser General Public License version 2.1, with the *
#* special exception on linking described in the file LICENSE. *
#* *
#**************************************************************************
# This makefile contains common definitions and rules shared by
# other Makefiles
include $(ROOTDIR)/Makefile.config_if_required
# %(DEPDIR) must be kept in sync with entries in .gitignore
DEPDIR=.dep
D=d
MKDIR=mkdir -p
# $(EMPTY) is defined in Makefile.config, but may not have been loaded
EMPTY :=
# $(SPACE) contains a single space
SPACE := $(EMPTY) $(EMPTY)
# $( ) suppresses warning from the alignments in the V_ macros below
$(SPACE) :=
ifeq "$(UNIX_OR_WIN32)" "win32"
DIR_SEP := \$ # There must a space following the $
CONVERT_PATH = $(subst /,$(DIR_SEP),$(strip $(1)))
else
DIR_SEP = /
CONVERT_PATH = $(strip $(1))
endif
V ?= 0
ifeq "$(V)" "0"
V_CC = @$(info $ CC $@)
V_CCDEPS = @$(info $ CCDEPS $@)
V_OCAMLC = @$(info $ OCAMLC $@)
V_OCAMLOPT = @$(info $ OCAMLOPT $@)
V_GEN = @$(info $ GEN $@)
V_LINKC = @$(info $ LINKC $@)
V_LINKOPT = @$(info $ LINKOPT $@)
V_MKEXE = @$(info $ MKEXE $@)
V_MKLIB = @$(info $ MKLIB $@)
V_MKDLL = @$(info $ MKDLL $@)
V_OCAMLLEX = @$(info $ OCAMLLEX $@)
V_OCAMLYACC = @$(info $ OCAMLYACC $@)
V_OCAMLDEP = @$(info $ OCAMLDEP $@)
V_ASM = @$(info $ ASM $@)
V_OCAMLMKLIB = @$(info $ OCAMLMKLIB $@)
V_OCAMLDOC = @$(info $ OCAMLDOC $@)
V_ODOC = @$(info $ ODOC $@)
else
V_CC =
V_CCDEPS =
V_OCAMLC =
V_OCAMLOPT =
V_GEN =
V_LINKC =
V_LINKOPT =
V_MKEXE =
V_MKLIB =
V_MKDLL =
V_OCAMLLEX =
V_OCAMLYACC =
V_OCAMLDEP =
V_ASM =
V_OCAMLMKLIB =
V_OCAMLDOC =
V_ODOC =
endif
DESTDIR ?=
INSTALL_BINDIR := $(DESTDIR)$(BINDIR)
INSTALL_LIBDIR := $(DESTDIR)$(LIBDIR)
INSTALL_INCDIR=$(INSTALL_LIBDIR)/caml
INSTALL_STUBLIBDIR := $(DESTDIR)$(STUBLIBDIR)
INSTALL_LIBDIR_PROFILING = $(INSTALL_LIBDIR)/profiling
INSTALL_MANDIR := $(DESTDIR)$(MANDIR)
INSTALL_PROGRAMS_MAN_DIR := $(DESTDIR)$(PROGRAMS_MAN_DIR)
INSTALL_LIBRARIES_MAN_DIR := $(DESTDIR)$(LIBRARIES_MAN_DIR)
INSTALL_DOCDIR := $(DESTDIR)$(DOCDIR)
FLEXDLL_SUBMODULE_PRESENT := $(wildcard $(ROOTDIR)/flexdll/Makefile)
IN_COREBOOT_CYCLE ?= false
# Variables used to represent the OCaml runtime system
# Most of the time, boot/ocamlrun and runtime/ocamlrun are the same.
# However, under some circumstances it is important to be able to
# distinguish one from the other, hence these two variables.
# Boot/ocamlrun is the most frequently used in the build system, so
# we use OCAMLRUN to designate it and keep NEW_OCAMLRUN to refer
# to runtime/ocamlrun, because it's less frequently used.
OCAMLRUN ?= $(ROOTDIR)/boot/ocamlrun$(EXE)
NEW_OCAMLRUN ?= $(ROOTDIR)/runtime/ocamlrun$(EXE)
# Standard library flags
STDLIBFLAGS ?= -nostdlib -I $(ROOTDIR)/stdlib
BOOT_STDLIBFLAGS ?= -nostdlib -I $(ROOTDIR)/boot
TEST_BOOT_OCAMLC_OPT = $(shell \
test $(ROOTDIR)/boot/ocamlc.opt -nt $(ROOTDIR)/boot/ocamlc; \
echo $$?)
# Use boot/ocamlc.opt if available
ifeq "$(TEST_BOOT_OCAMLC_OPT)" "0"
BOOT_OCAMLC = $(ROOTDIR)/boot/ocamlc.opt
else
BOOT_OCAMLC = $(OCAMLRUN) $(ROOTDIR)/boot/ocamlc
endif
BOOT_OCAMLDEP = $(BOOT_OCAMLC) -depend
# Takes an implicit path and converts it to a path expression which returns to
# the current directory. e.g. $(call ROOT_FROM, foo/bar/) expands to ../..
REMOVE_SLASH = $(strip $(patsubst %/,%, $(1)))
ROOT_FROM = \
$(subst $(SPACE),/,$(patsubst %,..,$(subst /, ,$(call REMOVE_SLASH, $(1)))))
BYTE_BUILD_TREE = byte
OPT_BUILD_TREE = opt
BYTE_BINDIR = $(BYTE_BUILD_TREE)/bin
OPT_BINDIR = $(OPT_BUILD_TREE)/bin
ifeq "$(BOOTSTRAPPING_FLEXDLL)" "true"
override REAL_ROOT_DIR := $(realpath $(ROOTDIR))
ifeq "$(filter $(REAL_ROOT_DIR)/$(BYTE_BINDIR), $(subst :, ,$(PATH)))" ""
export PATH := \
$(REAL_ROOT_DIR)/$(OPT_BINDIR):$(REAL_ROOT_DIR)/$(BYTE_BINDIR):$(PATH)
endif
undefine REAL_ROOT_DIR
endif
# List of other libraries
ALL_OTHERLIBS = dynlink str systhreads unix runtime_events
# Flags to pass to the C preprocessor when preprocessing assembly files
OC_ASPPFLAGS=$(OC_CPPFLAGS) $(OC_NATIVE_CPPFLAGS)
OPTCOMPFLAGS=
ifeq "$(FUNCTION_SECTIONS)" "true"
OPTCOMPFLAGS += -function-sections
endif
# The rule to compile C files
# This rule is similar to GNU make's implicit rule, except that it is more
# general (it supports both .o and .obj)
ifeq "$(COMPUTE_DEPS)" "true"
RUNTIME_HEADERS :=
REQUIRED_HEADERS :=
else
RUNTIME_HEADERS := $(wildcard $(ROOTDIR)/runtime/caml/*.tbl) \
$(wildcard $(ROOTDIR)/runtime/caml/*.h)
REQUIRED_HEADERS := $(RUNTIME_HEADERS) $(wildcard *.h)
endif
%.$(O): %.c $(REQUIRED_HEADERS)
$(V_CC)$(CC) -c $(OC_CFLAGS) $(CFLAGS) $(OC_CPPFLAGS) $(CPPFLAGS) \
$(OUTPUTOBJ)$@ $<
$(DEPDIR):
$(MKDIR) $@
# When executable files have an extension (e.g. ".exe"),
# provide phony synonyms
define PROGRAM_SYNONYM
ifneq ($(EXE),)
.PHONY: $(1)
$(1): $(1)$(EXE)
endif
endef # PROGRAM_SYNONYM
# Definitions related to ocamldep
# Default value for OCAMLDEP
# In those directories where this needs to be overridden, the overriding
# should take place *before* Makefile.common is included.
OCAMLDEP ?= $(BEST_OCAMLDEP)
OCAMLDEPFLAGS ?=
OC_OCAMLDEPFLAGS = -slash
OC_OCAMLDEPDIRS =
OCAMLDEP_CMD = $(OCAMLDEP) $(OC_OCAMLDEPFLAGS) \
$(addprefix -I ,$(OC_OCAMLDEPDIRS)) $(OCAMLDEPFLAGS)
# Lexer generation
BOOT_OCAMLLEX ?= $(OCAMLRUN) $(ROOTDIR)/boot/ocamllex
# Default value for OCAMLLEX
# In those directories where this needs to be overridden, the overriding
# should take place *before* Makefile.common is included.
OCAMLLEX ?= $(BEST_OCAMLLEX)
OCAMLLEXFLAGS ?= -q
%.ml: %.mll
$(V_OCAMLLEX)$(OCAMLLEX) $(OCAMLLEXFLAGS) $<
# Parser generation
OCAMLYACC ?= $(ROOTDIR)/yacc/ocamlyacc$(EXE)
OCAMLYACCFLAGS ?= --strict -v
%.ml %.mli: %.mly
$(V_OCAMLYACC)$(OCAMLYACC) $(OCAMLYACCFLAGS) $<
SAK = $(ROOTDIR)/runtime/sak$(EXE)
# Used with the Microsoft toolchain to merge generated manifest files into
# executables
if_file_exists = ( test ! -f $(1) || $(2) && rm -f $(1) )
MERGEMANIFESTEXE = $(call if_file_exists, $(1).manifest, \
mt -nologo -outputresource:$(1) -manifest $(1).manifest)
# Macros and rules to compile OCaml programs and libraries
# The following variable is used to accumulate a list of all the CMX
# files that get built. Is is then used in the root Makefile to express
# the dependency on all these files on the native compiler, so that
# they get rebuilt if the native compiler is updated
ALL_CMX_FILES =
# We use secondary expansion here so that variables like
# foo_LIBRARIES and foo_SOURCES can be defined after the calls
# to the macros below. Without secondary expansion, those variables
# would have to be defined before the calls to OCAML_BYTECODE_PROGRAM etc.
.SECONDEXPANSION:
# Definitions that are common to both programs and libraries
define _OCAML_COMMON_BASE
$(basename $(notdir $(1)))_C_FILES = \
$$(filter %.c, $$($(basename $(notdir $(1)))_SOURCES))
$(basename $(notdir $(1)))_MLI_FILES = \
$$(filter %.mli, \
$$(subst .mly,.mli,\
$$($(basename $(notdir $(1)))_SOURCES)))
$(basename $(notdir $(1)))_CMI_FILES = \
$$(subst .mli,.cmi,$$($(basename $(notdir $(1)))_MLI_FILES))
$(basename $(notdir $(1)))_ML_FILES = \
$$(filter %.ml, \
$$(subst .ml.in,.ml,$$(subst .mll,.ml,$$(subst .mly,.ml,\
$$($(basename $(notdir $(1)))_SOURCES)))))
$(basename $(notdir $(1)))_MLL_FILES = \
$$(filter %.mll, \
$$($(basename $(notdir $(1)))_SOURCES))
$(basename $(notdir $(1)))_MLY_FILES = \
$$(filter %.mly, \
$$($(basename $(notdir $(1)))_SOURCES))
$(basename $(notdir $(1)))_SECONDARY_FILES = \
$$(patsubst %.mll,%.ml, $$($(basename $(notdir $(1)))_MLL_FILES)) \
$$(patsubst %.mly,%.mli, $$($(basename $(notdir $(1)))_MLY_FILES)) \
$$(patsubst %.mly,%.ml, $$($(basename $(notdir $(1)))_MLY_FILES))
.SECONDARY: $$$$($(basename $(notdir $(1)))_SECONDARY_FILES)
beforedepend:: $$$$($(basename $(notdir $(1)))_SECONDARY_FILES)
$(basename $(notdir $(1)))_GENERATED_FILES = \
$$($(basename $(notdir $(1)))_SECONDARY_FILES) \
$$(patsubst %.mly,%.output, $$($(basename $(notdir $(1)))_MLY_FILES))
endef # _OCAML_COMMON_BASE
# Macros to build OCaml programs
# Each program foo is characterised by the foo_LIBRARIES and foo_SOURCES
# variables. The following macros provide the infrastructure to build foo
# from the object files whose names are derived from these two
# varialbes. In particular, the following macros define several
# variables whose names are prefixed with foo_ to compute the
# different lists of files used to build foo.
# The first macro, _OCAML_PROGRAM_BASE, is a private macro (hence the _ at the
# beginning of its name) which defines foo_ variables common to both
# bytecode and native programs. The next two macros, OCAML_BYTECODE_PROGRAM
# and OCAML_NATIVE_PROGRAM are used to define programs that are provided
# only in bytecode or native form, respectively. Programs provided
# in both forms should use OCAML_PROGRAM.
define _OCAML_PROGRAM_BASE
$(eval $(call _OCAML_COMMON_BASE,$(1)))
endef # _OCAML_PROGRAM_BASE
LINK_BYTECODE_PROGRAM =\
$(CAMLC) $(OC_COMMON_LINKFLAGS) $(OC_BYTECODE_LINKFLAGS)
# The _OCAML_BYTECODE_PROGRAM macro defines a bytecode program but assuming
# that _OCAML_PROGRAM_BASE has already been called. Its public counterpart
# does not rely on this assumption and rather does call _OCAML_PROGRAM_BASE
# itself.
define _OCAML_BYTECODE_PROGRAM
$(eval $(call PROGRAM_SYNONYM,$(1)))
$(basename $(notdir $(1)))_CMA_FILES = \
$$(patsubst %,%.cma, $$($(basename $(notdir $(1)))_LIBRARIES))
$(basename $(notdir $(1)))_BO_FILES = \
$$(patsubst %.c,%.b.$(O), $$($(basename $(notdir $(1)))_C_FILES))
$(basename $(notdir $(1)))_CMO_FILES = \
$$(patsubst %.ml,%.cmo, $$($(basename $(notdir $(1)))_ML_FILES))
$(basename $(notdir $(1)))_BCOBJS = \
$$($(basename $(notdir $(1)))_CMA_FILES) \
$$($(basename $(notdir $(1)))_BO_FILES) \
$$($(basename $(notdir $(1)))_CMO_FILES)
$(1)$(EXE): $$$$($(basename $(notdir $(1)))_BCOBJS)
$$(V_LINKC)$$(LINK_BYTECODE_PROGRAM) -o $$@ \
$$($(basename $(notdir $(1)))_BCOBJS)
endef # _OCAML_BYTECODE_PROGRAM
define OCAML_BYTECODE_PROGRAM
$(eval $(call _OCAML_PROGRAM_BASE,$(1)))
$(eval $(call _OCAML_BYTECODE_PROGRAM,$(1)))
endef # OCAML_BYTECODE_PROGRAM
LINK_NATIVE_PROGRAM =\
$(CAMLOPT) $(OC_COMMON_LINKFLAGS) $(OC_NATIVE_LINKFLAGS)
define _OCAML_NATIVE_PROGRAM
$(eval $(call PROGRAM_SYNONYM,$(1)))
$(basename $(notdir $(1)))_CMXA_FILES = \
$$(patsubst %,%.cmxa, $$($(basename $(notdir $(1)))_LIBRARIES))
$(basename $(notdir $(1)))_NO_FILES = \
$$(patsubst %.c,%.n.$(O), $$($(basename $(notdir $(1)))_C_FILES))
$(basename $(notdir $(1)))_CMX_FILES = \
$$(patsubst %.ml,%.cmx, $$($(basename $(notdir $(1)))_ML_FILES))
ALL_CMX_FILES += $$($(basename $(notdir $(1)))_CMX_FILES)
$(basename $(notdir $(1)))_NCOBJS = \
$$($(basename $(notdir $(1)))_CMXA_FILES) \
$$($(basename $(notdir $(1)))_NO_FILES) \
$$($(basename $(notdir $(1)))_CMX_FILES)
$(1)$(EXE): $$$$($(basename $(notdir $(1)))_NCOBJS)
$$(V_LINKOPT)$$(LINK_NATIVE_PROGRAM) -o $$@ \
$$($(basename $(notdir $(1)))_NCOBJS)
endef # _OCAML_NATIVE_PROGRAM
define OCAML_NATIVE_PROGRAM
$(eval $(call _OCAML_PROGRAM_BASE,$(1)))
$(eval $(call _OCAML_NATIVE_PROGRAM,$(1)))
endef # OCAML_NATIVE_PROGRAM
define OCAML_PROGRAM
$(eval $(call _OCAML_PROGRAM_BASE,$(1)))
$(eval $(call _OCAML_BYTECODE_PROGRAM,$(1)))
$(eval $(call _OCAML_NATIVE_PROGRAM,$(1).opt))
endef # OCAML_PROGRAM
# Macros for OCaml libraries, similar to those for OCaml programs
define _OCAML_LIBRARY_BASE
$(eval $(call _OCAML_COMMON_BASE,$(1)))
endef # _OCAML_LIBRARY_BASE
LINK_BYTECODE_LIBRARY =\
$(CAMLC) $(OC_COMMON_LINKFLAGS) $(OC_BYTECODE_LINKFLAGS)
# The _OCAML_BYTECODE_LIBRARY macro defines a bytecode library but assuming
# that _OCAML_LIBRARY_BASE has already been called. Its public counterpart
# does not rely on this assumption and rather does call _OCAML_LIBRARY_BASE
# itself.
define _OCAML_BYTECODE_LIBRARY
$(basename $(notdir $(1)))_BYTE_CMI_FILES = \
$$(foreach F,$$($(basename $(notdir $(1)))_CMI_FILES),\
$$(if $$(findstring /native/,$$(F)),,$$(F)))
$(basename $(notdir $(1)))_BO_FILES = \
$$(patsubst %.c,%.b.$(O), $$($(basename $(notdir $(1)))_C_FILES))
$(basename $(notdir $(1)))_CMO_FILES = \
$$(patsubst %.ml,%.cmo, \
$$(foreach F,$$($(basename $(notdir $(1)))_ML_FILES),\
$$(if $$(findstring /native/,$$(F)),,$$(F))))
$(basename $(notdir $(1)))_BCOBJS = \
$$($(basename $(notdir $(1)))_BO_FILES) \
$$($(basename $(notdir $(1)))_CMO_FILES)
$(1).cma: \
$$$$($(basename $(notdir $(1)))_BYTE_CMI_FILES) \
$$$$($(basename $(notdir $(1)))_BCOBJS)
$$(V_LINKC)$$(LINK_BYTECODE_LIBRARY) -a -o $$@ \
$$($(basename $(notdir $(1)))_BCOBJS)
endef # _OCAML_BYTECODE_LIBRARY
define OCAML_BYTECODE_LIBRARY
$(eval $(call _OCAML_LIBRARY_BASE,$(1)))
$(eval $(call _OCAML_BYTECODE_LIBRARY,$(1)))
endef # OCAML_BYTECODE_LIBRARY
LINK_NATIVE_LIBRARY =\
$(CAMLOPT) $(OC_COMMON_LINKFLAGS) $(OC_NATIVE_LINKFLAGS)
define _OCAML_NATIVE_LIBRARY
$(basename $(notdir $(1)))_NATIVE_CMI_FILES = \
$$(foreach F,$$($(basename $(notdir $(1)))_CMI_FILES),\
$$(if $$(findstring /byte/,$$(F)),,$$(F)))
$(basename $(notdir $(1)))_NO_FILES = \
$$(patsubst %.c,%.n.$(O), $$($(basename $(notdir $(1)))_C_FILES))
$(basename $(notdir $(1)))_CMX_FILES = \
$$(patsubst %.ml,%.cmx, \
$$(foreach F,$$($(basename $(notdir $(1)))_ML_FILES),\
$$(if $$(findstring /byte/,$$(F)),,$$(F))))
ALL_CMX_FILES += $$($(basename $(notdir $(1)))_CMX_FILES)
$(basename $(notdir $(1)))_NCOBJS = \
$$($(basename $(notdir $(1)))_NO_FILES) \
$$($(basename $(notdir $(1)))_CMX_FILES)
$(1).cmxa: \
$$$$($(basename $(notdir $(1)))_NATIVE_CMI_FILES) \
$$$$($(basename $(notdir $(1)))_NCOBJS)
$$(V_LINKOPT)$$(LINK_NATIVE_LIBRARY) -a -o $$@ \
$$($(basename $(notdir $(1)))_NCOBJS)
endef # _OCAML_NATIVE_LIBRARY
define OCAML_NATIVE_LIBRARY
$(eval $(call _OCAML_LIBRARY_BASE,$(1)))
$(eval $(call _OCAML_NATIVE_LIBRARY,$(1)))
endef # OCAML_NATIVE_LIBRARY
define OCAML_LIBRARY
$(eval $(call _OCAML_LIBRARY_BASE,$(1)))
$(eval $(call _OCAML_BYTECODE_LIBRARY,$(1)))
$(eval $(call _OCAML_NATIVE_LIBRARY,$(1)))
endef # OCAML_LIBRARY
# Installing a bytecode executable, with debug information removed
define INSTALL_STRIPPED_BYTE_PROG
$(OCAMLRUN) $(ROOTDIR)/tools/stripdebug $(1) $(1).tmp \
&& $(INSTALL_PROG) $(1).tmp $(2) \
&& rm $(1).tmp
endef # INSTALL_STRIPPED_BYTE_PROG