ocaml/otherlibs/Makefile.otherlibs.common

145 lines
4.2 KiB
Makefile
Raw Normal View History

#**************************************************************************
#* *
#* 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. *
#* *
#**************************************************************************
# Common Makefile for otherlibs
ROOTDIR=../..
include $(ROOTDIR)/Makefile.common
include $(ROOTDIR)/Makefile.best_binaries
CAMLRUN ?= $(ROOTDIR)/boot/ocamlrun
CAMLC := $(BEST_OCAMLC) -nostdlib -I $(ROOTDIR)/stdlib
CAMLOPT := $(BEST_OCAMLOPT) -nostdlib -I $(ROOTDIR)/stdlib
OC_CFLAGS += $(SHAREDLIB_CFLAGS) $(EXTRACFLAGS)
OC_CPPFLAGS += -I$(ROOTDIR)/runtime $(EXTRACPPFLAGS)
# Compilation options
2016-08-01 07:06:59 -07:00
COMPFLAGS=-absname -w +a-4-9-41-42-44-45-48 -warn-error A -bin-annot -g \
-safe-string -strict-sequence -strict-formats $(EXTRACAMLFLAGS)
MKLIB=$(CAMLRUN) $(ROOTDIR)/tools/ocamlmklib$(EXE)
# Variables that must be defined by individual libraries:
# LIBNAME
# CAMLOBJS
# Variables that can be defined by individual libraries,
# but have sensible default values:
COBJS ?=
EXTRACFLAGS ?=
EXTRACPPFLAGS ?=
EXTRACAMLFLAGS ?=
LINKOPTS ?=
LDOPTS ?=
HEADERS ?=
CMIFILES ?= $(CAMLOBJS:.cmo=.cmi)
CAMLOBJS_NAT ?= $(CAMLOBJS:.cmo=.cmx)
CLIBNAME ?= $(LIBNAME)
2019-02-25 07:47:18 -08:00
ifeq "$(COBJS)" ""
STUBSLIB=
else
STUBSLIB=lib$(CLIBNAME).$(A)
endif
.PHONY: all allopt opt.opt # allopt and opt.opt are synonyms
2019-02-25 07:47:18 -08:00
all: $(STUBSLIB) $(LIBNAME).cma $(CMIFILES)
2019-02-25 07:47:18 -08:00
allopt: $(STUBSLIB) $(LIBNAME).cmxa $(LIBNAME).$(CMXS) $(CMIFILES)
opt.opt: allopt
$(LIBNAME).cma: $(CAMLOBJS)
2019-02-25 07:47:18 -08:00
ifeq "$(COBJS)" ""
$(CAMLC) -o $@ -a -linkall $(CAMLOBJS) $(LINKOPTS)
else
$(MKLIB) -o $(LIBNAME) -oc $(CLIBNAME) -ocamlc '$(CAMLC)' -linkall \
$(CAMLOBJS) $(LINKOPTS)
2019-02-25 07:47:18 -08:00
endif
$(LIBNAME).cmxa: $(CAMLOBJS_NAT)
2019-02-25 07:47:18 -08:00
ifeq "$(COBJS)" ""
$(CAMLOPT) -o $@ -a -linkall $(CAMLOBJS_NAT) $(LINKOPTS)
else
$(MKLIB) -o $(LIBNAME) -oc $(CLIBNAME) -ocamlopt '$(CAMLOPT)' -linkall \
$(CAMLOBJS_NAT) $(LINKOPTS)
2019-02-25 07:47:18 -08:00
endif
2019-02-25 07:47:18 -08:00
$(LIBNAME).cmxs: $(LIBNAME).cmxa $(STUBSLIB)
2018-09-06 07:12:42 -07:00
$(CAMLOPT_CMD) -shared -o $(LIBNAME).cmxs -I . $(LIBNAME).cmxa
lib$(CLIBNAME).$(A): $(COBJS)
2018-09-06 07:12:42 -07:00
$(MKLIB_CMD) -oc $(CLIBNAME) $(COBJS) $(LDOPTS)
install::
if test -f dll$(CLIBNAME)$(EXT_DLL); then \
$(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
dll$(CLIBNAME)$(EXT_DLL) \
"$(INSTALL_STUBLIBDIR)/"; \
fi
2019-02-25 07:47:18 -08:00
ifneq "$(STUBSLIB)" ""
$(INSTALL_DATA) $(STUBSLIB) "$(INSTALL_LIBDIR)/"
cd "$(INSTALL_LIBDIR)"; $(RANLIB) lib$(CLIBNAME).$(A)
2019-02-25 07:47:18 -08:00
endif
$(INSTALL_DATA) \
$(LIBNAME).cma $(CMIFILES) \
"$(INSTALL_LIBDIR)/"
ifeq "$(INSTALL_SOURCE_ARTIFACTS)" "true"
$(INSTALL_DATA) \
$(CMIFILES:.cmi=.mli) \
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
$(CMIFILES:.cmi=.cmti) \
"$(INSTALL_LIBDIR)/"
endif
if test -n "$(HEADERS)"; then \
$(INSTALL_DATA) $(HEADERS) "$(INSTALL_LIBDIR)/caml/"; \
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
fi
installopt:
$(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
$(CAMLOBJS_NAT) $(LIBNAME).cmxa $(LIBNAME).$(A) \
"$(INSTALL_LIBDIR)/"
cd "$(INSTALL_LIBDIR)"; $(RANLIB) $(LIBNAME).a
if test -f $(LIBNAME).cmxs; then \
$(INSTALL_PROG) $(LIBNAME).cmxs "$(INSTALL_LIBDIR)/"; \
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
fi
partialclean:
rm -f *.cm*
clean:: partialclean
rm -f *.dll *.so *.a *.lib *.o *.obj
rm -rf $(DEPDIR)
.SUFFIXES: .ml .mli .cmi .cmo .cmx
.mli.cmi:
$(CAMLC) -c $(COMPFLAGS) $<
.ml.cmo:
$(CAMLC) -c $(COMPFLAGS) $<
.ml.cmx:
$(CAMLOPT) -c $(COMPFLAGS) $(OPTCOMPFLAGS) $<
ifeq "$(COMPUTE_DEPS)" "true"
ifneq "$(COBJS)" ""
include $(addprefix $(DEPDIR)/, $(COBJS:.$(O)=.$(D)))
endif
endif
$(DEPDIR)/%.$(D): %.c | $(DEPDIR)
$(DEP_CC) $(OC_CPPFLAGS) $< -MT '$*.$(O)' -MF $@