p4est 2020 HCM Summer School: Build

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.