p4est 2020 HCM Summer School: Build
Author: Carsten Burstedde

We are organizing a `p4est` summer school sponsored by the Hausdorff Center for Mathematics at the University of Bonn, Germany. Please see also the school's home page and application forms.

## Building the library and a new example

We distribute `p4est` as source code. The usual way to work with it is to download it in one of severaly possible ways and to compile it. This generates a binary software library and some ready-to-run examples that come with it. There exist contributed binary packages for some operating system distributions, which let you get away without compiling `p4est` yourself. In this tutorial, we talk about the most common ways to build the software and to write your own hello-world example program.

Required skills
  Programming in C! Furthermore, know how to work with a command shell, how to extract a tar file or how to git clone, and know how to run a compiler and make in general. In case you did not know, `make` is a command line utility to help building projects consisting of many files, rebuilding only files that have changed. It reads its configuration from a file called `Makefile`.
Skills acquired
  Brushing up on calling a `configure` script, creating one's own example program that compiles with `p4est`.
Additional material
  See also the installation document in the source tree and any documentation on `configure` scripts. To me, autoconf is ok but the real winner is automake. I have linked to the documentation below.
Next steps
  Extend your hello-world program with a typical `p4est` workflow as described in the forest tutorial, and write some graphics output along the lines of the I/O tutorial.

### Getting to the source

If you are working with a Debian Linux distribution, you may install libp4est-dev using the Debian package manager. We are thankful to the maintainers for compiling and packaging the code in this convenient binary form. You get a frozen and stable version of the code with the least amount of hassle, but cannot contribute back to the software this way.

Alternatively, you may find the latest tarball online, unpack it, then run configure and make. If you specify an installation prefix to configure and run make install, you will find the libraries and example programs in their proper directory. From here on, you may include the `p4est` header files in your own source code and link your program to the library. This method is fine to get going, or to provide a `p4est` installation to other software that requires it to compile. As with the binary package, you get a frozen and stable version of the code.

A more active way of getting involved is to clone the p4est github repository. This requires to know how to use the revision control tool git or one of its many gui frontends. We recommend to use the branch prev3-develop, which has minimized dependencies and contains the most modern set of algorithms. Using the source code on github enables you to contribute to the software in the future and to receive latest updates by calling git pull. Note that the tarballs generated by github do not work. We do not include the configure script on github either. To generate it, call the ./bootstrap script in the p4est toplevel source directory. This requires a working installation of GNU autoconf, automake and libtool.

### Configure, make, install

Suppose now that we have a local `p4est` source code directory with an existing configure file. If it is missing or other things are funny with the autoconf system, calling bootstrap should fix it. In general, however, calling bootstrap repeatedly is not required. You may build `p4est` with MPI or without it. My personal recommendation is to use MPICH, either from a binary package or manually compiled. Make sure your PATH environment variable includes the MPICH binaries such as mpicc and mpirun. We recommend the following procedure to build `p4est`.

1. `configure --help` prints a list of available options to configure. When working with the branch prev3-develop, defaults are usually ok. To get the tarballs working quickly, add `--without-blas`.
2. Create a build directory parallel to the `p4est` source, enter it, and decide on yet another directory for installation (the latter not necessary for general hacking).
3. Make a relative call such as `../path-to-source/configure CFLAGS="-Wall -Wuninitialized -O0 -g" --enable-debug --enable-mpi --prefix=absolute-path-to-install`. The debug option enables assertions that we recommend highly to add also in your own programs. Omit the debug option only if you really must have the fastest running code.
4. Call `make -j8 V=0` to build the software. The `-j` switch allows for parallel make processes, speeding up the build noticeably, and `V=0` disables echoing the compile command lines.
5. If you're curious, call `make -j2 check V=0`. This will compile and execute our complimentary test programs.
6. If you have specified an installation prefix, you can run `make -j10 install V=0`. This call will neatly arrange all exported header files, library files, example binaries, some configuration files and documentation in mostly standard-conforming directories.
7. If you're preparing a code version that shall be clean enough to create a tarball from it in the future, or clean enough for us to merge into upstream `p4est`, run `make distcheck`. If all goes well and after all warnings and errors have been eliminated, you will be presented with a brandnew `.tar.gz` including your contributions.

### Creating a new example

There are two options to create a new example program: inside the `p4est` build system or outside of it. First, the inside way! You will notice the example subdirectories in the source. Create your own, say `example/mytest/`, and place there a minimal C file with a main function:

    #include <p4est.h>

    int main (int argc, char ** argv) {
      sc_MPI_Comm mpicomm = sc_MPI_COMM_WORLD;
      int mpiret = sc_MPI_Init (&argc, &argv);
      SC_CHECK_MPI (mpiret);
      sc_init (mpicomm, 1, 1, NULL, SC_LP_DEFAULT);
      p4est_init (NULL, SC_LP_DEFAULT);

      mpiret = sc_MPI_Finalize ();
      SC_CHECK_MPI (mpiret);
      return 0;
    }

The two init functions are optional, strictly speaking. `p4est` will work fine without them. The MPI communicator `mpicomm` is remembered to determine the ranks for logging messages. This communicator does not need to be the same as the one later passed to `p4est_new` and friends, but we recommand the later ones to be at least subsets with identical rank zero such that the prefixes of log messages make sense.

If you are not writing your `main` function but rather use `p4est` from library code, replace the two `1` arguments with `0`, which disables some sytem-level error hooks, and possibly bump the log level to `SC_LP_ERROR` to make the library quiet.

Now, copy a `Makefile.am` from a parallel example directory and adapt it, doing a careful manual search-and-replace and if necessary consulting the automake documentation. Finally, edit the Makefile.am in the toplevel source directory. It contains a block of include example lines, where you need to add yours. If you run make now, your example will compile.

The second way to build with `p4est` is to create an independent project directory containing your main program and a Makefile that pulls in the required files. You may do this manually, adding `-I` and `-L` paths to the compile and link lines, respectively, and specify `-lp4est -lsc -lz` when linking. Make sure to use the same compiler and MPI installation as for compiling `p4est`. This method works most reliably when referring to an installed `p4est` compile. A shortcut is to include `etc/Makefile.p4est.mk` from the `p4est` installation in your project Makefile. Take a look at this file to see which variables it defines. When creating an independent project like this, there is no need to mess with the `p4est` source tree.