Authors Top

If you have a few years of experience in the Linux ecosystem, and you’re interested in sharing that experience with the community, have a look at our Contribution Guidelines.

 1. Overview

When installing a package, it is usually installed in a default directory. However, each Linux user is different and we may want to use other directories. For instance, some prefer to use /usr, and others use /usr/local. Also, we may want to install a package for a specific user instead of installing it for the whole system.

In this tutorial, we’ll look at how to change the destination path when installing a package using make install.

2. Using ./configure Parameters

When a package uses Autotools, it provides a ./configure script to change its configuration. This script accepts several standard parameters, and each package may add more custom parameters to it. Some packages may not use Autotools, but sometimes they provide a similar and compatible ./configure script.

When we run ./configure, we can use parameters to change the directories where make install will install the files:

  • –prefix=<dir> – This is usually /usr or /usr/local by default, and it is the prefix used in other parameters
  • –libdir=<dir> – This is the libraries directory, and it’s usually ${prefix}/lib or ${prefix}/lib64 by default
  • –bindir=<dir> – This is the executables directory, and it’s usually ${prefix}/bin by default

We can see that libdir and bindir use the prefix parameter by default. Therefore, we can change the installation directory just using the prefix argument.

A common usage is when want to be sure the package follows our system structure. We can use GNU’s diffutils package as an example. This package installs to /usr/local by default. Let’s set prefix to /usr, and libdir to /usr/lib64:

$ ./configure --prefix=/usr --libdir=/usr/lib64

Because we didn’t configure bindir, it is automatically set to /usr/bin since we defined prefix to be /usr. The prefix parameter only applies to directories we don’t set explicitly.

Next, we can run make install and the diffutils package will be installed in the desired directories. Since we’re installing to /usr, we’ll need root privileges. Let’s install it:

$ make install
$ ls -l /usr/bin/diff
-rwxr-xr-x 1 root root 1078184 Jun  6 11:21 diff

We can also change the directory to install the package in our user’s home directory. When we do this, we don’t need root privileges to install it.

Let’s clean the package with make clean and re-configure it to install it in /home/baeldung/diffutils/usr:

$ make clean
$ ./configure --prefix=/home/baeldung/diffutils/usr

As we changed prefix, other parameters such as libdir and bindir will use the /home/baeldung/diffutils/usr as the base directory.

3. Using DESTDIR

When we use ./configure, we’re changing the building and installation process, so the installed files will use those directories. For instance, the package may install resources such as icons and sounds, and it needs to know their location. Let’s search for the prefix inside the binary installed with –prefix=/home/baeldung/diffutils/usr:

$ strings /home/baeldung/diffutils/usr/bin/diff | grep /home/baeldung/diffutils/usr
/home/baeldung/diffutils/usr/share/locale

We can notice that strings found the path /home/baeldung/diffutils/usr/share/locale inside the installed binary. This is OK as long as we don’t move the installed package to another location.

Sometimes, we just want to install the package in another place without changing its internal directory structure. One example is when we want to make a tarball of the installed package and copy it to another PC. In that case, we usually install the package in an empty and temporary directory. So, the package shouldn’t have any reference to this temporary location.

To do that properly, we’ll set the DESTDIR=<dir> variable when running make install. This path will be prepended to all installation directories. Let’s remove our previous installation and re-install diffutils using DESTDIR instead:

$ rm -r /home/baeldung/diffutils
$ make clean
$ ./configure --prefix=/usr
$ make
$ make DESTDIR=/home/baeldung/diffutils install

With this configuration, make will install it using /home/baeldung/diffutils as the destination directory. Also, we configured diffutils to use /usr as the prefix. Let’s see the result:

$ ls -l /home/baeldung/diffutils/usr/bin
total 1740
-rwxr-xr-x 1 baeldung users  191456 Jun  6 12:48 cmp
-rwxr-xr-x 1 baeldung users 1078184 Jun  6 12:48 diff
-rwxr-xr-x 1 baeldung users  300552 Jun  6 12:48 diff3
-rwxr-xr-x 1 baeldung users  204376 Jun  6 12:48 sdiff
$ strings /home/baeldung/diffutils/usr/bin/diff | /home/baeldung/diffutils

As we see, we installed the package in /home/baeldung/diffutils. This time, there’s no reference to the path configured with DESTDIR.

4. Using Makefile Parameters

Some packages don’t have a ./configure script, but they provide a Makefile file. If the Makefile follows GNU conventions, we can use the same parameters used with ./configure.

If we want to set a variable with make, we’ll use the parameter variable=value. Let’s change the prefix to /usr and libdir to /usr/lib64:

$ make clean
$ make prefix=/usr libdir=/usr/lib64
$ make prefix=/usr libdir=/usr/lib64 install

Those directories may be stored in the compiled binaries, so we have to compile the package and install it with the same configuration.

The variables in the Makefile will follow the same ./configure convention, and the prefix variable is used as the base directory for other parameters.

Finally, we can use DESTDIR in a similar way as we did in the previous section. By doing so, we can install the packages in any destination without changing the package structure. Let’s use prefix=/usr/local this time, and let’s add DESTDIR to install diffutils in /home/baeldung/diffutils:

$ rm -r /home/baeldung/diffutils
$ make clean
$ make prefix=/usr/local
$ make prefix=/usr/local DESTDIR=/home/baeldung/diffutils install

We first remove the destination directory in case there are old files from the previous installation. Let’s see the result:

$ ls -l /home/baeldung/diffutils/usr/local/bin
total 1740
-rwxr-xr-x 1 baeldung users  191456 Jun 6 22:59 cmp
-rwxr-xr-x 1 baeldung users 1078184 Jun 6 22:59 diff
-rwxr-xr-x 1 baeldung users  300552 Jun 6 22:59 diff3
-rwxr-xr-x 1 baeldung users  204376 Jun 6 22:59 sdiff
$ strings /home/baeldung/diffutils/usr/local/bin/diff | /home/baeldung/diffutils

As we see, we installed diffutils in /home/baeldung/diffutils using the prefix /usr/local. Also, there are no traces of the DESTDIR directory inside the binary.

Note that only DESTDIR is in uppercase, while prefix, libdir, and others are in lowercase.

Finally, we can also use the Makefile variables when the package provides the ./configure script. In this case, the make variables will override the ./configure parameters.

5. Conclusion

In this article, we discussed how we can configure the installation directory when we install a package using make install.

First, we saw how to run ./configure and change the directories. Then, we saw that if we don’t have a ./configure script, we can change the Makefile variables. And in both cases, we saw we can use the DESTDIR variable to change where make installs the package without altering the package’s internal structure.

Authors Bottom

If you have a few years of experience in the Linux ecosystem, and you’re interested in sharing that experience with the community, have a look at our Contribution Guidelines.

Comments are closed on this article!