Let’s see how things are organized in the Git repository. We will focus on the master branch.

Build configuration

This is not very interesting. It’s a lot of stuff that makes Emacs compile and run on many platforms and architectures.

Emacs --like a lot of GNU projects– use the GNU autotools.

I recommand reading the INSTALL.REPO if you want to build the git ‘master’ branch. Basically, if you have all dependancies to build the default Emacs, run:

$ make # does the needed autogen, configure, make with default settings
$ ./src/emacs -Q # run it!

I recommend using -jPROC flag for make where PROC is the number of CPU core you have in order to speed up the compilation.

Emacs core

The core of Emacs is written in C.

Lisp objects

Let’s look at src/lisp.h for fundamental definitions.

A Lisp object (Lisp_Object) is basically a number (an integer). For 32bits Lisp_Object, in hexadecimal:


This number is split in 2 parts in terms of bits:

The value is either a memory address or an integer i.e. the fixnum Lisp type. The tag indicates the type of the value.

On my 64bit build of Emacs, a Lisp object is stored on a 64bits signed integer which is called (typedef’ed to) EMACS_INT.

Everytime an object is allocated its address is aligned to 8 bytes. That way the 3 least significant bits are always 0 and thus can be used for the tag. The allocation code is in src/alloc.c.

The tag is 3 bit long and thus can have 8 different values. The value uses the remaining bits. Integers use another 1 bit of the 3 tag bits.

This technique makes integer handling fast but has the downside of limiting the available range of integers. This is problematic on 32bit systems where the point in a buffer can’t go past a 2^28 (256MB).

Lisp types

See enum Lisp_Type in lisp.h:243. It’s the value of each tag.

Two objects are equal (with EQ(a, b)) if both their Lisp_Object values are equal.

There are several macros defined to extract the relevant data from a Lisp_Object.

There’s a bunch of type predicates macros:

Pseudovector types

Due to having limited available tag space, most Lisp_Objects are internally represented as vector-like objects. These objects are tagged structs each containing a union vectorlike_header at the beginning (which stores tag and type information), a section composed of Lisp_Objects, and a section optionally containing miscellaneous information. Here is a typical Lisp_Vectorlike struct:

struct xyzzy
  /* This is our vectorlike header */
  union vectorlike_header header; 
  /* A few Lisp_Object fields follow */
  Lisp_Object foo;
  Lisp_Object bar;
  /* Miscellaneous fields follow */
  int baz;
  void *quux;

Lisp_Vectorlike types are stored in the enum pvec_types, in lisp.h . A new type should be created with each new vectorlike.

Lisp_Vectorlikes should be allocated with ALLOCATE_PSEUDOVECTOR, a macro in lisp.h which accepts the C type of the pseudovector, the name of the last Lisp field in the pseudovector, and the pvec_type of the pseudovector. Assuming that PVEC_XYZZY is the pvec_type of the pseudovector, a typical make_xyzzy function would read:

struct xyzzy *
make_xyzzy (Lisp_Object foo, int baz, void *quux)
  struct xyzzy *retv = ALLOCATE_PSEUDOVECTOR (struct xyzzy, foo, PVEC_XYZZY);
  retv->foo = foo;
  retv->bar = Ffoobar (foo);
  retv->baz = baz;
  retv->quux = quux;
  return retv;

To convert between the returned struct, and the corresponding Lisp_Object, a common idiom is to define a macro in lisp.h, that invokes the macro XSETPSEUDOVECTOR, which sets the field a to the Lisp_Object representation of the pseudovector b. For example:


When creating pseudovectors, a new switch clause should be placed in print_vectorlike (a C function in print.c), which prints a textual representation of the Lisp_Vectorlike. For our hypothetical xyzzy object, a typical entry would read:

static bool
print_vectorlike (Lisp_Object obj ... Lisp_Object printcharfun ...)
    case PVEC_XYZZY:
      print_c_string ("#<xyzzy>", printcharfun);

Defining functions

There is a DEFUN macro in lisp.h:1987. Have a look at the manual, it’s pretty well written. Writing Emacs Primitives


Iterating on a list

Lisp_Object tail;

for (tail = list; CONSP (tail); tail = XCDR (tail))
    List_Object e = XCAR (tail); /* current element */
    /* ... */

Configure script and build flags

If you know how to write basic shell scripts you’re good to go. This is a crash course in autoconf for Emacs. Have a look at autoconf doc for more.

Adding a enable/disable configure flag

Open configure.ac, it’s a big shell script template that is processed by autoconf to generate the actual configure.sh script.

Look for OPTION_DEFAULT_ON or OPTION_DEFAULT_OFF depending on if you want your option to be turn on or off by default.

The syntax is OPTION_DEFAULT_ON([thing],[description]) where:

This macro will define a with_thing shell variable available in the rest of the script. Its value will be either “yes” or “no”.

The convention is later in the script:

Exporting a C macro

If you need to export something to make it available in the C sources (as a define macro written in src/config.h), use:

AC_DEFINE(YOUR_MACRO, value, [Purpose of the macro])

This will define YOUR_MACRO to the verbatim value. In case you want to export the content of a shell variable (expand it), simply putting $value will not work, you have to use:

AC_DEFINE_UNQUOTED(YOUR_MACRO, "$your_variable", [ description ])

Exporting a shell variable to rest of autoconf machinery

If you need to export a shell variable to src/Makefile.in (the file that is processed by autoconf to generate the actual Makefile) you need to use


This will replace any occurence of @YOUR_SHELL_VAR@ in files processed by autoconf with the content of the shell var. If you look at src/Makefile.in for example, you can see:


This define a Makefile variable to the value of the shell variable defined earlier in configure.ac.


# first define the configure option

# ...

# Thing support
## declare here other variable you need
## like additional build flags, etc.
## the convention is to use
##  - THING_OBJ for additional object files (use AC_SUBST to export!)
##  - LIBTHING for additional librares to add to the linker flags (use AC_SUBST to export!)

if test "${with_thing}" != "no"; then
 # do your check to see if you can actually enable it
 HAVE_THING=yes # (lets assume you can)
 # define

if test "${HAVE_THING}" = yes; then
  # now you *have* to enable Thing!
  # AC_SUBST, AC_DEFINE, etc usually go here
  AC_DEFINE(HAVE_THING, 1, [Define to 1 if Thing enabled])

# ...

# add a "summary line" printed at the end of configuration
echo "  Does Emacs has Thing?                 ${HAVE_THING}"