$ ./configure --prefix=$HOME/.local $ make $ make install
This guide is aimed at developers who are familiar with using Linux but are less acquainted with typical Linux development tools, and who do not have root access to the box they are working on. It is written with PBC in mind, but should work for most libraries.
This Program Library HOWTO contains a thorough explanation of why libraries are setup the way they are in Linux.
For information on how to use the PBC library, please consult the manual. One of the chapters is a tutorial.
You can skim most of the text and just type in what you see in the examples.
For most libraries,
once you have decompressed the source package, type the following
to install it to the .local
subdirectory of your home directory.
$ ./configure --prefix=$HOME/.local $ make $ make install
Occasionally a library does not conform to this standard, in which case you may have to edit a Makefile or similar to tell it where to install. In this case, there ought to be documentation specifying how to do this.
We call the destination directory .local
because
it functions as the system-wide /usr/local
directory (except
that it’s for your user account only), and the preceding period prevents it from
cluttering directory listings. (Of course, if you prefer to see everything
in your directory listings you don’t need the period, and in this case
you may even wish to use --prefix=$HOME
.)
If everything worked, you should see new files in assorted
subdirectories of $HOME/.local
with names such as
include
, lib
and bin
.
A PBC program foo.c
might look like the following.
#include "pbc.h" int main(void) { /* call PBC functions */ return 0; }
Simply typing gcc -o foo foo.c
will fail for two reasons.
Firstly,
gcc
does not know where to find the include file pbc.h
.
You must explicitly tell gcc
where to do this, using the
-I
option, because gcc
normally only searches
the standard
system-wide include directories.
However, even if this is done correctly, the compilation still fails,
this time because the library file (which contains the compiled library
routines) has not been mentioned in any way. Not only do you have to mention
which library you want to link with using the -l
option,
you must also tell gcc
where to find it
because the library is somewhere in your home directory and
not in a standard location.
This can be done with the -L
option.
But even if you did all this, although your program would compile, it would not run. This is because it is dynamically linked (that is, the library routines are not placed in the binary so when run, the program needs to know where to find the library).
There are two ways around this. One is to use the -static
option which will put all the required library routines in your binary.
Your binary will be a lot bigger, and every time you upgrade your library you
have to recompile the binary. On the other hand, it may be faster.
The other way is to embed the location of the library in the binary.
This can only be done by the linker, not the compiler, so we use the
-Wl
option to pass another option on to the linker.
The linker option we want is the -rpath
option (which is sometimes
called the -R
option).
Thus to compile foo.c
type:
$ gcc -o foo foo.c -I ~/.local/include/pbc -L ~/.local/lib -Wl,-rpath ~/.local/lib -l pbc
Actually, there is another way, but it is considered harmful.
If you add $HOME/.local/lib
to
the environment variable named LD_LIBRARY_PATH
all binaries will now look in that directory for any libraries they need.
I recommend only doing this in special situations. For example, if you moved the library to a different location and want to test a binary without recompiling, or if you forgot to use the rpath option and you want to test the binary without recompiling.
Typing in all these options is an annoyance. You can eliminate the need
for the -L
and -rpath
options with environment
variables LDFLAGS
or LD_RUN_PATH
,
but you still have to type the other ones.
One solution to this is to use
the make
program.
You should eventually follow a proper make
tutorial,
but for now, create
a file named Makefile
with the following contents.
target: gcc -o foo foo.c -I ~/.local/include/pbc -L ~/.local/lib -Wl,-rpath ~/.local/lib -l pbc
The second line must begin with a tab and not spaces, otherwise it will not work.
Now running make
will compile your program.
You may be wondering why there’s a pbc
on the end of the -I
option but not the -L
option. This is PBC’s fault: instead of
having a single header file named "pbc.h", there are many other
header files that the developer never needs to know about, and to stop
them messing up the include directory, all the PBC header files are
placed in a separate subdirectory of their own. Other libraries also
follow this convention.
It might seem pointless to have an rpath
option. Why not
have the binary automatically
search for the library in the directory specified by the
-L
option? While this may suit you now, situations
where this behaviour is undesirable can easily occur.
For example, say you don’t have root access on the system you develop
on and the "Foo" library is not installed (so you need the L option),
but on the target systems
that your binaries end up on, the "Foo" library is always found
in a standard location (so you don’t want the rpath option). Or maybe
"Foo" is located somewhere special on the target machine, so
you want rpath to point to a different directory altogether.