Merge release-4-5-patches into release-4-6
[alexxy/gromacs.git] / CMakeLists.txt
index 8fd987745f8af01c9a51ac40f57220922d917557..b4af587c314fe96b63f0be9fbc8c67d1cb9ee54b 100644 (file)
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.6)
+cmake_minimum_required(VERSION 2.8)
 # Keep CMake suitably quiet on Cygwin
 set(CMAKE_LEGACY_CYGWIN_WIN32 0) # Remove when CMake >= 2.8.4 is required
 
@@ -14,7 +14,7 @@ mark_as_advanced(DART_ROOT)
 # machine with no git. 
 #
 # NOTE: when releasing the "-dev" suffix needs to be stripped off!
-set(PROJECT_VERSION "4.5.5-dev")
+set(PROJECT_VERSION "4.6-dev")
 set(CUSTOM_VERSION_STRING ""
     CACHE STRING "Custom version string (if empty, use hard-coded default)")
 mark_as_advanced(CUSTOM_VERSION_STRING)
@@ -24,8 +24,8 @@ endif (CUSTOM_VERSION_STRING)
 set(SOVERSION 6)
 # It is a bit irritating, but this has to be set separately for now!
 SET(CPACK_PACKAGE_VERSION_MAJOR "4")
-SET(CPACK_PACKAGE_VERSION_MINOR "5")
-SET(CPACK_PACKAGE_VERSION_PATCH "5")
+SET(CPACK_PACKAGE_VERSION_MINOR "6")
+#SET(CPACK_PACKAGE_VERSION_PATCH "0")
 
 
 # Cmake modules/macros are in a subdirectory to keep this file cleaner
@@ -93,25 +93,12 @@ ENDIF()
 
 set(GMX_EXTRA_LIBRARIES)
 
-
-
-######################################################################
-# compiler tests
-# these need ot be done early (before further tests).
-#####################################################################
-
-include(CheckCCompilerFlag)
-include(CheckCXXCompilerFlag)
-
-include(gmxCFlags)
-gmx_c_flags()
-
 ########################################################################
 # User input options                                                   #
 ########################################################################
 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_THREADS    "Build a parallel (thread-based) version of GROMACS (cannot be combined with MPI yet)" ON)
+option(GMX_THREAD_MPI  "Build a thread-MPI-based multithreaded version of GROMACS (not compatible with MPI)" ON)
 option(GMX_SOFTWARE_INVSQRT "Use GROMACS software 1/sqrt" ON)
 mark_as_advanced(GMX_SOFTWARE_INVSQRT)
 option(GMX_POWERPC_INVSQRT "Use PowerPC hardware 1/sqrt" OFF)
@@ -123,7 +110,7 @@ set(GMX_ACCELERATION "auto"
     CACHE STRING "Accelerated kernels. Pick one of: auto, none, SSE, BlueGene, Power6, ia64, altivec, fortran")
 
 set(GMX_FFT_LIBRARY "fftw3" 
-    CACHE STRING "FFT library choices: fftw3,fftw2,mkl,fftpack[built-in]")
+    CACHE STRING "FFT library choices: fftw3,mkl,fftpack[built-in]")
 option(GMX_DISABLE_FFTW_MEASURE 
        "Do not optimize FFTW setups (not needed with SSE)" OFF)
 mark_as_advanced(GMX_DISABLE_FFTW_MEASURE)
@@ -134,8 +121,8 @@ mark_as_advanced(GMX_BROKEN_CALLOC)
 option(BUILD_SHARED_LIBS "Enable shared libraries (can be problematic with MPI, Windows)" ${SHARED_LIBS_DEFAULT})
 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_DLOPEN "Compile with dlopen, needed to read VMD supported file formats" ON)
-mark_as_advanced(GMX_DLOPEN)
+option(GMX_LOAD_PLUGINS "Compile with plugin support, needed to read VMD supported file formats" ON)
+mark_as_advanced(GMX_LOAD_PLUGINS)
 
 
 option(GMX_IA32_ASM "Add SSE assembly files for IA32" OFF)
