diff --git a/doc/binary_c2.lyx b/doc/binary_c2.lyx
index 126e83e3ac3abc7ceb64960fe2fb73a4a24ba820..ebf54e58877ce6290f9ec91458755b7f194ff064 100644
--- a/doc/binary_c2.lyx
+++ b/doc/binary_c2.lyx
@@ -3919,6 +3919,91 @@ pip3 install meson
 \end_inset
 
 which should get you the latest version.
+\begin_inset Newline newline
+\end_inset
+
+
+\begin_inset Newline newline
+\end_inset
+
+Note: 
+\begin_inset Flex Software
+status open
+
+\begin_layout Plain Layout
+emacs
+\end_layout
+
+\end_inset
+
+ users should install the meson-mode.
+ Go to 
+\begin_inset CommandInset href
+LatexCommand href
+target "https://github.com/wentasah/meson-mode"
+literal "false"
+
+\end_inset
+
+ and download 
+\begin_inset Flex File
+status open
+
+\begin_layout Plain Layout
+meson-mode.el
+\end_layout
+
+\end_inset
+
+ to your 
+\begin_inset Flex File
+status open
+
+\begin_layout Plain Layout
+~/.emacs-el
+\end_layout
+
+\end_inset
+
+ directory.
+ In your 
+\begin_inset Flex File
+status open
+
+\begin_layout Plain Layout
+~/.emacs
+\end_layout
+
+\end_inset
+
+ file add the following.
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+; meson support
+\end_layout
+
+\begin_layout Plain Layout
+
+(load "~/.emacs-el/meson-mode.el")
+\end_layout
+
+\end_inset
+
+You can edit the 
+\begin_inset Flex File
+status open
+
+\begin_layout Plain Layout
+meson-mode.el
+\end_layout
+
+\end_inset
+
+ to suit your needs: I changed the indentation from 2 to 4, for example.
 \end_layout
 
 \begin_layout Itemize
@@ -4092,6 +4177,32 @@ gdb
 .
 \end_layout
 
+\begin_layout Itemize
+I highly recommend the use of 
+\begin_inset Flex Software
+status open
+
+\begin_layout Plain Layout
+
+\emph off
+ccache
+\end_layout
+
+\end_inset
+
+ to speed up builds.
+ You can usually install this as a system package, or see 
+\begin_inset CommandInset href
+LatexCommand href
+name "the ccache homepage"
+target "https://ccache.dev/"
+literal "false"
+
+\end_inset
+
+.
+\end_layout
+
 \begin_layout Standard
 By using 
 \emph on
@@ -4381,6 +4492,135 @@ unzip
  the files in the appropriate places.
 \end_layout
 
