Merge branch 'release-2016'
[alexxy/gromacs.git] / CMakeLists.txt
index 52634bf9b89732faafceaaf2399679e3e035bea7..3aa958f4b1eb8bf2fb8918f8d58b9c05e7d059d9 100644 (file)
 # To help us fund GROMACS development, we humbly ask that you cite
 # the research papers on the package. Check out http://www.gromacs.org.
 
-cmake_minimum_required(VERSION 2.8.8)
-# When we require cmake >= 2.8.12, it will provide
-# CMAKE_MINIMUM_REQUIRED_VERSION automatically, but in the meantime we
-# need to set a variable, and it must have a different name.
-set(GMX_CMAKE_MINIMUM_REQUIRED_VERSION "2.8.8")
+cmake_minimum_required(VERSION 3.4.3)
 
 # CMake modules/macros are in a subdirectory to keep this file cleaner
 # This needs to be set before project() in order to pick up toolchain files
@@ -70,11 +66,10 @@ include(gmxBuildTypeMSAN)
 include(gmxBuildTypeReleaseWithAssert)
 
 if(NOT CMAKE_BUILD_TYPE)
-    set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel Reference RelWithAssert Profile." FORCE)
-    # There's no need to offer a user the choice of ThreadSanitizer
+    set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel Reference RelWithAssert Profile TSAN ASAN MSAN." FORCE)
     # Set the possible values of build type for cmake-gui
     set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
-        "MinSizeRel" "RelWithDebInfo" "Reference" "RelWithAssert" "Profile")
+        "MinSizeRel" "RelWithDebInfo" "Reference" "RelWithAssert" "Profile" "TSAN" "ASAN" "MSAN")
 endif()
 if(CMAKE_CONFIGURATION_TYPES)
     # Add appropriate GROMACS-specific build types for the Visual
@@ -90,14 +85,8 @@ set(build_types_with_explicit_flags RELEASE DEBUG RELWITHDEBINFO RELWITHASSERT M
 
 set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS ON)
 
-# Set a default valgrind suppression file.
-# This unfortunately needs to duplicate information from CTest to work as
-# expected...
-set(MEMORYCHECK_SUPPRESSIONS_FILE
-    "${CMAKE_SOURCE_DIR}/cmake/legacy_and_external.supp"
-    CACHE FILEPATH
-    "File that contains suppressions for the memory checker")
-include(CTest)
+include(gmxCTestUtilities)
+gmx_ctest_init()
 
 include(gmxCPackUtilities)
 gmx_cpack_init()
@@ -106,6 +95,21 @@ gmx_cpack_init()
 set(INSTALLED_HEADER_INCLUDE_DIRS "")
 set(INSTALLED_HEADER_DEFINITIONS "")
 
+########################################################################
+# Global non-cache variables for implementing the build system
+########################################################################
+
+# These variables collect libraries that GROMACS requires for
+# linking. They should be appended to with list(APPEND ${name}
+# new-library) calls. They are:
+#  - Libraries that are required for libgromacs (only)
+set(GMX_EXTRA_LIBRARIES "")
+#  - Libraries that are required for all code in the repository
+set(GMX_COMMON_LIBRARIES "")
+#  - Libraries that all code linked against libgromacs needs
+#    (i.e., something that is exposed in installed headers).
+set(GMX_PUBLIC_LIBRARIES "")
+
 ########################################################################
 # Check and warn if cache generated on a different host is being reused
 ########################################################################
@@ -197,12 +201,16 @@ gmx_add_cache_dependency(GMX_COOL_QUOTES BOOL "NOT GMX_FAHCORE" OFF)
 
 option(GMX_USE_OPENCL "Enable OpenCL acceleration" OFF)
 
-# Decide on GPU settings based on user-settings and GPU/CUDA detection.
-# GCC 4.6 requires CUDA 5.0 and VS2015 requires CUDA 8.0
+# Decide on GPU settings based on user-settings and GPU/CUDA
+# detection.  GCC 4.8 requires CUDA 6.0 (but we choose 6.5 for the
+# preliminary C++11 support), icc 15 requires CUDA 7.0, and VS2015
+# requires CUDA 8.0
 if(MSVC)
     set(REQUIRED_CUDA_VERSION 8.0)
+elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
+    set(REQUIRED_CUDA_VERSION 7.0)
 else()
