Use apt-get build-dep to install build dependencies
Or, how to build the latest tmux on Ubuntu
There are times you want to use a more up-to-date software than what comes with your Linux Distribution (distro). I had to do this when I was using Ubuntu 16.04. I wanted to use the latest tmux for its advanced mouse support but Ubuntu 16.04 came with an older version of tmux without the feature. Since the LTS versions rarely do a major-version upgrade, the only way to get the newer version was to build it from source.
Sometimes, building from source can be as easy as
./configure && make && sudo make install. More often than not though, it can be a real test of patience. What I do usually is to run the build script, read the error message, search the name of the missing component, rinse and repeat.
Here's an example of me trying to build
tmux from scratch on Ubuntu (⛔ indicates a trial-and-error cycle):
# Get Git $ sudo apt-get install -y git # Get the source $ git clone https://github.com/tmux/tmux.git; cd tmux # Well, this is the only executable, so let's go. $ sh autogen.sh ... aclocal: not found ⛔ # after googling $ sudo apt install -y automake $ sh autogen.sh # ✅ works this time. $ ./configure ... configure: error: no acceptable C compiler found in $PATH ⛔ # I guess I should install gcc, since that's a popular compiler. $ sudo apt install -y gcc $ ./configure ... configure: error: "libevent not found" ⛔ # Let's install the development package $ sudo apt install -y libevent-dev $ ./configure ... configure: error: "curses not found" ⛔ # I just happen to know that the package is not called libcurses-dev 😏 $ apt install -y ncurses-dev $ ./configure ... config.status: error: Something went wrong bootstrapping makefile fragments for automatic dependency tracking. If GNU make was not used, consider re-running the configure script with MAKE="gmake" (or whatever is necessary) ... ⛔ # What is totally not obvious is from the message above is that # I am actually missing make entirely. $ sudo apt install -y make $ ./configure # succeeds ✅ $ make ... ./etc/ylwrap: line 175: yacc: command not found ⛔ # Googles to find out that GNU bison provides yacc $ sudo apt install -y bison $ make # Finally succeeds ✅
This was just 6 tries, but with bigger packages, this trial-and-error approach can be extremely time consuming. Worse, even after building, you can still end up with random missing features because some of the optional features are included only when the library is found on the system.
Fortunately, on a Debian-based distro (like Ubuntu), there is a quick way to install the build dependencies for the software that already exists in the repo. This relatively obscure command
apt-get build-dep will install all the build dependencies for you.
Additional Notes for Ubuntu
On Ubuntu, the first step to use
apt-get build-dep is to add the source code repositories to the system source repositories. Source repositories contain the metadata necessary to find out the build-time dependencies for packages. We need to do this on Ubuntu once because recent versions of Ubuntu ships with the source repositories excluded by default. Presumably, this is to make apt-get update faster but I was never able to confirm. If anyone knows the answer, please let me know.
To enable the source code repositories, you can uncomment the lines starting with
deb-src, or run the following command:
# The old sources.list will be backed up as /etc/apt/sources.list.bak $ sudo sed -i.bak 's/^# *deb-src/deb-src/g' /etc/apt/sources.list && \ sudo apt-get update # restore with sudo mv /etc/apt/sources.list.bak /etc/apt/sources.list
Real-life Example: Building tmux
With the source repository enabled, let's try building tmux again.
Install the build dependencies of
$ sudo apt-get build-dep -y tmux
Now we can start building.
cd tmux sh autogen.sh && ./configure && make -j 4
For the latest tmux on Ubuntu 20.04, you will get an error like this (as of Feb 2022):
./etc/ylwrap: line 175: yacc: command not found
We can fix this by installing the yacc-compatible GNU bison:
sudo apt-get install -y bison. Re-running the build should work.
If everything went well, you should be able to run
./tmux to test it.
In the end, I still had to go through 1 trial-and-error cycle (yacc) but that's 5 less that the original.
Bonus 1: Safe Installation of Compiled Packages
Here's one more tip to manage the installation of source-compiled packages. Many guides at this point would tell you to run
sudo make install but often there is a nasty surprise waiting for you after - You are at the mercy of package maintainer to be able to uninstall the package cleanly. Often the
uninstall target just doesn't exist, in which case you can't easily uninstall the software. There are a couple ways to handle this (e.g., GNU stow - a topic for another blog). Here I will show how you can use
checkinstall to easily create a reasonably well-behaved
dpkg from the source. To use
checkinstall, run the following command:
$ sudo apt-get install -y checkinstall
Now you can run
checkinstall to create a
dpkg (Debian package) and install it.
It will ask you a bunch of questions, you can go with the default most of the time. As for the version string I just used 9999 (a convention that I borrowed from Gentoo) to express that I want my package to be the latest version.
# make a package - may have to answer some prompts $ checkinstall --pkgname=tmux --pkgversion=9999 \ --install=no --fstrans=yes # install the package (replace amd64 with your architecture) $ sudo dpkg -i tmux_9999-1_amd64.deb
Now you can see that your tmux is installed as
/usr/local/bin/tmux (Technically it's in a wrong place for a
dpkg package but it's not that important).
Now if you try to install tmux from apt, it will say you have the latest version.
$ sudo apt-get install -y tmux Reading package lists... Done Building dependency tree Reading state information... Done tmux is already the newest version (9999-1). # And to uninstall this package, # you can simply run apt-get remove -y tmux
Bonus 2: What if I just want to find the list of dependencies without installing them?
Found this answer on askubuntu.com:
# replace tmux with the package in question apt-cache showsrc tmux | grep ^Build-Depends
Bonus 3: What if I am on Redhat/Fedora?
Use dnf builddep or