+\begin_layout Subsubsection
+Set up ccache (optional)
+\end_layout
+
+\begin_layout Standard
+If you have 
+\begin_inset Flex Software
+status open
+
+\begin_layout Plain Layout
+ccache
+\end_layout
+
+\end_inset
+
+ installed, you will need to set it up so that it works with precompiled
+ headers.
+ To do this, run the following command.
+\begin_inset listings
+lstparams "language=bash"
+inline false
+status open
+
+\begin_layout Plain Layout
+
+ccache --set-config=sloppiness=pch_defines,time_macros
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
+\begin_layout Standard
+Alternatively, if you are using 
+\begin_inset Flex Software
+status open
+
+\begin_layout Plain Layout
+bash
+\end_layout
+
+\end_inset
+
+ as your shell and 
+\begin_inset Flex Software
+status open
+
+\begin_layout Plain Layout
+ccache
+\end_layout
+
+\end_inset
+
+ is installed in 
+\begin_inset Flex File
+status open
+
+\begin_layout Plain Layout
+binary_c
+\end_layout
+
+\end_inset
+
+ (the standard location in 
+\begin_inset Flex OS
+status open
+
+\begin_layout Plain Layout
+Ubuntu Linux
+\end_layout
+
+\end_inset
+
+, put the following in your 
+\begin_inset Flex File
+status open
+
+\begin_layout Plain Layout
+.bashrc
+\end_layout
+
+\end_inset
+
+ to have 
+\begin_inset Flex Software
+status open
+
+\begin_layout Plain Layout
+ccache
+\end_layout
+
+\end_inset
+
+ always behave as you wish.
+\begin_inset listings
+inline false
+status open
+
+\begin_layout Plain Layout
+
+# use ccache if available
+\end_layout
+
+\begin_layout Plain Layout
+
+if [[ -d /usr/lib/ccache ]]; then
+\end_layout
+
+\begin_layout Plain Layout
+
+    export PATH=/usr/lib/ccache/:$PATH
+\end_layout
+
+\begin_layout Plain Layout
+
+    export CCACHE_SLOPPINESS=pch_defines,time_macros
+\end_layout
+
+\begin_layout Plain Layout
+
+fi
+\end_layout
+
+\end_inset
+
+
+\end_layout
+
 \begin_layout Subsubsection
 Building with Meson
 \begin_inset CommandInset label
@@ -6000,24 +6240,21 @@ tbse
 \end_inset
 
 pgo Profile guided optimization.
- This builds 
-\emph on
+ This option is deprecated.
+ Please use the 
+\begin_inset Flex File
+status open
+
+\begin_layout Plain Layout
+meson/pgo.sh
+\end_layout
 
-\begin_inset Formula $\binaryc$
 \end_inset
 
+ script instead (see
+\begin_inset space ~
+\end_inset
 
-\emph default
- once, runs a number of systems, then rebuilds with extra optimization based
- on the profile generated by the runs.
- This works for 
-\emph on
-GCC
-\emph default
- and probably also 
-\emph on
-clang
-\emph default
 .
 \end_layout
 
@@ -19081,70 +19318,64 @@ tbse <filename>
 \end_layout
 
 \begin_layout Subsection
-How to use profile guided optimization (PGO)
+How to use profile-guided optimization (PGO)
 \end_layout
 
 \begin_layout Standard
-When compiling with 
-\begin_inset Flex Software
-status open
-
-\begin_layout Plain Layout
-gcc
-\end_layout
-
-\end_inset
+\begin_inset CommandInset label
+LatexCommand label
+name "subsec:How-to-use-PGO"
 
-, just run
-\begin_inset Newline newline
 \end_inset
 
 
-\family typewriter
-\series bold
-
-\begin_inset listings
-lstparams "language=bash"
-inline false
+\begin_inset Flex Software
 status open
 
 \begin_layout Plain Layout
-
-tbse pgo
+Meson
 \end_layout
 
 \end_inset
 
-
-\end_layout
-
-\begin_layout Standard
-You may want to change the 
-\begin_inset Flex Args
+ supports profile-guided optimization (PGO), and this has been written into
+ the 
+\begin_inset Flex File
 status open
 
 \begin_layout Plain Layout
-REPEAT
+meson/pgo.sh
 \end_layout
 
 \end_inset
 
- variable as defined in 
-\begin_inset Flex bashscript
+ script which you can use to test it.
+ You should just run this, with an optional argument that is the number
+ of test systems (this defaults to 1000), e.g.
+\begin_inset space ~
+\end_inset
+
+from the 
+\begin_inset Formula $\binaryc$
+\end_inset
+
+ root directory:
+\begin_inset listings
+inline false
 status open
 
 \begin_layout Plain Layout
-tbse
+
+./meson/pgo.sh 1000
 \end_layout
 
 \end_inset
 
-.
- It is set to 10000, but if your code is running too slowly, set it to less.
+
 \end_layout
 
 \begin_layout Standard
-For details see 
+For details about profile-guided optimization, please see 
 \begin_inset Flex URL
 status open
 
@@ -19155,11 +19386,7 @@ https://en.wikipedia.org/wiki/Profile-guided_optimization
 
 \end_inset
 
-
-\end_layout
-
-\begin_layout Standard
-Generally, I find a 5-10% speedup from PGO.
+ or your compiler's documentation.
 \end_layout
 
 \begin_layout Subsection
diff --git a/meson.build b/meson.build
index 240f6edc428e19285c7983e43a5174ef0b3875c5..acb9198eeb0c23b9a39700fc67a5ea3f3c1fe09f 100644
--- a/meson.build
+++ b/meson.build
@@ -10,7 +10,6 @@
 ############################################################
 # TODO:
 #
-# automate symlink of libbinary_c.so?
 # 'gprof'/'gcov' builds
 # profile-guided optimization
 # build data_objects in builddir, not in source tree
@@ -19,6 +18,12 @@
 #
 ############################################################
 #
+# See also
+# https://github.com/mesonbuild/meson/blob/master/docs/markdown/howtox.md
+# as a useful cookbook.
+#
+############################################################
+#
 # A typical clean build with gcc and "time make" gives 
 # 95.23user 21.08system 0:34.64elapsed 335%CPU (0avgtext+0avgdata 425420maxresident)k
 #
@@ -28,12 +33,13 @@
 ############################################################
 # define the binary_c project
 project(
-        'binary_c','c',
-        version : run_command('sh','-c','meson/binary_c_version.sh').stdout().strip(),
-        default_options : [
-                            'c_std=gnu99',
-                          ]
-                )
+    'binary_c','c',
+    version : run_command('sh','-c','meson/binary_c_version.sh').stdout().strip(),
+    default_options : [
+        'c_std=gnu99',
+    ]
+)
+binary_c_version = run_command('sh','-c','meson/binary_c_version.sh').stdout().strip()
 compiler = meson.get_compiler('c')
 
 ############################################################
@@ -58,34 +64,27 @@ git_url = run_command('sh','-c','meson/git_url.sh').stdout().strip()
 svn_url = run_command('sh','-c','meson/svn_url.sh').stdout().strip()
 
 ############################################################
-# default include directories
+# default include and library search directories
 incdirs = [ '.', './src' ]
 libdirs = [ './src' ]
 absolute_incdirs = [ binary_c, binary_c_src ]
 absolute_libdirs = [ ]
 
-############################################################
-# list of libraries with which we should link: libs come
-# first and are appended to, postlibs come last.
-libs = ['-lc','-lm']
-postlibs = ['-lc','-lm','-ldl']
-
 ############################################################
 # determine whether we're a debug or generic build
 have_gnu99 = compiler.has_argument('-std=gnu99')
 have_avx = compiler.has_argument('-mavx')
 
 ############################################################
-# default C flags (compiler options)
-
-# TODO: do not omit frame pointer if profile guided
-cflags = ['-fPIC','-DALIGNSIZE=16']
+# default C flags
+#
+cflags = ['-DALIGNSIZE=16']
 
 if have_gnu99
-   cflags += [ '-std=gnu99' ]
+    cflags += [ '-std=gnu99' ]
 endif
 if have_avx and get_option('generic') == false
-   cflags += [ '-mavx' ]
+    cflags += [ '-mavx' ]
 endif
 
 ############################################################
@@ -95,45 +94,48 @@ optional_flags = [ ]
 
 # generic build
 if get_option('generic') == true
-   optional_flags += [
-                  '-mtune=generic',
-                 ]
+    optional_flags += [
+        '-mtune=generic',
+    ]
 else   
-   optional_flags += [
-                  '-march=native',
-                  '-mtune=native',
-                 ]
+    optional_flags += [
+        '-march=native',
+        '-mtune=native',
+    ]
 endif
 
 # accurate mathematical options
 if get_option('accurate') == true
-   optional_flags += [
-                  '-frounding-math',
-                  '-fno-stack-protector',
-                  '-ffloat-store',
-                  '-fno-fast-math'
-                  ]
+    optional_flags += [
+        '-frounding-math',
+        '-fno-stack-protector',
+        '-ffloat-store',
+        '-fno-fast-math'
+    ]
 else
-   optional_flags += [
-                  '-ffast-math',
-                  '-fno-associative-math',
-                  ]
+    optional_flags += [
+        '-ffast-math',
+        '-fno-associative-math',
+    ]
 endif
 
 optional_flags += [
-                 '-fno-finite-math-only',
-                 '-fsignaling-nans',
-                 '-fomit-frame-pointer',
-                 '-fvisibility=hidden',
-                 ]
-                
+    '-fno-finite-math-only',
+    '-fsignaling-nans',
+    '-fomit-frame-pointer',
+    '-fvisibility=hidden',
+]
+
 ############################################################
 # debug C flags
 if get_option('buildtype').startswith('debug')