-    set(REQUIRED_CUDA_VERSION 5.0)
+    set(REQUIRED_CUDA_VERSION 6.5)
 endif()
 set(REQUIRED_CUDA_COMPUTE_CAPABILITY 2.0)
 
@@ -228,14 +236,11 @@ else()
     endif()
 endif()
 
-include(gmxDetectSimd)
-gmx_detect_simd(GMX_SUGGESTED_SIMD)
-
 gmx_option_multichoice(
     GMX_SIMD
     "SIMD instruction set for CPU kernels and compiler optimization"
-    "${GMX_SUGGESTED_SIMD}"
-    None SSE2 SSE4.1 AVX_128_FMA AVX_256 AVX2_256 AVX_512 AVX_512_KNL MIC ARM_NEON ARM_NEON_ASIMD IBM_QPX IBM_VMX IBM_VSX Sparc64_HPC_ACE Reference)
+    "AUTO"
+    AUTO None SSE2 SSE4.1 AVX_128_FMA AVX_256 AVX2_256 AVX2_128 AVX_512 AVX_512_KNL MIC ARM_NEON ARM_NEON_ASIMD IBM_QPX IBM_VMX IBM_VSX Sparc64_HPC_ACE Reference)
 
 if(GMX_TARGET_MIC)
     set(GMX_FFT_LIBRARY_DEFAULT "mkl")
@@ -339,17 +344,6 @@ set(EXTRA_CXX_FLAGS "")
 # Run through a number of tests for buggy compilers and other issues
 include(gmxTestCompilerProblems)
 gmx_test_compiler_problems()
-# GMX_SIMD will not be set automatically until the second
-# pass (which is not strictly guaranteed to occur), so putting this
-# check here among logically-related tests is inefficient, but the
-# potential loss is likely zero.
-if(GMX_SIMD STREQUAL "AVX_256"
-        AND CMAKE_COMPILER_IS_GNUCC
-        AND (C_COMPILER_VERSION VERSION_EQUAL "4.6.1"
-            OR CXX_COMPILER_VERSION VERSION_EQUAL "4.6.1"))
-    message(FATAL_ERROR "gcc 4.6.1 has buggy support for AVX, and GROMACS mdrun will not work. If you want simulation performance, use a more recent compiler. Otherwise, use GMX_SIMD=SSE4.1")
-    # See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49002
-endif()
 
 # Implement double-precision option. This is complicated because we
 # need installed headers to use the precision mode of the build that
@@ -469,11 +463,6 @@ include(gmxManageSharedLibraries)
 # Find external packages                                               #
 ########################################################################
 
-# TNG wants zlib if it is available. And static libxml2 might have a dependency
-find_package(ZLIB QUIET)
-include(gmxTestZLib)
-gmx_test_zlib(HAVE_ZLIB)
-
 # Unconditionally find the package, as it is also required for unit
 # tests. This exports LIBXML2_FOUND, which we should not use because
 # it does not tell us that linking will succeed. Instead, we test that
@@ -519,7 +508,7 @@ endif()
 option(GMX_HWLOC "Add support for hwloc Portable Hardware locality library" ${GMX_HWLOC_DEFAULT})
 if(GMX_HWLOC)
     if(HWLOC_FOUND)
-        include_directories(${HWLOC_INCLUDE_DIRS})
+        include_directories(SYSTEM ${HWLOC_INCLUDE_DIRS})
         list(APPEND GMX_EXTRA_LIBRARIES ${HWLOC_LIBRARIES})
     else()
         message(FATAL_ERROR "Hwloc package support requested, but not found.")
@@ -578,7 +567,6 @@ if (TMPI_ATOMICS_DISABLED)
    add_definitions(-DTMPI_ATOMICS_DISABLED)
 endif()
 
-# Note this relies on zlib detection having already run
 include(gmxManageTNG)
 
 include(gmxManageLmfit)
@@ -586,8 +574,6 @@ include(gmxManageLmfit)
 if(GMX_GPU)
     # now that we have detected the dependencies, do the second configure pass
     gmx_gpu_setup()
-else()
-    mark_as_advanced(CUDA_HOST_COMPILER)
 endif()
 
 if(CYGWIN)
@@ -620,7 +606,9 @@ gmx_add_cache_dependency(GMX_BUILD_UNITTESTS BOOL BUILD_TESTING OFF)
 
 add_definitions( -DHAVE_CONFIG_H )
 include_directories(BEFORE ${CMAKE_SOURCE_DIR}/src)
