Building using `configure`
==========================

The instructions will assume that you're working from a command-line shell.
If you prefer to work from an IDE, you'll have to know how your IDE likes to
do things, and you'll want to follow the shell instructions as a guide.


Prerequisites
-------------

Before building and installing the `libpqxx` library, you first need to
install the `libpq` library. This is the official C client library for
PostgreSQL that allows `libpqxx` to communicate with the database backend
server. Methods for installing the `libpq` library will vary depending
on your operating system and individual setup.

It also requires Python 3, which comes pre-installed on many systems.  And, you
may need various standard Unix or GNU command-line utilities.


Quick start
-----------

Once you have downloaded the `libpqxx` source code, you can build and
install it quickly by entering the following commands:

```shell
    ./configure --disable-shared
    make
    sudo make install
```

This installation automatically places the `libpqxx` libraries in the
appropriate locations for your system. If you wish, you may delete the
downloaded folder after the installation process completes.

Want more detail?  Read on.


Stages
------

I'll explain the main build steps in more detail below, but here's a quick
overview:

1. Configure
2. Compile
3. Test
4. Install

The Test step is optional.


Configure
---------

The `configure` script configures your build.  It figures out various
parameters, such as where libpq and its headers are, which C++ features your
compiler supports, and which options your compiler needs.  It generates
Makefiles, which in turn tell the `make` utility how to perform tasks such as
compiling libpqxx, running tests, cleaning up after itself, and installing
libpqxx.

The `configure` step is also where you can set these options, e.g. to instruct
the compiler to look for libpq in a non-standard place, or to use a different
compiler, or pass different compiler flags.  Don't try to specify those while
doing the actual compile; set them once when running `configure`.

Let's say `$BUILD` is the directory where you want to build libpqxx, and
`$SRC` is where its source code is.  So for example, the readme file will be at
`$SRC/README.md`.

In the simplest case, you just do:

```shell
    cd $BUILD
    $SRC/configure
```

Add `configure` options as needed.  There's more about the options below, or in
the output of `configure --help`.  I'll also explain the two directories.


### Cheat sheet

Here are some popular `configure` options:

* `--disable-documentation` skips building of the documentation.
* `CXXFLAGS=-O0` disables optimisation.  Slower code, but faster build.
* `CXXFLAGS=-O3` asks for _more_ optimisation.  Faster code, slower build.
* `CXX=clang++` compiles with `clang++` as the compiler.
* `--enable-maintainer-mode` makes the compiler more pedantic about the code.
* `--enable-audit` enables expensive run-time checks for debugging.
* `--with-postgres-lib=$DIR` looks for libpq in `$DIR`.
* `--with-postgres-include=$DIR` looks for the libpq headers in `$DIR`.
* `--prefix=$PATH` prepares to install libpqxx in `$PATH`.
* `--enable-shared` enables compilation of libpqxx as a shared library.
* `--disable-shared` disbles compilation of libpqxx as a shared library.
* `--enable-static` enables compilation of libpqxx as a static library.
* `--disable-static` disables compilation of libpqxx as a static library.
* `--help` shows you a lot more of the options.

So for example, to get a very quick build but produce very inefficient code:

```shell
    ./configure --disable-documentation CXXFLAGS=-O0
```


Or if you want to pull out all the stops to find problems in the code:

```shell
    ./configure --enable-maintainer-mode --enable-audit CXXFLAGS=-O3
```

(Requesting `-O3` optimisation will make some compilers perform extra analysis
which may, as a side effect, cause them to notice and warn about certain kinds
of mistakes in the code, such as occasionally-unused variables.)


### Finding libpq

One of `configure`'s most important jobs in the libpqxx build is to find the
headers and library for libpq.  It has three ways of finding those:

1. Asking a popular tool called `pkg-config`, if installed.
2. Asking postgres' deprecated `pg_config` tool, if installed.
3. Through explicit command-line options to `configure`.

The explicit command-line options are `--with-postgres-lib` (for the libpq
library binary) and `--with-postgres-include` (for the libpq headers).

If you want to use a version of libpq that's not installed in a standard
location, e.g. if you're cross-compiling to produce a binary for a different
CPU architecture than your native system's, use the explicit options.


### Where does the `configure` script come from?

I didn't write the `configure` script.  It was generated by GNU `autoconf` and
related GNU tools.  There's a script to re-generate it, called `autogen.sh`.