-   optional_flags += [ '-rdynamic', '-O0' ]
+    optional_flags += [ '-rdynamic', '-O0' ]
 endif
 
-# flags that are not strictly required, but that help a lot
+############################################################
+# Now go through the optional_flags, and use those that
+# are supported by the compiler.
+#
 foreach _flag : optional_flags 
     if compiler.has_argument(_flag)
         cflags += _flag
@@ -145,195 +147,221 @@ endforeach
 # per-compiler options
 
 if compiler.get_id() == 'clang'
-   # clang flags
-   cflags += [ '-fbracket-depth=512' ]
+    # clang flags
+    cflags += [ '-fbracket-depth=512' ]
 else
-   # default to gcc flags
-   cflags += []
+    # default to gcc flags
+    cflags += []
 endif
 
-libs += []
-
 ############################################################
 # system options
 cflags += '-DCPUFREQ=' + cpufreq
 
 if host_machine.system() == 'linux'
-   # Linux system
-   cflags += ['-DLINUX', '-DLARGEFILE_SOURCE']
-
-   # check for perf_event_paranoid
-   _perf_event = run_command('cat','/proc/sys/kernel/perf_event_paranoid').stdout().strip()
-   if _perf_event == '1' or _perf_event == '2'
-      cflags += '-D__HAVE_PERF_EVENTS__'
-   endif
+    # Linux system
+    cflags += ['-DLINUX', '-DLARGEFILE_SOURCE']
 endif
 
 if compiler.compiles('int main(int argc,char **argv){return 0;}',
                      args : '-m64',
                      name : '64-bit check')  
-   # 64-bit system
-   cflags += '-D_FILE_OFFSET_BITS=64'
+    # 64-bit system
+    cflags += '-D_FILE_OFFSET_BITS=64'
 else
-   # assume 32-bit system
+    # assume 32-bit system
 endif
 
 ############################################################
 # version control options
 
 if git_revision != ''
-   _flag = '-DGIT_REVISION="' + git_revision + '"'
-   cflags += _flag
+    _flag = '-DGIT_REVISION="' + git_revision + '"'
+    cflags += _flag
 endif  
 if svn_revision != ''
-   _flag = '-DSVN_REVISION="' + svn_revision + '"'
-   cflags += _flag
+    _flag = '-DSVN_REVISION="' + svn_revision + '"'
+    cflags += _flag
 endif
 
 if git_url != ''
-   _flag = '-DGIT_URL="' + git_url + '"'
-   cflags += _flag
+    _flag = '-DGIT_URL="' + git_url + '"'
+    cflags += _flag
 endif  
 if svn_url != ''
-   _flag = '-DSVN_URL="' + svn_url + '"'
-   cflags += _flag
+    _flag = '-DSVN_URL="' + svn_url + '"'
+    cflags += _flag
 endif  
 
 
 ############################################################
-# dependencies that have pkg-config
-libgsl_dep = compiler.find_library('gsl',required: true)
-
+# dependencies are put in the list called dependencies
+#
+dependencies = [ ]
 
 ############################################################
 # dependencies that usually have no pkg-config
 # THESE NEED TO BE SET IN $LIBRARY_PATH (or $LIBPATH on Windoze)
 #
-# required system libraries
-libc_dep = compiler.find_library('c', required: true)
-libm_dep = compiler.find_library('m', required: true)
-
-############################################################
-# dependencies
-#
-
-#######
-# GSL #
-#
-# todo : https://mesonbuild.com/Reference-tables.html see "Dependency lookup methods"
-if libgsl_dep.found()
-   cflags += run_command('sh','-c','gsl-config --cflags').stdout().strip().split(' ')
-   cflags += '-DUSE_GSL'
-   libs += run_command('sh','-c','gsl-config --libs').stdout().strip().split(' ')
-   gsl_libdirs = run_command('sh','-c','gsl-config  --libs | tr " " "\n"|grep ^-L | tr "\n" " "').stdout().strip().split(' ')
-   libdirs += gsl_libdirs
-   incdirs += run_command('sh','-c','gsl-config --prefix').stdout().strip()+'/include'
-endif
-
-
-#############################
-# required libraries        #
-# libgsl etc.               #
-#
-foreach libname : ['gsl']
-   _dep = compiler.find_library(libname,required:false) 
+# system libraries : note that libm may not be required
+#                    on some systems (GSL may also specify)
+dependencies += [
+    compiler.find_library('c', required: true),
+    compiler.find_library('m', required: false),
+]
+
+
+############################################################
+# libraries : required and optional
+#
+_required_libraries  = [
+    'c',
+    'gsl',
+    'gslcblas',
+]
+_optional_libraries = [
+    'backtrace',
+    'bfd',
+    'bsd',
+    'iberty',
+    'm', # optional on some platforms (gsl probably required is)
+    'memoize',
+    'rinterpolate',
+]
+libs = [] # list sent to the compiler
+foreach libname : _required_libraries
+    _dep = compiler.find_library(libname,
+                                 required:true) 
     if _dep.found()
