HackerGuide

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). 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:

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

Idioms

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

AC_SUBST(YOUR_SHELL_VAR)

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:

LIBZ = @LIBZ@

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

Summary

# first define the configure option
OPTION_DEFAULT_ON([thing],[description])

# ...

# Thing support
HAVE_THING=no
## 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
fi

if test "${HAVE_MODULES}" = 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])
fi

# ...

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