g42so
=====

This is `g42so`, a simple Python script that compiles
[Geant4](https://geant4.web.cern.ch/) detector-construction and
primary-generator-action classes, wraps them in C-style (unmangled) adapter
functions and produces a shared library. The library can then be loaded via
`dlopen` by third-party code, allowing instantiation of a Geant4 detector
construction or primary generator action even if the name of the specific class
is not known in advance.

Compilation is delegated to [`g++`](https://gcc.gnu.org/) by default (no, I did
not reimplement `gcc` from scratch), but this can be configured.

Running `./g42so -h` gives a list of available options. You will typically want
to run something along the lines of the following:

    $ ./g42so -I /path/to/include/ \
       /path/to/src/MyDetectorConstruction.cc /path/to/src/MyPrimaryGeneratorAction.cc


Installing `g42so`
------------------

The recommended installation procedure for `g42so` is to use `pip`:

    $ pip install g42so


Notes
-----

* Geant4 must be installed and the `geant4-config` script must be in the
  `$PATH`, or its location can be specified with the `--geant4-config` option.

* `g42so` tries to automatically detect the names of the classes you want to
  wrap.  If it fails or is unsure, it will ask you to explicitly specify your
  class names.

* If your class constructors require arguments, you will need to customise the
  C wrappers generated by the code. First run

      $ ./g42so --dump-detector-wrapper >detectorWrapper.cc

  to dump the relevant wrapper. Modify it to your needs and pass it to `g42so`
  along with the `--custom-detector-wrapper` option, which tells `g42so` not to
  include its default wrapper. For instance:

      $ ./g42so --custom-detector-wrapper -I /path/to/include/ \
        /path/to/src/MyDetectorConstruction.cc detectorWrapper.cc

  The `--dump-pga-wrapper` and `--custom-pga-wrapper` do the same job for
  primary-generator-action classes.

* Note that `dlopen`ing shared libraries that link to Geant4 is likely to fail
  if Geant4 was compiled is multi-threaded mode (the
  `GEANT4_BUILD_MULTITHREADED` CMake flag is set to ON) with the default value
  for the `GEANT4_BUILD_TLS_MODEL` (the default is `initial-exec`). If you want
  to `dlopen` the libraries created by `g42so` (which is the whole point of
  this tool, really!), then you should make sure that either Geant4 was
  compiled in single-threaded mode, or `GEANT4_BUILD_TLS_MODEL` was set to
  `global-dynamic`.