-      cflags += '-D__HAVE_LIB' + libname.to_upper() +'__'
-      libs += '-l' + libname
+        cflags += '-D__HAVE_LIB' + libname.to_upper() +'__'
+        libs += '-l' + libname
+
+        # extras
+        if libname == 'gsl'
+            # use gsl-config to find cflags, libraries, etc.
+            message('Adding GSL-specific flags from gsl-config')
+            cflags += run_command('sh','-c','gsl-config --cflags').stdout().strip().split(' ')
+            cflags += '-DUSE_GSL'
+            libs += run_command('sh','-c','gsl-config --libs').stdout().strip().split(' ')
+            gsl_libdirs = run_command('sh','-c','gsl-config  --libs | tr " " "\n"|grep ^-L | tr "\n" " "').stdout().strip().split(' ')
+            libdirs += gsl_libdirs
+            incdirs += run_command('sh','-c','gsl-config --prefix').stdout().strip()+'/include'
+        endif
     endif
+    dependencies += _dep
 endforeach
 
+# Note : this should work, but does not :(
+#
+#gsl_dep = dependency(
+#    'gsl',
+#    required : true,
+#    version : '>=2.4',
+#    method : 'config-tool',
+#             )
+
 #############################
-# optional libraries        #
-# libbacktrace, libbfd etc. #
+# optional libraries       
+# libbacktrace, libbfd etc.
+# (generic builds should not use these)
 #
 if get_option('generic') == false
-   foreach libname : ['bfd','backtrace','bsd','iberty','memoize','rinterpolate']
-       _dep = compiler.find_library(libname,required:false) 
-       if _dep.found()
-          cflags += '-D__HAVE_LIB' + libname.to_upper() +'__'
-          libs += '-l' + libname
-       endif
-   endforeach
+    foreach libname : _optional_libraries
+        _dep = compiler.find_library(libname,required:false) 
+        if _dep.found()
+            cflags += '-D__HAVE_LIB' + libname.to_upper() +'__'
+            libs += '-l' + libname
+        endif
+    endforeach
 endif
+
+############################################################
+# features which are converted into preprocessor flags (-D)
+#
+
 ###########
 # drand48 #
 #
 if compiler.sizeof('drand48_r',
                    prefix : '#include <stdlib.h>') > 0
-   cflags += '-D__HAVE_DRAND48__'
+    cflags += '-D__HAVE_DRAND48__'
 endif
-   
+
 ############
 # malloc.h #
 #
 if compiler.has_header('malloc.h')
-   cflags += '-D__HAVE_MALLOC_H__'
+    cflags += '-D__HAVE_MALLOC_H__'
 endif
 
 #################################
 # pkg-config (external command) #
 #
 if run_command('pkg-config','--version').returncode() == 0
-   cflags += '-D__HAVE_PKG_CONFIG__'
+    cflags += '-D__HAVE_PKG_CONFIG__'
 endif
 
 ###########################
 # valgrind (header files) #
 #
 if compiler.has_header('valgrind/valgrind.h')
-   cflags += '-D__HAVE_VALGRIND__'
+    cflags += '-D__HAVE_VALGRIND__'
 endif
 
 ###################
 # show_starstruct #
 #
 if run_command('sh','-c','meson/make_starstruct.sh').returncode() == 0
-   cflags += '-D__SHOW_STARDATA__'
+    cflags += '-D__SHOW_STARDATA__'
 endif
 
 ###################
 # diff_starstruct #
 #
 if run_command('sh','-c','meson/diff_starstruct.sh').returncode() == 0
-   cflags += '-D__DIFF_STARDATA__'
+    cflags += '-D__DIFF_STARDATA__'
 endif
 
 ########################
 # Unsupported features #
 #
 if compiler.get_id() != 'gcc' and compiler.get_id() != 'clang'
-   cflags += '-UBACKTRACE'
+    cflags += '-UBACKTRACE'
 endif
 
 ############################################################
 # make a list of include directories
+# We do this so that $HOME/include is searched (e.g. for
+# libgsl)
+#
 my_incdirs = []
 found = false
-foreach idir : [
-                homedir + '/include',
-                '/usr/include',
-                '/usr/local/include',
-                ]
-  inc_arg = idir
-  _Inc_arg = '-I' + idir
-  if not found and compiler.has_header('gsl/gsl_blas.h',
-                                       args: _Inc_arg)
-    my_incdirs += [inc_arg]
-    found = true
-  endif
+_include_search_paths = [
+    homedir + '/include',
+    '/usr/include',
+    '/usr/local/include',
+] 
+foreach idir : _include_search_paths
+    inc_arg = idir
+    _Inc_arg = '-I' + idir
+    if not found and compiler.has_header('gsl/gsl_blas.h',
+                                         args: _Inc_arg)
+        my_incdirs += [inc_arg]
+        found = true
+    endif
 endforeach
 
-incdirs += [my_incdirs]
+incdirs += [ my_incdirs ]
 
 ############################################################
 # data objects
 #
 # list and build them
+message('Checking and building data objects')
 data_objects = run_command('meson/data_object_list_and_build.sh').stdout().strip().split(' ')
 
 if get_option('clean_data_objects') == true
-   run_command('meson/clean_data_objects.sh')
+    run_command('meson/clean_data_objects.sh')
 endif
 
 ############################################################
@@ -345,17 +373,12 @@ run_command('meson/make_version_macros.pl')
 # source files
 #
 c_sourcefiles = run_command('meson/c_sourcefiles.sh').stdout().strip().split('\n')
