Building OpenFOAM with the Meson build system

Volker Weißmann
volker.weissmann@gmx.de
https://weissmann.pm
No company or university, just too much time

Gnu Make

make is a program, not affiliated with OpenFOAM or me, that reads $CWD/Makefile (and usually also $CWD/subdir/Makefile) and if any of these files contains e.g.

					foo.o: foo.c
						gcc foo.c -c -o foo.o
					  
it runs

					gcc foo.c -c -o foo.o
				

Ninja

ninja is a program, not affiliated with OpenFOAM or me, that reads $CWD/ninja.build and if $CWD/ninja.build contains e.g.

					rule cc
  						command = gcc $in -c -o $out
					build foo.o: cc foo.c
					  
it runs

					gcc foo.c -c -o foo.o
				

CMake

cmake is a program, not affiliated with OpenFOAM or me, that reads $CWD/CMakeLists.txt (and usually also $CWD/subdir/CMakeLists.txt) and if these files contain something like

					add_executable(example foo.c)
				
it will create the Makefile's or the ninja.build-file we talked about.

					cmake -B builddir -G "Unix Makefiles"
					cmake -B builddir -G Ninja
				

Meson

Meson is a program, not affiliated with OpenFOAM or barely affiliated me, that reads $CWD/meson.build (and usually also $CWD/subdir/meson.build) and if these files contain something like

					executable('example', 'foo.c')
				
it will create the ninja.build-file we talked about.

					meson setup builddir
				
  • The Makefile's and ninja.build-file generated by cmake or meson cannot be moved to another machine.
  • Contain absolute paths to the source directory
  • Detection which optional dependency exits happens when ninja.build is generated
  • You cannot commit these generated files to the git repo.
  • Anyone who wants to build $project needs not just make and ninja, but also cmake, meson and python installed.

OpenFOAM, status quo


					cd openfoam
					source etc/bashrc
					./Allwmake
					cd src/surfMesh
					wmake
				
  • source etc/bashrc puts /path/to/openfoam/wmake in $PATH
  • which wmake will print /path/to/openfoam/wmake/wmake
  • ./Allwmake calls wmake

OpenFOAM, status quo

wmake calls

					make -f /path/to/openfoam/wmake/makefiles/general
				
wmake/makefiles/general contains

					include $(OBJECTS_DIR)/options
				
src/surfMesh/Make/options

					EXE_INC = \
						-I$(LIB_SRC)/fileFormats/lnInclude

					LIB_LIBS = \
						-lOpenFOAM \
						-lfileFormats
				
src/surfMesh/Make/files

					MeshedSurfaceAllocator/MeshedSurfaceIOAllocator.C
					MeshedSurface/MeshedSurfaceCore.C
					MeshedSurface/MeshedSurfaces.C

					LIB = $(FOAM_LIBBIN)/libsurfMesh
				

OpenFOAM, what I did

I wrote a python script.

  • Reads */Make/files and */Make/options
  • Writes meson.build files to the openfoam source tree
  • Machine independent output

					git clone https://develop.openfoam.com/Development/openfoam
					git clone https://codeberg.org/Volker_Weissmann/foam_meson
					cd foam_meson
					./generate_meson_build.py ../openfoam
					cd ../openfoam
					meson setup some_path
					cd some_path
					ninja
					meson devenv # Launches a subshell
					cd ../tutorials/basic/laplacianFoam/flange
					./Allrun
				

Dependencies and Installation

ninja

  • Packaged in every major distro
  • Also available as a single binary
  • Depends on libc, libm, libstdc++, gcc-libs

meson

  • We need 0.59.0 minimum (2021-07-18)
  • Packaged in every major distro
  • pip install meson
  • git clone https://github.com/mesonbuild/meson/
  • curl https://github.com/mesonbuild/meson/releases/download/0.59.0/meson-0.59.0.tar.gz
  • ./meson.py
  • Newest meson version needs Python 3.7 or greater (2018-06-27)
  • Meson version 0.59.0 needs Python 3.6 or greater (2016-12-23)

Dependencies and Installation

foam_meson

  • git clone https://codeberg.org/Volker_Weissmann/foam_meson
  • ./generate_meson_build.py
  • Python 3.6 or newer
  • Make

					print_stuff:
						echo $(LIB_INC)
						echo $(EXE_INC)
						echo $(LIB_LIBS)
						echo $(EXE_LIBS)
				

Meson description

  • More high-level than Gnu Make
  • Much logic is moved from the Makefiles inside of meson itself instead of meson.build
  • Meson wants to take control more than Gnu Make does
  • Hacks are hard (e.g. lnInclude, .C. vs .cpp), escape hatches are limited
  • meson.build is not turing complete
  • Can't add your own abstraction layer
  • Way more opinionated than Gnu Make

Why switch to meson

Let's say someone is somewhat familiar with meson, but completely new to openfoam. He will have a very easy time doing $thing with build. With $thing being e.g.

  • IDE Integration
  • Adding an optional dependency
  • ...

The same cannot be said about gnu wmake.

  • Unlike wmake, Not the only project using meson
  • Googling "How to do $thing in meson" gives more results than "How to do $thing in wmake"
  • meson.build files are very easy to read

