From: Andrea Corallo Date: Sun, 4 Apr 2021 15:10:08 +0000 (+0200) Subject: Output native compiled preloaded files into the 'preloaded' subfolder X-Git-Tag: emacs-28.0.90~2727^2~42 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=6f8ec1449197f1fcd730df91dddf6f7750284593;p=emacs.git Output native compiled preloaded files into the 'preloaded' subfolder * src/comp.c (fixup_eln_load_path): Account the fact that the file can be dumped in the 'preloaded' subfolder. * lisp/loadup.el: Likewise. * src/lread.c (maybe_swap_for_eln1): New function. (maybe_swap_for_eln): Handle 'preloaded' subfolder. * src/Makefile.in (LISP_PRELOADED): Export preloaded files. --- diff --git a/lisp/loadup.el b/lisp/loadup.el index 57058ac4aa1..c3948e465f2 100644 --- a/lisp/loadup.el +++ b/lisp/loadup.el @@ -465,17 +465,25 @@ lost after dumping"))) (when (subr-native-elisp-p f) (puthash (subr-native-comp-unit f) nil h))))) (maphash (lambda (cu _) - (native-comp-unit-set-file - cu - (cons - ;; Relative filename from the installed binary. - (file-relative-name (concat eln-dest-dir - (file-name-nondirectory - (native-comp-unit-file cu))) - bin-dest-dir) - ;; Relative filename from the built uninstalled binary. - (file-relative-name (native-comp-unit-file cu) - invocation-directory)))) + (let* ((file (native-comp-unit-file cu)) + (preloaded (equal (substring (file-name-directory file) + -10 -1) + "preloaded")) + (eln-dest-dir-eff (if preloaded + (expand-file-name "preloaded" + eln-dest-dir) + eln-dest-dir))) + (native-comp-unit-set-file + cu + (cons + ;; Relative filename from the installed binary. + (file-relative-name (expand-file-name + (file-name-nondirectory + file) + eln-dest-dir-eff) + bin-dest-dir) + ;; Relative filename from the built uninstalled binary. + (file-relative-name file invocation-directory))))) h)))) (when (hash-table-p purify-flag) diff --git a/src/Makefile.in b/src/Makefile.in index c6b1f556440..b8bad73b006 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -500,6 +500,7 @@ shortlisp := $(filter-out ${shortlisp_filter},${shortlisp}) ## the critical path (relevant in parallel compilations). ## We don't really need to sort, but may as well use it to remove duplicates. shortlisp := loaddefs.el loadup.el $(sort ${shortlisp}) +export LISP_PRELOADED = ${shortlisp} lisp = $(addprefix ${lispsource}/,${shortlisp}) ## Construct full set of libraries to be linked. diff --git a/src/comp.c b/src/comp.c index 67c8e39315b..9bad9b9667f 100644 --- a/src/comp.c +++ b/src/comp.c @@ -4091,6 +4091,7 @@ for new compilations. If BASE-DIR is nil use the first entry in `comp-eln-load-path'. */) (Lisp_Object filename, Lisp_Object base_dir) { + Lisp_Object source_filename = filename; filename = Fcomp_el_to_eln_rel_filename (filename); /* If base_dir was not specified search inside Vcomp_eln_load_path @@ -4129,9 +4130,18 @@ If BASE-DIR is nil use the first entry in `comp-eln-load-path'. */) if (!file_name_absolute_p (SSDATA (base_dir))) base_dir = Fexpand_file_name (base_dir, Vinvocation_directory); - return Fexpand_file_name (filename, - Fexpand_file_name (Vcomp_native_version_dir, - base_dir)); + /* In case the file being compiled is found in 'LISP_PRELOADED' + target for output the 'preloaded' subfolder. */ + Lisp_Object lisp_preloaded = + Fgetenv_internal (build_string ("LISP_PRELOADED"), Qnil); + base_dir = Fexpand_file_name (Vcomp_native_version_dir, base_dir); + if (!NILP (lisp_preloaded) + && !NILP (Fmember (CALL1I (file-name-base, source_filename), + Fmapcar (intern_c_string ("file-name-base"), + CALL1I (split-string, lisp_preloaded))))) + base_dir = Fexpand_file_name (build_string ("preloaded"), base_dir); + + return Fexpand_file_name (filename, base_dir); } DEFUN ("comp--install-trampoline", Fcomp__install_trampoline, @@ -4750,10 +4760,15 @@ fixup_eln_load_path (Lisp_Object directory) Lisp_Object eln_cache_sys = Ffile_name_directory (concat2 (Vinvocation_directory, directory)); - /* One directory up... */ - eln_cache_sys = - Ffile_name_directory (Fsubstring (eln_cache_sys, Qnil, - make_fixnum (-1))); + bool preloaded = + !NILP (Fequal (Fsubstring (eln_cache_sys, make_fixnum (-10), + make_fixnum (-1)), + build_string ("preloaded"))); + /* One or two directories up... */ + for (int i = 0; i < (preloaded ? 2 : 1); i++) + eln_cache_sys = + Ffile_name_directory (Fsubstring (eln_cache_sys, Qnil, + make_fixnum (-1))); Fsetcar (last_cell, eln_cache_sys); } diff --git a/src/lread.c b/src/lread.c index 156df73de82..e53e1f65ab9 100644 --- a/src/lread.c +++ b/src/lread.c @@ -1645,6 +1645,40 @@ directories, make sure the PREDICATE function returns `dir-ok' for them. */) return file; } +#ifdef HAVE_NATIVE_COMP +static bool +maybe_swap_for_eln1 (Lisp_Object src_name, Lisp_Object eln_name, + Lisp_Object *filename, int *fd, struct timespec mtime) +{ + struct stat eln_st; + int eln_fd = emacs_open (SSDATA (ENCODE_FILE (eln_name)), O_RDONLY, 0); + + if (eln_fd > 0) + { + if (fstat (eln_fd, &eln_st) || S_ISDIR (eln_st.st_mode)) + emacs_close (eln_fd); + else + { + struct timespec eln_mtime = get_stat_mtime (&eln_st); + if (timespec_cmp (eln_mtime, mtime) >= 0) + { + emacs_close (*fd); + *fd = eln_fd; + *filename = eln_name; + /* Store the eln -> el relation. */ + Fputhash (Ffile_name_nondirectory (eln_name), + src_name, Vcomp_eln_to_el_h); + return true; + } + else + emacs_close (eln_fd); + } + } + + return false; +} +#endif + /* Look for a suitable .eln file to be loaded in place of FILENAME. If found replace the content of FILENAME and FD. */ @@ -1653,7 +1687,6 @@ maybe_swap_for_eln (bool no_native, Lisp_Object *filename, int *fd, struct timespec mtime) { #ifdef HAVE_NATIVE_COMP - struct stat eln_st; if (no_native || load_no_native) @@ -1687,36 +1720,24 @@ maybe_swap_for_eln (bool no_native, Lisp_Object *filename, int *fd, } Lisp_Object eln_rel_name = Fcomp_el_to_eln_rel_filename (src_name); + Lisp_Object dir = Qnil; FOR_EACH_TAIL_SAFE (eln_path_tail) { + dir = XCAR (eln_path_tail); Lisp_Object eln_name = Fexpand_file_name (eln_rel_name, - Fexpand_file_name (Vcomp_native_version_dir, - XCAR (eln_path_tail))); - int eln_fd = emacs_open (SSDATA (ENCODE_FILE (eln_name)), O_RDONLY, 0); - - if (eln_fd > 0) - { - if (fstat (eln_fd, &eln_st) || S_ISDIR (eln_st.st_mode)) - emacs_close (eln_fd); - else - { - struct timespec eln_mtime = get_stat_mtime (&eln_st); - if (timespec_cmp (eln_mtime, mtime) >= 0) - { - *filename = eln_name; - emacs_close (*fd); - *fd = eln_fd; - /* Store the eln -> el relation. */ - Fputhash (Ffile_name_nondirectory (eln_name), - src_name, Vcomp_eln_to_el_h); - return; - } - else - emacs_close (eln_fd); - } - } + Fexpand_file_name (Vcomp_native_version_dir, dir)); + if (maybe_swap_for_eln1 (src_name, eln_name, filename, fd, mtime)) + return; } + + /* Look also in preloaded subfolder of the last entry in + `comp-eln-load-path'. */ + dir = Fexpand_file_name (build_string ("preloaded"), + Fexpand_file_name (Vcomp_native_version_dir, + dir)); + maybe_swap_for_eln1 (src_name, Fexpand_file_name (eln_rel_name, dir), + filename, fd, mtime); #endif }