+c_main_sourcefiles = run_command('meson/c_main_sourcefiles.sh').stdout().strip().split('\n')
 h_sourcefiles = run_command('meson/h_sourcefiles.sh').stdout().strip().split('\n')
 
-############################################################
-# full list of libraries with which we wish to link
-#
-libs = libs + postlibs
-
 ############################################################
 # extra quoted flags to pass into binary_c
 #
-
 cflags_with_O = cflags + [ '-O' + get_option('optimization') ] # cflags with -O<n>
 cflags_quoted = ' '.join(cflags_with_O) # turn to string
 cflags_quoted = ''.join(cflags_quoted.split('"'))  # remove "
@@ -370,19 +393,25 @@ libs_quoted = '-DLIBS=' + ''.join(['"', ' '.join(libs),'"'])
 libs_quoted = '_slash_'.join(libs_quoted.split('/'))
 
 # hence a quoted version of the cflags
-quoted_cflags_list = [ cflags_quoted,
-                       cc_quoted,
-                       incdirs_quoted,
-                       ld_quoted,
-                       libdirs_quoted,
-                       libs_quoted,
-                        ]
+quoted_cflags_list = [
+    cflags_quoted,
+    cc_quoted,
+    incdirs_quoted,
+    ld_quoted,
+    libdirs_quoted,
+    libs_quoted,
+]
 
 ############################################################
 # compiler warning flags
 ############################################################
 warn_flags = []
-foreach _arg : ['all','format','strict-prototypes','format-signedness']
+foreach _arg : [
+    'all',
+    'format',
+    'strict-prototypes',
+    'format-signedness'
+]
     _warn_arg = '-W' + _arg
     if compiler.has_argument(_warn_arg)
         warn_flags += _warn_arg
@@ -401,90 +430,137 @@ cflags += warn_flags
 # its dependencies in a pch.d/gch.d file. This is a bit
 # complicated, as you will see below.
 #
-
-if get_option('usepch') == true 
-
-   _opt = '-O' + get_option('optimization') # required for __OPTIMIZE__
-   
-   # normal dep file
-   _depfile_path = binary_c_src + '/binary_c.h.gch.d'
-   
-   # make a list of incdirs each prefixed by -I
-   _incdirs = []
-   foreach _i : absolute_incdirs
-       _I = '-I' + _i
-       _incdirs += _I
-   endforeach
-   _incdirs += [ '-I.' ]
-
-   # choose your compiler...
-   if compiler.get_id() == 'clang'
-      # clang PCH
-   
-      _pch = 'binary_c.h.pch'
-      use_pch_cflags = [ '-include-pch', _pch ]
-      pch_cflags = [
-                 _opt,
-                 _incdirs,
-                 ]             
-      pch_sourcefiles = [ _pch ]
-      pch_post = [ '-o', _pch ]
-      pch_depfile =  ''
-
-   else
-      # GCC PCH
-   
-      _gch = 'binary_c.h.gch'
-      _gchd = '../src/' + _gch + '.d'
-      use_pch_cflags = [  ] # -include is not required
-      pch_cflags = [ _opt,
-                     _incdirs,
-                     '-MT', 'binary_c.h.gch',
-                     '-MMD',
-                     '-MP',
-                     '-MF', _depfile_path,
-                     '-x', 'c-header'
-                     ]
-      pch_sourcefiles = [ _gch ]
-      cflags += [ '-fpch-deps', '-fpch-preprocess' ]
-      pch_post = [ ]
-      pch_depfile = _gch + '.d'
-   endif
-
-
-   # make cflags for pch build
-   pch_cflags_array = cflags + pch_cflags
-
-   # append usage flags
-   cflags += use_pch_cflags
-
-   pch_compiler = compiler.cmd_array() + pch_cflags_array
-             
-   precompiled_headers = custom_target(
-                       'binary_c.h.pch',
-                       build_by_default : true,
-                       input : ['src/binary_c.h'],
-                       output :  pch_sourcefiles,
-                       command : [ pch_compiler, '-gdwarf-2', '@INPUT@', pch_post ],
-                       depend_files : [h_sourcefiles],
-                       )
+if get_option('usepch') == true
+    # get optimization level, required for __OPTIMIZE__
+    _opt = '-O' + get_option('optimization')
+
+    # make sure we precompile with fPIC and symbols
+    _pic = ['-g','-fPIC']
+    
+    # normal dep file
+    _depfile_path = binary_c_src + '/binary_c.h.gch.d'
+    
+    # make a list of incdirs each prefixed by -I
+    _incdirs = []
+    foreach _i : absolute_incdirs
+        _I = '-I' + _i
+        _incdirs += _I
+    endforeach
+    _incdirs += [ '-I.' ]
+
+    # choose your compiler...
+    if compiler.get_id() == 'clang'
+        # clang PCH
+        
+        _pch = 'binary_c.h.pch'
+        use_pch_cflags = [
+            '-include-pch',
+            _pch ]
+        pch_cflags = [
+            _opt,
+            _pic,
+            _incdirs,
+        ]             
+        pch_sourcefiles = [ _pch ]
+        pch_post = [ '-o', _pch ]
+        pch_depfile =  ''
+
+    else
+        # GCC PCH
+        
+        _gch = 'binary_c.h.gch'
+        _gchd = '../src/' + _gch + '.d'
+        use_pch_cflags = [  ] # -include is not required
+        pch_cflags = [
+              _opt,
+              _pic,
+              _incdirs,
+              '-MT', 'binary_c.h.gch',
+              '-MMD',
+              '-MP',
+              '-MF', _depfile_path,
+              '-x', 'c-header'
+            ]
+        pch_sourcefiles = [ _gch ]
+        cflags += [
+            '-fpch-deps',
+            '-fpch-preprocess'
+        ]
+        pch_post = [ ]
+        pch_depfile = _gch + '.d'
+    endif
+    
+    # make cflags for pch build
+    pch_cflags_array = cflags + pch_cflags
+
+    # append usage flags
+    cflags += use_pch_cflags
+
+    # make PCH compiler: this is just the normal compiler with PCH flags
+    pch_compiler = compiler.cmd_array() + pch_cflags_array
+
+    message('building precompiled headers')
+    precompiled_headers = custom_target(
+        'binary_c.h.pch',
+        build_by_default : true,
+        input : ['src/binary_c.h'],
+        output :  pch_sourcefiles,
+        command : [
+            pch_compiler,
+            '-gdwarf-2',
+            '@INPUT@',
+            pch_post
+        ],
+        depend_files : [ h_sourcefiles ],
+    )
 
 else