Why switch to meson

  • meson setup generates compilation_commands.json -> good for IDE support
  • If nothing has changed: ninja takes 2-5 seocnds, ./Allwmake takes over a minute
  • Meson is better at knowing what needs to be rebuild
  • Running wclean is sometimes required
  • If you change WM_COMPILE_OPTION, wmake does not rebuild anything
  • ninja can build a single binary
  • Meson errors out immediately if a dependency is missing
  • Meson can do out of tree builds
  • Make interleaves the output of multiple threads
  • Source code of meson seems good

About me

  • Master in Physics
  • Young (25) with lots of Energy
  • Good at C++, Python, debugging
  • Know a lot about Linux, tooling and the C++ ecosystem
  • watch talks, read blogposts, talk with other hackers
  • Limited knowledge about using OpenFOAM
  • Limited knowledge about OpenFOAM's source code
  • Next to no knowledge about OpenFOAM's organisational structure and development process
  • Next to no community connection (4th Openfoam Meeting)
  • Started as a proof of concept when I was young and stupid
  • No idea how to merge

Important General principle in Programming

Let's say you have stuff in format/language $foo, you want format/language $boo, and you have a tool that translates $foo to $bar.

Translate your stuff to $bar, use it, be happy

What if you want to change something? You have 3 options

  1. Manually change it in the $foo-code and rerun the tool
  2. Write a program that changes the $bar-code
  3. Manually change the $bar-code

If you do option 3, you cannot do option 1 ever again, at least not with manual labor or wiping your changes!

Example:

You have main.c, i.e. C-Code, but your CPU wants x86 assembly

gcc can translate C-Code to x86 assembly

  1. Change main.c using a text-editor, then rerun-gcc
  2. E.g. strip
  3. Changing the generated assembly, i.e. main.s, using a text-editor

If you do option 3, and rerun gcc it wipes your changes.

In our case

We have many Make/options and Make/files

generate_meson_build.py reads that and outputs meson.build files

Let's say we add another .C-file to openfoam. Two options:

  1. vim subdir/meson.build
  2. vim subdir/Make/files and re-run generate_meson_build.py

Heuristics in generate_meson_build.py

src/OSspecific/POSIX/Make/files:

					#ifdef __sun__
					printStack/dummyPrintStack.C
					#else
					printStack/printStack.C
					#endif
				
src/OSspecific/POSIX/meson.build

				if host_machine.system() == 'sunos'
					srcfiles += files('printStack/dummyPrintStack.C')
				else
					srcfiles += files('printStack/printStack.C')
				endif
				
The first snippet exist as a string-literal in my script.
Let's say someone changes

					#ifdef __sun__
					printStack/dummyPrintStack.C
					#else
					printStack/printStack.C
					#endif
				
to

					#ifndef __sun__
					printStack/printStack.C
					#else
					printStack/dummyPrintStack.C
					#endif
				

generate_meson_build.py will crash!

You have to fix/change/adapt generate_meson_build.py

Creating valid C-Code that gcc cannot correctly translate is hard.

Creating valid Make/options and Make/files that my script cannot correctly translate is easy.

This will never change!

Let's say we add another .C-file to openfoam. Two options:

  1. vim subdir/meson.build
  2. vim subdir/Make/files and re-run generate_meson_build.py

Option 3 can be done by basically anyone. You will only rarely run into any issues. Basic knowledge of openfoam and meson is enough, no knowledge of my script is required.

Option 1 might result in you getting a stacktrace of my script and you need to read, understand and modify my script. Only I, or people who want to co-maintain my script, or people that have me on speeddial should run my script. (At least if we want users to have a nice experience.)

The disadvantage of option 3 is that if you want both wmake and meson to keep working, you need to update two files.

Seperately compiled libraries

Let's say you have dust that is hitting the wall and rebounding.

openfoam/src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/Rebound/Rebound.C

				// Calculate motion relative to patch velocity
				U -= Up;

				scalar Un = U & nw;

				if (Un > 0.0)
				{
					U -= UFactor_*2.0*Un*nw;
				}

				// Return velocity to global space
				U += Up;
				
Let's say you want to change the physics for that.

Option 1

  1. Download openfoam source code
  2. Modify src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel/Rebound/Rebound.C
  3. Build the modified openfoam

Option 2

  1. Download openfoam source code
  2. Go to src/lagrangian/intermediate/submodels/Kinematic/PatchInteractionModel
  3. Copy Rebound to MyRebound
  4. Modify MyRebound/Rebound.C
  5. Modify Allwmake
  6. Build the modified openfoam
  7. Adjust your case to use MyRebound instead of Rebound

Option 3

  1. Download openfoam source code and build it
  2. Copy the Rebound folder from the openfoam source tree to MyRebound outside of the openfoam source tree.
  3. Build just the MyRebound folder
  4. Adjust your case to use MyRebound instead of Rebound
  • Step 3 and 4 work without write permissions to the source tree, so openfoam source tree could be shared between many users
  • Difficult to do something similar with meson

End of Presentation

  • Discuss if you want to merge.
  • Discuss how we want to merge.
  • Discuss how we handle the "externally build" MyRebound feature.

Volker Weißmann
volker.weissmann@gmx.de
https://weissmann.pm
No company or university, just too much time