The contents of `configure` are based on a higher-level script called
`configure.ac`.  This is where I script checks for specific features in libpq
or the compiler.  The `configure` script adds a lot of built-in items that I
don't need to worry about, such as figuring out exactly how your build tools
work.

Don't try to debug `configure` yourself if you can help it.  It's very hard to
read, partly because it's automatically generated, but also because it is
engineered to work with an extremely broad range of shells, compilers, tools,
and operating systems.  If you're going to do a "deep dive," try looking at
`configure.ac` instead.


### Source and Build trees

Where should you run `configure`?

Two directories matter when building libpqxx: the _source tree_ (where the
libpqxx source code is) and the _build tree_ (where you want your build
artefacts).  Here I will call them `$SRC` and `$BUILD`, but you can call them
anything you like.

They can be one and the same, if you like.  It's convenient, but less clean, as
source code and build artefacts will exist in the same directory tree.  If
you're going to delete the source tree after installing, of course it's fine to
make a mess in there.


Compile
-------

To start the compile, run the `make` tool.  It will go through all the steps to
produce a libpqxx library binary.

Beware though, it only runs _one_ compiler process at a time.  That could take
a while.  Use the `-j` option to make it run concurrent processes, e.g.:

```shell
    make -j8
```

Very roughly speaking, it's probably fastest if you run one process per CPU
core in your system.  If you have the `nproc` utility installed:

```shell
    make -j$(nproc)
```

If you want a very fast build and don't mind missing out on efficient code or
documentation, tweak the Configure step above by adding `configure` options
like `CXXFLAGS=-O0` and `--disable-documentation`.


Test
----

Of course libpqxx comes with a test suite, to check that the library is
functioning correctly.

You can run it, but there's one caveat: you need to give it a database where it
can log in, without a password or any other parameters, and try out various
things.

And when I say you need to "give" it a database, I really mean "give."  The
test suite will create and drop tables.  Those will all have names prefixed
with "pqxx", so it's probably safe to use a database you already had, but if
any of the items in your database happen to have names starting with `pqxx`,
tough luck.  They're fair game.

Enter this in your  shell to build and run the tests:

```shell
    make check
```

As with compiling, use the `-j` option to make better use of your CPUs.  For
example:

```shell
    make check -j$(nproc)
```


### Configuring the test database

But what if you do need a password to log into your test database?  Or, what if
it's running on a different system so you need to pass that machine's address?
What if it's not running on the default port?

You can set these parameters for the test suite, or for any other libpq-based
application, using the following environment variables.  (They only set default
values, so they won't override parameters that the application sets in some
other way.)

* `PGHOST` — the IP address where we can contact the database's socket.  Or
  for a Unix domain socket, its absolute path on the filesystem.
* `PGPORT` —
* `PGDATABASE` — the name of the database to which you wish to connect.
* `PGUSER` — user name under which you wish to log in on the database.
* `PGPASSWORD` — user name's password for accessing the database.

See the full list at [
    https://www.postgresql.org/docs/current/libpq-envars.html
](https://www.postgresql.org/docs/current/libpq-envars.html).

**Be careful with passwords,** by the way.  Depending on your operating system
and configuration, an attacker with access to your machine could try to read
your password if you set it on the command line:

* Your shell may keep a log of the commands you have entered.
* Environment variables may be visible to other users on the system.

If at all possible, rely on postgres "peer authentication."  Once set up, it is
both more secure and more convenient than passwords.


Install
-------

Installing libpqxx will install the library and headers in a location chosen at
the time you can the `configure` script.  On some systems it defaults to the
`/usr/local/` tree, but it may be different in your environment.  Or, use the
`configure` script's `--prefix` option to set an install location.

(If you want to see exactly what happens, you can run any `make` command line
with the `-n` option, which means: don't actually do this, but print all the
commands you would execute if you did.  It's a lot of output though.)

To install, ensure that you have sufficient privileges to write the files to
their install locations, and run:

```shell
    make install
```

Save your build tree somewhere, so that you will be able to undo installation
in the future:

```shell
    make uninstall
```

When using the library, make sure the libpqxx headers are in your compiler's
include path.  (You will no longer need the libpq headers at that time.)

Also, building an application which uses libpqxx, make sure the libpqxx library
binary is in your compiler's library search path.  And if the library binary is
a shared library, you'll also need it in your loader's search path when running
your application.

This last part goes for libpq as well: when using libpq, make sure you have
the libpq library binary in your compiler's library search path, and if it's a
shared library, also have it in your loader's search path when running.