-include_directories(BEFORE ${CMAKE_SOURCE_DIR}/src/external/thread_mpi/include)
+# TODO required at high level because both libgromacs and progs/mdrun
+# require it, both for thread-MPI and its atomics and mutexes.
+include_directories(BEFORE SYSTEM ${CMAKE_SOURCE_DIR}/src/external/thread_mpi/include)
 # Required for config.h, maybe should only be set in src/CMakeLists.txt
 include_directories(BEFORE ${CMAKE_BINARY_DIR}/src)
 
@@ -629,24 +617,50 @@ gmx_test_inline_asm_gcc_x86(GMX_X86_GCC_INLINE_ASM)
 
 include(gmxSetBuildInformation)
 gmx_set_build_information()
-# Turn on RDTSCP if:
-# - the build system's CPU supports it
-# - the acceleration is set to AVX as all AVX-capable CPUs support AVX (which
-#   at this point means that the user set it).
-# Note: it's better to not use the later set value of GMX_SIMD because
-# it reflects the system's capability of both compiling and running AVX code.
-# TODO: After merge with 5.0 one could implement a cache variable dependency
-# such that GMX_USE_RDTSCP can change if GMX_SIMD is changed to AVX
-# after the first cmake pass.
-if (BUILD_CPU_FEATURES MATCHES "rdtscp" OR GMX_SIMD MATCHES "AVX")
-    set(GMX_USE_RDTSCP_DEFAULT_VALUE ON)
-else()
-    set(GMX_USE_RDTSCP_DEFAULT_VALUE OFF)
-endif()
-option(GMX_USE_RDTSCP "Use RDTSCP for better CPU-based timers (available on recent x86 CPUs; might need to be off when compiling for heterogeneous environments)" ${GMX_USE_RDTSCP_DEFAULT_VALUE})
+
+gmx_option_multichoice(
+    GMX_USE_RDTSCP
+    "Use low-latency RDTSCP instruction for CPU-based timers for mdrun execution; might need to be off when compiling for heterogeneous environments)"
+    "AUTO"
+    OFF ON AUTO DETECT)
 mark_as_advanced(GMX_USE_RDTSCP)
-if(GMX_USE_RDTSCP)
+
+macro(gmx_check_rdtscp)
+    if (CPU_DETECTION_FEATURES MATCHES "rdtscp")
+        set(HAVE_RDTSCP 1)
+        set(RDTSCP_DETECTION_MESSAGE " - detected on the build host")
+    else()
+        set(RDTSCP_DETECTION_MESSAGE " - not detected on the build host")
+    endif()
+endmacro()
+
+set(HAVE_RDTSCP 0)
+if (GMX_USE_RDTSCP STREQUAL "ON")
     set(HAVE_RDTSCP 1)
+elseif(GMX_USE_RDTSCP STREQUAL "DETECT")
+    gmx_check_rdtscp()
+elseif(GMX_USE_RDTSCP STREQUAL "AUTO")
+    # If the user specified automated SIMD selection, that the choice
+    # is made based on detection on the build host. If so, then RDTSCP
+    # should be chosen the same way.
+    #
+    # If the user specified an AVX SIMD level (e.g. when
+    # cross-compiling GROMACS) then they will get our best guess, ie
+    # that in practice AVX mostly correlates with rdtscp (and anyway
+    # is only relevant in rather old x86 hardware).
+    if (GMX_SIMD STREQUAL "AUTO")
+        gmx_check_rdtscp()
+    elseif (GMX_SIMD MATCHES "AVX")
+        set(HAVE_RDTSCP 1)
+    endif()
+endif()
+gmx_check_if_changed(HAVE_RDTSCP_CHANGED HAVE_RDTSCP)
+if (HAVE_RDTSCP_CHANGED)
+    if (HAVE_RDTSCP)
+        message(STATUS "Enabling RDTSCP support${RDTSCP_DETECTION_MESSAGE}")
+    else()
+        message(STATUS "Disabling RDTSCP support${RDTSCP_DETECTION_MESSAGE}")
+    endif()
 endif()
 
 include(gmxTestLargeFiles)
@@ -720,8 +734,8 @@ if(HAVE_TIME_H AND HAVE_UNISTD_H AND HAVE_CLOCK_GETTIME)
 endif()
 
 # Math and thread libraries must often come after all others when linking...
