Emacs, scripting and anything text oriented.

Building Org Development version (2017)

Kaushal Modi
<2022-05-13>
⚠️ This post is outdated! Visit here for the latest version of this post.
<2018-02-20>
Refactor the code using more canonical methods.
<2018-01-03>
Update the Org repo links as per the announcement on Org mailing list on <2017-12-28 Thu>.

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

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

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

Clone the Org repo #

git clone https://code.orgmode.org/bzg/org-mode.git

Build Setup #

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

Customizing local.mk #

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.

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. Below enables generation of the Info and PDF Org manuals and the Org reference cards (in PDF too).
# Define below you only need info documentation, the default includes html and pdf
ORG_MAKE_DOC = info pdf card # html
ORG_ADD_CONTRIB
Packages from the contrib/ directory that you’d like to build along with Org. Below are the ones on my must-have list.
# Define if you want to include some (or all) files from contrib/lisp
# just the filename please (no path prefix, no .el suffix), maybe with globbing
#   org-eldoc - Headline breadcrumb trail in minibuffer
#   ox-extra - Allow ignoring just the heading, but still export the body of those headings
#   org-mime - Convert org buffer to htmlized format for email
ORG_ADD_CONTRIB = org-eldoc ox-extra org-mime

Build #

make autoloads
make
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.

Set the correct paths in your emacs config #

  1. Remove the default Org version that ships with Emacs from the load-path. Do the same if you have Org installed via Melpa/Org Elpa too (the latest stable versions).
  2. Remove the older Org Info directory references too from Info-directory-list.
  3. Update the load-path and Info-directory-list variables with values based on the lispdir and infodir variables above.

Below snippet of code does all that – Make sure this code is executed after you do (package-initialize), but before you require the org package.

(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 Org Elpa.
When set to `emacs', the Org version shipped with Emacs is used.

The value is defaulted to `elpa' as few things in this config
need Org version to be at least 9.x.")

(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))))

    (>=e "25.0" ;`directory-files-recursively' is not available in older emacsen
        ;; 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\\(-plus-contrib\\)*-[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 to ensure
            ;; that the correct Org Info is used, 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'.
        (setq load-path (delete dev-org-path load-path))
        (with-eval-after-load 'info
          ;; Also ensure that the associated path is removed from Info search
          ;; list.
          (setq Info-directory-list (delete dev-org-info Info-directory-list)))))))

To simplify the “before you require the org package” part, if using the use-package, above code would go in HERE:

(use-package org
  :preface
  <HERE>)

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

You may refer to my setup-packages.el to see how I fine-tune the Emacs package manager setup to work well with the development version of Org.

  • Prevent adding Org Elpa to package-archives.
  • Prevent auto-installation of the older versions of Org triggered by package-dependency checks.
  • Even if you install Org from (M)Elpa, do not prompt to upgrade it (as you would be rocking the shiniest and newest version of Org from its master branch from now on! 😄).

Search for modi/org-version-select in there.

Testing that the right Org 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.0.9 (release_9.0.9-648-gc56021 @ /home/kmodi/usr_local/apps/6/emacs/master/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 match to your expectations, congratulations!

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.