GNU Astronomy Utilities

3.3.1.2 Installation directory

One of the most commonly used options to ./configure is
--prefix, it is used to define the directory that will host all
the installed files (or the “prefix” in their final absolute file
name). For example, when you are using a server and you don’t have
administrator or root access. In this example scenario, if you don’t use
the --prefix option, you won’t be able to install the built files
and thus access them from anywhere without having to worry about where they
are installed. However, once you prepare your startup file to look into the
proper place (as discussed thoroughly below), you will be able to easily
use this option and benefit from any software you want to install without
having to ask the system administrators or install and use a different
version of a software that is already installed on the server.

The most basic way to run an executable is to explicitly write its full
file name (including all the directory information) and run it. One example
is running the configuration script with the $ ./configure
command (see Quick start). By giving a specific directory (the
current directory or ./), we are explicitly telling the shell to
look in the current directory for an executable file named
‘configure’. Directly specifying the directory is thus useful for
executables in the current (or nearby) directories. However, when the
program (an executable file) is to be used a lot, specifying all those
directories will become a significant burden. For example, the ls
executable lists the contents in a given directory and it is (usually)
installed in the /usr/bin/ directory by the operating system
maintainers. Therefore, if using the full address was the only way to
access an executable, each time you wanted a listing of a directory, you
would have to run the following command (which is very inconvenient, both
in writing and in remembering the various directories).

$ /usr/bin/ls

To address this problem, we have the PATH environment variable. To
understand it better, we will start with a short introduction to the shell
variables. Shell variable values are basically treated as strings of
characters. For example, it doesn’t matter if the value is a name (string
of alphabetic characters), or a number (string of numeric
characters), or both. You can define a variable and a value for it by
running

$ myvariable1=a_test_value
$ myvariable2="a test value"

