CMake helper for dependent cache variables.
authorTeemu Murtola <teemu.murtola@gmail.com>
Fri, 24 May 2013 15:16:41 +0000 (18:16 +0300)
committerGerrit Code Review <gerrit@gerrit.gromacs.org>
Thu, 26 Sep 2013 00:23:49 +0000 (02:23 +0200)
Added somewhat extended version of cmake_dependent_option() and used
that for declaring cache variables that are only used if some condition
is satisfied.  Again, not a big change in functionality, but makes
things work more uniformly, and makes it easier to add such options and
not need to think how to implement all the details.

Some dependent options remain that are not yet using the new macros.

Change-Id: I72f4bd19d24c06475bc7f55b6bd561381e5776aa

CMakeLists.txt
cmake/gmxOptionUtilities.cmake

index b4867a97ca6763874aa04c5ec1fc6bfe41eb8193..81b3f45d26f2b1c0e1ab0cd81ee7bad742d6d210 100644 (file)
@@ -114,19 +114,26 @@ endif()
 ########################################################################
 include(gmxOptionUtilities)
 
-option(GMX_COOL_QUOTES "Enable Gromacs cool quotes" ON)
-mark_as_advanced(GMX_COOL_QUOTES)
-
 set(CMAKE_PREFIX_PATH "" CACHE STRING "Extra locations to search for external libraries and tools (give directory without lib, bin, or include)")
 
 option(GMX_DOUBLE "Use double precision (much slower, use only if you really need it)" OFF)
 option(GMX_MPI    "Build a parallel (message-passing) version of GROMACS" OFF)
 option(GMX_THREAD_MPI  "Build a thread-MPI-based multithreaded version of GROMACS (not compatible with MPI)" ON)
+gmx_dependent_option(
+    GMX_MPI_IN_PLACE
+    "Enable MPI_IN_PLACE for MPIs that have it defined"
+    ON
+    GMX_MPI)
+mark_as_advanced(GMX_MPI_IN_PLACE)
 option(GMX_SOFTWARE_INVSQRT "Use GROMACS software 1/sqrt" ON)
 mark_as_advanced(GMX_SOFTWARE_INVSQRT)
 option(GMX_FAHCORE "Build a library with mdrun functionality" OFF)
 mark_as_advanced(GMX_FAHCORE)
 
+option(GMX_COOL_QUOTES "Enable Gromacs cool quotes" ON)
+mark_as_advanced(GMX_COOL_QUOTES)
+gmx_add_cache_dependency(GMX_COOL_QUOTES BOOL "NOT GMX_FAHCORE" OFF)
+
 # decide on GPU settings based on user-settings and GPU/CUDA detection
 include(gmxManageGPU)
 
@@ -155,11 +162,17 @@ gmx_option_multichoice(
     "FFT library"
     "fftw3"
     fftw3 mkl "fftpack[built-in]")
-
-option(GMX_BUILD_OWN_FFTW "Download and build FFTW 3 during the GROMACS build process, rather than fall back on the really slow fftpack." OFF)
+gmx_dependent_option(
+    GMX_BUILD_OWN_FFTW
+    "Download and build FFTW 3 during the GROMACS build process, rather than fall back on the really slow fftpack."
+    OFF
+    "GMX_FFT_LIBRARY STREQUAL FFTW3")
+gmx_dependent_option(
+    GMX_DISABLE_FFTW_MEASURE
+    "Do not optimize FFTW setups (not needed with SSE)"
+    OFF
+    "GMX_FFT_LIBRARY STREQUAL FFTW3")
 mark_as_advanced(GMX_BUILD_OWN_FFTW)