-if(HAVE_LIBM)
-    list(APPEND GMX_EXTRA_LIBRARIES m)
+if (HAVE_LIBM)
+    list(APPEND GMX_PUBLIC_LIBRARIES m)
 endif()
 
 option(GMX_NACL "Configure for Native Client builds" OFF)
@@ -771,7 +785,7 @@ else()
     message("CMAKE_CXX_FLAGS_RELEASE: ${GMXC_CXXFLAGS_RELEASE}")
     message("CMAKE_CXX_FLAGS_DEBUG: ${GMXC_CXXFLAGS_DEBUG}")
     message("CMAKE_EXE_LINKER_FLAGS: ${FFT_LINKER_FLAGS} ${MPI_LINKER_FLAGS}")
-    message("CMAKE_SHARED_LINKER_FLAGS: ${MPI_LINKER_FLAGS}")
+    message("CMAKE_SHARED_LINKER_FLAGS: ${FFT_LINKER_FLAGS} ${MPI_LINKER_FLAGS}")
 endif()
 
 if(NOT GMX_OPENMP)
@@ -821,17 +835,12 @@ include(gmxManageSuffixes)
 ################################################################
 # Shared library load path settings
 ################################################################
-# CMake supports RPATH on OS X only from 2.8.12 upwards.
-# CMAKE_SYSTEM_VERSION > 8.0 matches OS X 10.5 and above, where RPATH support
-# was added.
-
 if(NOT GMX_BUILD_SHARED_EXE)
     # No rpath
     set(CMAKE_SKIP_RPATH TRUE)
     set(CMAKE_EXE_LINK_DYNAMIC_C_FLAGS) # remove -Wl,-Bdynamic
     set(CMAKE_EXE_LINK_DYNAMIC_CXX_FLAGS)
-elseif((NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin") OR
-   ((CMAKE_SYSTEM_VERSION VERSION_GREATER 8.0) AND (NOT CMAKE_VERSION VERSION_LESS 2.8.12)))
+else()
     # The build folder always has bin/ and lib/; if we are also going to
     # install to lib/, then the installation RPATH works also in the build
     # tree.  This makes installation slightly faster (no need to rewrite the
@@ -841,23 +850,13 @@ elseif((NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin") OR
     endif()
     # Set the RPATH as relative to the executable location to make the
     # binaries relocatable.
-    if(NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+    if(NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin") #Assume OS X >=10.5
         set(CMAKE_INSTALL_RPATH "\$ORIGIN/../${GMX_LIB_INSTALL_DIR}")
     else()
         set(CMAKE_INSTALL_RPATH "@executable_path/../${GMX_LIB_INSTALL_DIR}")
     endif()
     set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
     set(CMAKE_MACOSX_RPATH 1)
-else()
-    # We are on Darwin/OSX, and CMake cannot handle RPATHs automatically.
-    if(CMAKE_SYSTEM_VERSION VERSION_GREATER 8.0)
-        # Set the RPATH options manually.
-        set(CMAKE_INSTALL_NAME_DIR "@rpath")
-        set(GMX_EXE_LINKER_FLAGS ${GMX_EXE_LINKER_FLAGS} "-Wl,-rpath,@executable_path/../${GMX_LIB_INSTALL_DIR}")
-    else()
-        # Use the old INSTALL_NAME_DIR mechanism if RPATH is not supported.
-        set(CMAKE_INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}")
-    endif()
 endif()
 
 #COPYING file: Only necessary for binary distributions.
@@ -874,18 +873,7 @@ if (GMX_BUILD_FOR_COVERAGE)
 endif()
 
 if (BUILD_TESTING)
-    # "tests" target builds all the separate test binaries.
-    add_custom_target(tests)
-    # "run-ctest" is an internal target that actually runs the tests.
-    # This is necessary to be able to add separate targets that execute as part
-    # of 'make check', but are ensured to be executed after the actual tests.
-    add_custom_target(run-ctest
-                      COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure
-                      COMMENT "Running all tests"
-                      VERBATIM)
-    add_dependencies(run-ctest tests)
-    # "check" target builds and runs all tests.
-    add_custom_target(check DEPENDS run-ctest)
+    include(tests/CheckTarget.cmake)
 endif()
 
 if (NOT GMX_BUILD_MDRUN_ONLY)