@@ -143,6 +130,8 @@ mark_as_advanced(GMX_IA32_ASM)
 option(GMX_X86_64_ASM "Add SSE assembly files for X86_64" OFF)
 mark_as_advanced(GMX_X86_64_ASM)
 
+option(GMX_OPENMP "Enable OpenMP-based mutithreading. " ON)
+
 option(USE_VERSION_H "Generate development version string/information" ON)
 mark_as_advanced(USE_VERSION_H)
 
@@ -153,6 +142,24 @@ if(UNIX AND NOT APPLE)
     mark_as_advanced(GMX_PREFER_STATIC_LIBS)
 endif()
 
+
+######################################################################
+# compiler tests
+# these need ot be done early (before further tests).
+#####################################################################
+
+# cmake/Check{C,CXX}CompilerFlag.cmake are lifted from CMake git next
+# branch (proposed for v2.8.9) to be able to detect invalid options
+# with the Intel Compilers.
+# Remove these files from the source tree when a CMake version that
+# includes the features in question becomes required.
+include(CheckCCompilerFlag)
+include(CheckCXXCompilerFlag)
+
+include(gmxCFlags)
+gmx_c_flags()
+
+
 ########################################################################
 # Set up binary and library suffixing 
 ########################################################################
@@ -175,13 +182,18 @@ if (GMX_DEFAULT_SUFFIX)
     set (GMX_LIBS_SUFFIX "_gpu")
   endif(GMX_OPENMM)
   mark_as_advanced(FORCE GMX_BINARY_SUFFIX GMX_LIBS_SUFFIX)
