VisIt CMake Build System

From VisItusers.org

Jump to: navigation, search

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

[edit] Making the switch

This section contains some information related to switching to using the new CMake build system.

[edit] Required version

CMake 3.0 or later is required to build VisIt. The build_visit script will build the appropriate version for you.

[edit] 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.

[edit] 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.

[edit] 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.

[edit] 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

[edit] 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

[edit] Generating Visual Studio Projects

See the Using CMake with VisIt on Windows page for more information on configuring VisIt to build on Windows.

[edit] 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.

[edit] Plugin development

If you want to know more about developing plugins using the new build system, see Building plugins using CMake.

[edit] Installation

If you want to know more about installing VisIt using the new build system, see Installing using CMake.

[edit] Basic CMake

This section contains some basic information about using cmake.

[edit] 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.

[edit] 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.

[edit] 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

[edit] 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.

[edit] 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})

[edit] 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)

[edit] 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)

[edit] 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)

[edit] 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)

[edit] 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)

[edit] 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.

[edit] 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

[edit] 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

[edit] 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

[edit] 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)

[edit] 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.

[edit] Anatomy of the new build system

Also see:

[edit] Top level CMakeLists.txt

Organized into sections

  • include config-site
  • options
  • install-related stuff
  • platform checks
  • generate visit-config.h
  • add subdirectories
  • cpack section

[edit] 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

[edit] 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)

[edit] 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.

[edit] 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

[edit] 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.

[edit] 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)

[edit] 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")
Personal tools