emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] externals/caml 4c8c8d3 176/197: makefiles: use 'install' instea


From: Stefan Monnier
Subject: [nongnu] externals/caml 4c8c8d3 176/197: makefiles: use 'install' instead of 'cp' in 'make install' targets
Date: Sat, 21 Nov 2020 01:20:02 -0500 (EST)

branch: externals/caml
commit 4c8c8d3c8e0faa9361f87087dbd278b2fcb46abc
Author: Gabriel Scherer <gabriel.scherer@gmail.com>
Commit: Gabriel Scherer <gabriel.scherer@gmail.com>

    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.
---
 Makefile | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index 93b2d7d..fd48e8c 100644
--- a/Makefile
+++ b/Makefile
@@ -40,6 +40,9 @@ COMPILECMD=(progn \
              (byte-compile-file "caml-font.el") \
              (byte-compile-file "camldebug.el"))
 
+MDATA=u+rw,g+rw,o+r
+MPROG=u+rwx,g+rwx,o+rx
+
 install:
        @if test "$(EMACSDIR)" = ""; then \
          $(EMACS) --batch --eval 't; see PR#5403'; \
@@ -64,7 +67,7 @@ install-el:
 simple-install:
        @echo "Installing in $(EMACSDIR)..."
        if test -d $(EMACSDIR); then : ; else mkdir -p $(EMACSDIR); fi
-       cp $(FILES) $(EMACSDIR)
+       install -m $(MDATA) $(FILES) $(EMACSDIR)
        if [ -z "$(NOCOMPILE)" ]; then \
          cd $(EMACSDIR); $(EMACS) --batch --eval '$(COMPILECMD)'; \
        fi
@@ -74,7 +77,7 @@ ocamltags:    ocamltags.in
        chmod a+x ocamltags
 
 install-ocamltags: ocamltags
-       cp ocamltags $(SCRIPTDIR)/ocamltags
+       install -m $(MDATA) ocamltags $(SCRIPTDIR)/ocamltags
 
 # This is for testing purposes
 compile-only:



reply via email to

[Prev in Thread] Current Thread [Next in Thread]