-   # disable PCH by removing the files it would have generated
-   
-   all_pch_sourcefiles = [ 'binary_c.h.gch', 'binary_c.h.pch' ]
-   precompiled_headers = custom_target(
-                    'binary_c.h.pch',
-                    build_by_default : true,
-                    input : ['src/binary_c.h'],
-                    output :  all_pch_sourcefiles,
-                    command : [ 'rm', '-f', all_pch_sourcefiles ],
-                    depend_files : [h_sourcefiles],
-                    )
+    # disable PCH by removing the files it would have generated
+    
+    all_pch_sourcefiles = [ 'binary_c.h.gch', 'binary_c.h.pch' ]
+    precompiled_headers = custom_target(
+        'binary_c.h.pch',
+        build_by_default : true,
+        input : [ 'src/binary_c.h' ],
+        output :  all_pch_sourcefiles,
+        command : [ 'rm', '-f', all_pch_sourcefiles ],
+        depend_files : [h_sourcefiles],
+    )
 
 endif
 
+############################################################
+# command to install binary_c in its 'legacy' locations
+# (required for binary_grid2)
+binary_c_legacy_install_cmd = [
+    'cp','--remove-destination','binary_c','../',
+    '&&',
+    'cp','--remove-destination','libbinary_c.so','../src/',
+    '&&',
+    'echo','libbinary_c.so built with symbols:',
+    '&&',
+    '../meson/list_shared_symbols.sh','libbinary_c.so'
+]
+
+############################################################
+#
+# Convenience for Rob: try to locate binary_grid2.pm and
+# hence touch (and rebuild) it when the shared library is
+# rebuild
+#
+if run_command('sh','-c','meson/check_binary_grid2.sh').returncode() == 0
+    binary_grid2_file = run_command(
+        'sh',
+        '-c',
+        'meson/check_binary_grid2.sh'
+    ).stdout().strip()
 
+    binary_c_legacy_install_cmd += [
+        '&&',
+        'touch',
+        binary_grid2_file
+    ]
+endif    
 
 ############################################################
 #
@@ -492,30 +568,72 @@ endif
 # run: ninja libbinary_c_symlink
 #
 libbinary_c_symlink = custom_target(
-                    'libbinary_c_symlink',
-                    build_by_default: false,
-                    output: [ 'libbinary_c_symlink' ],
-                    command: [ 'sh', '-c', '../meson/symlink_libbinary_c.sh' ],
-              )
-              
+    'libbinary_c_symlink',
+    build_by_default: false,
+    output: [ 'libbinary_c_symlink' ],
+    command: [
+        'sh',
+        '-c',
+        '../meson/symlink_libbinary_c.sh'
+    ],
+)
+
+
+############################################################
+#
+# make binary_c objects
+#
+# We put the objects in here so they can be shared by
+# the executable and library builds. We're not really
+# interested in the static library, but we have to call
+# this build something.
+#
+binary_c_objects = build_target(
+    'binary_c_objects',
+    build_by_default: true,
+    pic: true,
+    target_type : 'static_library', # pretend we're a static library!
+    sources : [
+        c_sourcefiles,
+        h_sourcefiles,
+        precompiled_headers
+    ],
+    include_directories: include_directories(incdirs),
+    dependencies : dependencies,
+    c_args : [
+        cflags,
+        quoted_cflags_list,
+    ],
+    objects : data_objects,
+    link_args : [
+        libs,
+    ],
+    )
+
 ############################################################
 #
 # make shared library
 # run: ninja libbinary_c.so
 #
 binary_c_shared_library = shared_library(
-                        get_option('libname'),
-                         build_by_default : false,    
-                         install: true,
-                         sources : [c_sourcefiles, h_sourcefiles, precompiled_headers ],
-                         include_directories: include_directories(incdirs),
-                         dependencies : [ libgsl_dep  ],
-                         c_args : [ cflags, quoted_cflags_list, '-fvisibility=hidden' ],
-                         link_args : libs,
-                         objects : data_objects,
-                        )
-
-
+    get_option('libname'),
+    build_by_default : false,    
+    install: true,
+    include_directories: include_directories(incdirs),
+    dependencies : [ dependencies ],
+    c_args : [
+        cflags,
+        quoted_cflags_list,
+        '--whole-archive',
+    ],
+    link_whole: [
+        binary_c_objects,
+    ],
+    link_args : [
+        libs,
+        '-fvisibility=hidden',
+    ],
+)
 
 ############################################################
 #
