GeekSocket Plug in and be Geekified

GNU Emacs pretest builds for Fedora

I have been following GNU Emacs development through Debbugs and Sacha Chua’s newsletter. I always felt that I should use the latest development version of Emacs, instead of sticking to stable release. That way I get to use the latest improvements and also help in testing the changes. If I find any bugs, I can report those.

The motivation for building pretests

I was planning to build RPM packages for Fedora from master branch. While browsing the source code on Savannah cgit, I came across the 27.0.91 release tag. These releases are called pretest releases. Before a new release, which is n.1+, pretest releases are published. Usually the pretest releases have n.n.x version and are meant for testing. Basically, 26.1.90, 26.1.91, 26.2-rc1 are all the pretest releases for the 26.2 release. Read more about Emacs Pretest on EmacsWiki.

There might be multiple pretest releases before a new release. A major release takes time, so I decided to build packages for pretests as they are frequent enough and stable. Changes from master branch are stable too but then I will have to decide on the frequency of builds. I wanted to stay close to upcoming major release so that I can switch to that once it’s available.

Coincidentally, there was a recent discussion on emacs-devel mailing list titled “Do pretests reach end users?”. This gave me another reason to build pretests and make them available to more number of Fedora users.

The cycle of stable, pretest, stable

Let’s take an example of current pretest and see how the workflow will look like. Current version is 26.3 and upcoming release version is 27.1. When the first pretest is available, let’s say 27.0.50, we will upgrade to that. We will keep updating as the next pretest is released. Finally, when 27.1 is released, we will upgrade to that version and keep using it till the next version’s pretest is available i.e. 27.1.x for 27.2.

If you can’t wait, jump straight into the installation instructions.

Creating Copr repository for Emacs pretests

I decided to use Copr for hosting RPM packages of pretest releases.

Copr (“Community projects”) is a service that builds your open-source projects and creates your own RPM repositories.
Copr project’s page

Enabling a Copr repository is as easy as running one command, which is, dnf copr enable <user>/<project>.

Let’s see the steps I did to create a Copr repository.

Cloning the Git repository

I started by cloning the Git repository of build recipe available at https://src.fedoraproject.org/rpms/emacs.

$ fedpkg clone -a rpms/emacs

Take a look at blog post — Creating pull request on src.fedoraproject.org to learn more about working with src.fedoraproject.org.

Modifying the build scripts

The next step was to modify the spec file according to installation changes given in NEWS file of 27.1. Following are the changes which I have made as of now,

  • Build Emacs with Cairo and Jansson support.
  • Remove ImageMagick as it’s no longer used.
  • Keep the emacs.pdmp file as <executable_name>.pdmp in %{_bindir} (/usr/bin/).

Head over to the pull request on src.fedoraproject.org to know more about these changes.

Building the RPM packages locally

To test the modifications, I installed all the build time dependencies. These are the packages which are written as BuildRequires: <package_name> in emacs.spec file.

With all the dependencies installed, I used following fedpkg command to build the RPM files,

$ fedpkg local

This command generates RPM packages in noarch and x86_64 directories. This is because our spec file contains both architecture dependent and independent packages. If you are running this command on any other architecture, it will create directories according to that. For example, it will create noarch and aarch64 on an ARM64 machine.

$ ls noarch
emacs-filesystem-27.0.91-1.fc32.noarch.rpm  emacs-terminal-27.0.91-1.fc32.noarch.rpm

$ ls x86_64
emacs-27.0.91-1.fc32.x86_64.rpm
emacs-common-27.0.91-1.fc32.x86_64.rpm
…

Basically, the emacs-common package has all the common files used by different variants. These variants include emacs (uses GTK toolkit), emacs-lucid (uses LUCID toolkit) and emacs-nox (no X windows support).

A note about sources file

The Git servers of Fedora, CentOS etc, which host build recipes, have a place to store non text sources. This also include the source code tar files of the package. This place is called lookaside cache.

When package maintainers execute fedpkg new-sources command, it uploads these files to the lookaside cache. It also updates the sources file. The file looks something like this,

SHA512 (emacs-26.3.tar.xz) = 4d5a4319253afb…
…

The commands like fedpkg sources, fedpkg local try to find these files from lookaside cache. In our case, our build recipes don’t exist on a Git server which support this kind of lookaside cache. To stop the lookup from this cache, we have to delete the sources file. Once it is removed, all the commands as well as Copr fetches the source tar files from the URLs mentioned in the spec file.

Checkout Package Source Control: Lookaside Cache — Fedora Project Wiki and Sources: Non text sources — CentOS Wiki for more information.

Setting up the Copr project emacs-pretest

Once done with the changes, next step was to set up a project on Copr.

After logging in with FAS account, I performed following steps,

  • Create the emacs-pretest project.
  • Create emacs package in ‘Packages’ tab, by giving link to the GitLab repository.
  • Enable ‘Auto-rebuild’ for the package.
  • Use the webhook URL from ‘Integrations’, which is under ‘Settings’ to configure a webhook on GitLab.

With this setup, I was ready with automated builds. Whenever I push any commit to the Git repository, it builds a new package.

How to setup and install Emacs pretest builds

Let’s see how to install or update to these pretest builds. To install the latest pretest, run the following commands on your Fedora machine,

  • Enable the Copr repository,
    sudo dnf copr enable bhavin192/emacs-pretest
    
  • Install the latest pretest (if you don’t have Emacs installed already),
    sudo dnf install emacs
    
    or update the installed version,
    sudo dnf update emacs
    

Once updated, make sure you read the ‘GNU Emacs NEWS’ (the user-visible changes) by doing C-h n.

As an upgrade from current release to a pretest might be a major version upgrade, it’s recommended to recompile your Elisp files (including packages). For example, upgrading from 26.3 to 27.0.91. To recompile the installed packages run,

(byte-recompile-directory "~/.emacs.d/elpa" nil t)

You can run this by pressing M-: and pasting the above line. Emacs: Byte Compile Elisp Files has more details about this.

References


Comments

Comments are not enabled on this site. The old comments might still be displayed. You can reply on one of the platforms listed in ‘Posted on’ list, or email me.

jeroen on Wed Mar 3, 2021 01:17 IST

Thanks a lot for this guide! If I understand correctly you have a git repo on src.fp.o and on gitlab. Are they the same? How do you synchronise the two?

bhavin192 on Sat Mar 20, 2021 13:34 IST
Replying to comment by jeroen: "Thanks a lot for this guide! If I …"

Yes, you are right. I have a fork on src.fp.o and a repository on GitLab. They are not the same, on GitLab I have two extra commits, one for README and LICENSE and other for removing the sources file.

When a new pretest is released:
- I create a backup branch i.e as 27.2 pretest has released, I have created emacs-27.1 branch from main branch.
- Then I rebase / reset the main branch on GitLab with src.fp.o, add my two commits and then start working from there.
- When the final release is available, I just squash my all commits from master in a different local branch and create a pull request on src.fp.o to the package repository.