f29470ec6b7df5e39d6c1fd14c5d0db033196607
[alexxy/gromacs.git] / CMakeLists.txt
1 cmake_minimum_required(VERSION 2.8)
2 # Keep CMake suitably quiet on Cygwin
3 set(CMAKE_LEGACY_CYGWIN_WIN32 0) # Remove when CMake >= 2.8.4 is required
4
5 # Allows CPack to act differently for normal tools and mdrun (e.g. because of MPI)
6 set(CPACK_COMPONENT_GROUP_TOOLS_DESCRIPTION "All GROMACS executable tools")
7 set(CPACK_COMPONENT_GROUP_MDRUN_DESCRIPTION "GROMACS executable for running simulations")
8
9 # override bugs on OS X where Cmake picks gcc (GNU) for C instead of system default cc (Clang).
10 if(APPLE)
11     set(CMAKE_C_COMPILER_INIT "cc")
12 endif(APPLE)
13
14 project(Gromacs C)
15 include(Dart)
16 mark_as_advanced(DART_ROOT)
17
18 # PROJECT_VERSION should have the following structure: 
19 # VERSION-dev[-SUFFIX] where the VERSION should have the for: vMajor.vMinor.vPatch
20 #
21 # The "-dev" suffix is important to keep because it makes possible to distinguish 
22 # between a build from official release and a build from git release branch on a 
23 # machine with no git. 
24 #
25 # NOTE: when releasing the "-dev" suffix needs to be stripped off!
26 set(PROJECT_VERSION "4.6-dev")
27 set(CUSTOM_VERSION_STRING ""
28     CACHE STRING "Custom version string (if empty, use hard-coded default)")
29 mark_as_advanced(CUSTOM_VERSION_STRING)
30 if (CUSTOM_VERSION_STRING)
31     set(PROJECT_VERSION ${CUSTOM_VERSION_STRING})
32 endif (CUSTOM_VERSION_STRING)
33 set(SOVERSION 6)
34 # It is a bit irritating, but this has to be set separately for now!
35 SET(CPACK_PACKAGE_VERSION_MAJOR "4")
36 SET(CPACK_PACKAGE_VERSION_MINOR "6")
37 #SET(CPACK_PACKAGE_VERSION_PATCH "0")
38
39 # The numerical gromacs version. It is 40600 for 4.6.0.
40 # The #define GMX_VERSION in gmx_header_config_h is set to this value.
41 math(EXPR NUM_VERSION 
42     "${CPACK_PACKAGE_VERSION_MAJOR}*10000 + ${CPACK_PACKAGE_VERSION_MINOR}*100")
43 if(CPACK_PACKAGE_VERSION_PATCH)
44     math(EXPR NUM_VERSION 
45          "${NUM_VERSION} + ${CPACK_PACKAGE_VERSION_PATCH}")
46 endif()
47
48 # The API version tracks the numerical Gromacs version (for now).
49 # It is potentially different from the Gromacs version in the future, if
50 # the programs/libraries diverge from the presumably more stable API.
51 # The #define GMX_API_VERSION in version.h is set to this value to
52 # provide backward compatibility of software written against the Gromacs API.
53 set(API_VERSION ${NUM_VERSION})
54
55 # Cmake modules/macros are in a subdirectory to keep this file cleaner
56 set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
57
58 if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT AND UNIX)
59 set(CMAKE_INSTALL_PREFIX "/usr/local/gromacs" CACHE STRING "Installation prefix (installation will need write permissions here)" FORCE)
60 endif()
61
62 if(NOT CMAKE_BUILD_TYPE)
63     set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
64 endif(NOT CMAKE_BUILD_TYPE)
65
66 enable_language(C)
67
68 set(GMX_USE_RELATIVE_INSTALL_PATH OFF CACHE STRING "Use relative paths not absolute paths for cmake install. Has only an effect on cpack.")
69 mark_as_advanced(GMX_USE_RELATIVE_INSTALL_PATH)
70
71 set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
72 set(CPACK_PACKAGE_VENDOR "gromacs.org")
73 set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Gromacs - a toolkit for high-performance molecular simulation")
74 if (NOT GMX_USE_RELATIVE_INSTALL_PATH)
75     set(CPACK_SET_DESTDIR "ON")
76 endif()
77 set(CPACK_RESOURCE_FILE_WELCOME "${CMAKE_SOURCE_DIR}/admin/InstallWelcome.txt")
78 # Its GPL/LGPL, so they do not have to agree to a license for mere usage, but some installers require this...
79 set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/admin/InstallLicense.txt")
80 set(CPACK_RESOURCE_FILE_README "${CMAKE_SOURCE_DIR}/admin/InstallInfo.txt")
81 set(CPACK_SOURCE_IGNORE_FILES ".isreposource;.git;.gitignore")
82 set(CPACK_PROJECT_CONFIG_FILE "${CMAKE_SOURCE_DIR}/CPackInit.cmake")
83 SET(CPACK_SOURCE_INSTALLED_DIRECTORIES "${CMAKE_SOURCE_DIR};/;${CMAKE_BINARY_DIR}/man;man")
84
85 #must come after all cpack settings!
86 include(CPack)
87
88 ########################################################################
89 # Check and warn if cache generated on a different host is being reused
90 ########################################################################
91 if(CMAKE_HOST_UNIX)
92     execute_process(COMMAND hostname
93                     OUTPUT_VARIABLE TMP_HOSTNAME
94                     OUTPUT_STRIP_TRAILING_WHITESPACE)
95     if(GMX_BUILD_HOSTNAME AND NOT "${GMX_BUILD_HOSTNAME}" STREQUAL "${TMP_HOSTNAME}")
96         message(WARNING "
97             The CMake cache, probably generated on a different host (${GMX_BUILD_HOSTNAME}),
98             is being reused! This could lead to inconsitencies; therefore, it is
99             recommended to regenerate the cache!")
100     endif()
101     set(GMX_BUILD_HOSTNAME "${TMP_HOSTNAME}" CACHE INTERNAL
102             "Hostname of the machine where the cache was generated.")
103 endif()
104
105 ########################################################################
106 # User input options - enable C++ - before any CXX flags are changed   #
107 ########################################################################
108 option(GMX_GPU  "Enable GPU acceleration" ON)
109 option(GMX_OPENMM "Accelerated execution on GPUs through the OpenMM library (rerun cmake after changing to see relevant options)" OFF)
110 option(GMX_FORCE_CXX "Enable C++ compilation even if not necessary" OFF)
111 mark_as_advanced(GMX_FORCE_CXX)
112 if(GMX_GPU OR GMX_OPENMM OR GMX_FORCE_CXX)
113     enable_language(CXX)
114 endif()
115
116 ########################################################################
117 # Fix stupid flags on Windows
118 ########################################################################
119 SET(SHARED_LIBS_DEFAULT ON) 
120 IF( WIN32 AND NOT CYGWIN)
121   option(GMX_PREFER_STATIC_LIBS "When finding libraries prefer static system libraries (MT instead of MD)!" ON)
122   mark_as_advanced(GMX_PREFER_STATIC_LIBS)
123   SET(SHARED_LIBS_DEFAULT OFF)  #is currently not working on Windows
124
125   IF (GMX_PREFER_STATIC_LIBS)
126     #Only setting Debug and Release flags. Others configurations current not used.
127     STRING(REPLACE /MD /MT CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE})
128     SET(CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE} CACHE STRING "" FORCE)
129     STRING(REPLACE /MD /MT CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG})
130     SET(CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG} CACHE STRING "" FORCE)
131     if(CMAKE_CXX_COMPILER_LOADED)
132         STRING(REPLACE /MD /MT CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE})
133         SET(CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE} CACHE STRING "" FORCE)
134         STRING(REPLACE /MD /MT CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
135         SET(CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG} CACHE STRING "" FORCE)
136     endif()
137   ENDIF()
138
139   #Workaround for cmake bug 13174. Replace deprecated options.
140   IF( CMAKE_C_COMPILER_ID MATCHES "Intel" )
141     STRING(REPLACE /GZ /RTC1 CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG})
142     SET(CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG} CACHE STRING "" FORCE)
143   ENDIF()
144   IF( CMAKE_CXX_COMPILER_ID MATCHES "Intel" AND CMAKE_CXX_COMPILER_LOADED)
145     STRING(REPLACE /GZ /RTC1 CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
146     STRING(REPLACE /GX /EHsc CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
147     SET(CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG} CACHE STRING "" FORCE)
148
149     STRING(REPLACE /GX /EHsc CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE})
150     SET(CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE} CACHE STRING "" FORCE)
151   ENDIF()
152 ENDIF()
153
154
155 ########################################################################
156 # User input options                                                   #
157 ########################################################################
158 option(GMX_DOUBLE "Use double precision (much slower, use only if you really need it)" OFF)
159 option(GMX_MPI    "Build a parallel (message-passing) version of GROMACS" OFF)
160 option(GMX_THREAD_MPI  "Build a thread-MPI-based multithreaded version of GROMACS (not compatible with MPI)" ON)
161 option(GMX_SOFTWARE_INVSQRT "Use GROMACS software 1/sqrt" ON)
162 mark_as_advanced(GMX_SOFTWARE_INVSQRT)
163 option(GMX_POWERPC_INVSQRT "Use PowerPC hardware 1/sqrt" OFF)
164 mark_as_advanced(GMX_POWERPC_INVSQRT)
165 option(GMX_FAHCORE "Build a library with mdrun functionality" OFF)
166 mark_as_advanced(GMX_FAHCORE)
167
168 include(gmxDetectAcceleration)
169 if(NOT DEFINED GMX_ACCELERATION)
170     if(CMAKE_CROSSCOMPILING)
171         set(GMX_SUGGESTED_ACCELERATION "None")
172     else(CMAKE_CROSSCOMPILING)
173         gmx_detect_acceleration(GMX_SUGGESTED_ACCELERATION)
174     endif(CMAKE_CROSSCOMPILING)
175 endif(NOT DEFINED GMX_ACCELERATION)
176
177 set(GMX_ACCELERATION "@GMX_SUGGESTED_ACCELERATION@"
178     CACHE STRING "Accelerated kernels. Pick one of: None, SSE2, SSE4.1, AVX_128_FMA, AVX_256, BlueGene, Power6, Fortran")
179
180 set(GMX_FFT_LIBRARY "fftw3" 
181     CACHE STRING "FFT library choices: fftw3,mkl,fftpack[built-in]")
182 option(GMX_DISABLE_FFTW_MEASURE 
183        "Do not optimize FFTW setups (not needed with SSE)" OFF)
184 mark_as_advanced(GMX_DISABLE_FFTW_MEASURE)
185 set(GMX_QMMM_PROGRAM "none" 
186     CACHE STRING "QM package choices: none,gaussian,mopac,gamess,orca")
187 option(GMX_BROKEN_CALLOC "Work around broken calloc()" OFF)
188 mark_as_advanced(GMX_BROKEN_CALLOC)
189 option(GMX_MPI_IN_PLACE "Enable MPI_IN_PLACE for MPIs that have it defined" ON)
190 mark_as_advanced(GMX_MPI_IN_PLACE)
191 option(GMX_LOAD_PLUGINS "Compile with plugin support, needed to read VMD supported file formats" ON)
192 mark_as_advanced(GMX_LOAD_PLUGINS)
193
194 option(GMX_OPENMP "Enable OpenMP-based multithreading" ON)
195
196 option(USE_VERSION_H "Generate development version string/information" ON)
197 mark_as_advanced(USE_VERSION_H)
198
199 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)
200
201 if(UNIX AND NOT APPLE)
202     option(GMX_PREFER_STATIC_LIBS "When finding libraries prefer \".a\" static archives (NOTE: this is enabled only for UNIX (excluding APPLE) platforms but it might not always work!" OFF)
203     mark_as_advanced(GMX_PREFER_STATIC_LIBS)
204 endif()
205
206 option(GMX_CYCLE_SUBCOUNTERS "Enable cycle subcounters to get a more detailed cycle timings" OFF)
207 mark_as_advanced(GMX_CYCLE_SUBCOUNTERS)
208
209 ######################################################################
210 # compiler tests
211 # these need ot be done early (before further tests).
212 #####################################################################
213
214 # cmake/Check{C,CXX}CompilerFlag.cmake are lifted from CMake git next
215 # branch (proposed for v2.8.9) to be able to detect invalid options
216 # with the Intel Compilers.
217 # Remove these files from the source tree when a CMake version that
218 # includes the features in question becomes required.
219 include(CheckCCompilerFlag)
220 if(CMAKE_CXX_COMPILER_LOADED)
221     include(CheckCXXCompilerFlag)
222 endif()
223
224 # OpenMP check must come before other CFLAGS!
225 if(GMX_OPENMP)
226     find_package(OpenMP)
227     if(OPENMP_FOUND)
228         #- only set linker flag, if user didn't set them manual
229         #- cmake on windows doesn't support linker flags passed to target_link_libraries
230         #  (cmake treats /openmp as \openmp library file) and no openmp linker flags are needed
231         if(NOT (WIN32 AND NOT CYGWIN))
232             if(CMAKE_COMPILER_IS_GNUCC AND GMX_PREFER_STATIC_OPENMP)
233                 set(OpenMP_LINKER_FLAGS "-Wl,-static -lgomp -lrt -Wl,-Bdynamic -lpthread")
234                 set(OpenMP_SHARED_LINKER_FLAGS "")
235             else()
236                 if(NOT DEFINED OpenMP_LINKER_FLAGS)
237                     set(OpenMP_LINKER_FLAGS "${OpenMP_C_FLAGS}")
238                 endif()
239                 if(NOT DEFINED OpenMP_SHARED_LINKER_FLAGS)
240                     set(OpenMP_SHARED_LINKER_FLAGS "${OpenMP_C_FLAGS}")
241                 endif()
242             endif()
243         endif()
244     else(OPENMP_FOUND)
245         message(WARNING
246                 "Compiler not supporting OpenMP. This might hurt your performance a lot, "
247                 "in particular with GPUs. Try using a different compiler (Intel is good on x86) "
248                 "if you can - for now we are proceeding by turning off OpenMP.")
249         set(GMX_OPENMP OFF CACHE STRING "Compiler does not support OpenMP." FORCE)
250     endif(OPENMP_FOUND)
251 endif()
252
253
254 include(gmxCFlags)
255 gmx_c_flags()
256
257 include(gmxGetCompilerVersion)
258 get_compiler_version()
259
260 # gcc 4.4.x is buggy and crashes when compiling some files with O3 and OpenMP on.
261 # Detect here whether applying a workaround is needed and will apply it later
262 # on the affected files.
263 include(gmxGCC44O3BugWorkaround)
264 gmx_check_gcc44_bug_workaround_needed(GMX_USE_GCC44_BUG_WORKAROUND)
265
266 ########################################################################
267 # Set up binary and library suffixing 
268 ########################################################################
269 set(GMX_BINARY_SUFFIX "" CACHE STRING "Suffix for GROMACS binaries (default: _d for double, _mpi for MPI, _mpi_d for MPI and double).")
270 set(GMX_LIBS_SUFFIX "" 
271   CACHE STRING "Suffix for GROMACS libs (default: _d for double, _mpi for MPI, _mpi_d for MPI and double).")
272 if (GMX_DEFAULT_SUFFIX)
273   set(GMX_BINARY_SUFFIX "")
274   set(GMX_LIBS_SUFFIX "")
275   if (GMX_MPI)
276     set(GMX_BINARY_SUFFIX "_mpi")
277     set(GMX_LIBS_SUFFIX "_mpi")
278   endif(GMX_MPI)
279   if (GMX_DOUBLE)
280     set (GMX_BINARY_SUFFIX "${GMX_BINARY_SUFFIX}_d")
281     set (GMX_LIBS_SUFFIX "${GMX_LIBS_SUFFIX}_d")
282   endif(GMX_DOUBLE)
283   if (GMX_OPENMM)
284     set (GMX_BINARY_SUFFIX "-openmm")
285     set (GMX_LIBS_SUFFIX "_openmm")
286   endif(GMX_OPENMM)
287   mark_as_advanced(FORCE GMX_BINARY_SUFFIX GMX_LIBS_SUFFIX)
288   if (NOT SUFFIX_QUIETLY)
289     message(STATUS "Using default binary suffix: \"${GMX_BINARY_SUFFIX}\"")
290     message(STATUS "Using default library suffix: \"${GMX_LIBS_SUFFIX}\"")
291   endif (NOT SUFFIX_QUIETLY)
292 else(GMX_DEFAULT_SUFFIX)
293   mark_as_advanced(CLEAR GMX_BINARY_SUFFIX GMX_LIBS_SUFFIX)
294   if (NOT SUFFIX_QUIETLY)
295     message(STATUS "Using manually set binary suffix: \"${GMX_BINARY_SUFFIX}\"")
296     message(STATUS "Using manually set library suffix: \"${GMX_LIBS_SUFFIX}\"")
297   endif (NOT SUFFIX_QUIETLY)
298 endif(GMX_DEFAULT_SUFFIX)
299 set(SUFFIX_QUIETLY TRUE CACHE INTERNAL "")
300
301 set(PKG_CFLAGS "")
302 if(GMX_DOUBLE)
303     set(PKG_CFLAGS "${PKG_CFLAGS} -DGMX_DOUBLE")
304 endif(GMX_DOUBLE)
305 if(GMX_SOFTWARE_INVSQRT)
306   set(PKG_CFLAGS "${PKG_CFLAGS} -DGMX_SOFTWARE_INVSQRT")
307 endif(GMX_SOFTWARE_INVSQRT)
308 if(GMX_POWERPC_INVSQRT)
309   set(PKG_CFLAGS "${PKG_CFLAGS} -DGMX_POWERPC_INVSQRT")
310 endif(GMX_POWERPC_INVSQRT)
311
312 ########################################################################
313 #Process MPI settings
314 ########################################################################
315 include(gmxManageMPI)
316
317 #######################################################################
318 # Check for options incompatible with OpenMM build                    #
319 #######################################################################
320 if(GMX_OPENMM)
321     # we'll use the built-in fft to avoid unnecessary dependencies
322     string(TOUPPER ${GMX_FFT_LIBRARY} GMX_FFT_LIBRARY)
323     if(NOT ${GMX_FFT_LIBRARY} STREQUAL "FFTPACK")
324         message(STATUS "No external FFT libraries needed for the OpenMM build, switching to fftpack!")
325         set(GMX_FFT_LIBRARY "fftpack" CACHE STRING 
326                 "No external FFT libraries needed for the OpenMM build, switching to  fftpack!" FORCE)
327     endif()
328     if(GMX_MPI)
329         message(FATAL_ERROR "The OpenMM build is not compatible with MPI!")
330     endif(GMX_MPI)
331     if(GMX_THREAD_MPI)
332         message(STATUS "Thread-MPI not compatible with OpenMM, disabled!")
333         set(GMX_THREAD_MPI OFF CACHE BOOL
334                 "Thread-MPI not compatible with OpenMM build, disabled!" FORCE)
335     endif(GMX_THREAD_MPI)
336     if(GMX_OPENMP)
337         message(STATUS "OpenMP multithreading not compatible with OpenMM, disabled")
338         set(GMX_OPENMP OFF CACHE BOOL
339             "OpenMP multithreading not compatible with OpenMM, disabled!" FORCE)
340     endif()
341     if(GMX_SOFTWARE_INVSQRT)
342         set(GMX_SOFTWARE_INVSQRT OFF CACHE STRING 
343                 "The OpenMM build does not need GROMACS software 1/sqrt!" FORCE)
344     endif(GMX_SOFTWARE_INVSQRT)
345     string(TOUPPER ${GMX_ACCELERATION} GMX_ACCELERATION)
346     if(NOT GMX_ACCELERATION STREQUAL "NONE")
347         message(STATUS "Switching off CPU-based acceleration, the OpenMM build does not support/need any!")     
348         set(GMX_ACCELERATION "none" CACHE STRING 
349                 "Switching off CPU-based acceleration, the OpenMM build does not support/need any!" FORCE)
350     endif()
351     if(GMX_FAHCORE)
352         message(FATAL_ERROR "The OpenMM build does not support FAH build!")
353     endif(GMX_FAHCORE)
354     if(GMX_DOUBLE)
355         message(FATAL_ERROR  "The OpenMM-build does not support double precision calculations!")
356     endif()
357     # mark as advanced the unused variables
358     mark_as_advanced(FORCE GMX_ACCELERATION GMX_MPI GMX_FFT_LIBRARY 
359         GMX_QMMM_PROGRAM GMX_THREAD_MPI GMX_DOUBLE)
360 else(GMX_OPENMM)
361      mark_as_advanced(CLEAR GMX_ACCELERATION GMX_MPI GMX_FFT_LIBRARY 
362         GMX_QMMM_PROGRAM GMX_THREAD_MPI GMX_DOUBLE)
363 endif(GMX_OPENMM)
364
365
366 ########################################################################
367 # Basic system tests (standard libraries, headers, functions, types)   #
368 ########################################################################
369 include(CheckIncludeFiles)
370 check_include_files(string.h     HAVE_STRING_H)
371 check_include_files(math.h       HAVE_MATH_H)
372 check_include_files(limits.h     HAVE_LIMITS_H)
373 check_include_files(memory.h     HAVE_MEMORY_H)
374 check_include_files(unistd.h     HAVE_UNISTD_H)
375 check_include_files(direct.h     HAVE_DIRECT_H)
376 check_include_files(pwd.h        HAVE_PWD_H)
377 check_include_files(stdint.h     HAVE_STDINT_H)
378 check_include_files(stdlib.h     HAVE_STDLIB_H)
379 check_include_files(pthread.h    HAVE_PTHREAD_H)
380 check_include_files(dirent.h     HAVE_DIRENT_H)
381 check_include_files(inttypes.h   HAVE_INTTYPES_H)
382 check_include_files(regex.h      HAVE_REGEX_H)
383 check_include_files(sys/types.h  HAVE_SYS_TYPES_H)
384 check_include_files(sys/stat.h   HAVE_SYS_STAT_H)
385 check_include_files(sys/time.h   HAVE_SYS_TIME_H)
386 check_include_files(rpc/rpc.h    HAVE_RPC_RPC_H)
387 check_include_files("rpc/rpc.h;rpc/xdr.h"    HAVE_RPC_XDR_H)
388 check_include_files(io.h                 HAVE_IO_H)
389 check_include_files(sched.h      HAVE_SCHED_H)
390
391 include(CheckFunctionExists)
392 check_function_exists(strcasecmp        HAVE_STRCASECMP)
393 check_function_exists(strdup            HAVE_STRDUP)
394 check_function_exists(vprintf           HAVE_VPRINTF)
395 check_function_exists(memcmp            HAVE_MEMCMP)
396 check_function_exists(posix_memalign    HAVE_POSIX_MEMALIGN)
397 check_function_exists(memalign          HAVE_MEMALIGN)
398 check_function_exists(_aligned_malloc   HAVE__ALIGNED_MALLOC)
399 check_function_exists(gettimeofday      HAVE_GETTIMEOFDAY)
400 check_function_exists(isnan             HAVE_ISNAN)
401 check_function_exists(_isnan            HAVE__ISNAN)
402 check_function_exists(fsync             HAVE_FSYNC)
403 check_function_exists(_fileno           HAVE__FILENO)
404 check_function_exists(fileno            HAVE_FILENO)
405 check_function_exists(_commit           HAVE__COMMIT)
406 check_function_exists(lstat             HAVE_LSTAT)
407 check_function_exists(sigaction         HAVE_SIGACTION)
408 check_function_exists(sysconf           HAVE_SYSCONF)
409 check_function_exists(sched_setaffinity HAVE_SCHED_SETAFFINITY)
410
411 include(CheckLibraryExists)
412 check_library_exists(m sqrt "" HAVE_LIBM)
413 check_library_exists(m cbrt "" HAVE_CBRT)
414
415
416 include(CheckTypeSize)
417
418 check_type_size("bool"          SIZEOF_BOOL) # will also set HAVE_BOOL
419 check_type_size("int"           SIZEOF_INT) 
420 check_type_size("long int"      SIZEOF_LONG_INT) 
421 check_type_size("long long int" SIZEOF_LONG_LONG_INT) 
422 check_type_size("off_t"         SIZEOF_OFF_T)
423 check_type_size("void *"        SIZEOF_VOIDP)
424
425 if (CMAKE_C_SIZEOF_DATA_PTR EQUAL 8)
426     set(GMX_64_BIT TRUE)
427 else (CMAKE_C_SIZEOF_DATA_PTR EQUAL 8)
428     set(GMX_64_BIT FALSE)
429 endif (CMAKE_C_SIZEOF_DATA_PTR EQUAL 8)
430
431 # Check for some basic types that we *need*, so set these to int if they are not present 
432 check_type_size(uid_t uid_t)
433 if(NOT uid_t)
434   set(uid_t int)
435 else(NOT uid_t)
436   set(uid_t 0)
437 endif(NOT uid_t)
438
439 check_type_size(gid_t gid_t)
440 if(NOT gid_t)
441   set(gid_t 1)
442 else(NOT gid_t)
443   set(gid_t 0)
444 endif(NOT gid_t)
445
446 check_type_size(size_t size_t)
447 if(NOT size_t)
448   set(size_t int)
449 else(NOT size_t)
450   set(size_t 0)
451 endif(NOT size_t)
452
453 check_type_size(off_t off_t)
454 if(NOT off_t)
455   set(off_t int)
456 else(NOT off_t)
457   set(off_t 0)
458 endif(NOT off_t)
459
460 include(TestBigEndian)
461 test_big_endian(GMX_INTEGER_BIG_ENDIAN)
462
463
464
465
466 ########################################################################
467 # Find external packages                                               #
468 ########################################################################
469 if(UNIX AND NOT APPLE)
470     if(GMX_PREFER_STATIC_LIBS)
471         SET(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
472         if(SHARED_LIBS_DEFAULT)
473             if(BUILD_SHARED_LIBS) #Warn the user about the combination. But don't overwrite the request.
474                 message(WARNING "Static libraries requested, and shared Gromacs libraries requested.")
475             elseif(NOT DEFINED BUILD_SHARED_LIBS) #Change default to OFF. Don't warn if it's already off.
476                 message(WARNING "Static libraries requested, the GROMACS libraries will also be build static (BUILD_SHARED_LIBS=OFF)")
477                 set(SHARED_LIBS_DEFAULT OFF)
478             endif()
479         endif()
480     endif()
481 endif()
482 option(BUILD_SHARED_LIBS "Enable shared libraries (can be problematic with MPI, Windows)" ${SHARED_LIBS_DEFAULT})
483
484 option(GMX_XML "Use libxml2 to parse xml files" ON)
485 if (GMX_XML)
486   find_package(LibXml2)
487   set(PKG_XML "")
488   if(LIBXML2_FOUND)
489     include_directories(${LIBXML2_INCLUDE_DIR})
490     set(PKG_XML libxml-2.0)
491     set(XML_LIBRARIES ${LIBXML2_LIBRARIES})
492     set(HAVE_LIBXML2 1)
493   endif(LIBXML2_FOUND)
494 endif(GMX_XML)
495
496 option(GMX_GSL "Add support for gsl" OFF)
497 if (GMX_GSL)
498   find_package(gsl)
499   set(PKG_GSL "")
500   if(GSL_FOUND)
501     include_directories(${GSL_INCLUDE_DIR})
502     set(PKG_GSL gsl)
503     set(HAVE_LIBGSL 1)
504   endif(GSL_FOUND)
505 endif (GMX_GSL)
506
507 option(GMX_X11 "Use X window system" OFF)
508 if (GMX_X11)
509         find_package(X11)
510         # X11 includes/libraries are only set in the ngmx subdirectory!
511         if(X11_FOUND)
512         set(HAVE_X11 1)
513         endif(X11_FOUND)
514 endif(GMX_X11)
515
516 if(GMX_THREAD_MPI)
517     set(PKG_CFLAGS "${PKG_CFLAGS} -DGMX_THREAD_MPI")
518     include(ThreadMPI)
519     set(THREAD_MPI_LIB thread_mpi)
520     set(GMX_MPI 1)
521     string(TOUPPER ${GMX_FFT_LIBRARY} ${GMX_FFT_LIBRARY})
522 endif(GMX_THREAD_MPI)
523
524 if(GMX_OPENMM)
525     set(CUDA_BUILD_EMULATION OFF)
526     find_package(CUDA 3.1 REQUIRED)
527     add_definitions(-DGMX_OPENMM)
528     if(CMAKE_BUILD_TYPE STREQUAL "DEBUG")    
529         set(CUDA_VERBOSE_BUILD ON)
530     endif()
531     find_package(OpenMM) 
532 endif(GMX_OPENMM)
533
534
535 if(GMX_GPU)
536     if(GMX_DOUBLE)
537         message(WARNING "GPU acceleration is not available in double precision, disabled!")
538         set(GMX_GPU OFF CACHE BOOL "Enable GPU acceleration" FORCE)
539     endif()
540
541     # We support CUDA >=v3.2 on *nix, but <= v4.1 doesn't work with MSVC
542     if(MSVC)
543         find_package(CUDA 4.1)
544     else()
545         find_package(CUDA 3.2)
546     endif()
547
548     if (NOT EXISTS ${CUDA_TOOLKIT_ROOT_DIR})
549         message(FATAL_ERROR "
550     mdrun supports native GPU acceleration on NVIDIA hardware with compute
551     capability >=2.0. This requires the NVIDIA CUDA library, which was not
552     found; the location can be hinted by setting CUDA_TOOLKIT_ROOT_DIR.
553
554     CPU or GPU acceleration can be selected at runtime, but if you are
555     sure you can not make use of GPU acceleration, disable it by setting
556     the CMake variable GMX_GPU=OFF.")
557     endif()
558
559     if(NOT GMX_OPENMP)
560         message(WARNING "
561     In order to use GPU acceleration efficiently, mdrun requires OpenMP multithreding.
562     Without OpenMP only a single CPU core per GPU can be used which is suboptimal.
563     Note that with MPI multiple processes can be forced to use a single GPU, but this
564     typically inefficient.")
565     endif()
566
567     include(gmxManageNvccConfig)
568
569     # Check whether we can use atomic operations needed for polling wait for GPU
570     # (to avoid the cudaStreamSynchronize + ECC bug).
571     # With thread-MPI testing atomics has already been carried out, but without
572     # thread-MPI we need to invoke the atomics test independently.
573     if (NOT GMX_THREAD_MPI)
574         set(TEST_TMPI_ATOMICS_ONLY ON CACHE INTERNAL
575             "Test only the atomic operations of thread-MPI.")
576         include(ThreadMPI)
577     endif()
578
579     # we need this linker flag in case if we have ld >= 2.22 (typically with gcc 4.5+),
580     # but it's too cumbersome to check the ld version and the flag should not hurt
581     if(CMAKE_COMPILER_IS_GNUCC)
582         set(GROMACS_LINKER_FLAGS "-Wl,--add-needed ${GROMACS_LINKER_FLAGS}")
583     endif()
584
585     # annoyingly enough, FindCUDA leaves a few variables behind as non-advanced
586     mark_as_advanced(CUDA_BUILD_CUBIN CUDA_BUILD_EMULATION CUDA_SDK_ROOT_DIR CUDA_VERBOSE_BUILD)
587 endif()
588
589 if(APPLE)
590    find_library(ACCELERATE_FRAMEWORK Accelerate)
591    list(APPEND GMX_EXTRA_LIBRARIES ${ACCELERATE_FRAMEWORK})
592 endif(APPLE)
593
594 if(CYGWIN)
595     set(GMX_CYGWIN 1)
596 endif(CYGWIN)
597
598 if(WIN32 AND NOT CYGWIN)
599     set(GMX_NATIVE_WINDOWS 1)
600 endif()
601
602 # only bother with finding git and using version.h if the source is a git repo
603 if(EXISTS "${CMAKE_SOURCE_DIR}/.git")
604     if(USE_VERSION_H)
605         # We need at least git v1.5.3 be able to parse git's date output. If not
606         # found or the version is too small, we can't generate version information.
607         find_package(Git)
608
609         # Find out the git version
610         if(GIT_FOUND AND NOT GIT_VERSION)
611           execute_process(COMMAND ${GIT_EXECUTABLE} "--version"
612             OUTPUT_VARIABLE _exec_out
613             OUTPUT_STRIP_TRAILING_WHITESPACE)
614           string(REGEX REPLACE "git version (.*)" "\\1" GIT_VERSION ${_exec_out})
615           set(GIT_VERSION ${GIT_VERSION} CACHE STRING "Git version")
616           mark_as_advanced(GIT_VERSION)
617         endif()
618
619         if(NOT GIT_FOUND OR GIT_VERSION VERSION_LESS "1.5.3")
620           message("No compatible git version found, won't be able to generate proper development version information.")
621           set(USE_VERSION_H OFF)
622         endif()
623     endif()
624 else()
625     set(USE_VERSION_H OFF)
626 endif()
627
628 ########################################################################
629 # Generate development version info for cache
630 ########################################################################
631 # set(GEN_VERSION_INFO_INTERNAL "ON")
632 # include(gmxGenerateVersionString)
633
634 ########################################################################
635 # Our own GROMACS tests
636 ########################################################################
637
638 add_definitions( -DHAVE_CONFIG_H )
639 include_directories(${CMAKE_BINARY_DIR}/src)
640 include_directories(${CMAKE_BINARY_DIR}/include)
641 include_directories(${CMAKE_SOURCE_DIR}/include)
642
643 include(gmxTestInlineASM)
644 gmx_test_inline_asm_gcc_x86(GMX_X86_GCC_INLINE_ASM)
645
646 include(gmxSetBuildInformation)
647 gmx_set_build_information()
648 if(BUILD_CPU_FEATURES MATCHES "rdtscp")
649     # The timestep counter headers do not include config.h
650     add_definitions(-DHAVE_RDTSCP)
651 endif(BUILD_CPU_FEATURES MATCHES "rdtscp")
652
653 include(gmxTestFloatFormat)
654 gmx_test_float_format(GMX_FLOAT_FORMAT_IEEE754 
655                       GMX_IEEE754_BIG_ENDIAN_BYTE_ORDER
656                       GMX_IEEE754_BIG_ENDIAN_WORD_ORDER)
657
658 include(gmxTestLargeFiles)
659 gmx_test_large_files(GMX_LARGEFILES)
660 check_function_exists(fseeko     HAVE_FSEEKO)
661
662 include(gmxTestSignal)
663 gmx_test_sigusr1(HAVE_SIGUSR1)
664
665 include(gmxTestInline)
666 gmx_test_inline(INLINE_KEYWORD)
667
668 include(gmxTestRestrict)
669 gmx_test_inline(RESTRICT_KEYWORD)
670
671 include(gmxTestPipes)
672 gmx_test_pipes(HAVE_PIPES)
673
674 include(gmxTestIsfinite)
675 gmx_test_isfinite(HAVE_ISFINITE)
676 gmx_test__isfinite(HAVE__ISFINITE)
677 gmx_test__finite(HAVE__FINITE)
678
679 include(gmxTestXDR)
680 gmx_test_xdr(GMX_SYSTEM_XDR)
681 if(NOT GMX_SYSTEM_XDR)
682     set(GMX_INTERNAL_XDR 1)
683     set(PKG_CFLAGS "${PKG_CFLAGS} -DGMX_INTERNAL_XDR")
684 endif(NOT GMX_SYSTEM_XDR)
685
686 # Process nonbonded accelerated kernels settings
687 string(TOUPPER ${GMX_ACCELERATION} ${GMX_ACCELERATION})
688 if(${GMX_ACCELERATION} STREQUAL "NONE")
689     # nothing to do
690 elseif(${GMX_ACCELERATION} STREQUAL "SSE2")
691
692     GMX_TEST_CFLAG(GNU_SSE2_CFLAG "-msse2" GROMACS_C_FLAGS)
693     if(NOT GNU_SSE2_CFLAG)
694         GMX_TEST_CFLAG(MSVC_SSE2_CFLAG "/arch:SSE2" GROMACS_C_FLAGS)
695     endif(NOT GNU_SSE2_CFLAG)
696
697     if (CMAKE_CXX_COMPILER_LOADED)
698         GMX_TEST_CXXFLAG(GNU_SSE2_CXXFLAG "-msse2" GROMACS_CXX_FLAGS)
699         if(NOT GNU_SSE2_CXXFLAG)
700             GMX_TEST_CXXFLAG(MSVC_SSE2_CXXFLAG "/arch:SSE2" GROMACS_CXX_FLAGS)
701         endif(NOT GNU_SSE2_CXXFLAG)
702     endif()
703
704     # We dont warn for lacking SSE2 flag support, since that is probably standard today.
705
706     # Only test the include after we have tried to add the correct flag for SSE2 support
707     check_include_file(emmintrin.h  HAVE_EMMINTRIN_H ${GROMACS_C_FLAGS})
708
709     if(NOT HAVE_EMMINTRIN_H)
710         message(FATAL_ERROR "Cannot find emmintrin.h, which is required for SSE2 intrinsics support.")
711     endif(NOT HAVE_EMMINTRIN_H)
712
713     # The user should not be able to set this orthogonally to the acceleration
714     set(GMX_X86_SSE2 1)
715     if (NOT ACCELERATION_QUIETLY)
716       message(STATUS "Enabling SSE2 Gromacs acceleration, and it will help compiler optimization.")
717     endif()
718
719 elseif(${GMX_ACCELERATION} STREQUAL "SSE4.1")
720
721     GMX_TEST_CFLAG(GNU_SSE4_CFLAG "-msse4.1" GROMACS_C_FLAGS)
722     if (NOT GNU_SSE4_CFLAG)
723         GMX_TEST_CFLAG(MSVC_SSE4_CFLAG "/arch:SSE4.1" GROMACS_C_FLAGS)
724     endif(NOT GNU_SSE4_CFLAG)
725     if (NOT GNU_SSE4_CFLAG AND NOT MSVC_SSE4_CFLAG)
726         message(WARNING "No C SSE4.1 flag found. Consider a newer compiler, or disable SSE4.1 for slightly lower performance.")
727         # Not surprising if we end up here! MSVC current does not support the SSE4.1 flag. However, it appears to accept SSE4.1
728         # intrinsics when SSE2 support is enabled, so we try that instead.
729         GMX_TEST_CFLAG(MSVC_SSE2_CFLAG "/arch:SSE2" GROMACS_C_FLAGS)
730     endif(NOT GNU_SSE4_CFLAG AND NOT MSVC_SSE4_CFLAG)
731
732     if (CMAKE_CXX_COMPILER_LOADED)
733         GMX_TEST_CXXFLAG(GNU_SSE4_CXXFLAG "-msse4.1" GROMACS_CXX_FLAG)
734         if (NOT GNU_SSE4_CXXFLAG)
735             GMX_TEST_CXXFLAG(MSVC_SSE4_CXXFLAG "/arch:SSE4.1" GROMACS_CXX_FLAGS)
736         endif(NOT GNU_SSE4_CXXFLAG)
737         if (NOT GNU_SSE4_CXXFLAG AND NOT MSVC_SSE4_CXXFLAG) 
738             message(WARNING "No C++ SSE4.1 flag found. Consider a newer compiler, or disable SSE4.1 for slightly lower performance.")
739             # Not surprising if we end up here! MSVC current does not support the SSE4.1 flag. However, it appears to accept SSE4.1
740             # intrinsics when SSE2 support is enabled, so we try that instead.
741             GMX_TEST_CXXFLAG(MSVC_SSE2_CXXFLAG "/arch:SSE2" GROMACS_CXX_FLAGS)
742         endif(NOT GNU_SSE4_CXXFLAG AND NOT MSVC_SSE4_CXXFLAG)
743     endif()
744
745     # This must come after we have added the -msse4.1 flag on some platforms.
746     check_include_file(smmintrin.h  HAVE_SMMINTRIN_H ${GROMACS_C_FLAGS})
747
748     if(NOT HAVE_SMMINTRIN_H)
749         message(FATAL_ERROR "Cannot find smmintrin.h, which is required for SSE4.1 intrinsics support.")
750     endif(NOT HAVE_SMMINTRIN_H)
751
752     # The user should not be able to set this orthogonally to the acceleration
753     set(GMX_X86_SSE4_1 1)
754     set(GMX_X86_SSE2   1)
755     if (NOT ACCELERATION_QUIETLY)
756       message(STATUS "Enabling SSE4.1 Gromacs acceleration, and it will help compiler optimization.")
757     endif()
758
759 elseif(${GMX_ACCELERATION} STREQUAL "AVX_128_FMA" OR ${GMX_ACCELERATION} STREQUAL "AVX_256")
760
761     # Set the AVX compiler flag for both these choices!
762
763     GMX_TEST_CFLAG(GNU_AVX_CFLAG "-mavx" GROMACS_C_FLAGS)
764     if (NOT GNU_AVX_CFLAG)
765         GMX_TEST_CFLAG(MSVC_AVX_CFLAG "/arch:AVX" GROMACS_C_FLAGS)
766     endif (NOT GNU_AVX_CFLAG)
767     if (NOT GNU_AVX_CFLAG AND NOT MSVC_AVX_CFLAG)
768         message(WARNING "No C AVX flag found. Consider a newer compiler, or disable AVX for much lower performance.")
769     endif (NOT GNU_AVX_CFLAG AND NOT MSVC_AVX_CFLAG)
770
771     if (CMAKE_CXX_COMPILER_LOADED)
772         GMX_TEST_CXXFLAG(GNU_AVX_CXXFLAG "-mavx" GROMACS_CXX_FLAGS)
773         if (NOT GNU_AVX_CXXFLAG)
774             GMX_TEST_CXXFLAG(MSVC_AVX_CXXFLAG "/arch:AVX" GROMACS_CXX_FLAGS)
775         endif (NOT GNU_AVX_CXXFLAG)
776         if (NOT GNU_AVX_CXXFLAG AND NOT MSVC_AVX_CXXFLAG)
777             message(WARNING "No C++ AVX flag found. Consider a newer compiler, or disable AVX for much lower performance.")
778         endif (NOT GNU_AVX_CXXFLAG AND NOT MSVC_AVX_CXXFLAG)
779     endif()
780
781     # Only test the header after we have tried to add the flag for AVX support
782     check_include_file(immintrin.h  HAVE_IMMINTRIN_H ${GROMACS_C_FLAGS})
783
784     if(NOT HAVE_IMMINTRIN_H)
785         message(FATAL_ERROR "Cannot find immintrin.h, which is required for AVX intrinsics support. Consider switching compiler.")
786     endif(NOT HAVE_IMMINTRIN_H)
787
788     # AMD says we should include x86intrin.h for FMA support, but MSVC seems to do fine without it, so don't require it.
789     check_include_file(x86intrin.h HAVE_X86INTRIN_H ${GROMACS_C_FLAGS})
790
791     # The user should not be able to set this orthogonally to the acceleration
792     set(GMX_X86_SSE4_1 1)
793     set(GMX_X86_SSE2   1)
794
795     # But just enable one of the choices internally...
796     if(${GMX_ACCELERATION} STREQUAL "AVX_128_FMA")
797         set(GMX_X86_AVX_128_FMA 1)
798         if (NOT ACCELERATION_QUIETLY)
799           message(STATUS "Enabling 128-bit AVX Gromacs acceleration (with fused-multiply add), and it will help compiler optimization.")
800         endif()
801     else()
802         # If we are not doing AVX_128, it must be AVX_256...
803         set(GMX_X86_AVX_256 1)
804         if (NOT ACCELERATION_QUIETLY)
805           message(STATUS "Enabling 256-bit AVX Gromacs acceleration, and it will help compiler optimization.")
806         endif()
807     endif()
808
809 elseif(${GMX_ACCELERATION} STREQUAL "FORTRAN")
810
811 #    Fortran is temporarily disabled while we push in nbNxN kernels.
812 #    We need to fake it a bit here to avoid jenkins build errors!
813 #    add_definitions(-DGMX_FORTRAN)
814
815 elseif(${GMX_ACCELERATION} STREQUAL "BLUEGENE")
816 # GMX_ACCELERATION=BlueGene should be set in the Toolchain-BlueGene?-???.cmake file
817     if (NOT ACCELERATION_QUIETLY)
818       message(STATUS "Configuring for BlueGene")
819     endif()
820     set(GMX_BLUEGENE 1)
821     if (${CMAKE_SYSTEM_NAME} STREQUAL "BlueGeneL")
822         set(SHARED_LIBS_DEFAULT OFF CACHE BOOL "Shared libraries not compatible with BlueGene/L, disabled!" FORCE)
823         set(BUILD_SHARED_LIBS OFF CACHE BOOL "Shared libraries not compatible with BlueGene/L, disabled!" FORCE)
824     endif (${CMAKE_SYSTEM_NAME} STREQUAL "BlueGeneL")
825     set(GMX_SOFTWARE_INVSQRT OFF CACHE BOOL "Do not use software reciprocal square root on BlueGene" FORCE)
826     set(GMX_POWERPC_INVSQRT ON CACHE BOOL "Use hardware reciprocal square root on BlueGene" FORCE)
827     set(GMX_X11 OFF CACHE BOOL "X11 not compatible with BlueGene, disabled!" FORCE)
828     set(GMX_THREAD_MPI OFF CACHE BOOL "Thread-MPI not compatible with BlueGene, disabled!" FORCE)
829     set(GMX_MPI ON CACHE BOOL "Use MPI on BlueGene" FORCE)
830 # Access to /etc/passwd is not available on the back end of BlueGene,
831 # despite being detected by CMake. This can cause linker warnings
832 # about harmless things in src/gmxlib/string2.h.
833     set(HAVE_PWD_H OFF)
834 # The automatic testing for endianness does not work for the BlueGene cross-compiler
835     set(GMX_IEEE754_BIG_ENDIAN_BYTE_ORDER 1 CACHE INTERNAL "BlueGene has big endian FP byte order (by default)" FORCE)
836     set(GMX_IEEE754_BIG_ENDIAN_WORD_ORDER 1 CACHE INTERNAL "BlueGene has big endian FP word order (by default)" FORCE)
837 elseif(${GMX_ACCELERATION} STREQUAL "POWER6")
838     set(GMX_POWER6 1)
839     set(GMX_SOFTWARE_INVSQRT OFF CACHE BOOL "Do not use software reciprocal square root on Power6" FORCE)
840     set(GMX_POWERPC_INVSQRT ON CACHE BOOL "Use hardware reciprocal square root on Power6" FORCE)
841 else(${GMX_ACCELERATION} STREQUAL "NONE")
842     MESSAGE(FATAL_ERROR "Unrecognized option for accelerated kernels: ${GMX_ACCELERATION}. Pick one of None, SSE2, SSE4.1, AVX_128_FMA, AVX_256, Fortran, BlueGene, Power6")
843 endif(${GMX_ACCELERATION} STREQUAL "NONE")
844 set(ACCELERATION_QUIETLY TRUE CACHE INTERNAL "")
845
846 if(GMX_FORTRAN OR GMX_POWER6)
847     if (GMX_THREAD_MPI)
848         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).")
849     endif(GMX_THREAD_MPI)
850     enable_language(Fortran)
851     include(FortranCInterface)
852     discover_fortran_mangling(prefix isupper suffix extra_under_score found)
853     if(extra_under_score)
854         set(extrasuffix "_")
855     endif(extra_under_score)
856     if(prefix)
857       set(prefix "${prefix} ##")
858     endif(prefix)
859     if(suffix)
860       set(suffix "## ${suffix}")
861       if(extrasuffix)
862         set(extrasuffix "${suffix}${extrasuffix}")
863       endif(extrasuffix)
864     else(suffix)
865       if(extrasuffix)
866         # Don't know if this is needed, but it can't hurt
867         set(extrasuffix "## ${extrasuffix}")
868       endif(extrasuffix)
869     endif(suffix)
870
871     if(isupper)
872         set(F77_FUNCDEF   "${prefix} NAME ${suffix}")
873         set(F77_FUNCDEF_  "${prefix} NAME ${extrasuffix}")
874     else(isupper)
875         set(F77_FUNCDEF   "${prefix} name ${suffix}")
876         set(F77_FUNCDEF_  "${prefix} name ${extrasuffix}")
877     endif(isupper)
878 else(GMX_FORTRAN OR GMX_POWER6)
879         set(F77_FUNCDEF   "name ## _")
880         set(F77_FUNCDEF_  "name ## _")
881 endif(GMX_FORTRAN OR GMX_POWER6)
882
883 # Process QM/MM Settings
884 string(TOUPPER ${GMX_QMMM_PROGRAM} ${GMX_QMMM_PROGRAM})
885 if(${GMX_QMMM_PROGRAM} STREQUAL "GAUSSIAN")
886     set(GMX_QMMM_GAUSSIAN 1)
887 elseif(${GMX_QMMM_PROGRAM} STREQUAL "MOPAC")
888     set(GMX_QMMM_MOPAC 1)
889 elseif(${GMX_QMMM_PROGRAM} STREQUAL "GAMESS")
890     set(GMX_QMMM_GAMESS 1)
891 elseif(${GMX_QMMM_PROGRAM} STREQUAL "ORCA")
892     set(GMX_QMMM_ORCA 1)
893 elseif(${GMX_QMMM_PROGRAM} STREQUAL "NONE")
894     # nothing to do
895 else(${GMX_QMMM_PROGRAM} STREQUAL "GAUSSIAN")
896     MESSAGE(FATAL_ERROR "Invalid QM/MM program option: ${GMX_QMMM_PROGRAM}. Choose one of: Gaussian, Mopac, Gamess, Orca, None")
897 endif(${GMX_QMMM_PROGRAM} STREQUAL "GAUSSIAN")
898
899 # Process FFT library settings - if not OpenMM build 
900 string(TOUPPER ${GMX_FFT_LIBRARY} ${GMX_FFT_LIBRARY})
901 set(PKG_FFT "")
902 set(PKG_FFT_LIBS "")
903 if(${GMX_FFT_LIBRARY} STREQUAL "FFTW3")
904     if(GMX_DOUBLE)
905         find_package(FFTW 3 COMPONENTS fftw)
906     else(GMX_DOUBLE)
907         find_package(FFTW 3 COMPONENTS fftwf)
908     endif(GMX_DOUBLE)
909     if(NOT FFTW_FOUND)
910       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)!")
911     endif(NOT FFTW_FOUND)
912     include_directories(${FFTW_INCLUDE_DIRS})
913     set(FFT_LIBRARIES ${FFTW_LIBRARIES})
914     set(PKG_FFT "${FFTW_PKG}")
915
916     set(GMX_FFT_FFTW3 1)
917
918     if (${GMX_ACCELERATION} STREQUAL "SSE" AND NOT FFTW_HAVE_SSE)
919       message(WARNING "The fftw library found is compiled without SSE support, which makes it slow. Consider recompiling it or contact your admin")
920     endif (${GMX_ACCELERATION} STREQUAL "SSE" AND NOT FFTW_HAVE_SSE)
921
922 elseif(${GMX_FFT_LIBRARY} STREQUAL "MKL")
923 #    MESSAGE(STATUS "Using external FFT library - Intel MKL")
924     find_package(MKL REQUIRED)
925     include_directories(${MKL_INCLUDE_DIR})
926     set(FFT_LIBRARIES ${MKL_LIBRARIES})
927     set(PKG_FFT_LIBS ${MKL_LIBRARIES})
928
929     set(GMX_FFT_MKL 1)
930     set(HAVE_MKL 1)
931
932 #elseif(${GMX_FFT_LIBRARY} STREQUAL "ACML")
933 #    MESSAGE(STATUS "Using external FFT library - AMD core math library")
934 #    set(GMX_FFT_ACML 1)
935 elseif(${GMX_FFT_LIBRARY} STREQUAL "FFTPACK")
936     MESSAGE(STATUS "Using internal FFT library - fftpack")
937     set(GMX_FFT_FFTPACK 1)
938 else(${GMX_FFT_LIBRARY} STREQUAL "FFTW3")
939     MESSAGE(FATAL_ERROR "Invalid FFT library setting: ${GMX_FFT_LIBRARY}. Choose one of: fftw3, mkl, fftpack")
940 endif(${GMX_FFT_LIBRARY} STREQUAL "FFTW3")
941
942 # enable threaded fftw3 if we've found it 
943 if(FFTW3_THREADS OR FFTW3F_THREADS)
944     add_definitions(-DFFT5D_FFTW_THREADS)
945 endif()
946
947 set(GMX_EXTERNAL_BLAS TRUE CACHE BOOL "Use external BLAS instead of built-in")
948 set(GMX_EXTERNAL_LAPACK TRUE CACHE BOOL "Use external LAPACK instead of built-in")
949 # MKL has BLAS/LAPACK routines
950 if(NOT HAVE_MKL AND NOT ACCELERATE_FRAMEWORK)
951   if(GMX_EXTERNAL_BLAS)
952     if (GMX_BLAS_USER)
953         list(APPEND GMX_EXTRA_LIBRARIES ${GMX_BLAS_USER})
954     else(GMX_BLAS_USER)
955         set(BLAS_FIND_QUIETLY ON)
956         find_package(BLAS)
957         if (BLAS_FOUND)
958           list(APPEND GMX_EXTRA_LIBRARIES ${BLAS_LIBRARIES})
959         else()
960           MESSAGE(STATUS "Using internal BLAS library")
961           set(GMX_EXTERNAL_BLAS FALSE CACHE BOOL "Use external BLAS instead of built-in" FORCE)
962         endif()
963     endif(GMX_BLAS_USER)
964   endif(GMX_EXTERNAL_BLAS)
965   if(GMX_EXTERNAL_LAPACK)
966     if (GMX_LAPACK_USER)
967         list(APPEND GMX_EXTRA_LIBRARIES ${GMX_LAPACK_USER})
968     else(GMX_LAPACK_USER)
969         set(LAPACK_FIND_QUIETLY ON)
970         find_package(LAPACK)
971         if (LAPACK_FOUND)
972           list(APPEND GMX_EXTRA_LIBRARIES ${LAPACK_LIBRARIES})
973         else()
974           MESSAGE(STATUS "Using internal LAPACK library")
975           set(GMX_EXTERNAL_LAPACK FALSE CACHE BOOL "Use external LAPACK instead of built-in" FORCE)
976         endif()
977     endif(GMX_LAPACK_USER)
978   endif(GMX_EXTERNAL_LAPACK)
979 endif()
980 mark_as_advanced(GMX_EXTERNAL_LAPACK)
981 mark_as_advanced(GMX_EXTERNAL_BLAS)
982
983 set(GMX_USE_PLUGINS OFF CACHE INTERNAL "Whether GROMACS will really try to compile support for VMD plugins")
984
985 if(GMX_LOAD_PLUGINS)
986   if(CYGWIN OR NOT WIN32)
987     # Native Windows does not have, nor need dlopen
988     # Note that WIN32 is set with Cygwin, but Cygwin needs dlopen to use plug-ins
989     include(gmxTestdlopen)
990     gmx_test_dlopen(HAVE_DLOPEN)
991   endif()
992
993   # so, should we use plug-ins?
994   if((WIN32 AND NOT CYGWIN) OR (HAVE_DLOPEN AND BUILD_SHARED_LIBS))
995     if(NOT VMD_QUIETLY)
996       MESSAGE(STATUS
997           "Found the ability to use plug-ins when building shared libaries, "
998           "so will compile to use plug-ins (e.g. to read VMD-supported file "
999           "formats).")
1000     endif()
1001     if(NOT GMX_VMD_PLUGIN_PATH)
1002       find_package(VMD)
1003     endif()
1004     set(GMX_USE_PLUGINS ON)
1005     list(APPEND GMX_EXTRA_LIBRARIES ${CMAKE_DL_LIBS}) # magic cross-platform pre-set variable for dlopen library
1006     set(PKG_DL_LIBS "-l${CMAKE_DL_LIBS}")
1007   else()
1008     set(PKG_DL_LIBS)
1009   endif()
1010 endif(GMX_LOAD_PLUGINS)
1011 set(VMD_QUIETLY TRUE CACHE INTERNAL "")
1012
1013 if(EXISTS "${CMAKE_SOURCE_DIR}/admin/.isreposource")
1014     if(NOT CMAKE_CROSSCOMPILING)
1015         option(GMX_BUILD_MANPAGES "Build man pages" ON)
1016     else()
1017         message(STATUS "Building the man pages is not available when "
1018             "cross-compiling the developer version from git")
1019     endif()
1020 else()
1021     #make sure source package contains all man pages
1022     if(NOT EXISTS "${CMAKE_SOURCE_DIR}/man/man1/ngmx.1")
1023         message(FATAL_ERROR "Man pages are missing from source package.")
1024     endif()
1025 endif()
1026 mark_as_advanced(GMX_BUILD_MANPAGES)
1027
1028 # Math and thread libraries must often come after all others when linking...
1029 if(HAVE_LIBM)
1030     list(APPEND GMX_EXTRA_LIBRARIES m)
1031 endif(HAVE_LIBM)
1032
1033 if(GMX_FAHCORE)
1034   set(COREWRAP_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/../corewrap" CACHE STRING 
1035       "Path to swindirect.h")
1036   include_directories(${COREWRAP_INCLUDE_DIR})
1037 endif(GMX_FAHCORE)
1038
1039 # # # # # # # # # # NO MORE TESTS AFTER THIS LINE! # # # # # # # # # # #
1040 # these are set after everything else
1041 if (NOT DEFINED GROMACS_C_FLAGS_SET)
1042     set(GROMACS_C_FLAGS_SET true CACHE INTERNAL "Whether to reset the C flags" 
1043         FORCE)
1044     set(CMAKE_C_FLAGS "${GROMACS_C_FLAGS} ${CMAKE_C_FLAGS}" CACHE STRING 
1045         "Flags used by the compiler during all build types" FORCE)
1046     if (CMAKE_CXX_COMPILER_LOADED)
1047         set(CMAKE_CXX_FLAGS "${GROMACS_CXX_FLAGS} ${CMAKE_CXX_FLAGS}" CACHE STRING 
1048             "Flags used by the compiler during all build types" FORCE)
1049     endif()
1050     set(CMAKE_EXE_LINKER_FLAGS 
1051         "${GROMACS_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}" 
1052         CACHE STRING "Linker flags for creating executables" FORCE) 
1053     set(CMAKE_SHARED_LINKER_FLAGS 
1054         "${GROMACS_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS}" 
1055         CACHE STRING "Linker flags for creating shared libraries" FORCE) 
1056 endif (NOT DEFINED GROMACS_C_FLAGS_SET)
1057
1058 ######################################
1059 # Output compiler and CFLAGS used
1060 ######################################
1061 execute_process(COMMAND ${CMAKE_C_COMPILER} --version RESULT_VARIABLE TMP_RESULT OUTPUT_VARIABLE CC_VERSION ERROR_VARIABLE CC_VERSION)
1062 #try executing just the compiler command if that failed...
1063 if(TMP_RESULT)
1064     execute_process(COMMAND ${CMAKE_C_COMPILER} RESULT_VARIABLE TMP_RESULT OUTPUT_VARIABLE CC_VERSION ERROR_VARIABLE CC_VERSION)
1065 endif()
1066 string(LENGTH "${CC_VERSION}" len)
1067 if(len)
1068     string(REGEX MATCH "[^\n]*" CC_VERSION "${CC_VERSION}")
1069 endif()
1070
1071 set(BUILD_COMPILER "@CMAKE_C_COMPILER@ @CMAKE_C_COMPILER_ID@ @CC_VERSION@")
1072 set(BUILD_CFLAGS "@CMAKE_C_FLAGS@")
1073 if(CMAKE_BUILD_TYPE STREQUAL "Debug")
1074     set(BUILD_CFLAGS "@BUILD_CFLAGS@ @CMAKE_C_FLAGS_DEBUG@")
1075 elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
1076     set(BUILD_CFLAGS "@BUILD_CFLAGS@ @CMAKE_C_FLAGS_RELEASE@")
1077 elseif(CMAKE_BUILD_TYPE STREQUAL "MinSizeRel")
1078     set(BUILD_CFLAGS "@BUILD_CFLAGS@ @CMAKE_C_FLAGS_MINSIZEREL@")
1079 elseif(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
1080     set(BUILD_CFLAGS "@BUILD_CFLAGS@ @CMAKE_C_FLAGS_RELWITHDEBINFO@")
1081 endif()
1082
1083
1084 ########################################################################
1085 # Specify install locations and which subdirectories to process        #
1086 ########################################################################
1087 if (GMX_USE_RELATIVE_INSTALL_PATH)
1088     set(GMX_INSTALL_PREFIX "" CACHE STRING "Prefix gets appended to CMAKE_INSTALL_PREFIX. For cpack it sets the root folder of the archive.")
1089     mark_as_advanced(GMX_INSTALL_PREFIX)
1090 else()
1091     set(GMX_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/")
1092 endif()
1093
1094 if ( NOT DEFINED GMXLIB )
1095     set(GMXLIB lib)
1096 endif()
1097 set(LIB_INSTALL_DIR "${GMX_INSTALL_PREFIX}${GMXLIB}")
1098 set(BIN_INSTALL_DIR  ${GMX_INSTALL_PREFIX}bin)
1099 set(DATA_INSTALL_DIR ${GMX_INSTALL_PREFIX}share/gromacs)
1100 set(MAN_INSTALL_DIR  ${GMX_INSTALL_PREFIX}share/man)
1101 set(INCL_INSTALL_DIR ${GMX_INSTALL_PREFIX}include)
1102
1103 set(GMXLIBDIR        ${DATA_INSTALL_DIR}/top)
1104
1105 ##################################################################
1106 # Shared library settings - Darwin uses INSTALL_NAME_DIR instead!
1107 ##################################################################
1108 if(NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin")
1109     set(CMAKE_SKIP_BUILD_RPATH  FALSE)
1110     set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
1111     set(CMAKE_INSTALL_RPATH "\\\$ORIGIN/../${GMXLIB}")
1112     set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
1113 endif()
1114
1115 add_subdirectory(share)
1116 add_subdirectory(include)
1117 add_subdirectory(src)
1118 add_subdirectory(scripts)
1119
1120 #######################
1121 ## uninstall target
1122 #######################
1123     CONFIGURE_FILE(
1124                    "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
1125                    "${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake"
1126                    IMMEDIATE @ONLY)
1127 ###########################
1128 ADD_CUSTOM_TARGET(uninstall
1129                   "${CMAKE_COMMAND}" -P 
1130                   "${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake")
1131 ###########################
1132
1133
1134 ########################################################################
1135 # Tests                                                                #
1136 ########################################################################
1137
1138 include(CTest)
1139 mark_as_advanced(BUILD_TESTING)
1140 IF(BUILD_TESTING)
1141         enable_testing()
1142         add_subdirectory(tests)
1143 ENDIF()
1144