3.2.  Building Applications with Geant4

To build an application that uses the Geant4 toolkit, it is necessary to include Geant4 headers in the application sources and link the application to the Geant4 libraries. The details of how to implement source code for an application are described in detail in the Geant4 User's Guide for Application Developers. Here, we describe how you can build your sources into an application and compile and link it against Geant4.

We provide three main tools to help with building applications: a CMake "Geant4Config.cmake" config file, a GNUMake module "binmake.gmk" and a UNIX-only command line program "geant4-config". The following sections give an overview of each tool and how to use them to build a simple application.

3.2.1.  Using CMake to build Applications: Geant4Config.cmake

Geant4 installs a file named Geant4Config.cmake located in:

      +- CMAKE_INSTALL_PREFIX
          +- lib/
             +- Geant4-10.2.0/
                +- Geant4Config.cmake
    

which is designed for use with the CMake scripting language find_package command. Building a Geant4 application using CMake therefore involves writing a CMake script CMakeLists.txt using this and other CMake commands to locate Geant4 and describe the build of your application against it. Whilst it requires a bit of effort to write the script, CMake provides a very powerful and flexible tool, especially if you are working on multiple platforms. It is therefore the method we recommend for building Geant4 applications.

We'll use Basic Example B1, which you may find in the Geant4 source directory under examples/basic/B1, to demonstrate the use of CMake to build a Geant4 application. You'll find links to the latest CMake documentation for the commands used throughout, so please follow these for further information. The application sources and scripts are arranged in the following directory structure:

      +- B1/
         +- CMakeLists.txt
         +- exampleB1.cc
         +- include/
         |  ... headers.hh ...
         +- src/
            ... sources.cc ...
    

Here, exampleB1.cc contains main() for the application, with include/ and src/ containing the implementation class headers and sources respectively. This arrangement of source files is not mandatory when building with CMake, apart from the location of the CMakeLists.txt file in the root directory of the application.