@@ -523,48 +641,37 @@ binary_c_shared_library = shared_library(
 # run: ninja binary_c
 #
 binary_c_executable = executable(
-                      'binary_c',
-                      install: true,
-                      sources : [
-                                 c_sourcefiles,
-                                 h_sourcefiles,
-                                 precompiled_headers
-                                ],
-                      include_directories: include_directories(incdirs),
-                      dependencies : [ libgsl_dep ],
-                      c_args : [
-                                cflags,
-                                quoted_cflags_list
-                               ],
-                      link_args : libs,
-                      objects : data_objects,
-                      )
-
-
-############################################################
-#
-# symlink executable to binary_c directory
-# run : ninja binary_c_symlink
-#
-binary_c_symlink = custom_target('symlink_binary_c',
-                                 build_by_default: true,
-                                 output: ['binary_c_symlink'],
-                                 command: [ 'sh', '-c', '../meson/symlink_binary_c.sh' ],
-                                 depends : [ binary_c_executable ],
-              )
-
+    'binary_c',
+    build_by_default : true,    
+    install: true,
+    sources : [
+        c_main_sourcefiles,
+    ],
+    include_directories: include_directories(incdirs),
+    dependencies : [ dependencies ],
+    c_args : [
+        cflags,
+        quoted_cflags_list,
+    ],
+    objects : data_objects,
+    link_args : [
+        libs,
+    ],
+    link_with: [ binary_c_objects ],    
+)
 
 ############################################################
 # install both binary_c and libbinary_c.so in their legacy
 # locations
-binary_c_install_legacy = custom_target('binary_c_install_legacy',
-                                        build_by_default: false,
-                                        output: ['binary_c_install_legacy'],
-                                        command: [
-                                                   'cp','--remove-destination','binary_c','../',
-                                                   '&&',
-                                                   'cp','--remove-destination','libbinary_c.so','../src/'
-                                                   ],
-                                        depends : [ binary_c_executable, binary_c_shared_library ],
-                                        )
+#
+binary_c_install_legacy = custom_target(
+    'binary_c_install_legacy',
+    build_by_default: false,
+    output: [ 'binary_c_install_legacy' ],
+    command: binary_c_legacy_install_cmd,
+    depends : [
+        binary_c_executable,
+        binary_c_shared_library,
+    ],
+)
 
diff --git a/meson/c_main_sourcefiles.sh b/meson/c_main_sourcefiles.sh
new file mode 100755
index 0000000000000000000000000000000000000000..395085b7075535419111244adc32bb8abf0f52f2
--- /dev/null
+++ b/meson/c_main_sourcefiles.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+# list binary_c C source files for meson
+ls -1 src/*.c src/*/*.c |grep main.c
diff --git a/meson/check_binary_grid2.sh b/meson/check_binary_grid2.sh
new file mode 100755
index 0000000000000000000000000000000000000000..fb0c695f29d28e6cc6535744ce6fca9a594e7ee4
--- /dev/null
+++ b/meson/check_binary_grid2.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+# test if Rob's binary_grid2.pm exists
+#
+# if so, echo its path and return 0
+#
+# otherwise, return 1
+FILE="$HOME/progs/perl/modules/astro/binary_grid/lib/binary_grid2.pm"
+if [ -f $FILE ]; then
+    echo $FILE
+    exit 0
+else
+    exit 1
+fi
+
diff --git a/meson/list_shared_symbols.sh b/meson/list_shared_symbols.sh
new file mode 100755
index 0000000000000000000000000000000000000000..b9c524948b7d8c3bc4017269f2a2019710be8e66
--- /dev/null
+++ b/meson/list_shared_symbols.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+# list shared symbols in the library (file name passed in)
+SOFILE=$1
+
+# red
+echo -e "\e[31m"
+
+nm -CD -f p $SOFILE | awk '{if ($2 == "T"){print $1}}' | grep -v _fini|grep -v _init | tr "\n" " "
+
+#reset
+echo -e "\e[0m"
+
diff --git a/meson/pgo.sh b/meson/pgo.sh
new file mode 100755
index 0000000000000000000000000000000000000000..50b9960d447c0139262d239f86b1d390d15e4490
--- /dev/null
+++ b/meson/pgo.sh
@@ -0,0 +1,114 @@
+#!/bin/bash
+
+# script to do PGO with Meson
+
+
+# set defaults
+BUILDDIR="builddir"
+N=$1
+: ${N:="1000"}
+NCORES=`cat /proc/cpuinfo |grep -i Processor | wc -l`
+: ${NCORES:="1"}
+TMP="/tmp/"
+NCORES1=$((NCORES - 1))
+REPEAT_PER_CORE=$(($N/$NCORES))
+SLEEP=0
+MESON=meson
+NINJA=ninja
+
+# where to redirect stderr, stdout on meson and ninja calls
+MESON_STDERR=/dev/stderr
+MESON_STDOUT=/dev/null
+NINJA_STDERR=/dev/stderr
+NINJA_STDOUT=/dev/null
+
+# tbse command
+TBSE="./tbse"
+WARMUP_SECS=0
+COMMAND1="random_systems 1 repeat $REPEAT_PER_CORE warmup_cpu $WARMUP_SECS"
+
+# status message
+echo "Using Meson to build binary_c with Profile Guided Optimization (PGO) on $N systems across $NCORES cores"  
+
+# function to kill child processes
+KillChildren() {
+    local pid="${1}"
+    local self="${2:-false}"
+    if children="$(pgrep -P "$pid")"; then
+        for child in $children; do
+            KillChildren "$child" true
+        done
+    fi
+
+    if [ "$self" == true ]; then
+        #kill -s SIGTERM "$pid" || (sleep 10 && kill -9 "$pid" &)
+        kill -9 "$pid"
+    fi
+}
+
+# kill children on exit
+trap '[ -n "$(jobs -pr)" ] && KillChildren $$' INT QUIT TERM EXIT
+
+############################################################
+# first build: use builddir if already avaialble
+echo "Configure meson for PGO build 1"
+if [ -d $BUILDDIR ] ; then
+    meson configure $BUILDDIR -Db_pgo=generate > $MESON_STDOUT 2> $MESON_STDERR
+else
+    meson $BUILDDIR -Db_pgo=generate > $MESON_STDOUT 2> $MESON_STDERR
+fi
+echo "Build (1) with ninja"
+#ninja -C $BUILDDIR > $NINJA_STDOUT 2> $NINJA_STDERR
+
+
+
+############################################################
+# run and filter to files
+START=`date +%s%N`
+echo "Running binary_c"
+for i in `seq 0 $NCORES1`; do
+    echo "Launch tbse on core $i"
+    taskset -c $i $TBSE $COMMAND1 | grep At | awk '{print substr($0, index($0,$5))}' > /tmp/binary_c_pgo.$i &
+    sleep $SLEEP
+done
+wait
+END=`date +%s%N`
+PGO1_DURATION=$(echo "(0.000000001*($END - $START))"|bc)
+
+############################################################
+# rebuild
+echo "Configure meson for PGO build 2"
+meson configure $BUILDDIR -Db_pgo=use > $MESON_STDOUT 2> $MESON_STDERR
+echo "Build (2) with ninja" 
+ninja -C $BUILDDIR > $NINJA_STDOUT 2> $NINJA_STDERR
+
+# remove trap
+trap - INT QUIT TERM EXIT
+
+############################################################
+# rerun
+
+# kill children on exit
+trap '[ -n "$(jobs -pr)" ] && KillChildren $$' INT QUIT TERM EXIT
+
+START=`date +%s%N`
+echo "Running binary_c"
+for i in `seq 0 $NCORES1`; do
+    env FIRST_TBSE="warmup_cpu $WARMUP_SECS" taskset -c $i $TBSE /tmp/binary_c_pgo.$i 2>&1  >/dev/null &
+    sleep $SLEEP
+done
+wait
+END=`date +%s%N`
+PGO2_DURATION=$(echo "(0.000000001*($END - $START))"|bc)
+
+# remove trap
+trap - INT QUIT TERM EXIT
+
+echo "Run 1 (without PGO) took : $PGO1_DURATION s"
+echo "Run 2 (   with PGO) took : $PGO2_DURATION s"
+
+# final speedup %
+echo -n "Profile guided optimization speedup is "
+echo -n $(echo "(100.0*($PGO1_DURATION-$PGO2_DURATION)/$PGO1_DURATION)"|bc)
+echo "%"
+exit
diff --git a/src/perl/scripts2/template.pl b/src/perl/scripts2/template.pl
index 5a24038f53e834749cc8dc8beaf0345e70adfa9f..e457dc4df3b01e4ec024fc2caf230f12cf9d901e 100755
--- a/src/perl/scripts2/template.pl
+++ b/src/perl/scripts2/template.pl
@@ -102,7 +102,12 @@ $population->set(
 #                 stardata->star[0].mass,
 #                 stardata->model.probability,
 #                 stardata->model.dt);
-#                       '
+    #                       '
+
+
+    flexigrid => { 
+        'grid type' => 'monte carlo'
+    } 
     );
 
 ############################################################
