Emacs, scripting and anything text oriented.

Building Org Development version (2022)

Kaushal Modi

A guide on how to build Org mode from its main branch and load in Emacs without any path shadowing.

This post is a re-write of an earlier “Building Org Development version” post but minus all the outdated stuff.

I am assuming that you already know what Org mode is and that’s why you are here 😃.

You would want to build Org from its development branch (main branch) to get the latest and greatest goodies plus bug fixes! Go through the ORG-NEWS file to read about what’s new in the main branch.

If you like what you see there, here are the steps for installing the development version of Org.

1 Clone the Org repo #

git clone https://git.savannah.gnu.org/git/emacs/org-mode.git

2 Build Setup #

  1. Copy <REPO_ROOT>/mk/default.mk to <REPO_ROOT>/local.mk
  2. Tweak local.mk (optional)

Customizing local.mk (Optional) #

Here are few variables that you might like to change in the local.mk:

prefix
Org installation directory
prefix = /dir/where/you/want/to/install/org # Default: /usr/share

The .el files will go to $(prefix)/emacs/site-lisp/org by default. If you’d like to change that, change the lispdir variable too.

infodir
Org Info installation directory. I like to keep the Info file for development version of Org in a separate directory.
infodir = $(prefix)/org/info # Default: $(prefix)/info
ORG_MAKE_DOC
Types of Org documentation you’d like to build by default. Setting below generates only the Org Info manual.
ORG_MAKE_DOC = info # Default: html pdf

3 Build #

make autoloads
make
make doc
make install

Type make help for help on the Org Makefile. Type make helpall to get a detailed help, or see the Org build system help.

4 Set the correct paths in your Emacs config #

  1. Update load-path to remove the Org version that ships with Emacs. Do the same if you have Org installed via GNU ELPA  If you need the latest stable version of Org mode, install it from GNU ELPA. too.
  2. Also remove the associated old Org mode Info manuals from Info-directory-list.
  3. Update the load-path and Info-directory-list variables to point to the Org mode source code and Info manual built using the main branch.

Below code does all that but make sure this code is executed after you do (package-initialize), but before you require the org package . You can use use-package and make sure that this order of code evaluation is always correct — Just put the code from Code Snippet 2 where <HERE> is shown in the below snippet:

(use-package org
  :preface
  <HERE>)
Code Snippet 1: Update load-path and Info-directory-list in use-package :preface

(defvar modi/org-version-select 'dev
  "Variable to choose the version of Org to be loaded.
Valid values are `dev', `elpa' and `emacs'.

When set to `dev', the development version of Org built locally
is loaded.
When set to `elpa', Org is installed and loaded from GNU ELPA.
When set to `emacs', the Org version shipped with Emacs is used.")

(defvar modi/default-lisp-directory "/your/emacs/share/dir/version/lisp/"
  "Directory containing lisp files for the Emacs installation.

This value must match the path to the lisp/ directory of your
Emacs installation.

If Emacs is installed using --prefix=\"${PREFIX_DIR}\" this value
would typically be
\"${PREFIX_DIR}/share/emacs/<VERSION>/lisp/\".")

(defvar org-dev-lisp-directory "/value/of/lispdir/in/local.mk"
  "Directory containing lisp files for dev version of Org.

This value must match the `lispdir' variable in the Org local.mk.
By default the value is \"$prefix/emacs/site-lisp/org\", where
`prefix' must match that in local.mk too.")

(defvar org-dev-info-directory "/value/of/infodir/in/local.mk"
  "Directory containing Info manual file for dev version of Org.

This value must match the `infodir' variable in the Org local.mk.")

(when (and org-dev-lisp-directory
           org-dev-info-directory)
  (with-eval-after-load 'package
    ;; If `modi/org-version-select' is *not* `emacs', remove the Emacs
    ;; version of Org from the `load-path'.
    (unless (eq modi/org-version-select 'emacs)
      ;; Remove Org that ships with Emacs from the `load-path'.
      (let ((default-org-path (expand-file-name "org" modi/default-lisp-directory)))
        (setq load-path (delete default-org-path load-path))))

    ;; If `modi/org-version-select' is *not* `elpa', remove the Elpa
    ;; version of Org from the `load-path'.
    (unless (eq modi/org-version-select 'elpa)
      (dolist (org-elpa-install-path (directory-files-recursively
                                      package-user-dir
                                      "\\`org-[0-9.]+\\'"
                                      :include-directories))
        (setq load-path (delete org-elpa-install-path load-path))
        ;; Also ensure that the associated path is removed from Info
        ;; search list.
        (setq Info-directory-list (delete org-elpa-install-path Info-directory-list))))

    (let ((dev-org-path (directory-file-name org-dev-lisp-directory))
          (dev-org-info (directory-file-name org-dev-info-directory)))
      (if (eq modi/org-version-select 'dev)
          (progn
            (add-to-list 'load-path dev-org-path)
            ;; It's possible that `org-dev-info-directory' is set to
            ;; an unconventional value, in which case, it will not be
            ;; automatically added to `Info-directory-alist'. So add
            ;; it to `Info-directory-alist' manually.
            (add-to-list 'Info-directory-list dev-org-info))

        ;; If `modi/org-version-select' is *not* `dev', remove the
        ;; development version of Org from the `load-path', and its
        ;; Info from the Info search list.
        (setq load-path (delete dev-org-path load-path))
        (with-eval-after-load 'info
          (setq Info-directory-list (delete dev-org-info Info-directory-list)))))))
Code Snippet 2: Emacs config snippet to ensure that load-path and Info-directory-list use the right Org version
Note
Remember that you need to correctly set the values of these 3 variables in the above snippet:
  • modi/default-lisp-directory
  • org-dev-lisp-directory
  • org-dev-info-directory

5 Testing that the right Org version got loaded #

  1. Restart Emacs (Don’t be lazy — do it!)
  2. M-x org-version – That should show something like this in the echo area:
    Org mode version 9.5.3 (release_9.5.3-482-gd5a52b @ /home/kmodi/usr_local/apps/7/emacs/emacs-28/share/emacs/site-lisp/org/)
    
    This message format is broken down as:
    Org mode version <ORG-VERSION> (release_<ORG-VERSION>-NNN-g<GIT-HASH> @ <PREFIX>/emacs/site-lisp/org/)
    

If the GIT-HASH and PREFIX above are what you expect, congratulations! You did it! 🎉

Else, let me know in comments if I can help you.

Future Org development version updates #

  1. Below will do git pull and build Org.
    make update
    
  2. Restart Emacs.

References #