-  message(STATUS "Using default binary suffix: \"${GMX_BINARY_SUFFIX}\"")    
-  message(STATUS "Using default library 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)
-  message(STATUS "Using manually set binary suffix: \"${GMX_BINARY_SUFFIX}\"")    
-  message(STATUS "Using manually set library 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}\"")
+  endif (NOT SUFFIX_QUIETLY)
 endif(GMX_DEFAULT_SUFFIX)
+set(SUFFIX_QUIETLY TRUE CACHE INTERNAL "")
 
 set(PKG_CFLAGS "")
 if(GMX_DOUBLE)
@@ -197,71 +209,12 @@ endif(GMX_POWERPC_INVSQRT)
 ########################################################################
 #Process MPI settings
 ########################################################################
-include(CheckCSourceCompiles) # for gmxTestMPI_IN_PLACE
-if(GMX_MPI)
-    if(GMX_THREADS)
-        #message(FATAL_ERROR "Thread-based parallelization conflicts with MPI.")
-        set(GMX_THREADS OFF CACHE BOOL 
-            "Thread-based parallelization conflicts with MPI." FORCE)
-    endif(GMX_THREADS)
-    find_package(MPI)
-    if(MPI_FOUND)
-        set(GROMACS_C_FLAGS ${GROMACS_FLAGS} ${MPI_COMPILE_FLAGS})
-       set(GROMACS_LINKER_FLAGS ${GROMACS_LINKER_FLAGS} ${MPI_LINK_FLAGS})
-        
-        include_directories(${MPI_INCLUDE_PATH})
-        list(APPEND GMX_EXTRA_LIBRARIES ${MPI_LIBRARIES})
-        if(GMX_FAHCORE)
-            add_definitions( -DMPI ) #for FAHCORE
-        endif(GMX_FAHCORE)
-        include(gmxTestMPI_IN_PLACE)
-        if (GMX_MPI_IN_PLACE)
-            gmx_test_mpi_in_place(MPI_IN_PLACE_EXISTS)
-        endif (GMX_MPI_IN_PLACE)
-
-       # test for unsuitable versions of OpenMPI
-       exec_program(${MPIEXEC}
-         ARGS --version
-         OUTPUT_VARIABLE MPI_TYPE
-         RETURN_VALUE MPI_EXEC_RETURN)
-       if(MPI_EXEC_RETURN EQUAL 0)
-         if(MPI_TYPE MATCHES "Open MPI|OpenRTE")
-           string(REGEX MATCH "[0-9]+\\.[0-9]*\\.?[0-9]*" MPI_VERSION ${MPI_TYPE})
-           if(MPI_VERSION VERSION_LESS "1.4.1")
-             MESSAGE(WARNING "
-            There are known problems with OpenMPI version < 1.4.1.
-            Please consider updating your OpenMPI.")
-           endif(MPI_VERSION VERSION_LESS "1.4.1")
-           unset(MPI_VERSION)
-         else(MPI_TYPE MATCHES "Open MPI|OpenRTE")
-           # This is not OpenMPI, so give the old generic warning message
-           MESSAGE(WARNING "
-            There are known problems with some MPI implementations:
-                     MVAPICH2 version <= 1.4.1
-            Please consider updating your MPI if applicable.")
-         endif(MPI_TYPE MATCHES "Open MPI|OpenRTE")
-         unset(MPI_TYPE)
-       endif(MPI_EXEC_RETURN EQUAL 0)
-    else(MPI_FOUND)
-        message(FATAL_ERROR "MPI support requested, but no MPI compiler found.")
-    endif(MPI_FOUND)
-    include(gmxTestCatamount)
-    gmx_test_catamount(GMX_CRAY_XT3)
-    if(GMX_CRAY_XT3)
-        set(PKG_CFLAGS "${PKG_CFLAGS} -DGMX_CRAY_XT3")
-        set(GMX_NO_SYSTEM 1)
-        set(GMX_NO_NICE 1)
-    endif(GMX_CRAY_XT3)
-    set(GMX_LIB_MPI 1)
-    set(PKG_CFLAGS "${PKG_CFLAGS} -DGMX_LIB_MPI")
-endif(GMX_MPI)
-
+include(gmxManageMPI)
 
 #######################################################################
 # Check for options incompatible with OpenMM build                    #
 #######################################################################
 if(GMX_OPENMM)
-    cmake_minimum_required(VERSION 2.6.4)
     # we'll use the built-in fft to avoid unnecessary dependencies
     string(TOUPPER ${GMX_FFT_LIBRARY} GMX_FFT_LIBRARY)
     if(NOT ${GMX_FFT_LIBRARY} STREQUAL "FFTPACK")
@@ -272,11 +225,16 @@ if(GMX_OPENMM)
     if(GMX_MPI)
         message(FATAL_ERROR "The OpenMM build is not compatible with MPI!")
     endif(GMX_MPI)
-    if(GMX_THREADS)
-        message(STATUS "Threads are  not compatible with OpenMM build, disabled!")
-        set(GMX_THREADS OFF CACHE BOOL 
-               "Threads are not compatible with OpenMM build, disabled!" FORCE)
-    endif(GMX_THREADS)
+    if(GMX_THREAD_MPI)
+        message(STATUS "Thread-MPI not compatible with OpenMM, disabled!")
+        set(GMX_THREAD_MPI OFF CACHE BOOL
+               "Thread-MPI not compatible with OpenMM build, disabled!" FORCE)
+    endif(GMX_THREAD_MPI)
+    if(GMX_OPENMP)
+        message(STATUS "OpenMP multithreading not compatible with OpenMM, disabled")
+        set(GMX_OPENMP OFF CACHE BOOL
+            "OpenMP multithreading not compatible with OpenMM, disabled!" FORCE)
+    endif()
     if(GMX_SOFTWARE_INVSQRT)
         set(GMX_SOFTWARE_INVSQRT OFF CACHE STRING 
                 "The OpenMM build does not need GROMACS software 1/sqrt!" FORCE)
@@ -295,10 +253,10 @@ if(GMX_OPENMM)
     endif()
     # mark as advanced the unused variables
     mark_as_advanced(FORCE GMX_ACCELERATION GMX_MPI GMX_FFT_LIBRARY 
-        GMX_QMMM_PROGRAM GMX_THREADS GMX_DOUBLE)
+        GMX_QMMM_PROGRAM GMX_THREAD_MPI GMX_DOUBLE)
 else(GMX_OPENMM)
      mark_as_advanced(CLEAR GMX_ACCELERATION GMX_MPI GMX_FFT_LIBRARY 
-        GMX_QMMM_PROGRAM GMX_THREADS GMX_DOUBLE)   
+        GMX_QMMM_PROGRAM GMX_THREAD_MPI GMX_DOUBLE)
 endif(GMX_OPENMM)
 
 
@@ -348,6 +306,7 @@ check_function_exists(_fileno           HAVE__FILENO)
 check_function_exists(fileno            HAVE_FILENO)
 check_function_exists(_commit           HAVE__COMMIT)
 check_function_exists(lstat             HAVE_LSTAT)
+check_function_exists(sigaction         HAVE_SIGACTION)
 
 include(CheckLibraryExists)
 check_library_exists(m sqrt "" HAVE_LIBM)
@@ -449,16 +408,13 @@ if (GMX_X11)
        endif(X11_FOUND)
 endif(GMX_X11)
 
-if(GMX_THREADS)
-    set(PKG_CFLAGS "${PKG_CFLAGS} -DGMX_THREADS")
+if(GMX_THREAD_MPI)
+    set(PKG_CFLAGS "${PKG_CFLAGS} -DGMX_THREAD_MPI")
     include(ThreadMPI)
     set(THREAD_MPI_LIB thread_mpi)
     set(GMX_MPI 1)
     string(TOUPPER ${GMX_FFT_LIBRARY} ${GMX_FFT_LIBRARY})
-    if(${GMX_FFT_LIBRARY} STREQUAL "FFTW2")
-        message(FATAL_ERROR "FFTW2 can't be used with threads. Try fftw3 or mkl.")
-    endif()
-endif(GMX_THREADS)
+endif(GMX_THREAD_MPI)
 
 if(GMX_OPENMM)
     set(CUDA_BUILD_EMULATION OFF)
@@ -470,6 +426,13 @@ if(GMX_OPENMM)
     find_package(OpenMM) 
 endif(GMX_OPENMM)
 
+if(GMX_OPENMP)
+    find_package(OpenMP REQUIRED)
+    set(GROMACS_C_FLAGS "${OpenMP_C_FLAGS} ${GROMACS_C_FLAGS}")
+    set(GROMACS_CXX_FLAGS "${OpenMP_CXX_FLAGS} ${GROMACS_CXX_FLAGS}")
+    add_definitions(-DGMX_OPENMP)
+endif()
+
 if(APPLE)
    find_library(ACCELERATE_FRAMEWORK Accelerate)
    list(APPEND GMX_EXTRA_LIBRARIES ${ACCELERATE_FRAMEWORK})
@@ -479,29 +442,36 @@ if(CYGWIN)
     set(GMX_CYGWIN 1)
 endif(CYGWIN)
 
+if(WIN32 AND NOT CYGWIN)
+    set(GMX_NATIVE_WINDOWS 1)
+endif()
+
 # only bother with finding git and using version.h if the source is a git repo
 if(EXISTS "${CMAKE_SOURCE_DIR}/.git")
     if(USE_VERSION_H)
         # We need at least git v1.5.1 be able to parse git's date output. If not 
-        # fund or the version is too small, we can't generate version information.
-        find_package(Git 1.5.1)
-        # this should at some point become VERSION_LESS
-        if(NOT Git_FOUND OR Git_VERSION STRLESS "1.5.1")
-            message("No compatible git version found, won't be able to generate proper development version information.")
-            set(USE_VERSION_H OFF)
+        # found or the version is too small, we can't generate version information.
+        find_package(Git)
+
+       # Find out the git version
+       if(GIT_FOUND AND NOT GIT_VERSION)
+         execute_process(COMMAND ${GIT_EXECUTABLE} "--version"
+            OUTPUT_VARIABLE _exec_out
+            OUTPUT_STRIP_TRAILING_WHITESPACE)
+         string(REGEX REPLACE "git version (.*)" "\\1" GIT_VERSION ${_exec_out})
+         set(GIT_VERSION ${GIT_VERSION} CACHE STRING "Git version")
+         mark_as_advanced(GIT_VERSION)
+       endif()
+
+        if(NOT GIT_FOUND OR GIT_VERSION VERSION_LESS "1.5.1")
+          message("No compatible git version found, won't be able to generate proper development version information.")
+          set(USE_VERSION_H OFF)
         endif()
     endif()
 else()
     set(USE_VERSION_H OFF)
 endif()
 
-if (GMX_DLOPEN)
-    list(APPEND GMX_EXTRA_LIBRARIES ${CMAKE_DL_LIBS})
-    set(PKG_DL_LIBS "-l${CMAKE_DL_LIBS}")
-else(GMX_DLOPEN)
-    set(PKG_DL_LIBS)
-endif (GMX_DLOPEN)
-
 ########################################################################
 # Generate development version info for cache
 ########################################################################
@@ -514,6 +484,7 @@ endif (GMX_DLOPEN)
 
 add_definitions( -DHAVE_CONFIG_H )
 include_directories(${CMAKE_BINARY_DIR}/src)
+include_directories(${CMAKE_BINARY_DIR}/include)
 include_directories(${CMAKE_SOURCE_DIR}/include)
 
 include(gmxCheckBuildUserTime)
@@ -529,7 +500,6 @@ gmx_test_large_files(GMX_LARGEFILES)
 check_function_exists(fseeko     HAVE_FSEEKO)
 
 include(gmxTestSignal)
-gmx_test_retsigtype(RETSIGTYPE)
 gmx_test_sigusr1(HAVE_SIGUSR1)
 
 include(gmxTestInline)
@@ -637,7 +607,7 @@ elseif(${GMX_ACCELERATION} STREQUAL "BLUEGENE")
     set(GMX_SOFTWARE_INVSQRT OFF CACHE BOOL "Do not use software reciprocal square root on BlueGene" FORCE)
     set(GMX_POWERPC_INVSQRT ON CACHE BOOL "Use hardware reciprocal square root on BlueGene" FORCE)
     set(GMX_X11 OFF CACHE BOOL "X11 not compatible with BlueGene, disabled!" FORCE)
-    set(GMX_THREADS OFF CACHE BOOL "Threads not compatible with BlueGene, disabled!" FORCE)
+    set(GMX_THREAD_MPI OFF CACHE BOOL "Thread-MPI not compatible with BlueGene, disabled!" FORCE)
     set(GMX_MPI ON CACHE BOOL "Use MPI on BlueGene" FORCE)
 elseif(${GMX_ACCELERATION} STREQUAL "POWER6")
     set(GMX_POWER6 1)
@@ -657,9 +627,9 @@ else(${GMX_ACCELERATION} STREQUAL "NONE")
 endif(${GMX_ACCELERATION} STREQUAL "NONE")
 
 if(GMX_FORTRAN OR GMX_POWER6)
-    if (GMX_THREADS)
-        message(FATAL_ERROR "FORTRAN/POWER6 is incompatible with threads and only provides a speed-up on certain IBM compilers. Disable FORTRAN (or threads if you really want to use FORTRAN kernels).")
-    endif(GMX_THREADS)
+    if (GMX_THREAD_MPI)
+        message(FATAL_ERROR "FORTRAN/POWER6 is incompatible with thread-MPI and only provides a speed-up on certain IBM compilers. Disable FORTRAN (or threads if you really want to use FORTRAN kernels).")
+    endif(GMX_THREAD_MPI)
     enable_language(Fortran)
     include(FortranCInterface)
     discover_fortran_mangling(prefix isupper suffix extra_under_score found)
@@ -714,49 +684,24 @@ string(TOUPPER ${GMX_FFT_LIBRARY} ${GMX_FFT_LIBRARY})
 set(PKG_FFT "")
 set(PKG_FFT_LIBS "")
 if(${GMX_FFT_LIBRARY} STREQUAL "FFTW3")
-#    MESSAGE(STATUS "Using external FFT library - fftw3")
     if(GMX_DOUBLE)
-        find_package(FFTW3 REQUIRED)
-               include_directories(${FFTW3_INCLUDE_DIR})
-        set(FFT_LIBRARIES ${FFTW3_LIBRARIES})
-        set(PKG_FFT "fftw3")
+        find_package(FFTW 3 COMPONENTS fftw)
     else(GMX_DOUBLE)
-        find_package(FFTW3F REQUIRED)
-        include_directories(${FFTW3F_INCLUDE_DIR})
-        set(FFT_LIBRARIES ${FFTW3F_LIBRARIES})
-        set(PKG_FFT "fftw3f")
+        find_package(FFTW 3 COMPONENTS fftwf)
     endif(GMX_DOUBLE)
-
-    if(NOT FFTW3_FOUND AND NOT FFTW3F_FOUND)
-        MESSAGE(FATAL_ERROR "Cannot find fftw3 (with correct precision). Fix it, choose another FFT library, or use the Gromacs built-in fftpack (slower)!")
-    endif(NOT FFTW3_FOUND AND NOT FFTW3F_FOUND)
+    if(NOT FFTW_FOUND)
+      MESSAGE(FATAL_ERROR "Cannot find FFTW3 (with correct precision - libfftw3f for single precision GROMACS or libfftw3 for double precision GROMACS). Fix it, choose another FFT library, or use the Gromacs built-in fftpack (slower)!")
+    endif(NOT FFTW_FOUND)
+    include_directories(${FFTW_INCLUDE_DIRS})
+    set(FFT_LIBRARIES ${FFTW_LIBRARIES})
+    set(PKG_FFT "${FFTW_PKG}")
 
     set(GMX_FFT_FFTW3 1)
 
-elseif(${GMX_FFT_LIBRARY} STREQUAL "FFTW2")
-#    MESSAGE(STATUS "Using external FFT library - fftw2")
-    if(GMX_DOUBLE)
-        find_package(FFTW2 REQUIRED)
-    else(GMX_DOUBLE)
-        find_package(FFTW2F REQUIRED)
-    endif(GMX_DOUBLE)
+    if (${GMX_ACCELERATION} STREQUAL "SSE" AND NOT FFTW_HAVE_SSE)
+      message(WARNING "The fftw library found is compiled without SSE support, which makes it slow. Consider recompiling it or contact your admin")
+    endif (${GMX_ACCELERATION} STREQUAL "SSE" AND NOT FFTW_HAVE_SSE)
 
-    if(NOT FFTW2_FOUND)
-          MESSAGE(FATAL_ERROR "Cannot find fftw2 (with correct precision). Fix it, choose another FFT library, or use the Gromacs built-in fftpack (slower)!")
-    endif(NOT FFTW2_FOUND)
-    include_directories(${FFTW2_INCLUDE_DIR})
-    set(FFT_LIBRARIES ${FFTW2_LIBRARIES})
-    set(PKG_FFT_LIBS ${FFTW2_LIBRARIES})
-
-    if("${FFTW2_LIBRARIES}" MATCHES "dfftw")
-        set(FFTW2_NAME_DFFTW 1)
-    elseif("${FFTW2_LIBRARIES}" MATCHES "sfftw")
-        set(FFTW2_NAME_SFFTW 1)
-    else("${FFTW2_LIBRARIES}" MATCHES "dfftw")
-        set(FFTW2_NAME_FFTW 1) 
-    endif("${FFTW2_LIBRARIES}" MATCHES "dfftw")
-
-    set(GMX_FFT_FFTW2 1)
 elseif(${GMX_FFT_LIBRARY} STREQUAL "MKL")
 #    MESSAGE(STATUS "Using external FFT library - Intel MKL")
     find_package(MKL REQUIRED)
@@ -774,7 +719,7 @@ elseif(${GMX_FFT_LIBRARY} STREQUAL "FFTPACK")
     MESSAGE(STATUS "Using internal FFT library - fftpack")
     set(GMX_FFT_FFTPACK 1)
 else(${GMX_FFT_LIBRARY} STREQUAL "FFTW3")
-    MESSAGE(FATAL_ERROR "Invalid FFT library setting: ${GMX_FFT_LIBRARY}. Choose one of: fftw3, fftw2, mkl, acml, fftpack")
+    MESSAGE(FATAL_ERROR "Invalid FFT library setting: ${GMX_FFT_LIBRARY}. Choose one of: fftw3, mkl, fftpack")
 endif(${GMX_FFT_LIBRARY} STREQUAL "FFTW3")
 
 # MKL has BLAS/LAPACK routines
@@ -808,6 +753,70 @@ endif(HAVE_MKL OR ACCELERATE_FRAMEWORK)
 mark_as_advanced(GMX_EXTERNAL_LAPACK)
 mark_as_advanced(GMX_EXTERNAL_BLAS)
 
+set(GMX_USE_PLUGINS OFF CACHE INTERNAL "Whether GROMACS will really try to compile support for VMD plugins")
+set(GMX_VMD_PLUGIN_PATH)
+mark_as_advanced(GMX_VMD_PLUGIN_PATH)
+
+if(GMX_LOAD_PLUGINS)
+  if(CYGWIN OR NOT WIN32)
+    # Native Windows does not have, nor need dlopen
+    # Note that WIN32 is set with Cygwin, but Cygwin needs dlopen to use plug-ins
+    include(gmxTestdlopen)
+    gmx_test_dlopen(HAVE_DLOPEN)
+  endif()
+
+  find_package(VMD)
+
+  # Test for unsuitable versions of VMD
+
+  if(VMD_FOUND AND NOT GMX_VMD_PLUGIN_PATH)
+    message(STATUS "Checking for suitable VMD version")
+    exec_program(${VMD_EXECUTABLE}
+      ARGS --help
+      OUTPUT_VARIABLE VMD_HELP
+      RETURN_VALUE VMD_EXEC_RETURN)
+
+    if(VMD_EXEC_RETURN EQUAL 0)
+      # This is the accepted idiom for subexpression matching, unfortunately
+      string(REGEX REPLACE ".*VMD for .*, version ([0-9]+\\.[0-9]*\\.?[0-9]*).*" "\\1" VMD_VERSION ${VMD_HELP})
+      string(REGEX REPLACE ".*VMD for (.*), version .*" "\\1" VMD_ARCH ${VMD_HELP})
+
+      if(VMD_VERSION VERSION_LESS "1.8")
+        MESSAGE(WARNING "Found VMD version ${VMD_VERSION}, but GROMACS needs at least 1.8")
+        unset(VMD_EXECUTABLE)
+        set(VMD_FOUND FALSE)
+      else()
+        message(STATUS "VMD version ${VMD_VERSION} is suitable")
+        if(DEFINED ENV{VMDDIR})
+          # This permits GROMACS to avoid hard-coding a fall-back
+          # path that it can tell right now would be useless.
+          set(GMX_VMD_PLUGIN_PATH "$ENV{VMDDIR}/plugins/${VMD_ARCH}/molfile" CACHE PATH "Path to VMD plugins for molfile I/O")
+        else()
+          set(GMX_VMD_PLUGIN_PATH "/usr/local/lib/vmd/plugins/*/molfile" CACHE PATH "Path to VMD plugins for molfile I/O")
+        endif()
+      endif()
+
+      # clean up
+      unset(VMD_HELP)
+      unset(VMD_VERSION)
+      unset(VMD_ARCH)
+    endif()
+  endif()
+
+  # so, should we use plug-ins?
+  if((WIN32 AND NOT CYGWIN) OR (HAVE_DLOPEN AND BUILD_SHARED_LIBS))
+    if (NOT VMD_QUIETLY)
+      MESSAGE(STATUS "Found the ability to use plug-ins when building shared libaries, so will compile to use plug-ins (e.g. to read VMD-supported file formats).")
+    endif(NOT VMD_QUIETLY)
+    set(GMX_USE_PLUGINS ON)
+    list(APPEND GMX_EXTRA_LIBRARIES ${CMAKE_DL_LIBS}) # magic cross-platform pre-set variable for dlopen library
+    set(PKG_DL_LIBS "-l${CMAKE_DL_LIBS}")
+  else()
+    set(PKG_DL_LIBS)
+  endif()
+endif(GMX_LOAD_PLUGINS)
+set(VMD_QUIETLY TRUE CACHE INTERNAL "")
+
 # Math and thread libraries must often come after all others when linking...
 if(HAVE_LIBM)
     list(APPEND        GMX_EXTRA_LIBRARIES m)