-option(GMX_DISABLE_FFTW_MEASURE 
-       "Do not optimize FFTW setups (not needed with SSE)" OFF)
 mark_as_advanced(GMX_DISABLE_FFTW_MEASURE)
 
 gmx_option_multichoice(
@@ -170,8 +183,6 @@ gmx_option_multichoice(
 
 option(GMX_BROKEN_CALLOC "Work around broken calloc()" OFF)
 mark_as_advanced(GMX_BROKEN_CALLOC)
-option(GMX_MPI_IN_PLACE "Enable MPI_IN_PLACE for MPIs that have it defined" ON)
-mark_as_advanced(GMX_MPI_IN_PLACE)
 option(GMX_LOAD_PLUGINS "Compile with plugin support, needed to read VMD supported file formats" ON)
 mark_as_advanced(GMX_LOAD_PLUGINS)
 
@@ -181,7 +192,6 @@ option(GMX_OPENMP "Enable OpenMP-based multithreading" ON)
 option(GMX_GIT_VERSION_INFO "Generate git version information" ${SOURCE_IS_GIT_REPOSITORY})
 mark_as_advanced(GMX_GIT_VERSION_INFO)
 
-option(GMX_DEFAULT_SUFFIX "Use default suffixes for GROMACS binaries and libs (_d for double, _mpi for MPI; rerun cmake after changing to see relevant options)" ON)
 if(UNIX)
     option(GMX_SYMLINK_OLD_BINARY_NAMES "Create symbolic links for pre-5.0 binary names" ON)
 endif()
@@ -574,6 +584,7 @@ endif()
 
 option(GMX_BUILD_UNITTESTS "Build unit tests with BUILD_TESTING (uses Google C++ Testing and Mocking Frameworks, requires libxml2)" ${LIBXML2_FOUND})
 mark_as_advanced(GMX_BUILD_UNITTESTS)
+gmx_add_cache_dependency(GMX_BUILD_UNITTESTS BOOL BUILD_TESTING OFF)
 if (GMX_BUILD_UNITTESTS AND NOT LIBXML2_FOUND)
     message(FATAL_ERROR
         "Cannot build unit tests without libxml2. "
@@ -892,11 +903,29 @@ endif()
 # Process FFT library settings
 set(PKG_FFT "")
 set(PKG_FFT_LIBS "")
+# Intel 11 and up makes life somewhat easy if you just want to use
+# all their stuff. It's not easy if you only want some of their
+# stuff...
+set(MKL_MANUALLY FALSE)
+if (GMX_FFT_LIBRARY STREQUAL "MKL" AND
+    NOT (CMAKE_C_COMPILER_ID MATCHES "Intel" AND C_COMPILER_VERSION VERSION_GREATER "11"))
+    # The user will have to provide the set of magic libraries in
+    # MKL_LIBRARIES (see below), which we cache (non-advanced), so that they
+    # don't have to keep specifying it, and can easily see that
+    # CMake is still using that information.
+    set(MKL_MANUALLY TRUE)
+endif()
 set(MKL_LIBRARIES_FORMAT_DESCRIPTION "Use full paths to library files, in the right order, and separated by semicolons.")
-set(MKL_LIBRARIES "" CACHE STRING "List of libraries for linking to MKL. Only used with GMX_FFT_LIBRARY=mkl. ${MKL_LIBRARIES_FORMAT_DESCRIPTION}")
-set(MKL_INCLUDE_DIR "" CACHE PATH "Path to mkl.h (non-inclusive). Only used with GMX_FFT_LIBRARY=mkl.")
-mark_as_advanced(FORCE MKL_LIBRARIES)
-mark_as_advanced(FORCE MKL_INCLUDE_DIR)
+gmx_dependent_cache_variable(
+    MKL_LIBRARIES
+    "List of libraries for linking to MKL. ${MKL_LIBRARIES_FORMAT_DESCRIPTION}"
+    STRING ""
+    MKL_MANUALLY)
+gmx_dependent_cache_variable(
+    MKL_INCLUDE_DIR
+    "Path to mkl.h (non-inclusive)."
+    PATH ""
+    MKL_MANUALLY)
 if(${GMX_FFT_LIBRARY} STREQUAL "FFTW3")
     if(GMX_DOUBLE)
         set(FFTW fftw)
@@ -936,7 +965,7 @@ elseif(${GMX_FFT_LIBRARY} STREQUAL "MKL")
     # Intel 11 and up makes life somewhat easy if you just want to use
     # all their stuff. It's not easy if you only want some of their
     # stuff...
-    if (CMAKE_C_COMPILER_ID MATCHES "Intel" AND C_COMPILER_VERSION VERSION_GREATER "11")
+    if (NOT MKL_MANUALLY)
         # The next line takes care of everything for MKL
         if (WIN32)
             set(FFT_LINKER_FLAGS "/Qmkl=sequential")
@@ -949,14 +978,7 @@ elseif(${GMX_FFT_LIBRARY} STREQUAL "MKL")
 
         set(MKL_ERROR_MESSAGE "Make sure you have configured your compiler so that ${FFT_LINKER_FLAGS} will work.")
     else()
-        # The user will have to provide the set of magic libraries in
-        # MKL_LIBRARIES, which we cache (non-advanced), so that they
-        # don't have to keep specifying it, and can easily see that
-        # CMake is still using that information.
-        set(MKL_LIBRARIES "${MKL_LIBRARIES}" CACHE STRING "User-specified libraries for linking to MKL")
-        mark_as_advanced(CLEAR MKL_LIBRARIES)
         include_directories(${MKL_INCLUDE_DIR})
-        mark_as_advanced(CLEAR MKL_INCLUDE_DIR)
         set(FFT_LIBRARIES "${MKL_LIBRARIES}")
         set(MKL_ERROR_MESSAGE "The include path to mkl.h in MKL_INCLUDE_DIR, and the link libraries in MKL_LIBRARIES=${MKL_LIBRARIES} need to match what the MKL documentation says you need for your system. ${MKL_LIBRARIES_FORMAT_DESCRIPTION}")
         # Convert the semi-colon separated list to a list of
@@ -1063,7 +1085,6 @@ if(GMX_FAHCORE)
   set(COREWRAP_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/../corewrap" CACHE STRING
       "Path to swindirect.h")
   include_directories(${COREWRAP_INCLUDE_DIR})
-  set_property(CACHE GMX_COOL_QUOTES PROPERTY VALUE OFF)
 endif(GMX_FAHCORE)
 
 # # # # # # # # # # NO MORE TESTS AFTER THIS LINE! # # # # # # # # # # #
@@ -1122,9 +1143,20 @@ set(GMXLIBDIR        ${DATA_INSTALL_DIR}/top)
 ########################################################################
 # Set up binary and library suffixing
 ########################################################################
-set(GMX_BINARY_SUFFIX "" CACHE STRING "Suffix for GROMACS binaries (default: _d for double, _mpi for MPI, _mpi_d for MPI and double).")
-set(GMX_LIBS_SUFFIX ""
-  CACHE STRING "Suffix for GROMACS libs (default: _d for double, _mpi for MPI, _mpi_d for MPI and double).")
+option(
+    GMX_DEFAULT_SUFFIX
+    "Use default suffixes for GROMACS binaries and libs (_d for double, _mpi for MPI; rerun cmake after changing to see relevant options)"
+    ON)
+gmx_dependent_cache_variable(
+    GMX_BINARY_SUFFIX
+    "Suffix for GROMACS binaries (default: _d for double, _mpi for MPI, _mpi_d for MPI and double)."
+    STRING ""
+    "NOT GMX_DEFAULT_SUFFIX")
+gmx_dependent_cache_variable(
+    GMX_LIBS_SUFFIX
+    "Suffix for GROMACS libraries (default: _d for double, _mpi for MPI, _mpi_d for MPI and double)."
+    STRING ""
+    "NOT GMX_DEFAULT_SUFFIX")
 if (GMX_DEFAULT_SUFFIX)
   set(GMX_BINARY_SUFFIX "")
   set(GMX_LIBS_SUFFIX "")
@@ -1136,13 +1168,11 @@ if (GMX_DEFAULT_SUFFIX)
     set (GMX_BINARY_SUFFIX "${GMX_BINARY_SUFFIX}_d")
     set (GMX_LIBS_SUFFIX "${GMX_LIBS_SUFFIX}_d")
   endif(GMX_DOUBLE)
-  mark_as_advanced(FORCE GMX_BINARY_SUFFIX GMX_LIBS_SUFFIX)
   if (NOT SUFFIX_QUIETLY)
     message(STATUS "Using default binary suffix: \"${GMX_BINARY_SUFFIX}\"")
     message(STATUS "Using default library suffix: \"${GMX_LIBS_SUFFIX}\"")
   endif (NOT SUFFIX_QUIETLY)
 else(GMX_DEFAULT_SUFFIX)
-  mark_as_advanced(CLEAR GMX_BINARY_SUFFIX GMX_LIBS_SUFFIX)
   if (NOT SUFFIX_QUIETLY)
     message(STATUS "Using manually set binary suffix: \"${GMX_BINARY_SUFFIX}\"")
     message(STATUS "Using manually set library suffix: \"${GMX_LIBS_SUFFIX}\"")
index 1545f565a50fce6be7c396ab90a4996a965a2094..9387de5273840fda99c959c80733f12e1609e02c 100644 (file)
@@ -88,3 +88,70 @@ endfunction()
 function(GMX_INVALID_OPTION_VALUE NAME)
     message(FATAL_ERROR "Invalid value for ${NAME}: ${${NAME}}")
 endfunction()
+
+# Hides or shows a cache value based on conditions
+#
+# Usage:
+#   gmx_add_cache_dependency(VAR TYPE CONDITIONS VALUE)
+# where
+#   VAR        is a name of a cached variable
+#   TYPE       is the type of VAR
+#   CONDITIONS is a list of conditional expressions (see below)
+#   VALUE      is a value that is set to VAR if CONDITIONS is not satisfied
+#
+# Evaluates each condition in CONDITIONS, and if any of them is false,
+# VAR is marked internal (hiding it from the user) and its value is set to
+# VALUE.  The previous user-set value of VAR is still remembered in the cache,
+# and used when CONDITIONS become true again.
+#
+# The conditions is a semicolon-separated list of conditions as specified for
+# CMake if() statements, such as "GMX_FFT_LIBRARY STREQUAL FFTW3",
+# "NOT GMX_MPI" or "GMX_MPI;NOT GMX_DOUBLE".  Note that quotes within the
+# expressions don't work for some reason (even if escaped).
+#
+# The logic is adapted from cmake_dependent_option().
+#
+function(GMX_ADD_CACHE_DEPENDENCY NAME TYPE CONDITIONS FORCED_VALUE)
+    set(_available TRUE)
+    foreach(_cond ${CONDITIONS})
+        string(REGEX REPLACE " +" ";" _cond_as_list ${_cond})
+        if (${_cond_as_list})
+        else()
+            set(_available FALSE)
+        endif()
+    endforeach()
+    if (_available)
+        set_property(CACHE ${NAME} PROPERTY TYPE ${TYPE})
+    else()
+        set(${NAME} "${FORCED_VALUE}" PARENT_SCOPE)
+        set_property(CACHE ${NAME} PROPERTY TYPE INTERNAL)
+    endif()
+endfunction()
+
+# Works like cmake_dependent_option(), but allows for an arbitrary cache value
+# instead of only an ON/OFF option
+#
+# Usage:
+#   gmx_dependent_cache_variable(VAR "Description" TYPE DEFAULT CONDITIONS)
+#
+# Creates a cache variable VAR with the given description, type and default
+# value.  If any of the conditions listed in CONDITIONS is not true, then
+# the cache variable is marked internal (hiding it from the user) and the
+# value of VAR is set to DEFAULT.  The previous user-set value of VAR is still
+# remembered in the cache, and used when CONDITIONS become true again.
+# Any further changes to the variable can be done with simple set()
+# (or set_property(CACHE VAR PROPERTY VALUE ...) if the cache needs to be
+# modified).
+#
+# See gmx_add_cache_dependency() on how to specify the conditions.
+#
+macro(GMX_DEPENDENT_CACHE_VARIABLE NAME DESCRIPTION TYPE DEFAULT CONDITIONS)
+    set(${NAME} "${DEFAULT}" CACHE ${TYPE} "${DESCRIPTION}")
+    gmx_add_cache_dependency(${NAME} ${TYPE} "${CONDITIONS}" "${DEFAULT}")
+endmacro()
+
+# Works like cmake_dependent_option(), but reuses the code from
+# gmx_dependent_cache_variable() to make sure both behave the same way.
+macro(GMX_DEPENDENT_OPTION NAME DESCRIPTION DEFAULT CONDITIONS)
+    gmx_dependent_cache_variable(${NAME} "${DESCRIPTION}" BOOL "${DEFAULT}" "${CONDITIONS}")
+endmacro()