@@ -135,6 +140,7 @@ if($duplicity == 0)
         'precode'    =>'$m1=exp($lnm1);',
         'probdist'   =>'Kroupa2001($m1)*$m1',
         'dphasevol'  =>'$dlnm1',
+        'gridtype'   =>'monte carlo',
         );
 }
 elsif($duplicity == 1)
diff --git a/src/setup/version.c b/src/setup/version.c
index 6d2195f0371a8c155b8b9e8fa76625498fcdaa91..e28a53fb93b7dc10fcc2b84e75bd7e7d97a457f8 100644
--- a/src/setup/version.c
+++ b/src/setup/version.c
@@ -760,7 +760,6 @@ void version(struct stardata_t * RESTRICT const stardata)
     Macrotest(__APPLE__);
     Macrotest(__arm__);
     Macrotest(__i386__);
-    Macrotest(__HAVE_PERF_EVENTS__);
 #ifdef ALIGNSIZE
     Printf("Memory is aligned to %d bytes (set in ALIGNSIZE)\n",ALIGNSIZE);
 #else
diff --git a/tbse b/tbse
index f1ec1c1070e9d93a698d0b323f21f434788c88c1..8866bff0f01de9b946acb30ad541ea73c496b1bb 100755
--- a/tbse
+++ b/tbse
@@ -2366,7 +2366,7 @@ then
                 ARGS=$(echo $ARGS | sed -e s/At\ 20[0-9][0-9]-[0-9][0-9]-[0-9][0-9]\ [0-9][0-9]\:[0-9][0-9]\:[0-9][0-9]\ \:\ //)
 
                 # run binary_c
-                $ARGS_PREFIX $DEFAULT_ARGS $ARGS $ARGS_POSTFIX $@ 
+                $ARGS_PREFIX $DEFAULT_ARGS $ARGS $ARGS_POSTFIX $@ $FIRST_TBSE 
 
                 ERROR=$? # save return code and exit if non-zero
                 if (($ERROR != 0)); then
@@ -2376,6 +2376,10 @@ then
                     echo
                     exit $ERROR
                 fi
+
+                if [[ ! -z $FIRST_TBSE ]]; then
+                    FIRST_TBSE=""
+                fi
             fi
         done < <(grep -v \# $argfile )
     done
@@ -2409,6 +2413,15 @@ fi
 if [ "$RUNMODE" == "pgo" ];
 then
 
+    echo "Profile-guided optimization (PGO) through tbse has been deprecated : please use Meson to do pgo. A bash script to do this (meson/pgo.sh), run with as 
+
+./meson/pgo.sh <N>
+
+where N is the number of systems to run, per CPU core, in a timing test.
+
+"
+    exit
+    
     # profile-guided optimisation build: this option 
     # configures, builds, runs, rebuilds and reruns bonnfires
     # so that it uses profile-guided optimisation, i.e.