2016-02-18 07:11:59 -08:00
|
|
|
#**************************************************************************
|
|
|
|
#* *
|
|
|
|
#* OCaml *
|
|
|
|
#* *
|
|
|
|
#* Xavier Leroy, projet Cristal, INRIA Rocquencourt *
|
|
|
|
#* *
|
|
|
|
#* Copyright 1999 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. *
|
|
|
|
#* *
|
|
|
|
#**************************************************************************
|
1999-11-17 10:59:06 -08:00
|
|
|
|
2016-09-16 00:35:29 -07:00
|
|
|
MAKEFLAGS := -r -R
|
2018-07-27 03:35:09 -07:00
|
|
|
ROOTDIR = ..
|
2018-07-26 08:27:00 -07:00
|
|
|
|
2020-04-17 05:53:49 -07:00
|
|
|
include $(ROOTDIR)/Makefile.common
|
2016-09-16 00:35:29 -07:00
|
|
|
|
|
|
|
ifeq ($(SYSTEM),unix)
|
|
|
|
override define shellquote
|
|
|
|
$i := $$(subst ",\",$$(subst $$$$,\$$$$,$$(subst `,\`,$i)))#")#
|
|
|
|
endef
|
2018-03-29 05:38:33 -07:00
|
|
|
$(foreach i,BINDIR LIBDIR STUBLIBDIR MANDIR,$(eval $(shellquote)))
|
2016-09-16 00:35:29 -07:00
|
|
|
endif
|
|
|
|
|
|
|
|
DESTDIR ?=
|
|
|
|
# Setup GNU make variables storing per-target source and target,
|
|
|
|
# a list of installed tools, and a function to quote a filename for
|
|
|
|
# the shell.
|
2020-05-11 08:50:29 -07:00
|
|
|
override installed_tools := ocamldep ocamlprof ocamlcp ocamloptp \
|
2016-09-16 00:35:29 -07:00
|
|
|
ocamlmktop ocamlmklib ocamlobjinfo
|
|
|
|
|
|
|
|
install_files :=
|
|
|
|
define byte2native
|
|
|
|
$(patsubst %.cmo,%.cmx,$(patsubst %.cma,%.cmxa,$1))
|
|
|
|
endef
|
|
|
|
|
|
|
|
# $1 = target, $2 = OCaml object dependencies, $3 = other dependencies
|
|
|
|
# There is a lot of subtle code here. The multiple layers of expansion
|
|
|
|
# are due to `make`'s eval() function, which evaluates the string
|
|
|
|
# passed to it as a makefile fragment. So it is crucial that variables
|
|
|
|
# not get expanded too many times.
|
|
|
|
define byte_and_opt_
|
|
|
|
# This check is defensive programming
|
|
|
|
$(and $(filter-out 1,$(words $1)),$(error \
|
|
|
|
cannot build file with whitespace in name))
|
2020-06-17 00:29:56 -07:00
|
|
|
$(call PROGRAM_SYNONYM, $1)
|
|
|
|
|
|
|
|
$1$(EXE): $3 $2
|
2018-07-26 08:27:00 -07:00
|
|
|
$$(CAMLC) $$(LINKFLAGS) -I $$(ROOTDIR) -o $$@ $2
|
2016-09-16 00:35:29 -07:00
|
|
|
|
2020-06-17 00:29:56 -07:00
|
|
|
$(call PROGRAM_SYNONYM, $1.opt)
|
|
|
|
|
|
|
|
$1.opt$(EXE): $3 $$(call byte2native,$2)
|
2018-09-06 07:12:42 -07:00
|
|
|
$$(CAMLOPT_CMD) $$(LINKFLAGS) -I $$(ROOTDIR) -o $$@ \
|
|
|
|
$$(call byte2native,$2)
|
2016-09-16 00:35:29 -07:00
|
|
|
|
|
|
|
all: $1
|
|
|
|
|
|
|
|
opt.opt: $1.opt
|
|
|
|
|
|
|
|
ifeq '$(filter $(installed_tools),$1)' '$1'
|
|
|
|
install_files += $1
|
|
|
|
endif
|
|
|
|
clean::
|
2020-06-17 00:29:56 -07:00
|
|
|
rm -f -- $1 $1.opt $1.exe $1.opt.exe
|
2016-09-16 00:35:29 -07:00
|
|
|
|
|
|
|
endef
|
|
|
|
|
|
|
|
# Escape any $ characters in the arguments and eval the result.
|
|
|
|
define byte_and_opt
|
|
|
|
$(eval $(call \
|
|
|
|
byte_and_opt_,$(subst $$,$$$$,$1),$(subst $$,$$$$,$2),$(subst $$,$$$$,$3)))
|
|
|
|
endef
|
|
|
|
|
2019-03-18 03:45:43 -07:00
|
|
|
CAMLC = $(BOOT_OCAMLC) -g -nostdlib -I $(ROOTDIR)/boot \
|
2018-07-27 03:35:09 -07:00
|
|
|
-use-prims $(ROOTDIR)/runtime/primitives -I $(ROOTDIR)
|
2020-06-17 00:29:56 -07:00
|
|
|
CAMLOPT = $(CAMLRUN) $(ROOTDIR)/ocamlopt$(EXE) -g -nostdlib -I $(ROOTDIR)/stdlib
|
2018-07-27 03:35:09 -07:00
|
|
|
CAMLLEX = $(CAMLRUN) $(ROOTDIR)/boot/ocamllex
|
2019-04-01 09:18:47 -07:00
|
|
|
INCLUDES = $(addprefix -I $(ROOTDIR)/,utils parsing typing bytecomp \
|
|
|
|
middle_end middle_end/closure middle_end/flambda \
|
|
|
|
middle_end/flambda/base_types driver toplevel \
|
|
|
|
file_formats lambda)
|
2018-07-27 03:35:09 -07:00
|
|
|
COMPFLAGS = -absname -w +a-4-9-41-42-44-45-48 -strict-sequence -warn-error A \
|
2019-09-30 12:14:06 -07:00
|
|
|
-principal -safe-string -strict-formats -bin-annot $(INCLUDES)
|
2018-07-27 03:35:09 -07:00
|
|
|
LINKFLAGS = $(INCLUDES)
|
2016-09-16 00:35:29 -07:00
|
|
|
VPATH := $(filter-out -I,$(INCLUDES))
|
|
|
|
|
2018-06-03 00:04:48 -07:00
|
|
|
.PHONY: all allopt opt.opt # allopt and opt.opt are synonyms
|
|
|
|
allopt: opt.opt
|
2016-09-16 00:35:29 -07:00
|
|
|
|
|
|
|
# The dependency generator
|
|
|
|
|
|
|
|
CAMLDEP_OBJ=ocamldep.cmo
|
2017-03-02 07:45:58 -08:00
|
|
|
CAMLDEP_IMPORTS= \
|
2018-07-26 08:27:00 -07:00
|
|
|
$(ROOTDIR)/compilerlibs/ocamlcommon.cma \
|
|
|
|
$(ROOTDIR)/compilerlibs/ocamlbytecomp.cma
|
2020-06-17 00:29:56 -07:00
|
|
|
ocamldep$(EXE): LINKFLAGS += -compat-32
|
2016-09-16 00:35:29 -07:00
|
|
|
$(call byte_and_opt,ocamldep,$(CAMLDEP_IMPORTS) $(CAMLDEP_OBJ),)
|
2020-06-17 00:29:56 -07:00
|
|
|
ocamldep$(EXE): depend.cmi
|
|
|
|
ocamldep.opt$(EXE): depend.cmi
|
2016-09-16 00:35:29 -07:00
|
|
|
|
|
|
|
clean::
|
2020-06-18 02:13:12 -07:00
|
|
|
rm -f ocamldep ocamldep.exe ocamldep.opt ocamldep.opt.exe
|
2016-09-16 00:35:29 -07:00
|
|
|
|
|
|
|
# The profiler
|
|
|
|
|
|
|
|
CSLPROF=ocamlprof.cmo
|
2018-07-27 03:25:23 -07:00
|
|
|
CSLPROF_IMPORTS=config.cmo build_path_prefix_map.cmo misc.cmo identifiable.cmo \
|
|
|
|
numbers.cmo arg_helper.cmo clflags.cmo terminfo.cmo \
|
2016-09-16 00:35:29 -07:00
|
|
|
warnings.cmo location.cmo longident.cmo docstrings.cmo \
|
2017-05-23 08:04:49 -07:00
|
|
|
syntaxerr.cmo ast_helper.cmo \
|
2018-08-25 05:46:51 -07:00
|
|
|
camlinternalMenhirLib.cmo parser.cmo \
|
2018-11-05 08:37:21 -08:00
|
|
|
pprintast.cmo \
|
2017-05-23 08:04:49 -07:00
|
|
|
lexer.cmo parse.cmo
|
2016-09-16 00:35:29 -07:00
|
|
|
|
|
|
|
$(call byte_and_opt,ocamlprof,$(CSLPROF_IMPORTS) profiling.cmo $(CSLPROF),)
|
|
|
|
|
2018-07-27 03:25:23 -07:00
|
|
|
ocamlcp_cmos = config.cmo build_path_prefix_map.cmo misc.cmo profile.cmo \
|
|
|
|
warnings.cmo identifiable.cmo numbers.cmo arg_helper.cmo \
|
2019-09-27 03:16:09 -07:00
|
|
|
clflags.cmo \
|
|
|
|
terminfo.cmo location.cmo load_path.cmo ccomp.cmo compenv.cmo \
|
|
|
|
main_args.cmo
|
2016-09-16 00:35:29 -07:00
|
|
|
|
|
|
|
$(call byte_and_opt,ocamlcp,$(ocamlcp_cmos) ocamlcp.cmo,)
|
2020-05-11 08:50:29 -07:00
|
|
|
$(call byte_and_opt,ocamloptp,$(ocamlcp_cmos) ocamloptp.cmo,)
|
2016-09-16 00:35:29 -07:00
|
|
|
|
|
|
|
opt:: profiling.cmx
|
|
|
|
|
|
|
|
install::
|
2018-03-29 05:24:51 -07:00
|
|
|
$(INSTALL_DATA) \
|
2018-05-14 00:15:44 -07:00
|
|
|
profiling.cmi profiling.cmo \
|
makefiles: use 'install' instead of 'cp' in 'make install' targets
I can observe weird performance bottlenecks on my machine caused by
the use of 'cp' in the 'install' scripts of OCaml. When installing
into a directory that is already populated by an existing
installation, 'make install' can routinely take 10s on my machine¹. After this
change it reliably takes 1.5s, independently of whether the
destination is already populated or not.
¹: a brtfs filesystem on an old-ish SSD
Why I care
----------
An extra 10s delay due to 'make install' can be noticeable in tight
change-build-install-test feedback loops for a compiler change where
we change the compiler, have a fast 'make world.opt' due to
incremental builds, install the change and test it -- possibly after
installing a couple opam packages, which can be fairly quick.
Partial diagnosis
-----------------
The performance issue seems to be caused by the fact that 'cp' (at
least the GNU coreutils version), when the file already exists,
replaces it by opening it in writeonly+truncate mode and writing the
file content ('strace' shows that the delay is caused within an
'openat' call). In particular, using the --remove-destination option
(which changes 'cp' to just remove the destination file before
copying) removes the performance issue, but this option seems missing
from the BSD/OSX 'cp' so it could cause portability issue.
Change
------
The present commit rewrites the 'install' targets of all Makefiles to
use the 'install' command instead. 'install' by default gives
executable-like permission to the destination file, instead of reusing
the source file's permissions, so we specify manually the permission
modes, depending on whether the installed file is an executable (or
dynamically-linked library) or just data (including other compiled
object files).
Testing
-------
I checked manually that the permissions of the installed files are
identical to the ones of the current 'cp'-using targets, except for
some '.mli' file in middle_end which currently have +x bits enabled
for no good reason.
Remark: To test this, playing with the DESTDIR variable is very useful
(this lets you install to a new directory (or the same as before)
without having to re-run the configure script). I used the following,
fairly slow shell script to collect permissions:
for f in $(find $DESTDIR); do \
echo $(basename $f) $(ls -l $f | cut -d' ' -f1); \
done | sort
Remark: it is important to run `sync` in-between 'make install' runs
to avoid timing effects due to filesystem or disk caching
strategies. I believe that this corresponds to the natural time delay
(and unrelated disk activity) that would occur in realistic
change-install-test feedback loops.
2018-03-28 08:46:34 -07:00
|
|
|
"$(INSTALL_LIBDIR)"
|
2018-05-14 00:15:44 -07:00
|
|
|
ifeq "$(INSTALL_SOURCE_ARTIFACTS)" "true"
|
|
|
|
$(INSTALL_DATA) \
|
|
|
|
profiling.cmt profiling.cmti \
|
|
|
|
"$(INSTALL_LIBDIR)"
|
|
|
|
endif
|
2016-09-16 00:35:29 -07:00
|
|
|
|
|
|
|
installopt::
|
2018-03-29 05:24:51 -07:00
|
|
|
$(INSTALL_DATA) \
|
makefiles: use 'install' instead of 'cp' in 'make install' targets
I can observe weird performance bottlenecks on my machine caused by
the use of 'cp' in the 'install' scripts of OCaml. When installing
into a directory that is already populated by an existing
installation, 'make install' can routinely take 10s on my machine¹. After this
change it reliably takes 1.5s, independently of whether the
destination is already populated or not.
¹: a brtfs filesystem on an old-ish SSD
Why I care
----------
An extra 10s delay due to 'make install' can be noticeable in tight
change-build-install-test feedback loops for a compiler change where
we change the compiler, have a fast 'make world.opt' due to
incremental builds, install the change and test it -- possibly after
installing a couple opam packages, which can be fairly quick.
Partial diagnosis
-----------------
The performance issue seems to be caused by the fact that 'cp' (at
least the GNU coreutils version), when the file already exists,
replaces it by opening it in writeonly+truncate mode and writing the
file content ('strace' shows that the delay is caused within an
'openat' call). In particular, using the --remove-destination option
(which changes 'cp' to just remove the destination file before
copying) removes the performance issue, but this option seems missing
from the BSD/OSX 'cp' so it could cause portability issue.
Change
------
The present commit rewrites the 'install' targets of all Makefiles to
use the 'install' command instead. 'install' by default gives
executable-like permission to the destination file, instead of reusing
the source file's permissions, so we specify manually the permission
modes, depending on whether the installed file is an executable (or
dynamically-linked library) or just data (including other compiled
object files).
Testing
-------
I checked manually that the permissions of the installed files are
identical to the ones of the current 'cp'-using targets, except for
some '.mli' file in middle_end which currently have +x bits enabled
for no good reason.
Remark: To test this, playing with the DESTDIR variable is very useful
(this lets you install to a new directory (or the same as before)
without having to re-run the configure script). I used the following,
fairly slow shell script to collect permissions:
for f in $(find $DESTDIR); do \
echo $(basename $f) $(ls -l $f | cut -d' ' -f1); \
done | sort
Remark: it is important to run `sync` in-between 'make install' runs
to avoid timing effects due to filesystem or disk caching
strategies. I believe that this corresponds to the natural time delay
(and unrelated disk activity) that would occur in realistic
change-install-test feedback loops.
2018-03-28 08:46:34 -07:00
|
|
|
profiling.cmx profiling.$(O) \
|
|
|
|
"$(INSTALL_LIBDIR)"
|
2016-09-16 00:35:29 -07:00
|
|
|
|
|
|
|
# To help building mixed-mode libraries (OCaml + C)
|
|
|
|
|
2018-07-27 03:25:23 -07:00
|
|
|
$(call byte_and_opt,ocamlmklib,ocamlmklibconfig.cmo config.cmo \
|
|
|
|
build_path_prefix_map.cmo misc.cmo ocamlmklib.cmo,)
|
2016-09-16 00:35:29 -07:00
|
|
|
|
|
|
|
|
2018-09-12 07:32:44 -07:00
|
|
|
ocamlmklibconfig.ml: $(ROOTDIR)/Makefile.config Makefile
|
2016-09-16 00:35:29 -07:00
|
|
|
(echo 'let bindir = "$(BINDIR)"'; \
|
|
|
|
echo 'let supports_shared_libraries = $(SUPPORTS_SHARED_LIBRARIES)';\
|
2017-03-13 08:15:55 -07:00
|
|
|
echo 'let default_rpath = "$(RPATH)"'; \
|
2016-09-16 00:35:29 -07:00
|
|
|
echo 'let mksharedlibrpath = "$(MKSHAREDLIBRPATH)"'; \
|
2018-10-22 04:31:47 -07:00
|
|
|
echo 'let toolpref = "$(TOOLPREF)"';) \
|
2016-09-16 00:35:29 -07:00
|
|
|
> ocamlmklibconfig.ml
|
|
|
|
|
|
|
|
beforedepend:: ocamlmklibconfig.ml
|
|
|
|
|
|
|
|
clean::
|
|
|
|
rm -f ocamlmklibconfig.ml
|
|
|
|
|
|
|
|
# To make custom toplevels
|
|
|
|
|
|
|
|
OCAMLMKTOP=ocamlmktop.cmo
|
2018-07-27 03:25:23 -07:00
|
|
|
OCAMLMKTOP_IMPORTS=config.cmo build_path_prefix_map.cmo misc.cmo \
|
2018-09-18 06:49:18 -07:00
|
|
|
identifiable.cmo numbers.cmo arg_helper.cmo clflags.cmo \
|
2019-08-23 06:20:45 -07:00
|
|
|
load_path.cmo profile.cmo ccomp.cmo
|
2016-09-16 00:35:29 -07:00
|
|
|
|
|
|
|
$(call byte_and_opt,ocamlmktop,$(OCAMLMKTOP_IMPORTS) $(OCAMLMKTOP),)
|
|
|
|
|
|
|
|
# Converter olabl/ocaml 2.99 to ocaml 3
|
|
|
|
|
2018-07-27 03:25:23 -07:00
|
|
|
LIBRARY3=config.cmo build_path_prefix_map.cmo misc.cmo warnings.cmo location.cmo
|
2016-09-16 00:35:29 -07:00
|
|
|
|
|
|
|
ifeq ($(UNIX_OR_WIN32),unix)
|
|
|
|
LN := ln -sf
|
|
|
|
else
|
|
|
|
LN := cp -pf
|
|
|
|
endif
|
|
|
|
|
|
|
|
install::
|
2018-05-14 01:44:01 -07:00
|
|
|
ifeq "$(INSTALL_BYTECODE_PROGRAMS)" "true"
|
2016-09-16 00:35:29 -07:00
|
|
|
for i in $(install_files); \
|
|
|
|
do \
|
2020-06-17 00:29:56 -07:00
|
|
|
$(INSTALL_PROG) "$$i$(EXE)" "$(INSTALL_BINDIR)/$$i.byte$(EXE)"; \
|
|
|
|
if test -f "$$i".opt$(EXE); then \
|
|
|
|
$(INSTALL_PROG) "$$i.opt$(EXE)" \
|
|
|
|
"$(INSTALL_BINDIR)/$$i.opt$(EXE)" && \
|
2016-09-16 00:35:29 -07:00
|
|
|
(cd "$(INSTALL_BINDIR)/" && $(LN) "$$i.opt$(EXE)" "$$i$(EXE)"); \
|
|
|
|
else \
|
|
|
|
(cd "$(INSTALL_BINDIR)/" && $(LN) "$$i.byte$(EXE)" "$$i$(EXE)"); \
|
|
|
|
fi; \
|
|
|
|
done
|
2018-05-14 01:44:01 -07:00
|
|
|
else
|
|
|
|
for i in $(install_files); \
|
|
|
|
do \
|
2020-06-17 00:29:56 -07:00
|
|
|
if test -f "$$i".opt$(EXE); then \
|
|
|
|
$(INSTALL_PROG) "$$i.opt$(EXE)" "$(INSTALL_BINDIR)/$$i.opt$(EXE)"; \
|
2019-08-06 01:23:06 -07:00
|
|
|
(cd "$(INSTALL_BINDIR)/" && $(LN) "$$i.opt$(EXE)" "$$i$(EXE)"); \
|
2018-05-14 01:44:01 -07:00
|
|
|
fi; \
|
|
|
|
done
|
|
|
|
endif
|
2016-09-16 00:35:29 -07:00
|
|
|
|
|
|
|
# The preprocessor for asm generators
|
|
|
|
|
2020-06-17 00:29:56 -07:00
|
|
|
cvt_emit := cvt_emit$(EXE)
|
2016-09-16 00:35:29 -07:00
|
|
|
|
2020-06-17 00:29:56 -07:00
|
|
|
$(eval $(call PROGRAM_SYNONYM,cvt_emit))
|
|
|
|
|
|
|
|
$(cvt_emit): cvt_emit.cmo
|
|
|
|
$(CAMLC) $(LINKFLAGS) -o $@ $^
|
2016-09-16 00:35:29 -07:00
|
|
|
|
|
|
|
clean::
|
2020-06-18 02:13:12 -07:00
|
|
|
rm -f cvt_emit.ml cvt_emit cvt_emit.exe
|
2016-09-16 00:35:29 -07:00
|
|
|
|
|
|
|
beforedepend:: cvt_emit.ml
|
|
|
|
|
|
|
|
# Reading cmt files
|
|
|
|
|
2020-06-17 00:29:56 -07:00
|
|
|
ocamlcmt_objects= \
|
2018-07-26 08:27:00 -07:00
|
|
|
$(ROOTDIR)/compilerlibs/ocamlcommon.cma \
|
|
|
|
$(ROOTDIR)/compilerlibs/ocamlbytecomp.cma \
|
2016-09-16 00:35:29 -07:00
|
|
|
\
|
2020-06-17 00:29:56 -07:00
|
|
|
ocamlcmt.cmo
|
2016-09-16 00:35:29 -07:00
|
|
|
|
|
|
|
# Reading cmt files
|
2020-06-17 00:29:56 -07:00
|
|
|
$(call byte_and_opt,ocamlcmt,$(ocamlcmt_objects),)
|
2016-09-16 00:35:29 -07:00
|
|
|
|
2017-05-11 04:56:19 -07:00
|
|
|
install::
|
2020-06-17 00:29:56 -07:00
|
|
|
if test -f ocamlcmt.opt$(EXE); then \
|
|
|
|
$(INSTALL_PROG)\
|
|
|
|
ocamlcmt.opt$(EXE) "$(INSTALL_BINDIR)/ocamlcmt$(EXE)"; \
|
2017-05-11 04:56:19 -07:00
|
|
|
else \
|
2020-06-17 00:29:56 -07:00
|
|
|
$(INSTALL_PROG) ocamlcmt$(EXE) "$(INSTALL_BINDIR)/ocamlcmt$(EXE)"; \
|
2017-05-11 04:56:19 -07:00
|
|
|
fi
|
|
|
|
|
2016-09-16 00:35:29 -07:00
|
|
|
|
|
|
|
# The bytecode disassembler
|
|
|
|
|
2018-07-23 05:19:41 -07:00
|
|
|
DUMPOBJ= \
|
2018-07-26 08:27:00 -07:00
|
|
|
$(ROOTDIR)/compilerlibs/ocamlcommon.cma \
|
|
|
|
$(ROOTDIR)/compilerlibs/ocamlbytecomp.cma \
|
2018-07-23 05:19:41 -07:00
|
|
|
\
|
|
|
|
opnames.cmo dumpobj.cmo
|
2016-09-16 00:35:29 -07:00
|
|
|
|
2018-07-23 05:19:41 -07:00
|
|
|
$(call byte_and_opt,dumpobj,$(DUMPOBJ),)
|
2016-09-16 00:35:29 -07:00
|
|
|
|
2020-06-17 00:29:56 -07:00
|
|
|
make_opcodes := make_opcodes$(EXE)
|
|
|
|
|
|
|
|
$(eval $(call PROGRAM_SYNONYM,make_opcodes))
|
2016-09-11 08:02:05 -07:00
|
|
|
|
2020-06-17 00:29:56 -07:00
|
|
|
$(make_opcodes): make_opcodes.ml
|
|
|
|
$(CAMLC) $< -o $@
|
|
|
|
|
|
|
|
opnames.ml: $(ROOTDIR)/runtime/caml/instruct.h $(make_opcodes)
|
|
|
|
$(ROOTDIR)/runtime/ocamlrun$(EXE) $(make_opcodes) -opnames < $< > $@
|
2016-09-16 00:35:29 -07:00
|
|
|
|
|
|
|
clean::
|
2020-06-17 00:29:56 -07:00
|
|
|
rm -f opnames.ml make_opcodes make_opcodes.exe make_opcodes.ml
|
2016-09-16 00:35:29 -07:00
|
|
|
|
|
|
|
beforedepend:: opnames.ml
|
|
|
|
|
|
|
|
# Display info on compiled files
|
|
|
|
|
2019-12-17 01:10:14 -08:00
|
|
|
DEF_SYMBOL_PREFIX = '-Dsymbol_prefix=""'
|
|
|
|
|
2016-09-16 00:35:29 -07:00
|
|
|
ifeq "$(SYSTEM)" "macosx"
|
|
|
|
DEF_SYMBOL_PREFIX = '-Dsymbol_prefix="_"'
|
2019-12-17 01:10:14 -08:00
|
|
|
endif
|
|
|
|
|
|
|
|
ifeq "$(SYSTEM)" "cygwin"
|
|
|
|
DEF_SYMBOL_PREFIX = '-Dsymbol_prefix="_"'
|
2016-09-16 00:35:29 -07:00
|
|
|
endif
|
|
|
|
|
2019-09-11 00:16:15 -07:00
|
|
|
objinfo_helper$(EXE): objinfo_helper.$(O)
|
2019-09-17 08:47:14 -07:00
|
|
|
$(CC) $(BFD_LDFLAGS) $(OC_CFLAGS) $(OUTPUTEXE)$@ $< $(BFD_LDLIBS)
|
2019-09-11 00:16:15 -07:00
|
|
|
|
|
|
|
objinfo_helper.$(O): $(ROOTDIR)/runtime/caml/s.h
|
|
|
|
|
|
|
|
objinfo_helper.$(O): \
|
2019-09-17 07:16:03 -07:00
|
|
|
OC_CPPFLAGS += -I$(ROOTDIR)/runtime $(DEF_SYMBOL_PREFIX) $(BFD_CPPFLAGS)
|
2016-09-16 00:35:29 -07:00
|
|
|
|
2018-07-26 08:27:00 -07:00
|
|
|
OBJINFO=$(ROOTDIR)/compilerlibs/ocamlcommon.cma \
|
|
|
|
$(ROOTDIR)/compilerlibs/ocamlbytecomp.cma \
|
|
|
|
$(ROOTDIR)/compilerlibs/ocamlmiddleend.cma \
|
2016-09-16 00:35:29 -07:00
|
|
|
objinfo.cmo
|
|
|
|
|
|
|
|
$(call byte_and_opt,ocamlobjinfo,$(OBJINFO),objinfo_helper$(EXE))
|
|
|
|
|
|
|
|
install::
|
2018-03-29 05:24:51 -07:00
|
|
|
$(INSTALL_PROG) \
|
makefiles: use 'install' instead of 'cp' in 'make install' targets
I can observe weird performance bottlenecks on my machine caused by
the use of 'cp' in the 'install' scripts of OCaml. When installing
into a directory that is already populated by an existing
installation, 'make install' can routinely take 10s on my machine¹. After this
change it reliably takes 1.5s, independently of whether the
destination is already populated or not.
¹: a brtfs filesystem on an old-ish SSD
Why I care
----------
An extra 10s delay due to 'make install' can be noticeable in tight
change-build-install-test feedback loops for a compiler change where
we change the compiler, have a fast 'make world.opt' due to
incremental builds, install the change and test it -- possibly after
installing a couple opam packages, which can be fairly quick.
Partial diagnosis
-----------------
The performance issue seems to be caused by the fact that 'cp' (at
least the GNU coreutils version), when the file already exists,
replaces it by opening it in writeonly+truncate mode and writing the
file content ('strace' shows that the delay is caused within an
'openat' call). In particular, using the --remove-destination option
(which changes 'cp' to just remove the destination file before
copying) removes the performance issue, but this option seems missing
from the BSD/OSX 'cp' so it could cause portability issue.
Change
------
The present commit rewrites the 'install' targets of all Makefiles to
use the 'install' command instead. 'install' by default gives
executable-like permission to the destination file, instead of reusing
the source file's permissions, so we specify manually the permission
modes, depending on whether the installed file is an executable (or
dynamically-linked library) or just data (including other compiled
object files).
Testing
-------
I checked manually that the permissions of the installed files are
identical to the ones of the current 'cp'-using targets, except for
some '.mli' file in middle_end which currently have +x bits enabled
for no good reason.
Remark: To test this, playing with the DESTDIR variable is very useful
(this lets you install to a new directory (or the same as before)
without having to re-run the configure script). I used the following,
fairly slow shell script to collect permissions:
for f in $(find $DESTDIR); do \
echo $(basename $f) $(ls -l $f | cut -d' ' -f1); \
done | sort
Remark: it is important to run `sync` in-between 'make install' runs
to avoid timing effects due to filesystem or disk caching
strategies. I believe that this corresponds to the natural time delay
(and unrelated disk activity) that would occur in realistic
change-install-test feedback loops.
2018-03-28 08:46:34 -07:00
|
|
|
objinfo_helper$(EXE) "$(INSTALL_LIBDIR)/objinfo_helper$(EXE)"
|
2016-09-16 00:35:29 -07:00
|
|
|
|
2018-07-26 08:27:00 -07:00
|
|
|
primreq=$(ROOTDIR)/compilerlibs/ocamlcommon.cma \
|
|
|
|
$(ROOTDIR)/compilerlibs/ocamlbytecomp.cma \
|
2018-07-23 05:19:41 -07:00
|
|
|
primreq.cmo
|
|
|
|
|
2016-09-16 00:35:29 -07:00
|
|
|
# Scan object files for required primitives
|
2018-07-23 05:19:41 -07:00
|
|
|
$(call byte_and_opt,primreq,$(primreq),)
|
2016-09-16 00:35:29 -07:00
|
|
|
|
2018-07-26 08:27:00 -07:00
|
|
|
LINTAPIDIFF=$(ROOTDIR)/compilerlibs/ocamlcommon.cmxa \
|
|
|
|
$(ROOTDIR)/compilerlibs/ocamlbytecomp.cmxa \
|
|
|
|
$(ROOTDIR)/compilerlibs/ocamlmiddleend.cmxa \
|
|
|
|
$(ROOTDIR)/otherlibs/str/str.cmxa \
|
2016-12-08 14:57:31 -08:00
|
|
|
lintapidiff.cmx
|
|
|
|
|
2020-06-17 00:29:56 -07:00
|
|
|
lintapidiff.opt$(EXE): INCLUDES+= -I $(ROOTDIR)/otherlibs/str
|
|
|
|
lintapidiff.opt$(EXE): $(LINTAPIDIFF)
|
2018-09-06 07:12:42 -07:00
|
|
|
$(CAMLOPT_CMD) $(LINKFLAGS) -I $(ROOTDIR) -o $@ $(LINTAPIDIFF)
|
2016-12-08 14:57:31 -08:00
|
|
|
clean::
|
2020-06-17 00:29:56 -07:00
|
|
|
rm -f -- lintapidiff.opt lintapidiff.opt.exe
|
|
|
|
rm -f lintapidiff.cm? lintapidiff.o lintapidiff.obj
|
2016-12-08 14:57:31 -08:00
|
|
|
|
|
|
|
|
2016-09-16 00:35:29 -07:00
|
|
|
clean::
|
2019-10-15 03:46:36 -07:00
|
|
|
rm -f "objinfo_helper" "objinfo_helper.manifest"
|
|
|
|
rm -f "objinfo_helper.exe" "objinfo_helper.exe.manifest"
|
2016-09-16 00:35:29 -07:00
|
|
|
|
2019-11-15 04:52:35 -08:00
|
|
|
# Eventlog metadata file
|
|
|
|
|
|
|
|
install::
|
|
|
|
$(INSTALL_DATA) \
|
|
|
|
eventlog_metadata \
|
|
|
|
"$(INSTALL_LIBDIR)"
|
2016-09-16 00:35:29 -07:00
|
|
|
|
|
|
|
# Copy a bytecode executable, stripping debug info
|
|
|
|
|
2018-07-26 08:27:00 -07:00
|
|
|
stripdebug=$(ROOTDIR)/compilerlibs/ocamlcommon.cma \
|
|
|
|
$(ROOTDIR)/compilerlibs/ocamlbytecomp.cma \
|
2016-09-16 00:35:29 -07:00
|
|
|
stripdebug.cmo
|
|
|
|
|
|
|
|
$(call byte_and_opt,stripdebug,$(stripdebug),)
|
|
|
|
|
|
|
|
# Compare two bytecode executables
|
|
|
|
|
2018-07-26 08:27:00 -07:00
|
|
|
CMPBYT=$(ROOTDIR)/compilerlibs/ocamlcommon.cma \
|
|
|
|
$(ROOTDIR)/compilerlibs/ocamlbytecomp.cma \
|
2016-09-16 00:35:29 -07:00
|
|
|
cmpbyt.cmo
|
|
|
|
|
|
|
|
$(call byte_and_opt,cmpbyt,$(CMPBYT),)
|
|
|
|
|
2020-06-17 00:29:56 -07:00
|
|
|
caml_tex_files := \
|
|
|
|
$(ROOTDIR)/compilerlibs/ocamlcommon.cma \
|
|
|
|
$(ROOTDIR)/compilerlibs/ocamlbytecomp.cma \
|
|
|
|
$(ROOTDIR)/compilerlibs/ocamltoplevel.cma \
|
|
|
|
$(ROOTDIR)/otherlibs/str/str.cma \
|
|
|
|
$(ROOTDIR)/otherlibs/$(UNIXLIB)/unix.cma \
|
|
|
|
caml_tex.ml
|
2018-07-25 01:38:08 -07:00
|
|
|
|
|
|
|
#Scan latex files, and run ocaml code examples
|
|
|
|
|
2020-06-17 00:29:56 -07:00
|
|
|
caml_tex := caml-tex$(EXE)
|
|
|
|
|
|
|
|
$(caml_tex): INCLUDES += $(addprefix -I $(ROOTDIR)/otherlibs/,str $(UNIXLIB))
|
|
|
|
$(caml_tex): $(caml_tex_files)
|
|
|
|
$(ROOTDIR)/runtime/ocamlrun$(EXE) $(ROOTDIR)/ocamlc$(EXE) -nostdlib \
|
2018-07-26 08:27:00 -07:00
|
|
|
-I $(ROOTDIR)/stdlib $(LINKFLAGS) -linkall \
|
2020-06-17 00:29:56 -07:00
|
|
|
-o $@ -no-alias-deps $^
|
2018-07-25 01:38:08 -07:00
|
|
|
|
|
|
|
# we need str and unix which depend on the bytecode version of other tools
|
|
|
|
# thus we delay building caml-tex to the opt.opt stage
|
2019-01-08 08:00:29 -08:00
|
|
|
ifneq "$(WITH_CAMLTEX)" ""
|
2020-06-17 00:29:56 -07:00
|
|
|
opt.opt: $(caml_tex)
|
2019-01-08 08:00:29 -08:00
|
|
|
endif
|
2018-07-25 01:38:08 -07:00
|
|
|
clean::
|
2020-06-17 00:29:56 -07:00
|
|
|
rm -f -- caml-tex caml-tex.exe caml_tex.cm?
|
2018-07-25 01:38:08 -07:00
|
|
|
|
2016-09-16 00:35:29 -07:00
|
|
|
# Common stuff
|
|
|
|
|
2019-05-07 02:32:05 -07:00
|
|
|
%.ml: %.mll
|
|
|
|
$(CAMLLEX) $(OCAMLLEX_FLAGS) $<
|
2016-09-16 00:35:29 -07:00
|
|
|
|
|
|
|
%.cmo: %.ml
|
|
|
|
$(CAMLC) -c $(COMPFLAGS) - $<
|
|
|
|
|
|
|
|
%.cmi: %.mli
|
|
|
|
$(CAMLC) -c $(COMPFLAGS) - $<
|
|
|
|
|
|
|
|
%.cmx: %.ml
|
|
|
|
$(CAMLOPT) $(COMPFLAGS) -c - $<
|
|
|
|
|
|
|
|
clean::
|
|
|
|
rm -f *.cmo *.cmi *.cma *.dll *.so *.lib *.a
|
|
|
|
|
2019-03-18 03:45:43 -07:00
|
|
|
CAMLDEP=$(BOOT_OCAMLC) -depend
|
2018-12-08 07:19:06 -08:00
|
|
|
DEPFLAGS=-slash
|
|
|
|
DEPINCLUDES=$(INCLUDES)
|
2016-09-16 00:35:29 -07:00
|
|
|
depend: beforedepend
|
2018-12-08 07:19:06 -08:00
|
|
|
$(CAMLDEP) $(DEPFLAGS) $(DEPINCLUDES) *.mli *.ml > .depend
|
2016-09-16 00:35:29 -07:00
|
|
|
|
|
|
|
.PHONY: clean install beforedepend depend
|
|
|
|
|
|
|
|
include .depend
|