As you see above, if the value contains white space characters, you have to
put the whole value (including white space characters) in double quotes
("). You can see the value it represents by running

$ echo $myvariable1
$ echo $myvariable2

If a variable has no value or it wasn’t defined, the last command will only
print an empty line. A variable defined like this will be known as long as
this shell or terminal is running. Other terminals will have no idea it
existed. The main advantage of shell variables is that if they are
exported74, subsequent programs that are run
within that shell can access their value. So by changing their value, you
can change the “environment” of a program which uses them. The shell
variables which are accessed by programs are therefore known as
“environment variables”75. You can see the full list of exported variables that your
shell recognizes by running:

$ printenv

HOME is one commonly used environment variable, it is any user’s
(the one that is logged in) top directory. Try finding it in the command
above. It is used so often that the shell has a special expansion
(alternative) for it: ‘~’. Whenever you see file names starting with
the tilde sign, it actually represents the value to the HOME
environment variable, so ~/doc is the same as $HOME/doc.

Another one of the most commonly used environment variables is PATH,
it is a list of directories to search for executable names. Its value is a
list of directories (separated by a colon, or ‘:’). When the address
of the executable is not explicitly given (like ./configure above),
the system will look for the executable in the directories specified by
PATH. If you have a computer nearby, try running the following
command to see which directories your system will look into when it is
searching for executable (binary) files, one example is printed here
(notice how /usr/bin, in the ls example above, is one of the
directories in PATH):

$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/bin

By default PATH usually contains system-wide directories, which are
readable (but not writable) by all users, like the above example. Therefore
if you don’t have root (or administrator) access, you need to add another
directory to PATH which you actually have write access to. The
standard directory where you can keep installed files (not just
executables) for your own user is the ~/.local/ directory. The names
of hidden files start with a ‘.’ (dot), so it will not show up in
your common command-line listings, or on the graphical user interface. You
can use any other directory, but this is the most recognized.

The top installation directory will be used to keep all the package’s
components: programs (executables), libraries, include (header) files,
shared data (like manuals), or configuration files (see Review of library fundamentals for a thorough introduction to headers and
linking). So it commonly has some of the following sub-directories for each
class of installed components respectively: bin/, lib/,
include/man/, share/, etc/. Since the
PATH variable is only used for executables, you can add the
~/.local/bin directory (which keeps the executables/programs or more
generally, “binary” files) to PATH with the following command. As
defined below, first the existing value of PATH is used, then your
given directory is added to its end and the combined value is put back in
PATH (run ‘$ echo $PATH’ afterwards to check if it was
added).

$ PATH=$PATH:~/.local/bin

Any executable that you installed in ~/.local/bin will now be usable
without having to remember and write its full address. However, as soon as
you leave/close your current terminal session, this modified PATH
variable will be forgotten. Adding the directories which contain
executables to the PATH environment variable each time you start a
terminal is also very inconvenient and prone to errors. Fortunately, there
are standard ‘startup files’ defined by your shell precisely for this (and
other) purposes. There is a special startup file for every significant
starting step:

/etc/profile and everything in /etc/profile.d/

These startup scripts are called when your whole system starts (for example
after you turn on your computer). Therefore you need administrator or root
privileges to access or modify them.

~/.bash_profile

If you are using (GNU) Bash as your shell, the commands in this file are
run, when you log in to your account through Bash. Most commonly
when you login through the virtual console (where there is no graphic user
interface).

~/.bashrc

If you are using (GNU) Bash as your shell, the commands here will be run
each time you start a terminal and are already logged in. For example, when
you open your terminal emulator in the graphic user interface.

For security reasons, it is highly recommended to directly type in your
HOME directory value by hand in startup files instead of using
variables. So in the following, let’s assume your user name is
‘name’ (so ~ may be replaced with /home/name). To add
~/.local/bin to your PATH automatically on any startup file,
you have to “export” the new value of PATH in the startup file
that is most relevant to you by adding this line:

export PATH=$PATH:/home/name/.local/bin

Now that you know your system will look into ~/.local/bin for
executables, you can tell Gnuastro’s configure script to install everything
in the top ~/.local directory using the --prefix
option. When you subsequently run $ make install, all the
install-able files will be put in their respective directory under
~/.local/ (the executables in ~/.local/bin, the compiled
library files in ~/.local/lib, the library header files in
~/.local/include and so on, to learn more about these different
files, please see Review of library fundamentals). Note that tilde
(‘~’) expansion will not happen if you put a ‘=’ between
--prefix and ~/.local76, so we have avoided
the = character here which is optional in GNU-style options, see
Options.

$ ./configure --prefix ~/.local

You can install everything (including libraries like GSL, CFITSIO, or
WCSLIB which are Gnuastro’s mandatory dependencies, see Mandatory dependencies) locally by configuring them as above. However, recall that
PATH is only for executable files, not libraries and that
libraries can also depend on other libraries. For example WCSLIB depends on
CFITSIO and Gnuastro needs both. Therefore, when you installed a library in
a non-recognized directory, you have to guide the program that depends on
them to look into the necessary library and header file directories. To do
that, you have to define the LDFLAGS and CPPFLAGS
environment variables respectively. This can be done while calling
./configure as shown below:

It can be annoying/buggy to do this when configuring every software that
depends on such libraries. Hence, you can define these two variables in the
most relevant startup file (discussed above). The convention on using these
variables doesn’t include a colon to separate values (as
PATH-like variables do), they use white space characters and each
value is prefixed with a compiler option77: note
the -L and -I above (see Options), for -I
see Headers, and for -L, see Linking. Therefore we
have to keep the value in double quotation signs to keep the white space
characters and adding the following two lines to the startup file of
choice:

Dynamic libraries are linked to the executable every time you run a program
that depends on them (see Linking to fully understand this important
concept). Hence dynamic libraries also require a special path variable
called LD_LIBRARY_PATH (same formatting as PATH). To
use programs that depend on these libraries, you need to add
~/.local/lib to your LD_LIBRARY_PATH environment variable
by adding the following line to the relevant start-up file:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/name/.local/lib

If you also want to access the Info (see Info) and man pages (see
Man pages) documentations add ~/.local/share/info and
~/.local/share/man to your INFOPATH78 and MANPATH environment variables
respectively.

A final note is that order matters in the directories that are searched for
all the variables discussed above. In the examples above, the new directory
was added after the system specified directories. So if the program,
library or manuals are found in the system wide directories, the user
directory is no longer searched. If you want to search your local
installation first, put the new directory before the already existing list,
like the example below.

export LD_LIBRARY_PATH=/home/name/.local/lib:$LD_LIBRARY_PATH

This is good when a library, for example CFITSIO, is already present on the
system, but the system-wide install wasn’t configured with the correct
configuration flags (see CFITSIO), or you want to use a newer version
and you don’t have administrator or root access to update it on the whole
system/server. If you update LD_LIBRARY_PATH by placing
~/.local/lib first (like above), the linker will first find the
CFITSIO you installed for yourself and link with it. It thus will never
reach the system-wide installation.

There are important security problems with using local installations first:
all important system-wide executables and libraries (important executables
like ls and cp, or libraries like the C library) can be
replaced by non-secure versions with the same file names and put in the
customized directory (~/.local in this example). So if you choose to
search in your customized directory first, please be sure to keep it
clean from executables or libraries with the same names as important system
programs or libraries.

Summary: When you are using a server which doesn’t give you
administrator/root access AND you would like to give priority to your own
built programs and libraries, not the version that is (possibly already)
present on the server, add these lines to your startup file. See above for
which startup file is best for your case and for a detailed explanation on
each. Don’t forget to replace ‘/YOUR-HOME-DIR’ with your home
directory (for example ‘/home/your-id’):

Afterwards, you just need to add an extra
--prefix=/YOUR-HOME-DIR/.local to the ./configure command
of the software that you intend to install. Everything else will be the
same as a standard build and install, see Quick start.

Info has the
following convention: “If the value of INFOPATH ends with a
colon [or it isn’t defined] ..., the initial list of directories is
constructed by appending the build-time default to the value of
INFOPATH.” So when installing in a non-standard directory and if
INFOPATH was not initially defined, add a colon to the end of
INFOPATH as shown below, otherwise Info will not be able to find
system-wide installed documentation:echo 'export
INFOPATH=$INFOPATH:/home/name/.local/share/info:' >> ~/.bashrc Note that
this is only an internal convention of Info, do not use it for other
*PATH variables.