Commit f42d57c7 authored by Paul Eggert's avatar Paul Eggert

Install C source code for C-h f etc.

Without this change, on typical GNU/Linux distributions
like Debian, the first button of ‘C-h f car RET’ does not work
because the source code for ‘car’ is not installed (Bug#37527).
Fix this by installing the (compressed) C source code alongside
the (compressed) Lisp source code that is already installed.
This adds about 3 MB (about 2%) to the size of the installed files
on my platform.
* (emacs_srcdir): New macro.
(epaths-force): Substitute PATH_EMACS_SOURCE.
(install-c-src): New rule, that installs a copy of the C source
code if emacs_srcdir says to.
(install-arch-indep): Depend on it.
* (emacs_srcdir): New var.
Add support for --disable-install-srcdir.
* lisp/emacs-lisp/find-func.el (find-function-C-source-directory):
Look in emacs-source-directory first.
(find-function-C-source): Also look for gzipped source files.
* lisp/startup.el (normal-top-level):
Also recode emacs-source-directory.
* src/ (PATH_EMACS_SOURCE): New macro.
* src/lread.c: Include dosname.h, for IS_ABSOLUTE_FILE_NAME.
(syms_of_lread): New var emacs-source-directory.
parent 0c6c8aa0
Pipeline #4687 passed with stage
in 58 minutes and 30 seconds
......@@ -214,41 +214,42 @@ like 'apt-get build-dep emacs' (on older systems, replace 'emacs' with
eg 'emacs25'). On Red Hat-based systems, the corresponding command is
'dnf builddep emacs' (on older systems, use 'yum-builddep' instead).
* Installed Emacs source code
Emacs installs a compressed copy of much of its source code, to make
it easy for users to read the source code of Emacs via commands like
M-x describe-function (C-h f) to display the definition of a function.
This compressed copy ordinarily includes both the Elisp source code
that Emacs is mostly written in, as well as the C source code for the
core Emacs executable.
* GNU/Linux source and debug packages
Many GNU/Linux systems provide separate packages containing the
sources and debug symbols of Emacs. They are useful if you want to
check the source code of Emacs primitive functions or debug Emacs on
the C level.
The names of the packages that you need vary according to the
GNU/Linux distribution that you use. On Debian-based systems, you can
install a source package of Emacs with a command like 'apt-get source
emacs' (on older systems, replace 'emacs' with eg 'emacs25'). The
target directory for unpacking the source tree is the current
directory. On Red Hat-based systems, the corresponding command is
'dnf install emacs-debugsource', with target directory /usr/src/debug
(this requires to add the *-debuginfo repositories first, via 'dnf
config-manager --set-enabled fedora-debuginfo updates-debuginfo').
Once you have installed the source package, for example at
/path/to/emacs-26.1, add the following line to your startup file:
(setq find-function-C-source-directory
The installation directory of the Emacs source package will contain
the exact package name and version number Emacs is installed on your
system. If a new Emacs package is installed, the source package must
be reinstalled as well, and the setting in your startup file must be
Emacs debugging symbols are distributed by a debug package. It does
not exist for every released Emacs package, this depends on the
distribution. On Debian-based systems, you can install a debug
package of Emacs with a command like 'apt-get install emacs-dbg' (on
older systems, replace 'emacs' with eg 'emacs25'). On Red Hat-based
systems, the corresponding command is 'dnf debuginfo-install emacs'.
sources and debug symbols of Emacs. They can help you debug the
installed Emacs on the C level. The procedures for installing these
packages depend on the GNU/Linux system that you use.
Emacs debugging symbols are distributed by a debug package if one
exists for your system. On Debian-based systems, you can
install a debug package of Emacs with a command like 'apt-get install
emacs-dbg' (on older systems, replace 'emacs' with e.g. 'emacs25').
On Red Hat-based systems, the corresponding command is 'dnf
debuginfo-install emacs'; this may require adding the *-debuginfo
repositories first, via 'dnf config-manager --set-enabled
fedora-debuginfo updates-debuginfo'.
Some systems also have an Emacs source package that is also helpful
when debugging the installed Emacs. To unpack an Emacs source package
into the current directory on Debian-based systems, you can use a
command like 'apt-get source emacs' (on older systems, replace 'emacs'
with e.g. 'emacs25'); you may first need to add the appropriate
'source' URIs to your sources.list. On Red Hat-based systems,
installing the debugging symbols automatically installs the
corresponding source package in the appropriate location.
......@@ -266,6 +266,9 @@ etcdir=@etcdir@
# once.
# Where to install Emacs C source code, or empty if it is not installed.
# Where to put the etc/DOC file.
......@@ -374,6 +377,7 @@ epaths-force:
-e 's;\(#.*PATH_BITMAPS\).*$$;\1 "${bitmapdir}";' \
-e 's;\(#.*PATH_X_DEFAULTS\).*$$;\1 "${x_default_search_path}";' \
-e 's;\(#.*PATH_GAME\).*$$;\1 $(PATH_GAME);' \
-e 's;\(#.*PATH_EMACS_SOURCE\).*$$;\1 "${emacs_srcdir}";' \
-e 's;\(#.*PATH_DOC\).*$$;\1 "${etcdocdir}";') && \
${srcdir}/build-aux/move-if-change epaths.h.$$$$ src/epaths.h
......@@ -461,7 +465,7 @@ $(srcdir)/configure: $(srcdir)/ $(srcdir)/m4/*.m4
# ==================== Installation ====================
.PHONY: install install-arch-dep install-arch-indep install-etcdoc install-info
.PHONY: install-man install-etc install-strip install-$(NTDIR)
.PHONY: install-man install-c-src install-etc install-strip install-$(NTDIR)
.PHONY: uninstall uninstall-$(NTDIR)
## If we let lib-src do its own installation, that means we
......@@ -568,7 +572,8 @@ set_installuser=for installuser in $${LOGNAME} $${USERNAME} $${USER} \
## work correctly, and therefore no idea when tar can be replaced.
## See also these comments from 2004 about cp -r working fine:
install-arch-indep: lisp install-info install-man ${INSTALL_ARCH_INDEP_EXTRA}
install-arch-indep: lisp install-info install-man install-c-src \
umask 022 && $(MKDIR_P) "$(DESTDIR)$(includedir)"
$(INSTALL_DATA) src/emacs-module.h "$(DESTDIR)$(includedir)/emacs-module.h"
-set ${COPYDESTS} ; \
......@@ -700,6 +705,28 @@ install-man:
${GZIP_PROG} -9n "$(DESTDIR)${man1dir}/$${dest}" || true; \
ifneq (,$(emacs_srcdir))
-unset CDPATH; \
umask 022; $(MKDIR_P) "$(DESTDIR)$(emacs_srcdir)/src" && \
exp_sourcesrcdir=`cd "$(DESTDIR)$(emacs_srcdir)/src" && /bin/pwd` && \
[ "`cd $(srcdir)/src && /bin/pwd`" = "$$exp_sourcesrcdir" ] || { \
$(set_installuser); \
printf 'Copying compressed C sources to %s ...\n' \
"$(DESTDIR)$(emacs_srcdir)/src"; \
for file in `cd $(srcdir) && echo src/*.[cm]`; do \
installed_file="$(DESTDIR)$(emacs_srcdir)/$$file" && \
$(INSTALL_DATA) "$$file" "$$installed_file" && \
[ -z "$(GZIP_PROG)" ] || { \
rm -f "$$installed_file.gz" && \
$(GZIP_PROG) -9n "$$installed_file" && \
installed_file=$$installed_file.gz; \
} || exit; \
chown $$installuser "$$installed_file" || true; \
done; \
## Install those items from etc/ that need to end up elsewhere.
## If you prefer, choose "emacs22" at installation time.
......@@ -194,6 +194,7 @@ locallisppath='${datadir}/emacs/${version}/site-lisp:'\
......@@ -540,6 +541,15 @@ elif test "${enableval}" != "yes"; then
locallisppath=${enableval} locallisppathset=yes
[do not install low-level Emacs source code useful for debugging.])],
[case $enableval in
yes) ;;
no) emacs_srcdir=;;
*) AC_MSG_ERROR([invalid install-srcdir]);;
[enable expensive checks. With LIST,
......@@ -2048,6 +2058,9 @@ if test "${HAVE_NS}" = yes; then
dnl This one isn't really used, only archlibdir is.
case $emacs_srcdir in
?*) emacs_srcdir="\${ns_appresdir}";;
dnl FIXME maybe set datarootdir instead.
......@@ -5230,6 +5243,7 @@ AC_SUBST(lisppath)
......@@ -58,6 +58,12 @@ shaping, so 'configure' now recommends that combination.
** The ftx font backend driver has been removed.
It was declared obsolete in Emacs 27.1.
** Emacs now installs a copy of its C source code, used for debugging help.
For example, pressing the first button in the *Help* buffer generated
by 'C-h f car RET' now takes you to a copy of the C-language
implementation of the function 'car'.
* Startup Changes in Emacs 28.1
......@@ -142,6 +148,9 @@ called when the function object is garbage-collected. Use
** 'parse-time-string' can now parse ISO 8601 format strings,
such as "2020-01-15T16:12:21-08:00".
** The new variable 'emacs-source-directory' gives the Emacs source
code location.
* Changes in Emacs 28.1 on Non-Free Operating Systems
......@@ -219,8 +219,10 @@ LIBRARY should be a string (the name of the library)."
(locate-file basename (list dir) (find-library-suffixes)))))))
(defvar find-function-C-source-directory
(let ((dir (expand-file-name "src" source-directory)))
(if (file-accessible-directory-p dir) dir))
(let ((dir (expand-file-name "src" emacs-source-directory)))
(if (file-accessible-directory-p dir) dir
(setq dir (expand-file-name "src" source-directory))
(if (file-accessible-directory-p dir) dir)))
"Directory where the C source files of Emacs can be found.
If nil, do not try to find the source code of functions and variables
defined in C.")
......@@ -245,7 +247,10 @@ TYPE should be nil to find a function, or `defvar' to find a variable."
(let ((dir (or find-function-C-source-directory
(read-directory-name "Emacs C source dir: " nil nil t))))
(setq file (expand-file-name file dir))
(if (file-readable-p file)
(if (or (file-readable-p file)
(let ((file-gz (concat file ".gz")))
(and (file-readable-p file-gz)
(setq file file-gz))))
(if (null find-function-C-source-directory)
(setq find-function-C-source-directory dir))
(error "The C source file %s is not available"
......@@ -623,7 +623,8 @@ It is the default value of the variable `top-level'."
(set pathsym (mapcar (lambda (dir)
(decode-coding-string dir coding t))
(dolist (filesym '(data-directory doc-directory exec-directory
(dolist (filesym '(data-directory doc-directory emacs-source-directory
invocation-directory invocation-name
......@@ -73,5 +73,9 @@ along with GNU Emacs. If not, see <>. */
/* Where Emacs should store game score files. */
#define PATH_GAME "/usr/local/var/games/emacs"
/* Where Emacs should look for its own installed source code,
or the empty string if the source code is not installed. */
#define PATH_EMACS_SOURCE "/usr/local/share/emacs"
/* Where Emacs should look for the application default file. */
#define PATH_X_DEFAULTS "/usr/lib/X11/%L/%T/%N%C%S:/usr/lib/X11/%l/%T/%N%C%S:/usr/lib/X11/%T/%N%C%S:/usr/lib/X11/%L/%T/%N%S:/usr/lib/X11/%l/%T/%N%S:/usr/lib/X11/%T/%N%S"
......@@ -44,6 +44,7 @@ along with GNU Emacs. If not, see <>. */
#include "blockinput.h"
#include "pdumper.h"
#include <c-ctype.h>
#include <dosname.h>
#include <vla.h>
#ifdef MSDOS
......@@ -4992,11 +4993,18 @@ and is not meant for users to change. */);
DEFVAR_LISP ("source-directory", Vsource_directory,
doc: /* Directory in which Emacs sources were found when Emacs was built.
You cannot count on them to still be there! */);
You cannot count on them to still be there! Also see
`emacs-source-directory'. */);
= Fexpand_file_name (build_string ("../"),
Fcar (decode_env_path (0, PATH_DUMPLOADSEARCH, 0)));
DEFVAR_LISP ("emacs-source-directory", Vemacs_source_directory,
doc: /* Directory where Emacs sources can be found. */);
Vemacs_source_directory = (IS_ABSOLUTE_FILE_NAME (PATH_EMACS_SOURCE)
? build_string (PATH_EMACS_SOURCE)
: Vsource_directory);
DEFVAR_LISP ("preloaded-file-list", Vpreloaded_file_list,
doc: /* List of files that were preloaded (when dumping Emacs). */);
Vpreloaded_file_list = Qnil;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment