7

I wish to distribute an elisp package that uses json.el (http://edward.oconnor.cx/2006/03/json.el). I need this to work for versions of emacs that do not come with json pre-installed (such as OSX, which ships with emacs 22.1). Is there a recommended way for me to ship a third party package like json with my package?

I am going to be distributing this in source form directly to clients.

  • 1
    If you're supporting Emacs versions < 23, probably best not to use the term "package" (which implies ELPA). "Library" is the more agnostic term. – phils Apr 19 '16 at 7:20
  • 2
    One option would be to use locate-library -- or simply act upon (require 'json nil :noerror) failing -- to ascertain whether json is already available and, if not, add the subdirectory for your own copy to the load-path before requireing it. – phils Apr 19 '16 at 7:31
  • 2
    Why do you need to ship json.el with your library? Just include (require 'json) and add a note in the Commentary (file-header comments) that tells users where to obtain json.el. That is polite, sufficient, and easy for users. If your library does not really require json.el, and it is just a nice-to-have or is needed only for some functionality (not all), then use (require 'json nil t) and add conditions in your code that test for its presence (e.g. featurep or fboundp or boundp). You can also use (require 'json nil t) in a given function definition. – Drew Apr 19 '16 at 13:31
  • OSX's builtin Emacs-22 is not only ancient, I hear it's also crippled by its lack of GUI support, so you're better off not using it. – Stefan Apr 20 '16 at 1:30
7

As others have pointed out if you're targeting Emacs 23 or even 22 you don't have a “package” but only a library. “Packages” don't exist in Emacs prior to Emacs 24 when the package manager was added.

Bundling with a library

Bundle it.

Since there's no standard way to install libraries before packages you can bundle json.el into whatever you give to your users—some kind of an archive I presume. They'll have to install it manually anyway and can thus pick whatever files they need: Just your library for Emacs 24/25 users, your library + json.el for those with older versions.

As long as you document this it won't cause any trouble.

Bundling with a package

Do absolutely not bundle it.

However, if you build a proper package for Emacs 24 and upwards you must not include json.el.

The package manager will happily install your bundled copy of json.el along with your actual library. Since packages come first in load-path your bundled copy of json.el will now override the built-in one, causing all sorts of trouble for packages that expect a more recent version of json.el.

The way to go (in my opinion)

Create two distributions of your package:

  • A proper Emacs package for Emacs 24 and above, e.g. a TAR with the corresponding package metadata. You could even host a small package repository with your package to distribute updates to Emacs 24 users automatically.
  • A TAR file with your library and json.el, but without package metadata for users of older Emacs versions.

The only thing that you need to watch out for is when users of older Emacs versions update to Emacs 24. In this case they'll have to manually remove the previous installation of your library along with json.el and install the proper Emacs 24 package again.

An alternative

If you don't want to maintain two different distributions you can bundle json.el, but under a different name, e.g. my-library-json-compat.el. With a different name your bundle copy of json.el will never override the built-in one.

Since the functions and symbols in the bundled copy would still conflict with the built-in one, you must take care not to load your bundled copy when the real json.el is available, but this is easy:

(unless (require 'json nil 'no-error)
  (require 'json "my-library-json-compat"))

Emacs will try to load json.el, and failing that fall back to your bundled copy under a different name.

The real way to go (in my opinion)

Tell your users to update to Emacs 24. The last release of Emacs 22 is eight(!) years ago, the last release of Emacs 23 still four years ago. Both versions are outdated and lack a lot of features, and many packages (e.g. Magit) only support Emacs 24 nowadays. Emacs 22/23 are a dead end and there's no way forward from them.

Updating to Emacs 24 is easy enough: Most modern Linux distribution include at least Emacs 24.1 in their package repositories. For OS X pre-built App bundles are available, and the latest stable Emacs 24 is included in the popular OS X package manager Homebrew.

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.