What should Linux/Unix 'make install' consist of?
Installation
A less trivial installer will copy several things into place, first insuring that the appropriate paths exists (using mkdir -p
or similar). Typically something like this:
- the executable goes in
$INSTALL_PATH/bin
- any libraries built for external consumption go in
$INSTALL_PATH/lib
or$INSTALL_PATH/lib/yourappname
- man pages go in
$INSTALL_PATH/share/man/man1
and possibly other sections if appropriate - other docs go in
$INSTALL_PATH/share/yourappname
- default configuration files go in
$INSTALL_PATH/etc/yourappname
- headers for other to link against go in
$INSTALL_PATH/include/yourappname
Installation path
The INSTALL_PATH
is an input to the build system, and usually defaults to /usr/local
. This gives your user the flexibility to install under their $HOME without needing elevated permission.
In the simplest case just use
INSTALL_PATH?=/usr/local
at the top of the makefile. Then the user can override it by setting an environment variable in their shell.
Deinstallation
You also occasionally see make install
s that build a manifest to help with de-installation. The manifest can even be written as a script to do the work.
Another approach is just to have a make uninstall
that looks for the things make install
places, and removes them if they exist.
Why always ./configure; make; make install; as 3 separate steps?
Because each step does different things
Prepare(setup) environment for building
./configure
This script has lots of options that you should change. Like --prefix
or --with-dir=/foo
. That means every system has a different configuration. Also ./configure
checks for missing libraries that should be installed. Anything wrong here causes not to build your application. That's why distros have packages that are installed on different places, because every distro thinks it's better to install certain libraries and files to certain directories. It is said to run ./configure
, but in fact you should change it always.
For example have a look at the Arch Linux packages site. Here you'll see that any package uses a different configure parameter (assume they are using autotools for the build system).
Building the system
make
This is actually make all
by default. And every make has different actions to do. Some do building, some do tests after building, some do checkout from external SCM repositories. Usually you don't have to give any parameters, but again some packages execute them differently.
Install to the system
make install
This installs the package in the place specified with configure. If you want you can specify ./configure
to point to your home directory. However, lots of configure options are pointing to /usr
or /usr/local
. That means then you have to use actually sudo make install
because only root can copy files to /usr and /usr/local.
Now you see that each step is a pre-requirement for next step. Each step is a preparation to make things work in a problemless flow. Distros use this metaphor to build packages (like RPM, deb, etc.).
Here you'll see that each step is actually a different state. That's why package managers have different wrappers. Below is an example of a wrapper that lets you build the whole package in one step. But remember that each application has a different wrapper (actually these wrappers have a name like spec, PKGBUILD, etc.):
def setup:
... #use ./configure if autotools is used
def build:
... #use make if autotools is used
def install:
... #use make all if autotools is used
Here one can use autotools, that means ./configure
, make
and make install
. But another one can use SCons, Python related setup or something different.
As you see splitting each state makes things much easier for maintaining and deployment, especially for package maintainers and distros.
What are makefiles, 'make install', etc.?
make
is part of the build system commonly used in Unix-type systems - binutils.
It looks at make files which hold configuration information and build targets.
Specifically -
- ./configure - this is a script that sets up the environment for the build
- make - calls
make
with the default build target. Normally builds the application. - make install - calls
make
with theinstall
build target. Normally installs the application.
why make before make install
When you run make
, you're instructing it to essentially follow a set of build steps for a particular target. When make
is called with no parameters, it runs the first target, which usually simply compiles the project. make install
maps to the install
target, which usually does nothing more than copy binaries into their destinations.
Frequently, the install
target depends upon the compilation target, so you can get the same results by just running make install
. However, I can see at least one good reason to do them in separate steps: privilege separation.
Ordinarily, when you install your software, it goes into locations for which ordinary users do not have write access (like /usr/bin
and /usr/local/bin
). Often, then, you end up actually having to run make
and then sudo make install
, as the install step requires a privilege escalation. This is a "Good Thing™", because it allows your software to be compiled as a normal user (which actually makes a difference for some projects), limiting the scope of potential damage for a badly-behaving build procedure, and only obtains root privileges for the install step.
What are the './configure, make, make install' projects called?
Autoconf and automake are collectively called the GNU autotools (and libtool may be included in that category as well), so autotools is the most general name.
Note that not all programs that have a configure
script to generate a makefile are necessarily using the autotools, or not all of them.
Make install, but not to default directories?
It depends on the package. If the Makefile is generated by GNU autotools (./configure
) you can usually set the target location like so:
./configure --prefix=/somewhere/else/than/usr/local
If the Makefile is not generated by autotools, but distributed along with the software, simply open it up in an editor and change it. The install target directory is probably defined in a variable somewhere.
Related Topics
How Set Multiple Env Variables for a Bash Command
Exclude List of Files from Find
How to Check the Version of Openmp on Linux
How to Continue One Thread at a Time When Debugging a Multithreaded Program in Gdb
How to Simulate a Failed Disk During Testing
How to Find All the Files That Were Created Today in Unix/Linux
How to Send List of File in a Folder to a Txt File in Linux
Detecting Keyboard, Mouse Activity in Linux
How to Use Variables in a Bash for Loop
Postgresql -Bash: Psql: Command Not Found
Do (Statically Linked) Dlls Use a Different Heap Than the Main Program
How Are Sbrk/Brk Implemented in Linux
Differencebetween Clock_Monotonic & Clock_Monotonic_Raw
Bypass Rsync Prompt "Are You Sure You Want to Continue Connecting"