The text file CMakeLists.txt is the CMake script containing commands which describe how to build the exampleB1 application:

  # (1)
  cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
  project(B1)

  # (2)
  option(WITH_GEANT4_UIVIS "Build example with Geant4 UI and Vis drivers" ON)
  if(WITH_GEANT4_UIVIS)
    find_package(Geant4 REQUIRED ui_all vis_all)
  else()
    find_package(Geant4 REQUIRED)
  endif()

  # (3)
  include(${Geant4_USE_FILE})
  include_directories(${PROJECT_SOURCE_DIR}/include)

  # (4)
  file(GLOB sources ${PROJECT_SOURCE_DIR}/src/*.cc)
  file(GLOB headers ${PROJECT_SOURCE_DIR}/include/*.hh)

  # (5)
  add_executable(exampleB1 exampleB1.cc ${sources} ${headers})
  target_link_libraries(exampleB1 ${Geant4_LIBRARIES})

  # (6)
  set(EXAMPLEB1_SCRIPTS
    exampleB1.in
    exampleB1.out
    init_vis.mac
    run1.mac
    run2.mac
    vis.mac
    )

  foreach(_script ${EXAMPLEB1_SCRIPTS})
    configure_file(
      ${PROJECT_SOURCE_DIR}/${_script}
      ${PROJECT_BINARY_DIR}/${_script}
      COPYONLY
      )
  endforeach()

  # (7)
  install(TARGETS exampleB1 DESTINATION bin)
    

For clarity, the above listing has stripped out the main comments (CMake comments begin with a "#") you'll find in the actual file to highlight each distinct task:

  1. Basic Configuration

    The cmake_minimum_required command simply ensures we're using a suitable version of CMake. Though the build of Geant4 itself requires CMake 3.3 and we recommend this version for your own projects, Geant4Config.cmake can support earlier versions from 2.6.4 and the 2.8.X series. The project command sets the name of the project and enables and configures C and C++ compilers.

  2. Find and Configure Geant4

    The aforementioned find_package command is used to locate and configure Geant4 (we'll see how to specify the location later when we run CMake), the REQUIRED argument being supplied so that CMake will fail with an error if it cannot find Geant4. The option command specifies a boolean variable which defaults to ON , and which can be set when running CMake via a -D command line argument, or toggled in the CMake GUI interfaces. We wrap the calls to find_package in a conditional block on the option value. This allows us to configure the use of Geant4 UI and Visualization drivers by exampleB1 via the ui_all vis_all "component" arguments to find_package . These components and their usage is described later.

  3. Configure the Project to Use Geant4 and B1 Headers

    To automatically configure the header path, compiler flags and compiler definitions needed for linking to Geant4, we use the include command to load a CMake script supplied by Geant4. The CMake variable named Geant4_USE_FILE is set to the path to this module when Geant4 is located by find_package . We use the include_directories command to add the B1 header directory to the compiler's header search path. The CMake variable PROJECT_SOURCE_DIR points to the top level directory of the project and is set by the earlier call to the project command.

  4. List the Sources to Build the Application

    Use the globbing functionality of the file command to prepare lists of the B1 source and header files.

    Note however that CMake globbing is only used here as a convenience. The expansion of the glob only happens when CMake is run, so if you later add or remove files, the generated build scripts will not know a change has taken place. Kitware strongly recommend listing sources explicitly as CMake automatically makes the build depend on the CMakeLists.txt file. This means that if you explicitly list the sources in CMakeLists.txt, any changes you make will be automatically picked when you rebuild. This is most useful when you are working on a project with sources under version control and multiple contributors.

  5. Define and Link the Executable

    The add_executable command defines the build of an application, outputting an executable named by its first argument, with the sources following. Note that we add the headers to the list of sources so that they will appear in IDEs like Xcode.

    After adding the executable, we use the target_link_libraries command to link it with the Geant4 libraries. The Geant4_LIBRARIES variable is set by find_package when Geant4 is located, and is a list of all the libraries needed to link against to use Geant4.

  6. Copy any Runtime Scripts to the Build Directory

    Because we want to support out of source builds so that we won't mix CMake generated files with our actual sources, we copy any scripts used by the B1 application to the build directory. We use foreach to loop over the list of scripts we constructed, and configure_file to perform the actual copy.

    Here, the CMake variable PROJECT_BINARY_DIR is set by the earlier call to the project command and points to the directory where we run CMake to configure the build.

  7. If Required, Install the Executable

    Use the install command to create an install target that will install the executable to a bin directory under CMAKE_INSTALL_PREFIX.

    If you don't intend your application to be installable, i.e. you only want to use it locally when built, you can leave this out.

This sequence of commands is the most basic needed to compile and link an application with Geant4, and is easily extendable to more involved use cases such as using other third party packages (via find_package ) or platform specific configuration.

With the CMake script in place, using it to build an application is a two step process. First CMake is run to generate buildscripts to describe the build. By default, these will be Makefiles on Unix platforms, and Visual Studio solutions on Windows, but you can generate scripts for other tools like Xcode and Eclipse if you wish. Second, the buildscripts are run by the chosen build tool to compile and link the application.

A key concept with CMake is that we generate the buildscripts and run the build in a separate directory, the so-called build directory, from the directory in which the sources reside, the so-called source directory. This is the exact same technique we used when building Geant4 itself. Whilst this may seem awkward to begin with, it is a very useful technique to employ. It prevents mixing of CMake generated files with those of your application, and allows you to have multiple builds against a single source without having to clean up, reconfigure and rebuild.

We'll illustrate this configure and build process on Linux/Mac using Makefiles, and on Windows using Visual Studio. The example script and Geant4's Geant4Config.cmake script are vanilla CMake, so you should be able to use other Generators (such as Xcode and Eclipse) without issue.

3.2.1.1.  Building ExampleB1 with CMake on Unix with Makefiles

We'll assume, for illustration only, that you've copied the exampleB1 sources into a directory under your home area so that we have

          +- /home/you/B1/
             +- CMakeLists.txt
             +- exampleB1.cc
             +- include/
             +- src/
             +- ...
        

Here, our source directory is /home/you/B1, in other words the directory holding the CMakeLists.txt file.

Let's also assume that you have already installed Geant4 in your home area under, for illustration only, /home/you/geant4-install.

Our first step is to create a build directory in which build the example. We will create this alongside our B1 source directory as follows:

        $ cd $HOME
        $ mkdir B1-build
      

We now change to this build directory and run CMake to generate the Makefiles needed to build the B1 application. We pass CMake two arguments:

  $ cd $HOME/B1-build
  $ cmake -DGeant4_DIR=/home/you/geant4-install/lib64/Geant4-10.2.0 $HOME/B1
      

Here, the first argument points CMake to our install of Geant4. Specifically, it is the directory holding the Geant4Config.cmake file that Geant4 installs to help CMake find and use Geant4. You should of course adapt the value of this variable to the location of your actual Geant4 install.

The second argument is the path to the source directory of the application we want to build. Here it's just the B1 directory as discussed earlier. You should of course adapt the value of that variable to where you copied the B1 source directory.

CMake will now run to configure the build and generate Makefiles. On Linux, you will see the output

  $ cmake -DGeant4_DIR=/home/you/geant4-install/lib64/Geant4-10.2.0 $HOME/B1
  -- The C compiler identification is GNU 4.9.2
  -- The CXX compiler identification is GNU 4.9.2
  -- Check for working C compiler: /usr/bin/gcc-4.9
  -- Check for working C compiler: /usr/bin/gcc-4.9 -- works
  -- Detecting C compiler ABI info
  -- Detecting C compiler ABI info - done
  -- Detecting C compile features
  -- Detecting C compile features - done
  -- Check for working CXX compiler: /usr/bin/g++-4.9
  -- Check for working CXX compiler: /usr/bin/g++-4.9 -- works
  -- Detecting CXX compiler ABI info
  -- Detecting CXX compiler ABI info - done
  -- Detecting CXX compile features
  -- Detecting CXX compile features - done
  -- Configuring done
  -- Generating done
  -- Build files have been written to: /home/you/B1-build
      

On Mac OS X, you will see slightly different output, but the last three lines should be identical.

If you now list the contents of you build directory, you can see the files generated:

  $ ls
  CMakeCache.txt       exampleB1.in   Makefile      vis.mac
  CMakeFiles           exampleB1.out  run1.mac
  cmake_install.cmake  init_vis.mac   run2.mac
      

Note the Makefile and that all the scripts for running the exampleB1 application we're about to build have been copied across. With the Makefile available, we can now build by simply running make:

        $ make -jN
      

CMake generated Makefiles support parallel builds, so can set N suitable for the number of cores on your machine (e.g. on a dual core processor, you could set N to 2). When make runs, you should see the output

  $ make
  Scanning dependencies of target exampleB1
  [ 16%] Building CXX object CMakeFiles/exampleB1.dir/exampleB1.cc.o
  [ 33%] Building CXX object CMakeFiles/exampleB1.dir/src/B1PrimaryGeneratorAction.cc.o
  [ 50%] Building CXX object CMakeFiles/exampleB1.dir/src/B1EventAction.cc.o
  [ 66%] Building CXX object CMakeFiles/exampleB1.dir/src/B1RunAction.cc.o
  [ 83%] Building CXX object CMakeFiles/exampleB1.dir/src/B1DetectorConstruction.cc.o
  [100%] Building CXX object CMakeFiles/exampleB1.dir/src/B1SteppingAction.cc.o
  Linking CXX executable exampleB1
  [100%] Built target exampleB1
      

CMake Unix Makefiles are quite terse, but you can make them more verbose by adding the VERBOSE argument to make:

        $ make VERBOSE=1
      

If you now list the contents of your build directory you will see the exampleB1 application executable has been created:

  $ ls
  CMakeCache.txt       exampleB1      init_vis.mac      run2.mac
  CMakeFiles           exampleB1.in   Makefile          vis.mac
  cmake_install.cmake  exampleB1.out  run1.mac
      

You can now run the application in place:

  $ ./exampleB1
  Available UI session types: [ GAG, tcsh, csh ]

  *************************************************************
   Geant4 version Name: geant4-10-02-ref-00 [MT]   (4-December-2015)
    << in Multi-threaded mode >>
                        Copyright : Geant4 Collaboration
                        Reference : NIM A 506 (2003), 250-303
                              WWW : http://cern.ch/geant4
  *************************************************************

  <<< Reference Physics List QBBC
  Visualization Manager instantiating with verbosity "warnings (3)"...
  Visualization Manager initialising...
  Registering graphics systems...
      

Note that the exact output shown will depend on how both Geant4 and your application were configured. Further output and behaviour beyond the Registering graphics systems... line will depend on what UI and Visualization drivers your Geant4 install supports. If you recall the use of the ui_all vis_all in the find_package command, this results in all available UI and Visualization drivers being activated in your application. If you didn't want any UI or Visualization, you could rerun CMake as:

  $ cmake -DWITH_GEANT4_UIVIS=OFF -DGeant4_DIR=/home/you/geant4-install/lib64/Geant4-10.2.0 $HOME/B1
      

This would switch the option we set up to false, and result in find_package not activating any UI or Visualization for the application. You can easily adapt this pattern to provide options for your application such as additional components or features.

Once the build is configured, you can edit code for the application in its source directory. You only need to rerun make in the corresponding build directory to pick up and compile the changes. However, note that due to the use of CMake globbing to create the source file list, if you add or remove files, you need to rerun CMake to pick up the changes! This is another reason why Kitware recommend listing the sources explicitly.

3.2.1.2.  Building ExampleB1 with CMake on Windows with Visual Studio

As with building Geant4 itself, the simplest system to use for building applications on Windows is a Visual Studio Developer Command Prompt, which can be started from StartAll ProgramsVisual Studio 2015Visual Studio ToolsDeveloper Command Prompt for VS2015.

We'll assume, for illustration only, that you've copied the exampleB1 sources into a directory C:\Users\YourUsername\Geant4\B1 so that we have

  +- C:\Users\YourUsername\Geant4\B1
     +- CMakeLists.txt
     +- exampleB1.cc
     +- include\
     +- src\
     +- ...
   

Here, our source directory is C:\Users\YourUsername\Geant4\B1, in other words the directory holding the CMakeLists.txt file.

Let's also assume that you have already installed Geant4 in your home area under, for illustration only, C:\Users\YourUsername\Geant4\geant4_10_02-install.

Our first step is to create a build directory in which build the example. We will create this alongside our B1 source directory as follows, working from the Visual Studio Developer Command Prompt:

  > cd %HOMEPATH%\Geant4
  > mkdir B1-build
      

We now change to this build directory and run CMake to generate the Visual Studio solution needed to build the B1 application. We pass CMake two arguments:

  > cd %HOMEPATH%\Geant4\B1-build
  > cmake -DGeant4_DIR=%HOMEPATH%\geant4_10_02-install\lib\Geant4-10.2.0 %HOMEPATH%\Geant4\B1
      

Here, the first argument points CMake to our install of Geant4. Specifically, it is the directory holding the Geant4Config.cmake file that Geant4 installs to help CMake find and use Geant4. You should of course adapt the value of this variable to the location of your actual Geant4 install.

The second argument is the path to the source directory of the application we want to build. Here it's just the B1 directory as discussed earlier. You should of course adapt the value of that variable to where you copied the B1 source directory.

CMake will now run to configure the build and generate Visual Studio solutions and you will see the output

  > cmake -DGeant4_DIR=%HOMEPATH%\geant4_10_02-install\lib\Geant4-10.2.0 %HOMEPATH%\Geant4\B1
  -- Building for: Visual Studio 14 2015
  -- The C compiler identification is MSVC 19.0.23026.0
  -- The CXX compiler identification is MSVC 19.0.23026.0
  -- Check for working C compiler using: Visual Studio 14 2015
  -- Check for working C compiler using: Visual Studio 14 2015 -- works
  -- Detecting C compiler ABI info
  -- Detecting C compiler ABI info - done
  -- Check for working CXX compiler using: Visual Studio 14 2015
  -- Check for working CXX compiler using: Visual Studio 14 2015 -- works
  -- Detecting CXX compiler ABI info
  -- Detecting CXX compiler ABI info - done
  -- Detecting CXX compile features
  -- Detecting CXX compile features - done
  -- Configuring done
  -- Generating done
  -- Build files have been written to: C:/Users/YourUsername/Geant4/B1-build
      

If you now list the contents of you build directory, you can see the files generated:

  > dir /B
  ALL_BUILD.vcxproj
  ALL_BUILD.vcxproj.filters
  B1.sln
  B1.vcxproj
  B1.vcxproj.filters
  CMakeCache.txt
  CMakeFiles
  cmake_install.cmake
  exampleB1.in
  exampleB1.out
  exampleB1.vcxproj
  exampleB1.vcxproj.filters
  init_vis.mac
  INSTALL.vcxproj
  INSTALL.vcxproj.filters
  run1.mac
  run2.mac
  vis.mac
  ZERO_CHECK.vcxproj
  ZERO_CHECK.vcxproj.filters

      

Note the B1.sln solution file and that all the scripts for running the exampleB1 application we're about to build have been copied across. With the solution available, we can now build by running cmake to drive MSBuild:

  > cmake --build . --config RelWithDebInfo
      

Solution based builds are quite verbose, but you should not see any errors at the end. In the above, we have built the B1 program in RelWithDebInfo mode, meaning that it is optimized and has debugging symbols. If we list the contents of the build directory again

  > dir /B
  ALL_BUILD.vcxproj
  ALL_BUILD.vcxproj.filters
  B1.sln
  B1.vcxproj
  B1.vcxproj.filters
  CMakeCache.txt
  CMakeFiles
  cmake_install.cmake
  exampleB1.dir
  exampleB1.in
  exampleB1.out
  exampleB1.vcxproj
  exampleB1.vcxproj.filters
  init_vis.mac
  INSTALL.vcxproj
  INSTALL.vcxproj.filters
  RelWithDebInfo
  run1.mac
  run2.mac
  vis.mac
  Win32
  ZERO_CHECK.vcxproj
  ZERO_CHECK.vcxproj.filters

  > dir /B RelWithDebInfo
  exampleB1.exe
  exampleB1.ilk
  exampleB1.pdb

      

Here, the RelWithDebInfo subdirectory contains the executable, and the main build directory contains all the .mac scripts for running the program. You can now run the application in place:

  > .\RelWithDebInfo\exampleB1.exe
  Available UI session types: [ Win32, GAG, csh ]

  *************************************************************
   Geant4 version Name: geant4-10-02-ref-00 [MT]   (4-December-2015)
    << in Multi-threaded mode >>
                        Copyright : Geant4 Collaboration
                        Reference : NIM A 506 (2003), 250-303
                              WWW : http://cern.ch/geant4
  *************************************************************

  <<< Reference Physics List QBBC
  Visualization Manager instantiating with verbosity "warnings (3)"...
  Visualization Manager initialising...
  Registering graphics systems...
      

Note that the exact output shown will depend on how both Geant4 and your application were configured. Further output and behaviour beyond the Registering graphics systems... line will depend on what UI and Visualization drivers your Geant4 install supports.

Whilst the Visual Studio Developer Command prompt provides the simplest way to build an application, the generated Visual Studio Solution file (B1.sln in the above example) may also be opened directly in the Visual Studio IDE. This provides a more comprehensive development and debugging environment, and you should consult its documentation if you wish to use this.

One key CMake related item to note goes back to our listing of the headers for the application in the call to add_executable. Whilst CMake will naturally ignore these for configuring compilation of the application, it will add them to the Visual Studio Solution. If you do not list them, they will not be editable in the Solution in the Visual Studio IDE.

3.2.1.3.  Usage of Geant4Config.cmake

Geant4Config.cmake is designed to be used with CMake's find_package command. When found, it sets several CMake variables and provides a mechanism for checking and activating optional features of Geant4. This allows you to use it in many ways in your CMake project to configure Geant4 for use by your application.

The most basic usage of Geant4Config.cmake in a CMakeLists.txt file is just to locate Geant4 with no requirements on its existence, version number or components:

        find_package(Geant4)
      

If you must find Geant4, then you can use

        find_package(Geant4 REQUIRED)
      

This will cause CMake to fail with an error should an install of Geant4 not be located.

When an install of Geant4 is found, the module sets a sequence of CMake variables that can be used elsewhere in the project:

  • Geant4_FOUND

    Set to CMake boolean true if an install of Geant4 was found.

  • Geant4_INCLUDE_DIRS

    Set to a list of directories containing headers needed by Geant4. May contain paths to third party headers if these appear in the public interface of Geant4.

  • Geant4_LIBRARIES

    Set to the list of libraries that need to be linked to an application using Geant4.

  • Geant4_DEFINITIONS

    The list of compile definitions needed to compile an application using Geant4. This is most typically used to correctly activate UI and Visualization drivers.

  • Geant4_CXX_FLAGS

    The compiler flags used to build this install of Geant4. Usually most important on Windows platforms.

  • Geant4_CXX_FLAGS_<CONFIG>

    The compiler flags recommended for compiling Geant4 and applications in mode CONFIG (e.g. Release, Debug, etc). Usually most important on Windows platforms.

  • Geant4_CXXSTD

    The C++ standard, e.g. "c++11" against which this install of Geant4 was compiled.

  • Geant4_TLS_MODEL

    The thread-local storage model, e.g. "initial-exec" against which this install of Geant4 was compiled. Only set if the install was compiled with multithreading support.

  • Geant4_USE_FILE

    A CMake script which can be included to handle certain CMake steps automatically. Most useful for very basic applications.

  • Geant4_builtin_clhep_FOUND

    A CMake boolean which is set to true if this install of Geant4 was built using the internal CLHEP.

  • Geant4_system_clhep_ISGRANULAR

    A CMake boolean which is set to true if this install of Geant4 was built using the system CLHEP and linked to the granular CLHEP libraries.

  • Geant4_builtin_expat_FOUND

    A CMake boolean which is set to true if this install of Geant4 was built using the internal Expat.

  • Geant4_builtin_zlib_FOUND

    A CMake boolean which is set to true if this install of Geant4 was built using the internal zlib.

  • Geant4_DATASETS

    A CMake list of the names of the physics datasets used by physics models in Geant4. It is provided to help iterate over the Geant4_DATASET_XXX_YYY variables documented below.

  • Geant4_DATASET_<NAME>_ENVVAR

    The name of the environment variable used by Geant4 to locate the dataset with name <NAME>.

  • Geant4_DATASET_<NAME>_PATH

    The absolute path to the dataset with name <NAME>. Note that the setting of this variable does not guarantee the existence of the dataset, and no checking of the path is performed. This checking is not provided because the action you take on non-existing data will be application dependent.

    You can access the Geant4_DATASET_XXX_YYY variables in a CMake script in the following way:

      find_package(Geant4_REQUIRED)                 # Find Geant4
    
      foreach(dsname ${Geant4_DATASETS})            # Iterate over dataset names
        if(NOT EXISTS ${Geant4_DATASET_${dsname}_PATH})  # Check existence
          message(WARNING "${dsname} not located at ${Geant4_DATASET_${dsname}_PATH}")
        endif()
      endforeach()
              

    A typical use case for these variables is to automatically set the dataset environment variables for your application without the use of the shell scripts described in Section 3.1. This could typically be via a shell script wrapper around your application, or runtime configuration of the application environment via the relevant C/C++ API for your system.

The typical usage of find_package and these variables to configure a build requiring Geant4 is thus:

  find_package(Geant4 REQUIRED)                       # Find Geant4
  include_directories(${Geant4_INCLUDE_DIRS})         # Add -I type paths
  add_definitions(${Geant4_DEFINITIONS})              # Add -D type defs
  set(CMAKE_CXX_FLAGS ${Geant4_CXX_FLAGS})            # Optional

  add_executable(myg4app myg4app.cc)                  # Compile application
  target_link_libraries(myg4app ${Geant4_LIBRARIES})  # Link it to Geant4
      

Alternatively, the CMake script pointed to by Geant4_USE_FILE may be included:

  find_package(Geant4 REQUIRED)                       # Find Geant4
  include(${Geant4_USE_FILE})                         # Auto configure includes/flags

  add_executable(myg4app myg4app.cc)                  # Compile application
  target_link_libraries(myg4app ${Geant4_LIBRARIES})  # Link it to Geant4
      

When included, the Geant4_USE_FILE script performs the following actions:

  1. Adds the definitions in Geant4_DEFINITIONS to the global compile definitions.

  2. Appends the directories listed in Geant4_INCLUDE_DIRS to those the compiler uses for search for include paths, marking them as system include directories.

  3. Prepends Geant4_CXX_FLAGS to CMAKE_CXX_FLAGS, and similarly for the extra compiler flags for each build mode (Release, Debug etc).

This use file is very useful for basic applications, but if your use case requires finer control over compiler definitions, include paths and flags you should use the relevant Geant4_NAME variables directly.

By default, CMake will look in several platform dependent locations for the Geant4Config.cmake file (see find_package for listings). You can also specify the location directly when running CMake by setting the Geant4_DIR variable to the path of the directory holding Geant4Config.cmake. It may be set on the command line via a -D option, or by adding an entry to the CMake GUI. For example, if we have an install of Geant4 located in

        +- opt/
           +- Geant4/
           +- lib/
              +- libG4global.so
              +- ...
              +- Geant4-10.2.0/
                 +- Geant4Config.cmake
      

then we would pass the argument -DGeant4_DIR=/opt/Geant4/lib/Geant4-10.2.0 to CMake. The CMAKE_PREFIX_PATH variable may also be used to point CMake to Geant4 by adding, to take the example above, /opt/Geant4 to the list of paths it holds. This may be set either on the command line or as a path-style UNIX environment variable.

You can also, if you wish, build an application against a build of Geant4 without installing it. If you look in the directory where you built Geant4 itself (e.g. on UNIX, where you ran make), you see there is a Geant4Config.cmake file. This is a perfectly valid file, so you can also point CMake to this file when building your application. Simply set Geant4_DIR to the directory where you built Geant4. This feature is most useful for Geant4 developers, but it can be useful if you cannot, or do not want to, install Geant4.

A version number may also be supplied to search for a Geant4 install greater than or equal to the supplied version, e.g.

        find_package(Geant4 10.0 REQUIRED)
      

would make CMake search for a Geant4 install whose version number is greater than or equal to 10.0. An exact version number may also be specified:

        find_package(Geant4 10.2.0 EXACT REQUIRED)
      

In both cases, CMake will fail with an error if a Geant4 install meeting these version requirements is not located.

Geant4 can be built with many optional components, and the presence of these can also be required by passing extra "component" arguments. For example, to require that Geant4 is found and that it support Qt UI and visualization, we can do

        find_package(Geant4 REQUIRED qt)
      

In this case, if CMake finds a Geant4 install that does not support Qt, it will fail with an error. Multiple component arguments can be supplied, for example

        find_package(Geant4 REQUIRED qt gdml)
      

requires that we find a Geant4 install that supports both Qt and GDML. If the component(s) is(are) found, any needed header paths, libraries and compile definitions required to use the component are appended to the variables Geant_INCLUDE_DIRS, Geant4_LIBRARIES and Geant4_DEFINITIONS respectively. Variables Geant4_<COMPONENTNAME>_FOUND are set to TRUE if component COMPONENTNAME is supported by the installation.

If you want to activate options only if they exist, you can use the pattern

        find_package(Geant4 REQUIRED)
        find_package(Geant4 QUIET COMPONENTS qt)
      

which will require CMake to locate a core install of Geant4, and then check for and activate Qt support if the install provides it, continuing without error otherwise. A key thing to note here is that you can call find_package multiple times to append configuration of components. If you use this pattern and need to check if a component was found, you can use the Geant4_<COMPONENTNAME>_FOUND variables described earlier to check the support.

The components which can be supplied to find_package for Geant4 are as follows:

  • static

    Geant4_static_FOUND is TRUE if the install of Geant4 provides static libraries.

    Use of this component forces the variable Geant4_LIBRARIES to contain static libraries, if they are available. It can therefore be used to force static linking if your application requires this, but note that this does not guarantee that static version of third party libraries will be used.

  • multithreaded

    Geant4_multithreaded_FOUND is TRUE if the install of Geant4 was built with multithreading support.

    Note that this only indicates availability of multithreading support and activates the required compiler definition to build a multithreaded Geant4 application. Multithreading in your application requires creation and usage of the appropriate C++ objects and interfaces as described in the Application Developers Guide.

  • usolids

    Geant4_usolids_FOUND is TRUE if the install of Geant4 was built with USolids replacing the Geant4 solids.

    Note that this only indicates that the replacement of Geant4 solids with USolids has taken place. Further information on the use of USolids applications is provided in the Application Developers Guide.

  • gdml

    Geant4_gdml_FOUND is TRUE if the install of Geant4 was built with GDML support.

  • g3tog4

    Geant4_g3tog4_FOUND is TRUE if the install of Geant4 provides the G3ToG4 library. If so, the G3ToG4 library is added to Geant4_LIBRARIES.

  • freetype

    Geant4_freetype_FOUND is TRUE if the install of Geant4 was built with Freetype support.

  • ui_tcsh

    Geant4_ui_tcsh_FOUND is TRUE if the install of Geant4 provides the TCsh command line User Interface. Using this component allows use of the TCsh command line interface in the linked application.

  • ui_win32

    Geant4_ui_win32_FOUND is TRUE if the install of Geant4 provides the Win32 command line User Interface. Using this component allows use of the Win32 command line interface in the linked application.

  • motif

    Geant4_motif_FOUND is TRUE if the install of Geant4 provides the Motif(Xm) User Interface and Visualization driver. Using this component allows use of the Motif User Interface and Visualization Driver in the linked application.

  • qt

    Geant4_qt_FOUND is TRUE if the install of Geant4 provides the Qt4 User Interface and Visualization driver. Using this component allows use of the Qt User Interface and Visualization Driver in the linked application.

  • wt

    Geant4_wt_FOUND is TRUE if the install of Geant4 provides the Wt Web User Interface and Visualization driver. Using this component allows use of the Wt User Interface and Visualization Driver in the linked application.

  • vis_network_dawn

    Geant4_vis_network_dawn_FOUND is TRUE if the install of Geant4 provides the Client/Server network interface to DAWN visualization. Using this component allows use of the Client/Server DAWN Visualization Driver in the linked application.

  • vis_network_vrml

    Geant4_vis_network_vrml_FOUND is TRUE if the install of Geant4 provides the Client/Server network interface to VRML visualization. Using this component allows use of the Client/Server VRML Visualization Driver in the linked application.

  • vis_opengl_x11

    Geant4_vis_opengl_x11_FOUND is TRUE if the install of Geant4 provides the X11 interface to the OpenGL Visualization driver. Using this component allows use of the X11 OpenGL Visualization Driver in the linked application.

  • vis_opengl_win32

    Geant4_vis_opengl_win32_FOUND is TRUE if the install of Geant4 provides the Win32 interface to the OpenGL Visualization driver. Using this component allows use of the Win32 OpenGL Visualization Driver in the linked application.

  • vis_openinventor

    Geant4_vis_openinventor_FOUND is TRUE if the install of Geant4 provides the OpenInventor Visualization driver. Using this component allows use of the OpenInventor Visualization Driver in the linked application.

  • ui_all

    Activates all available UI drivers. Does not set any variables, and never causes CMake to fail.

  • vis_all

    Activates all available Visualization drivers. Does not set any variables, and never causes CMake to fail.

Please note that whilst the above aims to give a complete summary of the functionality of Geant4Config.cmake, it only gives a sampling of the ways in which you may use it, and other CMake functionality, to configure your application. We also welcome feedback, suggestions for improvement and bug reports on Geant4Config.cmake.

3.2.2.  Using Geant4Make to build Applications: binmake.gmk

Geant4Make is the Geant4 GNU Make toolchain formerly used to build the toolkit and applications. It is installed on UNIX systems (except for Cygwin) for backwards compatibility with the Geant4 Examples and your existing applications which use a GNUmakefile and the Geant4Make binmake.gmk file. However, please note that the system is now deprecated, meaning that it is no longer supported and may be removed in future releases without warning. You should migrate your application to be built using CMake via the Geant4Config.cmake script, or any other build tool of your choice, using the geant4-config program to query the relevant compiler/linker flags.

The files for Geant4Make are installed under:

      +- CMAKE_INSTALL_PREFIX/
         +- share/
            +- geant4make/
               +- geant4make.sh
               +- geant4make.csh
               +- config/
                  +- binmake.gmk
                  +- ...
    

The system is designed to form a self-contained GNUMake system which is configured primarily by environment variables (though you may manually replace these with Make variables if you prefer). Building a Geant4 application using Geant4Make therefore involves configuring your environment followed by writing a GNUmakefile using the Geant4Make variables and GNUMake modules.

To configure your environment, simply source the relevant configuration script CMAKE_INSTALL_PREFIX/share/Geant4-10.2.0/geant4make/geant4make.(c)sh for your shell. Whilst both scripts can be sourced interactively, if you are using the C shell and need to source the script inside another script, you must use the commands:

  cd CMAKE_INSTALL_PREFIX/share/Geant4-10.2.0/geant4make
  source geant4make.csh
    

or alternatively

  source CMAKE_INSTALL_PREFIX/share/Geant4-10.2.0/geant4make/geant4make.csh \\
    CMAKE_INSTALL_PREFIX/share/Geant4-10.2.0/geant4make
    

In both cases, you should replace CMAKE_INSTALL_PREFIX with the actual prefix you installed Geant4 under. Both of these commands work around a limitation in the C shell which prevents the script locating itself.

Please also note that due to limitations of Geant4Make, you should not rely on the environment variables it sets for paths into Geant4 itself. In particular, note that the G4INSTALL variable is not equivalent to CMAKE_INSTALL_PREFIX.

Once you have configured your environment, you can start building your application. Geant4Make enforces a specific organization and naming of your sources in order to simplify the build. We'll use Basic Example B1, which you may find in the Geant4 source directory under examples/basic/B1, as the canonical example again. Here, the sources are arranged as follows

     +- B1/
         +- GNUmakefile
         +- exampleB1.cc
         +- include/
         |  ... headers.hh ...
         +- src/
            ... sources.cc ...
    

As before, exampleB1.cc contains main() for the application, with include/ and src/ containing the implementation class headers and sources respectively. You must organise your sources in this structure with these filename extensions to use Geant4Make as it will expect this structure when it tries to build the application.

With this structure in place, the GNUmakefile for exampleB1 is very simple:

      name := exampleB1
      G4TARGET := $(name)
      G4EXLIB := true

      .PHONY: all
      all: lib bin

      include $(G4INSTALL)/config/binmake.gmk
    

Here, name is set to the application to be built, and it must match the name of the file containing the main() program without the .cc extension. The rest of the variables are structural to prepare the build, and finally the core Geant4Make module is included. The G4INSTALL variable is set in the environment by the geant4make script to point to the root of the Geant4Make directory structure.

With this structure in place, simply run make to build your application:

      $ make
    

If you need extra detail on the build, you append CPPVERBOSE=1 to the make command to see a detailed log of the command executed.

The application executable will be output to $(G4WORKDIR)/bin/$(G4SYSTEM)/exampleB1, where $(G4SYSTEM) is the system and compiler combination you are running on, e.g. Linux-g++. By default, $(G4WORKDIR) is set by the geant4make scripts to $(HOME)/geant4_workdir, and also prepends this directory to your PATH. You can therefore run the application directly once it's built:

      $ exampleB1
    

If you prefer to keep your application builds separate, then you can set G4WORKDIR in the GNUmakefile before including binmake.gmk. In this case you would have to run the executable by supplying the full path.

Further documentation of the usage of Geant4Make and syntax and extensions for the GNUMakefile is described in the FAQ and Appendices of the Geant4 User's Guide for Application Developers.

Please note that the Geant4Make toolchain is provided purely for conveniance and backwards compatibility. We encourage you to use and migrate your applications to the new CMake and geant4-config tools. Geant4Make is deprecated in Geant4 10.0 and later.

3.2.3.  Other Unix Build Systems: geant4-config

If you wish to write your own Makefiles or use a completely different buildsystem for your application, a simple command line program named geant4-config is installed on Unix systems to help you query a Geant4 installation for locations and features. It is installed at

      +- CMAKE_INSTALL_PREFIX
          +- bin/
             +- geant4-config
    

It may be run using either a full or relative path, or directly if CMAKE_INSTALL_PREFIX/bin is in your PATH.

This program provides the following command line interface for querying various parameters of the Geant4 installation:

  $ geant4-config --help
  Usage: geant4-config [OPTION...]
    --prefix                output installation prefix of Geant4
    --version               output version for Geant4
    --cxxstd                C++ Standard compiled against
    --tls-model             Thread Local Storage model used
    --libs                  output all linker flags
    --cflags                output all preprocessor
                            and compiler flags

    --libs-without-gui      output linker flags without
                            GUI components
    --cflags-without-gui    output preprocessor and compiler
                            flags without GUI components

    --has-feature FEATURE   output yes if FEATURE is supported,
                            or no if not supported

    --datasets              output dataset name, environment variable
                            and path, with one line per dataset

    --check-datasets        output dataset name, installation status and
                            expected installation location, with one line
                            per dataset

    --install-datasets      download and install any missing datasets,
                            requires a network connection and for the dataset
                            path to be user writable

  Known Features:
   staticlibs[no]
   multithreading[yes]
   clhep[yes]
   expat[no]
   zlib[yes]
   gdml[no]
   usolids[no]
   freetype[no]
   g3tog4[no]
   qt[no]
   motif[no]
   raytracer-x11[no]
   opengl-x11[no]
   openinventor[no]

  Help options:
    -?, --help              show this help message
    --usage                 display brief usage message

You are completely free to organise your application sources as you wish and to use any buildsystem that can interface with the output of geant4-config.

The --cflags argument will print the required compile definitions and include paths (in -I<path> format) to use Geant4 to stdout. Note that default header search paths for the compiler Geant4 was built with are filtered out of the output of --cflags. The --libs argument will print the libraries (in -L<path> -lname1 ... -lnameN format) required to link with Geant4 to stdout. Note that this may include libraries for third party packages and may not be reliable for static builds. By default, all the flags and Geant4 libraries needed to activate all installed UI and Visualization drivers are provided in these outputs, but you may use the -without-gui variants of these arguments to suppress this.

You may also check the availability of features supported by the install of Geant4 with the --has-feature argument. If the argument to --has-feature is known to Geant4 and enabled in the installation, yes will be printed to stdout, otherwise no will be printed.

The --datasets argument may be used to print out a table of dataset names, environment variables and paths. No checking of the existence of the paths is performed, as the action to take on a non-existing dataset will depend on your use case. The table is printed with one row per dataset, with space separated columns for the dataset name, environment variable name and path. As with Geant4Config.cmake, this information is provided to help you configure your application environment to locate the Geant4 datasets without a preexisting setup, if your use case demands this.

The --check-datasets argument may be used to check whether the datasets are installed in the location expected (as set by the configuration of Geant4). A table is printed with one row per dataset, with space separated columns for the dataset name, installation status and expected path. If the expected path is found, the status column will contain INSTALLED, otherwise it will contain NOTFOUND. Note that this check only verifies the existence of the dataset path. It does not validate that the dataset files are all present nor that the relevant environment variables are set.

If you did not use the GEANT4_INSTALL_DATA option to install data when Geant4 itself was installed, you can use the --install-datasets argument to perform this task at a later time. Running geant4-config with this argument will download, unpack and install each dataset to the location expected by the Geant4 installation. These steps require a working network connection, the local dataset installation path to be writable by the user running geant4-config and the presence of the curl, openssl and tar programs. Note that no changes to the environment are made by the data installation, so you may need to update this using the relevant scripts documented in Section 3.1.

Due to the wide range of possible use cases, we do not provide an example of using geant4-config to build an application. However, it should not require more than appending the output of --cflags to your compiler flags and that of --libs to the list of libraries to link to. We welcome feedback, suggestions for improvement and bug reports on geant4-config.