VisIt CMake Build System
During 2009, VisIt's autoconf build system was replaced with one based on CMake. CMake was chosen as the replacement build system because of its ability to generate Makefiles for UNIX and project files for Visual Studio on Windows from the same build scripts. There has been an enduring problem of maintaining separate build systems for Windows and UNIX and CMake eliminates this problem by consolidating all of the build system logic into a single set of build scripts.
Contents
Making the switch
This section contains some information related to switching to using the new CMake build system.
Required version
CMake 3.0 or later is required to build VisIt. The build_visit script will build the appropriate version for you.
Getting started
We recommend that you rebuild your 3rd party libraries using build_visit because it can build them fairly painlessly on most systems. The build_visit script will also create a hostname.cmake file for your system that tells the VisIt cmake build where to locate the 3rd party libraries so they can be used in the build process. Once you have created a hostname.cmake (note that hostname will be the name of your computer) you can continue to use the 3rd party library files you have built in order to build VisIt. To make VisIt's cmake build automatically detect the hostname.cmake file, simply copy it into VisIt's src/config-site directory before running cmake.
Configuring
To configure cmake, if cmake is in your path, you will simply need to do this to configure using cmake:
cd src cmake .
On most platforms, cmake will generate Makefiles by default. There are a few "flavors" of Makefiles that can be generated if you use Eclipse or KDevelop3. In addition, CMake can create projects for native build environments like Visual Studio on Windows or XCode on Mac.
Generating an Out of Source Build
An out of source build is very useful because it avoids clutter in your source tree and allows you to create multiple builds from a single source tree. To generate an an out of source build simply create a directory to build in and invoke cmake from there with the path to VisIt's source directory:
mkdir build cd build cmake path/to/visit/src
Note: If an in source build has already been configured, you will need to remove the CMakeCache.txt file in VisIt's src directory.
Verbose Makefile
By default CMake will generate Makefiles that print out only a percentage complete and the filename. If you would like to see the commands that are executed as sources are compiled and linked, you can configure like this:
cmake -DVISIT_VERBOSE_MAKEFILE:BOOL=ON /path/to/visit/src
You can make this change permanent if you insert the following line into your src/config-site/host.cmake file:
SET(VISIT_VERBOSE_MAKEFILE TRUE)
If you already configured without setting the VISIT_VERBOSE_MAKEFILE option to ON then you can run make with additional arguments:
make VERBOSE=1
Debug & Release Builds
When configuring you can select a debug or release build by setting the CMAKE_BUILD_TYPE variable and cmake will include the appropriate compiler flags for the selected build type on your platform.
Debug:
cmake path/to/visit/src -DCMAKE_BUILD_TYPE:STRING=Debug
Release:
cmake path/to/visit/src -DCMAKE_BUILD_TYPE:STRING=Release
Generating Visual Studio Projects
See the Using CMake with VisIt on Windows page for more information on configuring VisIt to build on Windows.
Generating XCode Projects
To generate XCode projects on the Mac, do this:
cd src
cmake -G Xcode .
This will produce a top level VISIT project that you can open in XCode. Prepare for a delay though since VisIt's entire build system contains hundreds of targets.
Plugin development
If you want to know more about developing plugins using the new build system, see Building plugins using CMake.
Installation
If you want to know more about installing VisIt using the new build system, see Installing using CMake.
Basic CMake
This section contains some basic information about using cmake.
Where to get help
The cmake executable itself contains the best reference for using cmake. You may want to do this to see the entire help:
cmake --help-full | less
The top part of the cmake help is devoted to the various cmake commands that you can call. After that there are properties that can be set for global, targets, and source files. Properties influence how targets are generated or code is compiled.
The CMake Wiki is also a good place to learn about using CMake.
CMakeLists.txt
All build logic for the CMake build is contained in a file called CMakeLists.txt. Each subdirectory in VisIt that contributes to the build will contain its own CMakeLists.txt file, which can be as simple as creating an install target or adding a subdirectory or it can be very complex, generating many targets.
Style
VisIt's CMake build system uses the following coding style guidelines
- Include a copyright header at the top of CMakeLists.txt
- Use capital letters only for cmake code
- Use '#' comments where appropriate
- Use the provided macros and functions to make modifications easier
- Don't do anything non-portable!
- Don't indent when providing source code filenames
- Indent control flow 4 spaces
More about configuring
See the section above on configuring if you want to know how to configure cmake for the first time. After you run cmake, a file called CMakeCache.txt is created to contain the cached results of various queries performed during configuration. This includes information such as which compilers and settings were used and which VisIt options were set or where various 3rd party libraries are located.
If you change your settings or make important changes to the CMakeLists.txt file that could impact any of the answers that would be stored in the cache, you should DELETE CMakeCache.txt before you rerun cmake.
Another point worth mentioning is that if you edit a CMakeLists.txt file or any file that gets included into it then when you make cmake will regenerate your Makefiles or project files.
Adding source files
The typical VisIt CMakeLists.txt file contains source code that needs to be added to an executable or library. This is done by assigning the names of sources into a variable, much like was done in the old Makefile.in files.
In this example, we create a variable called SOURCES and add 4 source files to it. The sources can all be in the same directory or they may be in subdirectories. There may be absolute paths but all VisIt sources are given relative to the current directory.
For consistent style, do not indent the sources! This makes makes it easier to cut and paste them from a terminal where you've executed ls *.C | sort to get the list of source files.
# List of sources
SET(SOURCES
foo.C
bar.C
subdirectory/gorfo.C
main.C
)
# Make an executable with those sources
ADD_EXECUTABLE(foobar ${SOURCES})
Adding an executable
Adding an executable requires you to call the ADD_EXECUTABLE function. The first argument to ADD_EXECUTABLE is the name of the target that describes the executable program. In nearly all cases, this can be the name of the executable itself. If that name is taken, however, then create a unique target name (across all VisIt CMakeLists.txt) and you can set the executable name on the target using SET_TARGET_PROPERTIES.
The ADD_EXECUTABLE function can take any number of sources. In this example, it is assumed we've defined variables MYSOURCES and MYSOURCES2 using the SET command.
If your new executable is a program that should be distributed as part of VisIt, don't forget to add an install target for it using the VISIT_INSTALL_TARGETS function
ADD_EXECUTABLE(exename ${MYSOURCES} ${MYSOURCES2})
# Make sure we install this program as part of "make install"
VISIT_INSTALL_TARGETS(exename)
Adding a parallel executable
The top-level CMakeLists.txt for VisIt has defined a function called ADD_PARALLEL_EXECUTABLE that takes care of adding the relevent parallel compilation flags and MPI linking directives required to produce a parallel executable. Be sure to use this macro when you need to build a parallel executable. Your cmake code should look like this:
SET(SOURCES
foo.C
bar.C
main.C
)
# Build the serial version
ADD_EXECUTABLE(program_ser ${SOURCES})
# We can build a parallel version too
IF(VISIT_PARALLEL)
ADD_PARALLEL_EXECUTABLE(program_par ${SOURCES})
# Make sure we install this program as part of "make install"
VISIT_INSTALL_TARGETS(program_par)
ENDIF(VISIT_PARALLEL)
Adding a library
Creating a library is much like creating an executable, except you use the ADD_LIBRARY function. As with ADD_EXECUTABLE, the name of the target is usually the name of the library but you can use target properties to set a different library name. In the example below, a target name of foo produces a library called 'libfoo.so', if shared libraries are being produced. VisIt's build will by default create shared libraries unless the VISIT_STATIC option is set to true when you run cmake.
SET(SOURCES
foo.C
bar.C
)
ADD_LIBRARY(foo ${SOURCES})
# Make sure the library gets installed during "make install"
VISIT_INSTALL_TARGETS(foo)
Adding a parallel library
As with parallel executables, VisIt's CMake build provides a function to build parallel libraries. That function is: ADD_PARALLEL_LIBRARY.
IF(VISIT_PARALLEL)
ADD_PARALLEL_LIBRARY(foo_par ${SOURCES})
# Make sure the library gets installed during "make install"
VISIT_INSTALL_TARGETS(foo_par)
ENDIF(VISIT_PARALLEL)
Adding a new directory
If you need to add a new directory, you can tell cmake do descend into it by using the ADD_SUBDIRECTORY function.
ADD_SUBDIRECTORY(subdir)
Differences vs the old build system
This section is meant to list some of the different choices that were made and improvements that are found in the new build system.
Improvements
- make install works
- All of VisIt can be installed this way
- You can choose to install 3rd party I/O libraries for plugins to build against
- make package produces a VisIt binary distribution
- This currently produces a tar.gz but it can in theory produce RPMs and other formats
- dependencies are much better, though this is a double-edged sword
- The build system will reconfigure if you change any CMakeLists.txt
- This permits better parallel make since the build is not limited to being parallel within a single directory
- out of source build
- You can generate Makefiles or if your platform permits it, projects for your favorite IDE
- VisIt can be built statically
Includes
- The include/visit directory full of symlinks to other parts of VisIt is gone. Individual CMakeLists.txt now add each include directory they need to their INCLUDE_DIRECTORIES function
Libraries
- The new build system consolidates all of the common libraries into a single library called visitcommon
- All of the AVT libraries are now prefixed with avt
- Significant decoupling of libraries has been done for the new build system
- This results in better library design and better dependencies
- 3rd party libraries are no longer copied into src/lib; instead cmake uses rpath to tell VisIt where to find them
- 3rd party libraries do get installed using make install
- Each library target must include TARGET_LINK_LIBRARIES to ensure that it is built against its dependencies
- This is mandatory to keep the Windows build working
- Together with -fvisibility=hidden on Linux, this will discourage the tangling up of library dependencies. This means DO NOT JUST CALL A FUNCTION FROM SOME OTHER LIBRARY BECAUSE IT'S THERE. YOU BETTER HAVE A GOOD REASON. It also means that you might have to move a function from one library to another to ensure the best library design
Plugins
- When you create a new plugin or modify its XML file, you will need to rerun xml2cmake to regenerate the CMakeLists.txt file that lets CMake build the plugin
- CMakeLists.txt files for plugins are checked into SVN and a small subset may contain hand-edits (Volume plot)
Code generation
- Linux systems with gcc 4.0 or later will use -fvisibility=hidden to hide symbols by default from public scope in a shared library
- This forces the class XXX_API macro to be used, preventing a large class of Windows source incompatibilities
- This forces the developer to be more careful about introducing new library dependencies
- visit-config.h has been shrunk somewhat to remove some of the compile time macro definitions
- Those macro definitions are now passed on the compiler command line for the source files
- This reduces the number of times visit-config.h changes as a result of running cmake and reduces the number of sources that must be recompiled
- The SVN version was removed and put into an automatically generated C file so svn update would not cause extensive recompilation of the code
- DBIO_ONLY builds no longer add any definitions to visit-config.h. Instead all files build with -DDBIO_ONLY in order to reduce the number of important include files that referenced visit-config.h.
Anatomy of the new build system
Also see:
Top level CMakeLists.txt
Organized into sections
- include config-site
- options
- install-related stuff
- platform checks
- generate visit-config.h
- add subdirectories
- cpack section
Platform checks stored in CMake directory
- All 3rd party I/O have their own Find*.cmake file based on SetupThirdParty.cmake which locates includes and libraries and defines variables that the rest of CMake can use
Option variables
VisIt's CMake build allows you to set options that tell the build which features are enabled. This table lists the options that are not related to finding 3rd party libraries. You can use the option variables in various CMakeLists.txt files to influence control flow. The values for these options can be passed on the cmake command line using -D.
Example:
cmake -DVISIT_PARALLEL:BOOL=ON /path/to/visit/src
Option | Description | Default value |
VISIT_PARALLEL | Build VisIt's parallel compute engine. | OFF |
VISIT_TUVOK | Build VisIt with support for the Tuvok volume rendering library. | OFF |
VISIT_SLIVR | Build VisIt with support for the SLIVR volume rendering library. | ON |
VISIT_STATIC | Build VisIt statically. | OFF |
VISIT_PYTHON_SCRIPTING | Build VisIt with Python scripting support. | ON |
VISIT_BUILD_ALL_PLUGINS | Build all of VisIt's plugins. | OFF |
VISIT_BUILD_MINIMAL_PLUGINS | Build a minimal set of VisIt's plugins. | OFF |
VISIT_ZLIB | Use VisIt's internal libz | OFF |
VISIT_JAVA | Build the VisIt Java client interface | OFF |
VISIT_SERVER_COMPONENTS_ONLY | Build only vcl, mdserver, engine and their plugins | OFF |
VISIT_ENGINE_ONLY | Build only the compute engine and its plugins | OFF |
VISIT_DBIO_ONLY | Build only visitconvert and engine plugins | OFF |
VISIT_DISABLE_SELECT | Disable use of the select() function | OFF |
VISIT_USE_NOSPIN_BCAST | Use VisIt's no-spin Bcast in parallel | ON |
VISIT_INSTALL_THIRD_PARTY | Install VisIt's 3rd party I/O libs and includes to permit plugin development | OFF |
VISIT_NOLINK_MPI_WITH_LIBRARIES | Do not link MPI with VisIt's parallel shared libraries; just with executables | OFF |
VISIT_CREATE_SOCKET_RELAY | Create a separate executable that forwards VisIt's socket connection between engine and component launcher | OFF |
VISIT_RPATH_RELATIVE_TO_EXECUTABLE_PATH | Install rpath relative to executable location using \$ORIGIN tag | OFF |
VISIT_FORTRAN | Enable compilation of Fortran example progams | OFF |
VISIT_DATA_MANUAL_EXAMPLES | Build Getting Data Into VisIt examples | OFF |
VISIT_VERSION_STRING | If this variable is set then you can replace the typical svn version XXXXX string in the splashscreen with the string of your choosing. | not set |
VISIT_CONFIG_SITE | Pass the path to a config-site file that contains various options for the CMake build. The config-site file is usually generated by the build_visit script and it contains the paths to all of the 3rd party libraries that will be used in the build process (e.g. location of VTK, Qt, Python, Silo, Mesa, etc.). If this variable is not set then VisIt's CMake build will look in the src/config-site directory for a file called hostname.cmake where hostname is the name of the computer where VisIt is being built. | not used by default |
Example:
# Use the "VISIT_PARALLEL" option to determine whether an executable is built.
IF(VISIT_PARALLEL)
ADD_PARALLEL_EXECUTABLE(foo foo.cpp bar.cpp)
ENDIF(VISIT_PARALLEL)
Installation
VisIt's CMake build system makes heavy use of the INSTALL keyword to create rules that tell the build system how to install VisIt so simply typing make install will install VisIt. It is important that you be sure to add INSTALL directives for new targets that you add to the build system so your new target (library, program) gets installed as part of make install.
Important variables
This table includes important variables that you can use for checking for the existence of a library as well as for its includes and libs. Use these variables when adding libraries to TARGET_LINK_LIBRARIES. We better not see anything like -lhdf5 being added to TARGET_LINK_LIBRARIES. If we see that type of coding we will beat you.
Library name | Existence variable | IncludeDir variable | LibraryLinkDir variable | Library variable |
VTK | VTK_FOUND | VTK_INCLUDE_DIRS | VTK_LIBRARY_DIRS | Use major kits directly e.g. vtkCommon |
Qt | QT_FOUND, QT4_FOUND | QT_QTCORE_INCLUDE_DIR, QT_QTGUI_INCLUDE_DIR, QT_QTNETWORK_INCLUDE_DIR, QT_QTOPENGL_INCLUDE_DIR, QT_QTXML_INCLUDE_DIR | QT_LIBRARY_DIR | QT_QTCORE_LIBRARY, QT_QTGUI_LIBRARY, QT_QTNETWORK_LIBRARY, QT_QTOPENGL_LIBRARY, QT_QTXML_LIBRARY |
Python | PYTHONLIBS_FOUND | PYTHON_INCLUDE_PATH | N/A | PYTHON_LIBRARIES |
Mesa | MESA_FOUND | MESA_INCLUDE_DIR | MESA_LIBRARY_DIR | MESA_LIB |
OpenGL | OPENGL_FOUND | OPENGL_INCLUDE_DIR | N/A | OPENGL_gl_LIBRARY, OPENGL_glu_LIBRARY |
ICET | ICET_FOUND | ICET_INCLUDE_DIR | ICET_LIBRARY_DIR | ICET_LIB |
GLEW | GLEW_FOUND | GLEW_INCLUDE_DIR | GLEW_LIBRARY_DIR | Use library GLEW since it is a 3rd party builtin |
tcmalloc | TCMALLOC_FOUND | TCMALLOC_INCLUDE_DIR | TCMALLOC_LIBRARY_DIR | TCMALLOC_LIB |
Adios | ADIOS_FOUND | ADIOS_INCLUDE_DIR | ADIOS_LIBRARY_DIR | ADIOS_LIB |
AdvIO | ADVIO_FOUND | ADVIO_INCLUDE_DIR | ADVIO_LIBRARY_DIR | ADVIO_LIB |
Boxlib 2D | BOXLIB2D_FOUND | BOXLIB2D_INCLUDE_DIR | BOXLIB2D_LIBRARY_DIR | BOXLIB2D_LIB |
Boxlib 3D | BOXLIB3D_FOUND | BOXLIB3D_INCLUDE_DIR | BOXLIB3D_LIBRARY_DIR | BOXLIB3D_LIB |
CCMIO | CCMIO_FOUND | CCMIO_INCLUDE_DIR | CCMIO_LIBRARY_DIR | CCMIO_LIB |
CFITSIO | CFITSIO_FOUND | CFITSIO_INCLUDE_DIR | CFITSIO_LIBRARY_DIR | CFITSIO_LIB |
CGNS | CGNS_FOUND | CGNS_INCLUDE_DIR | CGNS_LIBRARY_DIR | CGNS_LIB |
Exodus II | EXODUSII_FOUND | EXODUSII_INCLUDE_DIR | EXODUSII_LIBRARY_DIR | EXODUSII_LIB |
FastBit | FASTBIT_FOUND | FASTBIT_INCLUDE_DIR | FASTBIT_LIBRARY_DIR | FASTBIT_LIB |
GDAL | GDAL_FOUND | GDAL_INCLUDE_DIR | GDAL_LIBRARY_DIR | GDAL_LIB |
H5Part | H5PART_FOUND | H5PART_INCLUDE_DIR | H5PART_LIBRARY_DIR | H5PART_LIB |
HDF4 | HDF4_FOUND | HDF4_INCLUDE_DIR | HDF4_LIBRARY_DIR | HDF4_LIB |
HDF5 | HDF5_FOUND | HDF5_INCLUDE_DIR | HDF5_LIBRARY_DIR | HDF5_LIB |
Mili | MILI_FOUND | MILI_INCLUDE_DIR | MILI_LIBRARY_DIR | MILI_LIB |
NETCDF | NETCDF_FOUND | NETCDF_INCLUDE_DIR | NETCDF_LIBRARY_DIR | NETCDF_LIB |
NETCDF C++ | NETCDF_CXX_FOUND | NETCDF_CXX_INCLUDE_DIR | NETCDF_CXX_LIBRARY_DIR | NETCDF_CXX_LIB |
Silo | SILO_FOUND | SILO_INCLUDE_DIR | SILO_LIBRARY_DIR | SILO_LIB |
Informing the build system about MPI
The cmake build system currently relies on certain variables being set in order to perform its MPI detection. These variables may need to be actual options at some point but right now they are handled as variables in a config-site .cmake file. There are 2 ways to tell VisIt about MPI. The first way is to tell VisIt the name of the mpicxx compiler that you want to use to deduce the proper MPI settings. Alternatively, you can provide all of the MPI information explicitly.
Using the MPI compiler driver
In order to use the MPI compiler driver (mpiCC, mpicxx) to deduce your MPI settings, you must set these variables in your config-site file:
- VISIT_MPI_COMPILER (e.g. /usr/local/bin/mpicxx)
- VISIT_MPI_FORTRAN_COMPILER (only if you are also using the VISIT_FORTRAN option)
These 2 variables are used to determine the MPI libraries and settings to be used when compiling and linking C/C++ and Fortran code, respectively.
Example:
SET(VISIT_PARALLEL ON)
SET(VISIT_MPI_COMPILER /usr/local/bin/mpicxx)
Setting up MPI explicitly
If you don't want to rely on a compiler driver to supply your MPI settings, you may also provide them explicitly.
General parallel options:
Variable name | Explanation |
VISIT_NOLINK_MPI_WITH_LIBRARIES | This BOOL option tells VisIt's CMake build system not to try and link shared libraries with your static MPI library. This comes up when you have a static MPI library that was not built with -fPIC. The best option is to use a shared MPI library but if you can't do that then option might get you farther. |
VISIT_PARALLEL_RPATH | This option lets you tell VisIt the path to be used when linking parallel executables so you can insert an rpath that lets the loader find your MPI libraries. |
Options for parallel C/C++ compilation:
Variable name | Explanation |
VISIT_MPI_LIBS | The MPI libraries to link into your parallel executable |
VISIT_MPI_C_FLAGS | CFLAGS to use when compiling your parallel C sources |
VISIT_MPI_CXX_FLAGS | CXXFLAGS to use when compiling your parallel C++ sources |
VISIT_MPI_LD_FLAGS | LDFLAGS to use when linking your parallel executable |
Options for parallel Fortran compilation:
Variable name | Explanation |
VISIT_MPI_FORTRAN_LIBS | The MPI libraries to link into your parallel executable |
VISIT_MPI_FORTRAN_FLAGS | Flags to use when compiling your parallel Fortran sources |
Example of providing MPI flags explicitly in your host.cmake file:
VISIT_OPTION_DEFAULT(VISIT_PARALLEL ON) VISIT_OPTION_DEFAULT(VISIT_MPI_CXX_FLAGS -I/usr/local/tools/mvapich-gnu/include) VISIT_OPTION_DEFAULT(VISIT_MPI_C_FLAGS -I/usr/local/tools/mvapich-gnu/include) VISIT_OPTION_DEFAULT(VISIT_MPI_LD_FLAGS "-L/usr/local/tools/mvapich-gnu/lib/shared -L/usr/local/tools/mvapich-gnu/lib -Wl,-rpath=/usr/local/tools/mvapich-gnu/lib/shared") VISIT_OPTION_DEFAULT(VISIT_MPI_LIBS mpich) VISIT_OPTION_DEFAULT(VISIT_PARALLEL_RPATH "/usr/local/tools/mvapich-gnu/lib/shared")