From c6a675bfaa4de32277245c72ba0a5df4f4603e74 Mon Sep 17 00:00:00 2001 From: Teemu Murtola Date: Sun, 6 Jul 2014 06:51:04 +0300 Subject: [PATCH] Use native CMake mechanism for find_package(GROMACS) Instead of various detection stuff that only worked well in the presence of pkg-config, use native CMake mechanisms: package configuration files and automatic export of library import definitions. Include directories and preprocessor macros influencing the installed headers are still propagated separately. The new mechanism also works for arbitrary suffixes, and is relocatable (as long as external libraries that GROMACS links against are not moved). A simple FindGROMACS.cmake is still there to hide some of the complexity to support multiple suffixes, but it is not strictly necessary if the using code wants to do those slightly more complex find_package() invocations directly. Generalize the machinery that populated libgromacs.pc to use it also for this purpose. TODO for later (requires changes that are better done outside this patch): - Improve the versioning logic The machinery and its current limitations are documented in the Doxygen page on using GROMACS as a library. Some of these could possibly be improved with additional effort, but the current approach is hopefully a reasonable compromise between usability, robustness, and complexity. Closes #1430, #1554 Change-Id: I49c50375a5abebfe8614704c175e6ed22c9daa56 --- CMakeLists.txt | 35 ++-- cmake/gmxManageMPI.cmake | 1 - cmake/gmxManageSharedLibraries.cmake | 5 +- cmake/gmxManageSuffixes.cmake | 3 + doxygen/usinglibrary.md | 139 ++++++++++++++- install-guide/install-guide.md | 7 + scripts/GMXRC.bash.cmakein | 4 +- scripts/GMXRC.csh.cmakein | 1 + share/template/CMakeLists.txt | 8 +- share/template/CMakeLists.txt.template | 66 ++++--- share/template/cmake/FindGROMACS.cmake | 75 ++++++++ share/template/cmake/FindGROMACS.cmakein | 161 ------------------ src/gromacs/CMakeLists.txt | 12 +- src/gromacs/InstallLibInfo.cmake | 99 +++++++++++ .../gromacs-config-version.cmake.cmakein | 45 +++++ src/gromacs/gromacs-config.cmake.cmakein | 130 ++++++++++++++ src/gromacs/libgromacs.pc.cmakein | 3 +- 17 files changed, 563 insertions(+), 231 deletions(-) create mode 100644 share/template/cmake/FindGROMACS.cmake delete mode 100644 share/template/cmake/FindGROMACS.cmakein create mode 100644 src/gromacs/InstallLibInfo.cmake create mode 100644 src/gromacs/gromacs-config-version.cmake.cmakein create mode 100644 src/gromacs/gromacs-config.cmake.cmakein diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f5678f58d..964612afad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -117,6 +117,10 @@ set(MEMORYCHECK_SUPPRESSIONS_FILE "File that contains suppressions for the memory checker") include(CTest) +# Variables that accumulate stuff influencing the installed headers +set(INSTALLED_HEADER_INCLUDE_DIRS "") +set(INSTALLED_HEADER_DEFINITIONS "") + ######################################################################## # Check and warn if cache generated on a different host is being reused ######################################################################## @@ -298,14 +302,12 @@ if(GMX_SIMD STREQUAL "AVX_256" endif() - -set(PKG_CFLAGS "") if(GMX_DOUBLE) add_definitions(-DGMX_DOUBLE) - set(PKG_CFLAGS "${PKG_CFLAGS} -DGMX_DOUBLE") + list(APPEND INSTALLED_HEADER_DEFINITIONS "-DGMX_DOUBLE") endif() if(GMX_SOFTWARE_INVSQRT) - set(PKG_CFLAGS "${PKG_CFLAGS} -DGMX_SOFTWARE_INVSQRT") + list(APPEND INSTALLED_HEADER_DEFINITIONS "-DGMX_SOFTWARE_INVSQRT") endif() if(WIN32 AND NOT CYGWIN) @@ -714,7 +716,6 @@ else() set(GMX_EXE_LINKER_FLAGS ${GMX_EXE_LINKER_FLAGS} ${OpenMP_LINKER_FLAGS}) set(GMX_SHARED_LINKER_FLAGS ${GMX_SHARED_LINKER_FLAGS} ${OpenMP_SHARED_LINKER_FLAGS}) endif() -set(PKG_CFLAGS "${PKG_CFLAGS} ${OpenMP_C_FLAGS}") ######################################################################## # Specify install locations @@ -731,17 +732,24 @@ mark_as_advanced(GMX_LIB_INSTALL_DIR GMX_DATA_INSTALL_DIR) # These variables are used internally to provide a central location for # customizing the install locations. -set(LIB_INSTALL_DIR ${GMX_LIB_INSTALL_DIR}) -set(BIN_INSTALL_DIR bin) -set(DATA_INSTALL_DIR share/${GMX_DATA_INSTALL_DIR}) -set(MAN_INSTALL_DIR share/man) -set(INCL_INSTALL_DIR include) +set(LIB_INSTALL_DIR ${GMX_LIB_INSTALL_DIR}) +set(BIN_INSTALL_DIR bin) +set(DATA_INSTALL_DIR share/${GMX_DATA_INSTALL_DIR}) +set(MAN_INSTALL_DIR share/man) +# If the nesting level wrt. the installation root is changed, +# gromacs-config.cmake.cmakein needs to be adapted. +set(CMAKE_INSTALL_DIR share/cmake) +# TODO: Make GMXRC adapt if this is changed +set(PKGCONFIG_INSTALL_DIR ${LIB_INSTALL_DIR}/pkgconfig) +set(INCL_INSTALL_DIR include) # These variables get written into config.h for use in finding the data # directories. set(GMXLIB_SEARCH_DIR share/${GMX_DATA_INSTALL_DIR}/top) set(GMXLIB_FALLBACK ${CMAKE_INSTALL_PREFIX}/${DATA_INSTALL_DIR}/top) +list(APPEND INSTALLED_HEADER_INCLUDE_DIRS ${INCL_INSTALL_DIR}) + # Binary and library suffix options include(gmxManageSuffixes) @@ -787,15 +795,14 @@ install(FILES COPYING DESTINATION ${DATA_INSTALL_DIR} COMPONENT data) if(GMX_EXTERNAL_BOOST) include_directories(${Boost_INCLUDE_DIRS}) - set(PKG_CFLAGS "${PKG_CFLAGS} -I${Boost_INCLUDE_DIRS}") + list(APPEND INSTALLED_HEADER_INCLUDE_DIRS ${Boost_INCLUDE_DIRS}) else() include_directories(BEFORE ${CMAKE_SOURCE_DIR}/src/external/boost) + list(APPEND INSTALLED_HEADER_INCLUDE_DIRS ${INCL_INSTALL_DIR}/gromacs/external/boost) + list(APPEND INSTALLED_HEADED_DEFINITIONS "-DBOOST_NO_TYPEID") # typeid not supported for minimal internal version # (would add significant amount of code) add_definitions(-DBOOST_NO_TYPEID) - # TODO: Propagate the above settings to the installed CMakeFiles.txt template - # (from share/template/) - set(PKG_CFLAGS "${PKG_CFLAGS} -DBOOST_NO_TYPEID -I${CMAKE_INSTALL_PREFIX}/${INCL_INSTALL_DIR}/gromacs/external/boost") if (NOT GMX_BUILD_MDRUN_ONLY) install(DIRECTORY ${CMAKE_SOURCE_DIR}/src/external/boost/boost DESTINATION ${INCL_INSTALL_DIR}/gromacs/external/boost diff --git a/cmake/gmxManageMPI.cmake b/cmake/gmxManageMPI.cmake index 5adc2627cd..5b35e0d644 100644 --- a/cmake/gmxManageMPI.cmake +++ b/cmake/gmxManageMPI.cmake @@ -162,5 +162,4 @@ if(GMX_MPI) endif() set(GMX_LIB_MPI 1) - set(PKG_CFLAGS "${PKG_CFLAGS} -DGMX_LIB_MPI") endif() diff --git a/cmake/gmxManageSharedLibraries.cmake b/cmake/gmxManageSharedLibraries.cmake index fced521e95..4a83ebe35c 100644 --- a/cmake/gmxManageSharedLibraries.cmake +++ b/cmake/gmxManageSharedLibraries.cmake @@ -123,8 +123,9 @@ IF( WIN32 AND NOT CYGWIN) #this combination segfaults (illegal passing of file handles) message(FATAL_ERROR "Static system libraries requested, and shared Gromacs libraries requested.") endif() - add_definitions(-DUSE_VISIBILITY -DTMPI_USE_VISIBILITY) - set(PKG_CFLAGS "$PKG_CFLAGS -DUSE_VISIBILITY -DTMPI_USE_VISIBILITY") + # Visibility not yet implemented + # add_definitions(-DUSE_VISIBILITY -DTMPI_USE_VISIBILITY) + # set(PKG_CFLAGS "$PKG_CFLAGS -DUSE_VISIBILITY -DTMPI_USE_VISIBILITY") endif() IF (GMX_PREFER_STATIC_LIBS) diff --git a/cmake/gmxManageSuffixes.cmake b/cmake/gmxManageSuffixes.cmake index 6d4eb672e0..1783f7f20d 100644 --- a/cmake/gmxManageSuffixes.cmake +++ b/cmake/gmxManageSuffixes.cmake @@ -68,6 +68,9 @@ if (GMX_DEFAULT_SUFFIX) message(STATUS "Using default library suffix: \"${GMX_LIBS_SUFFIX}\"") endif() else() + if ("${GMX_LIBS_SUFFIX}" MATCHES "^_mdrun") + message(FATAL_ERROR "Library suffix (GMX_LIBS_SUFFIX) cannot start with '_mdrun', as that is reserved for internal use") + endif() gmx_check_if_changed(SUFFIXES_CHANGED GMX_DEFAULT_SUFFIX GMX_BINARY_SUFFIX GMX_LIBS_SUFFIX) if (SUFFIXES_CHANGED) diff --git a/doxygen/usinglibrary.md b/doxygen/usinglibrary.md index 7419b5dcd4..8afcb715df 100644 --- a/doxygen/usinglibrary.md +++ b/doxygen/usinglibrary.md @@ -4,9 +4,6 @@ Using \Gromacs as a library {#page_usinglibrary} Getting started =============== -\todo -Describe how to link against \Gromacs (pkg-config, FindGromacs.cmake, etc.) - The \Gromacs library (`libgromacs`) provides a few different alternatives for using it. These are listed here from the highest level of abstraction to the low-level functions. @@ -51,6 +48,142 @@ think that it would be easy to expose, please drop a line on the `gmx-developers` mailing list, or contribute the necessary changes on http://gerrit.gromacs.org/. +Linking against `libgromacs` +============================ + +\Gromacs is a bit picky on how the headers need to be used: depending on +compilation options used for \Gromacs, some preprocessor defines may need to be +set, the required include path may also depend on compilation options, and some +extra libraries may need to be linked. You will also likely need to use the +same compiler (or sufficiently similar one that uses the same standard library) +that was used to compile \Gromacs. + +To manage this more easily, \Gromacs provides two mechanisms for getting the +correct flags for compilation and linking against the \Gromacs library: + - `pkg-config`: \Gromacs installs `libgromacs.pc` file (suffixed with the + library suffix) for use with `pkg-config` if that is present on the system. + Sourcing `GMXRC` adjusts the `pkg-config` search path such that these files + are found automatically. + See `Makefile.pkg` installed with the analysis template for one example of + how to use it (to use it with a differently suffixed \Gromacs, just replace + `libgromacs` with `libgromacs`_suffix in the `pkg-config` calls). + - CMake package configuration files and a find module that allow + `find_package(GROMACS)` to work. See below for details about how to use + this in CMake. Sourcing `GMXRC` sets an environment variable that allows + CMake to find the configuration file automatically. + See `CMakeLists.txt` installed with the analysis template for one example of + how to use it. + +These mechanisms are currently provided on a best-effort basis, but are not +routinely tested on a wide range of configurations. Please report any issues +with details of how \Gromacs was built so that the mechanism can be improved. +Known issues: + - `pkg-config` files are not relocatable, i.e., they hard-code the + installation prefix as an absolute path. + - Installing both static and shared libraries with the same suffix to the same + installation prefix is guaranteed to work only if both are built with + exactly the same configuration options (except for `BUILD_SHARED_LIBS`) from + exactly the same version. There are several files that are shared between + the installations in such a case, and the latter installation will overwrite + those from the former. + - Further, if both static and shared libraries have been installed in the past + to a prefix, then future installations to the same prefix should also + install both static and shared libraries. Otherwise, some obsolete CMake + package configuration files will be left behind which can lead to finding + the old library. Alternatively, you can delete `share/cmake/` from the + installation directory before doing the install. + - If a mechanism other than the CMake-generated `install` target is used to + install \Gromacs over an existing installation, and the build type (e.g., + Release vs.\ Debug) does not match what was previously installed, some + obsolete CMake import target definition files are left behind in + `share/cmake/`, and may cause failures whey trying to use the package + configuration files. + - If \Gromacs is built with `GMX_BUILD_OWN_FFTW=ON`, the CMake-generated + import definitions for `libgromacs` reference a `gmxfftw` target that was + used in the build to reference the `fftw` library. As this library only + exists in the \Gromacs build tree, and the CMake machinery does not write + any import definitions for it anywhere, linking will fail with errors about + not being able to find a `gmxfftw` library. So the CMake package + configuration files can only be used with `GMX_BUILD_OWN_FFTW=OFF`. + +CMake `find_package(GROMACS)` details +------------------------------------- + +The CMake machinery to support `find_package(GROMACS)` has two parts: a +`FindGROMACS.cmake` find module (found in `share/gromacs/template/cmake/` in +the installation and `share/template/cmake/` in the source tree), and actual +package configuration files (`gromacs-config.cmake` and supporting files +installed to `share/cmake/` from input files in `src/gromacs/`). + +`FindGROMACS.cmake` is a simple wrapper over the package configuration files, +providing a somewhat more convenient interface to the machinery that supports +multiple suffixed \Gromacs installations in the same installation prefix (see +`GROMACS_SUFFIX` variable below). This file is intended to be version-agnostic +and remain both forward- and backward-compatible even between major \Gromacs +releases. All version-specific information and the actual details about the +compilation and linking settings is in the package configuration files. +Build systems willing to utilize `FindGROMACS.cmake` can create a local copy of +it and use it like it is used in the installed +`share/gromacs/template/CMakeLists.txt`. +The package configuration files can also be used directly if desired, bypassing +`FindGROMACS.cmake`. + +Input options for influencing what to find: + +
+
`GROMACS_SUFFIX` (only for `FindGROMACS.cmake`)
+
This CMake variable can be set before calling `find_package(GROMACS)` to +specify the \Gromacs suffix to search for. If not set, an unsuffixed version +is searched for. If using the package configuration files directly, the suffix +must be set using `find_package(GROMACS NAMES gromacs)`.
+
`GROMACS_PREFER_STATIC`
+
This CMake variable can be set before calling `find_package(GROMACS)` to +specify whether static or shared libraries are preferred if both are available. +It does not affect which \Gromacs installation is chosen, but if that +installation has both static and shared libraries available (installed from two +different builds with the same suffix), then this chooses the library to be +returned in `GROMACS_LIBRARIES`.
+
`GROMACS_DIR`
+
This CMake (cache) variable is a standard mechanism provided by +`find_package`, and can be used to specify a hint where to search for \Gromacs. +Also `CMAKE_PREFIX_PATH` can be used for this purpose; see CMake documentation +for `find_package` for more details. +`GROMACS_DIR` can also be set as an environment variable, and this is done by +`GMXRC`.
+
+ +Output variables that specify how the found `libgromacs` and header should be +used: + +
+
`GROMACS_INCLUDE_DIRS`
+
List of include directories necessary to compile against the \Gromacs +headers. Currently, this includes the path to \Gromacs headers, as well as the +path to Boost headers that were used to compile \Gromacs.
+
`GROMACS_LIBRARIES`
+
List of libraries to link with to link against \Gromacs. +Under the hood, this uses imported CMake targets to represent `libgromacs`.
+
`GROMACS_DEFINITIONS`
+
List of compile definitions (with `-D` in front) that are required to +compile the \Gromacs headers.
+
`GROMACS_IS_DOUBLE`
+
Whether the found \Gromacs was compiled in double precision.
+
+ +Declared macros/functions that can be used for checking for correctness of some +settings: + +
+
`gromacs_check_double(GMX_DOUBLE)`
+
Checks that the found \Gromacs is in the expected precision. +The parameter `GMX_DOUBLE` should be the name of a cache variable that +specified whether double-precision was requested.
+
`gromacs_check_compiler(LANG)`
+
Checks that the found \Gromacs was compiled with the same compiler +that is used by the current CMake system. +Currently only `LANG=CXX` is supported.
+
+ Notes on \Gromacs API ===================== diff --git a/install-guide/install-guide.md b/install-guide/install-guide.md index 84481d0059..c8858a3bba 100644 --- a/install-guide/install-guide.md +++ b/install-guide/install-guide.md @@ -655,6 +655,13 @@ CMakeLists.txt. is determined by CMake. The name of the directory can be changed using `GMX_LIB_INSTALL_DIR` CMake variable. +`lib/pkgconfig/` + : Information about the installed `libgromacs` library for `pkg-config` is + installed here. The `lib/` part adapts to the installation location of the + libraries. The installed files contain the installation prefix as absolute + paths. +`share/cmake/` + : CMake package configuration files are installed here. `share/gromacs/` : Various data files and some documentation go here. The `gromacs` part can be changed using `GMX_DATA_INSTALL_DIR`. Using this diff --git a/scripts/GMXRC.bash.cmakein b/scripts/GMXRC.bash.cmakein index a7a1a0c22b..eed26cafe7 100644 --- a/scripts/GMXRC.bash.cmakein +++ b/scripts/GMXRC.bash.cmakein @@ -55,6 +55,7 @@ GMXBIN=${GMXPREFIX}/@BIN_INSTALL_DIR@ GMXLDLIB=${GMXPREFIX}/@LIB_INSTALL_DIR@ GMXMAN=${GMXPREFIX}/@MAN_INSTALL_DIR@ GMXDATA=${GMXPREFIX}/@DATA_INSTALL_DIR@ +GROMACS_DIR=${GMXPREFIX} LD_LIBRARY_PATH=${GMXLDLIB}${LD_LIBRARY_PATH:+:}${LD_LIBRARY_PATH} PKG_CONFIG_PATH=${GMXLDLIB}/pkgconfig${PKG_CONFIG_PATH:+:}${PKG_CONFIG_PATH} @@ -63,7 +64,8 @@ PATH=${GMXBIN}${PATH:+:}${PATH} MANPATH=${GMXMAN}:${MANPATH} # export should be separate, so /bin/sh understands it -export GMXBIN GMXLDLIB GMXMAN GMXDATA LD_LIBRARY_PATH PATH MANPATH PKG_CONFIG_PATH +export GMXBIN GMXLDLIB GMXMAN GMXDATA LD_LIBRARY_PATH PATH MANPATH +export PKG_CONFIG_PATH GROMACS_DIR IFS="$old_IFS" unset old_IFS diff --git a/scripts/GMXRC.csh.cmakein b/scripts/GMXRC.csh.cmakein index f22607920b..16a85df5c3 100644 --- a/scripts/GMXRC.csh.cmakein +++ b/scripts/GMXRC.csh.cmakein @@ -75,6 +75,7 @@ setenv GMXBIN ${GMXPREFIX}/@BIN_INSTALL_DIR@ setenv GMXLDLIB ${GMXPREFIX}/@LIB_INSTALL_DIR@ setenv GMXMAN ${GMXPREFIX}/@MAN_INSTALL_DIR@ setenv GMXDATA ${GMXPREFIX}/@DATA_INSTALL_DIR@ +setenv GROMACS_DIR ${GMXPREFIX} #make them begin with : if ($?LD_LIBRARY_PATH) setenv LD_LIBRARY_PATH ":${LD_LIBRARY_PATH}" diff --git a/share/template/CMakeLists.txt b/share/template/CMakeLists.txt index dbc671e398..29ef88ad49 100644 --- a/share/template/CMakeLists.txt +++ b/share/template/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of the GROMACS molecular simulation package. # -# Copyright (c) 2011,2012, by the GROMACS development team, led by +# Copyright (c) 2011,2012,2014, by the GROMACS development team, led by # Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, # and including many others, as listed in the AUTHORS file in the # top-level source directory and at http://www.gromacs.org. @@ -43,10 +43,6 @@ install(FILES README template.cpp Makefile.pkg DESTINATION ${DATA_INSTALL_DIR}/template COMPONENT development) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindGROMACS.cmakein - ${CMAKE_CURRENT_BINARY_DIR}/cmake/FindGROMACS.cmake @ONLY) - -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/cmake/FindGROMACS.cmake +install(FILES cmake/FindGROMACS.cmake DESTINATION ${DATA_INSTALL_DIR}/template/cmake COMPONENT development) - diff --git a/share/template/CMakeLists.txt.template b/share/template/CMakeLists.txt.template index 0cc6dcdfba..5d738b8d63 100644 --- a/share/template/CMakeLists.txt.template +++ b/share/template/CMakeLists.txt.template @@ -1,44 +1,42 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.8) -project(template) +project(template CXX) -# Cmake modules/macros are in a subdirectory to keep this file cleaner -set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) - -if(NOT CMAKE_BUILD_TYPE) +if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE) -endif(NOT CMAKE_BUILD_TYPE) +endif() -option(GMX_DOUBLE "Use double precision" OFF) +# CMake modules are in a subdirectory to keep this file cleaner +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) -######################################################################## -# Fix stupid flags on MSVC -######################################################################## -IF(CMAKE_GENERATOR MATCHES "Visual Studio") - STRING(REPLACE /MD /MT CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE}) - SET(CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE} CACHE STRING "" FORCE) - STRING(REPLACE /MD /MT CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG}) - SET(CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG} CACHE STRING "" FORCE) -ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio") - -######################################################################## -# Basic system tests (standard libraries, headers, functions, types) # -######################################################################## - -if (GMX_DOUBLE) - set(LIBGROMACS "libgromacs_d") -else(GMX_DOUBLE) - set(LIBGROMACS "libgromacs") -endif(GMX_DOUBLE) - -FIND_PACKAGE(GROMACS COMPONENTS ${LIBGROMACS} REQUIRED) -message("GROMACS version ${GROMACS_VERSION_STRING} found") -if ("${GROMACS_VERSION_STRING}" VERSION_LESS "5.0") - message(FATAL_ERROR "This template works with GROMACS 5.0 (and possibly later versions)") +# In principle, this could be deduced from GROMACS_IS_DOUBLE returned by +# find_package(GROMACS) based on the suffix alone, but it is clearer that the +# user explicitly sets what they want to get, and then need to provide a suffix +# to match. +option(GMX_DOUBLE "Use double precision" OFF) +set(GMX_SUFFIX "" CACHE STRING "Suffix for the GROMACS installation to use (empty for default)") + +# This does not allow for a non-suffixed double-precision libgromacs, but +# that should be rare enough for demonstration purposes. +if (GMX_DOUBLE AND NOT GMX_SUFFIX) + set(GROMACS_SUFFIX "_d") +else() + set(GROMACS_SUFFIX ${GMX_SUFFIX}) endif() -add_definitions( ${GROMACS_DEFINITIONS} ) -include_directories( ${GROMACS_INCLUDE_DIRS} ) +find_package(GROMACS 5.1 REQUIRED) +gromacs_check_double(GMX_DOUBLE) +gromacs_check_compiler(CXX) +include_directories(${GROMACS_INCLUDE_DIRS}) +add_definitions(${GROMACS_DEFINITIONS}) + +# Use static linking on MSVC +if (CMAKE_GENERATOR MATCHES "Visual Studio") + string(REPLACE /MD /MT CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE}) + set(CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE} CACHE STRING "" FORCE) + string(REPLACE /MD /MT CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG}) + set(CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG} CACHE STRING "" FORCE) +endif() add_executable(template template.cpp) target_link_libraries(template ${GROMACS_LIBRARIES}) diff --git a/share/template/cmake/FindGROMACS.cmake b/share/template/cmake/FindGROMACS.cmake new file mode 100644 index 0000000000..67a8a65299 --- /dev/null +++ b/share/template/cmake/FindGROMACS.cmake @@ -0,0 +1,75 @@ +# +# This file is part of the GROMACS molecular simulation package. +# +# Copyright (c) 2014, by the GROMACS development team, led by +# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, +# and including many others, as listed in the AUTHORS file in the +# top-level source directory and at http://www.gromacs.org. +# +# GROMACS is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public License +# as published by the Free Software Foundation; either version 2.1 +# of the License, or (at your option) any later version. +# +# GROMACS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with GROMACS; if not, see +# http://www.gnu.org/licenses, or write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# If you want to redistribute modifications to GROMACS, please +# consider that scientific software is very special. Version +# control is crucial - bugs must be traceable. We will be happy to +# consider code for inclusion in the official distribution, but +# derived work must not be called official GROMACS. Details are found +# in the README & COPYING files - if they are missing, get the +# official version at http://www.gromacs.org. +# +# To help us fund GROMACS development, we humbly ask that you cite +# the research papers on the package. Check out http://www.gromacs.org. + +# This file should remain version-agnostic, with all things specific to a +# particular GROMACS version remaining in the package configuration files. +# This find module only provides some convenience functionality to manage the +# suffixes etc. +# That should allow using the same FindGROMACS.cmake file with multiple +# different GROMACS installations on the same machine. + +# Propagate all flags passed to parent find_package() to the config call below. +set(_gmx_find_args "") +if (GROMACS_FIND_VERSION) + if (GROMACS_FIND_VERSION VERSION_LESS "5.1") + message(FATAL_ERROR + "This version of FindGROMACS.cmake requires GROMACS-provided " + "package configuration files, and only works to find " + "GROMACS 5.1 or later.") + endif() + list(APPEND _gmx_find_args ${GROMACS_FIND_VERSION}) + if (GROMACS_FIND_VERSION_EXACT) + list(APPEND _gmx_find_args EXACT) + endif() +endif() +if (GROMACS_FIND_REQUIRED) + list(APPEND _gmx_find_args REQUIRED) +endif() +if (GROMACS_FIND_QUIETLY) + list(APPEND _gmx_find_args QUIET) +endif() + +# Determine the actual name of the package configuration files. +set(_gmx_pkg_name gromacs) +if (DEFINED GROMACS_SUFFIX) + set(_gmx_pkg_name gromacs${GROMACS_SUFFIX}) +endif() +# Delegate all the actual work to the package configuration files. +# The CONFIGS option is not really necessary, but provides a bit better error +# messages, since we actually know what the config file should be called. +find_package(GROMACS ${_gmx_find_args} CONFIG + NAMES ${_gmx_pkg_name} + CONFIGS ${_gmx_pkg_name}-config.cmake) +unset(_gmx_find_args) +unset(_gmx_pkg_name) diff --git a/share/template/cmake/FindGROMACS.cmakein b/share/template/cmake/FindGROMACS.cmakein deleted file mode 100644 index 84a0fa6ed1..0000000000 --- a/share/template/cmake/FindGROMACS.cmakein +++ /dev/null @@ -1,161 +0,0 @@ -# -# This file is part of the GROMACS molecular simulation package. -# -# Copyright (c) 2009-2011, by the VOTCA Development Team (http://www.votca.org). -# Copyright (c) 2012,2013,2014, by the GROMACS development team, led by -# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, -# and including many others, as listed in the AUTHORS file in the -# top-level source directory and at http://www.gromacs.org. -# -# GROMACS is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public License -# as published by the Free Software Foundation; either version 2.1 -# of the License, or (at your option) any later version. -# -# GROMACS is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with GROMACS; if not, see -# http://www.gnu.org/licenses, or write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# -# If you want to redistribute modifications to GROMACS, please -# consider that scientific software is very special. Version -# control is crucial - bugs must be traceable. We will be happy to -# consider code for inclusion in the official distribution, but -# derived work must not be called official GROMACS. Details are found -# in the README & COPYING files - if they are missing, get the -# official version at http://www.gromacs.org. -# -# To help us fund GROMACS development, we humbly ask that you cite -# the research papers on the package. Check out http://www.gromacs.org. - -# - Finds parts of GROMACS -# Find the native GROMACS components headers and libraries. -# -# GROMACS_INCLUDE_DIRS - where to find GROMACS headers. -# GROMACS_LIBRARIES - List of libraries when used by GROMACS. -# GROMACS_FOUND - True if all GROMACS components were found. -# GROMACS_DEFINITIONS - Extra definies needed by GROMACS -# GROMACS_PKG - The name of the pkg-config package needed -# GROMACS_VERSION - GROMACS lib interface version -# GROMACS_MAJOR_VERSION - GROMACS lib interface major version -# GROMACS_MINOR_VERSION - GROMACS lib interface minor version -# GROMACS_PATCH_LEVEL - GROMACS lib interface patch level -# GROMACS_VERSION_STRING - GROMACS lib interface version string (e.g. "4.5.3") -# - -find_package(PkgConfig) -list(LENGTH GROMACS_FIND_COMPONENTS GROMACS_NUM_COMPONENTS_WANTED) -if(${GROMACS_NUM_COMPONENTS_WANTED} LESS 1) - message(FATAL_ERROR "find_package(GROMACS) needs to be supplied with the name of a GROMACS component for which it can search") -elseif(${GROMACS_NUM_COMPONENTS_WANTED} GREATER 1) - message(FATAL_ERROR "We only support finding one GROMACS component at this point, go and implement it ;-)") -elseif(${GROMACS_FIND_COMPONENTS} MATCHES "^lib(gmx|gromacs)(_d)?$") - set(GROMACS_PKG "${GROMACS_FIND_COMPONENTS}") - string(REGEX REPLACE "^lib(.*)" "\\1" GROMACS_LIBRARY_NAME "${GROMACS_PKG}") -else() - message(FATAL_ERROR "We do not support finding ${GROMACS_FIND_COMPONENTS}, go and implement it ;-)") -endif() - -if(GMX_DOUBLE AND NOT "${GROMACS_PKG}" MATCHES "_d$") - message(FATAL_ERROR "GMX_DOUBLE was true, but I was asked to find ${GROMACS_PKG} (without _d at the end) - illogical!") -endif(GMX_DOUBLE AND NOT "${GROMACS_PKG}" MATCHES "_d$") -if(NOT GMX_DOUBLE AND "${GROMACS_PKG}" MATCHES "_d$") - message(FATAL_ERROR "GMX_DOUBLE was false, but I was asked to find ${GROMACS_PKG} (with _d at the end) - illogical!") -endif(NOT GMX_DOUBLE AND "${GROMACS_PKG}" MATCHES "_d$") - -pkg_check_modules(PC_GROMACS ${GROMACS_PKG}) -if (GMX_DOUBLE) - list(APPEND GMX_DEFS "-DGMX_DOUBLE") -endif(GMX_DOUBLE) -if (PC_GROMACS_CFLAGS_OTHER) - foreach(DEF ${PC_GROMACS_CFLAGS_OTHER}) - if (${DEF} MATCHES "^-D") - list(APPEND GMX_DEFS ${DEF}) - endif (${DEF} MATCHES "^-D") - endforeach(DEF) - list(REMOVE_DUPLICATES GMX_DEFS) -endif (PC_GROMACS_CFLAGS_OTHER) -set(GROMACS_DEFINITIONS "${GMX_DEFS}" CACHE STRING "extra GROMACS definitions") - -find_library(GROMACS_LIBRARY NAMES ${GROMACS_LIBRARY_NAME} - HINTS ${PC_GROMACS_LIBRARY_DIRS} @CMAKE_INSTALL_PREFIX@/@LIB_INSTALL_DIR@) -if (GROMACS_LIBRARY) - if("${GROMACS_LIBRARY}" MATCHES "lib(gmx|gromacs)[^;]*\\.a") - if(PC_GROMACS_LIBRARIES) - list(REMOVE_ITEM PC_GROMACS_LIBRARIES ${GROMACS_LIBRARY_NAME}) - foreach (LIB ${PC_GROMACS_LIBRARIES}) - find_library(GROMACS_${LIB} NAMES ${LIB} - HINTS ${PC_GROMACS_LIBRARY_DIRS} @CMAKE_INSTALL_PREFIX@/@INCL_INSTALL_DIR@) - list(APPEND GMX_DEP_LIBRARIES ${GROMACS_${LIB}}) - unset(GROMACS_${LIB} CACHE) - endforeach(LIB) - endif(PC_GROMACS_LIBRARIES) - if(PC_GROMACS_CFLAGS_OTHER) - foreach(LIB ${PC_GROMACS_CFLAGS_OTHER}) - if (${LIB} MATCHES "thread") - find_package(Threads REQUIRED) - list(APPEND GMX_DEP_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) - endif (${LIB} MATCHES "thread") - endforeach(LIB) - endif(PC_GROMACS_CFLAGS_OTHER) - set(GROMACS_DEP_LIBRARIES "${GMX_DEP_LIBRARIES}" CACHE FILEPATH "GROMACS depency libs (only needed for static (.a) ${GROMACS_LIBRARY}") - endif("${GROMACS_LIBRARY}" MATCHES "lib(gmx|gromacs)[^;]*\\.a") - include(CheckLibraryExists) - check_library_exists("${GROMACS_LIBRARY};${GROMACS_DEP_LIBRARIES}" GromacsVersion "" FOUND_GROMACS_VERSION) - if(NOT FOUND_GROMACS_VERSION) - message(FATAL_ERROR "Could not find GromacsVersion in ${GROMACS_LIBRARY};${GROMACS_DEP_LIBRARIES}, take look at the error message in ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log to find out what was going wrong. If you don't have pkg-config installed you will most likely have to set GROMACS_LIBRARY and GROMACS_DEP_LIBRARY by hand which sets the GROMACS lib and its depencies (e.g. -DGROMACS_LIBRARY='/path/to/libgmx.so' -DGROMACS_DEP_LIBRARIES='/path/to/libblas.so;/path/to/libm.so') !") - endif(NOT FOUND_GROMACS_VERSION) - check_library_exists("${GROMACS_LIBRARY};${GROMACS_DEP_LIBRARIES}" init_mtop "" FOUND_GROMACS_INIT_MTOP) - if(NOT FOUND_GROMACS_INIT_MTOP) - message(FATAL_ERROR "Could not find init_mtop in the GROMACS library, take look at the error message in ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log to find out what was going wrong. This most likely means that your GROMACS version is too old, we need at least GROMACS 4.0.7.") - endif(NOT FOUND_GROMACS_INIT_MTOP) - set(GROMACS_VERSION 40000) - check_library_exists("${GROMACS_LIBRARY};${GROMACS_DEP_LIBRARIES}" output_env_done "" FOUND_GROMACS_OUTPUT_ENV_DONE) - if(FOUND_GROMACS_OUTPUT_ENV_DONE) - set(GROMACS_VERSION 40500) - endif(FOUND_GROMACS_OUTPUT_ENV_DONE) - check_library_exists("${GROMACS_LIBRARY};${GROMACS_DEP_LIBRARIES}" gmx_nonbonded_setup "" FOUND_GROMACS_GMX_NONBONDED_SETUP) - if(FOUND_GROMACS_GMX_NONBONDED_SETUP) - set(GROMACS_VERSION 40600) - endif(FOUND_GROMACS_GMX_NONBONDED_SETUP) - check_library_exists("${GROMACS_LIBRARY};${GROMACS_DEP_LIBRARIES}" init_domdec_vsites "" FOUND_GROMACS_INIT_DOMDEC_VSITES) - if(FOUND_GROMACS_INIT_DOMDEC_VSITES) - set(GROMACS_VERSION 50000) - endif(FOUND_GROMACS_INIT_DOMDEC_VSITES) - set(GROMACS_VERSION ${GROMACS_VERSION} CACHE STRING "GROMACS lib interface version") -else(GROMACS_LIBRARY) - set(GROMACS_VERSION 40500) -endif (GROMACS_LIBRARY) - -math(EXPR GROMACS_MAJOR_VERSION "${GROMACS_VERSION} / 10000") -math(EXPR GROMACS_MINOR_VERSION "${GROMACS_VERSION} / 100 % 100") -math(EXPR GROMACS_PATCH_LEVEL "${GROMACS_VERSION} % 100") -set(GROMACS_VERSION_STRING "${GROMACS_MAJOR_VERSION}.${GROMACS_MINOR_VERSION}.${GROMACS_PATCH_LEVEL}") - -if ("${GROMACS_PKG}" MATCHES "libgmx") - if (${GROMACS_VERSION} EQUAL 40000) - find_path(GROMACS_INCLUDE_DIR tpxio.h HINTS ${PC_GROMACS_INCLUDE_DIRS}) - else(${GROMACS_VERSION} EQUAL 40000) - find_path(GROMACS_INCLUDE_DIR gromacs/tpxio.h HINTS ${PC_GROMACS_INCLUDE_DIRS}) - endif(${GROMACS_VERSION} EQUAL 40000) -elseif("${GROMACS_PKG}" MATCHES "libgromacs") - find_path(GROMACS_INCLUDE_DIR gromacs/version.h HINTS ${PC_GROMACS_INCLUDE_DIRS}) -endif("${GROMACS_PKG}" MATCHES "libgmx") - -set(GROMACS_LIBRARIES "${GROMACS_LIBRARY};${GROMACS_DEP_LIBRARIES}" ) -set(GROMACS_INCLUDE_DIRS ${GROMACS_INCLUDE_DIR} ) -if (PC_GROMACS_INCLUDE_DIRS) - list(APPEND GROMACS_INCLUDE_DIRS ${PC_GROMACS_INCLUDE_DIRS}) -endif(PC_GROMACS_INCLUDE_DIRS) - -include(FindPackageHandleStandardArgs) -# handle the QUIETLY and REQUIRED arguments and set GROMACS_FOUND to TRUE -# if all listed variables are TRUE -find_package_handle_standard_args(GROMACS DEFAULT_MSG GROMACS_LIBRARY GROMACS_INCLUDE_DIR) - -mark_as_advanced(GROMACS_INCLUDE_DIR GROMACS_LIBRARY GROMACS_DEFINITIONS GROMACS_PKG GROMACS_VERSION GROMACS_DEP_LIBRARIES) diff --git a/src/gromacs/CMakeLists.txt b/src/gromacs/CMakeLists.txt index 21232899a2..0da72898c9 100644 --- a/src/gromacs/CMakeLists.txt +++ b/src/gromacs/CMakeLists.txt @@ -197,16 +197,14 @@ set_target_properties(libgromacs PROPERTIES # Only install the library in mdrun-only mode if it is actually necessary # for the binary if (NOT GMX_BUILD_MDRUN_ONLY OR BUILD_SHARED_LIBS) - install(TARGETS libgromacs DESTINATION ${LIB_INSTALL_DIR} COMPONENT libraries) + install(TARGETS libgromacs + EXPORT libgromacs + DESTINATION ${LIB_INSTALL_DIR} + COMPONENT libraries) endif() if (NOT GMX_BUILD_MDRUN_ONLY) - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libgromacs.pc.cmakein - ${CMAKE_CURRENT_BINARY_DIR}/libgromacs.pc @ONLY) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libgromacs.pc - DESTINATION ${LIB_INSTALL_DIR}/pkgconfig - RENAME "libgromacs${GMX_LIBS_SUFFIX}.pc" - COMPONENT development) + include(InstallLibInfo.cmake) endif() if (INSTALL_CUDART_LIB) #can be set manual by user diff --git a/src/gromacs/InstallLibInfo.cmake b/src/gromacs/InstallLibInfo.cmake new file mode 100644 index 0000000000..0635d666b3 --- /dev/null +++ b/src/gromacs/InstallLibInfo.cmake @@ -0,0 +1,99 @@ +# +# This file is part of the GROMACS molecular simulation package. +# +# Copyright (c) 2014, by the GROMACS development team, led by +# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, +# and including many others, as listed in the AUTHORS file in the +# top-level source directory and at http://www.gromacs.org. +# +# GROMACS is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public License +# as published by the Free Software Foundation; either version 2.1 +# of the License, or (at your option) any later version. +# +# GROMACS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with GROMACS; if not, see +# http://www.gnu.org/licenses, or write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# If you want to redistribute modifications to GROMACS, please +# consider that scientific software is very special. Version +# control is crucial - bugs must be traceable. We will be happy to +# consider code for inclusion in the official distribution, but +# derived work must not be called official GROMACS. Details are found +# in the README & COPYING files - if they are missing, get the +# official version at http://www.gromacs.org. +# +# To help us fund GROMACS development, we humbly ask that you cite +# the research papers on the package. Check out http://www.gromacs.org. + +function (do_pkgconfig) + set(PKG_CFLAGS "") + foreach (_dir ${INSTALLED_HEADER_INCLUDE_DIRS}) + if (IS_ABSOLUTE ${_dir}) + set(PKG_CFLAGS "${PKG_CFLAGS} -I${_dir}") + else() + set(PKG_CFLAGS "${PKG_CFLAGS} -I${CMAKE_INSTALL_PREFIX}/${_dir}") + endif() + endforeach() + if (INSTALLED_HEADER_DEFINITIONS) + foreach (_def ${INSTALLED_HEADER_DEFINITIONS}) + set(PKG_CFLAGS "${PKG_CFLAGS} ${_def}") + endforeach() + endif() + set(PKG_CFLAGS "${PKG_CFLAGS} ${OpenMP_C_FLAGS}") + + configure_file(libgromacs.pc.cmakein + libgromacs.pc @ONLY) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libgromacs.pc + DESTINATION ${PKGCONFIG_INSTALL_DIR} + RENAME "libgromacs${GMX_LIBS_SUFFIX}.pc" + COMPONENT development) +endfunction() + +function (do_cmake_config) + # Remove -dev suffix and similar, since we need a numeric version. + # TODO: Make also the full version string available from somewhere. + string(REGEX REPLACE "-.*$" "" PACKAGE_VERSION ${PROJECT_VERSION}) + # Install everything into a subdirectory, because + # 1. CMake expects things to be there for CMAKE_PREFIX_PATH to work, and + # 2. This nicely isolates files for different suffixes from each other. + set(CMAKE_PACKAGE_DIR ${CMAKE_INSTALL_DIR}/gromacs${GMX_LIBS_SUFFIX}) + + # Install import definitions that take care of the library locations and + # library dependencies. + set(EXPORT_FILE_NAME libgromacs.cmake) + if (NOT BUILD_SHARED_LIBS) + set(EXPORT_FILE_NAME libgromacs_static.cmake) + endif() + install(EXPORT libgromacs + FILE ${EXPORT_FILE_NAME} + DESTINATION ${CMAKE_PACKAGE_DIR} + COMPONENT libraries) + + get_filename_component(GROMACS_CXX_COMPILER ${CMAKE_CXX_COMPILER} REALPATH) + configure_file(gromacs-config.cmake.cmakein + gromacs-config.cmake @ONLY) + configure_file(gromacs-config-version.cmake.cmakein + gromacs-config-version.cmake @ONLY) + # The configuration files are also installed with the suffix, even though + # the directory already contains the suffix. This allows simple + # find_package(GROMACS NAMES gromacs_d) to find them, without also + # specifying CONFIGS. + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/gromacs-config.cmake + DESTINATION ${CMAKE_PACKAGE_DIR} + RENAME "gromacs${GMX_LIBS_SUFFIX}-config.cmake" + COMPONENT development) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/gromacs-config-version.cmake + DESTINATION ${CMAKE_PACKAGE_DIR} + RENAME "gromacs${GMX_LIBS_SUFFIX}-config-version.cmake" + COMPONENT development) +endfunction() + +do_pkgconfig() +do_cmake_config() diff --git a/src/gromacs/gromacs-config-version.cmake.cmakein b/src/gromacs/gromacs-config-version.cmake.cmakein new file mode 100644 index 0000000000..c3d70cd9f8 --- /dev/null +++ b/src/gromacs/gromacs-config-version.cmake.cmakein @@ -0,0 +1,45 @@ +# +# This file is part of the GROMACS molecular simulation package. +# +# Copyright (c) 2014, by the GROMACS development team, led by +# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, +# and including many others, as listed in the AUTHORS file in the +# top-level source directory and at http://www.gromacs.org. +# +# GROMACS is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public License +# as published by the Free Software Foundation; either version 2.1 +# of the License, or (at your option) any later version. +# +# GROMACS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with GROMACS; if not, see +# http://www.gnu.org/licenses, or write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# If you want to redistribute modifications to GROMACS, please +# consider that scientific software is very special. Version +# control is crucial - bugs must be traceable. We will be happy to +# consider code for inclusion in the official distribution, but +# derived work must not be called official GROMACS. Details are found +# in the README & COPYING files - if they are missing, get the +# official version at http://www.gromacs.org. +# +# To help us fund GROMACS development, we humbly ask that you cite +# the research papers on the package. Check out http://www.gromacs.org. + +set(PACKAGE_VERSION "@PACKAGE_VERSION@") + +if ("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}") + set(PACKAGE_VERSION_COMPATIBLE FALSE) +else() + # TODO: Check that major and minor version match. + set(PACKAGE_VERSION_COMPATIBLE TRUE) + if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}") + set(PACKAGE_VERSION_EXACT TRUE) + endif() +endif() diff --git a/src/gromacs/gromacs-config.cmake.cmakein b/src/gromacs/gromacs-config.cmake.cmakein new file mode 100644 index 0000000000..0d7f97d350 --- /dev/null +++ b/src/gromacs/gromacs-config.cmake.cmakein @@ -0,0 +1,130 @@ +# +# This file is part of the GROMACS molecular simulation package. +# +# Copyright (c) 2014, by the GROMACS development team, led by +# Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, +# and including many others, as listed in the AUTHORS file in the +# top-level source directory and at http://www.gromacs.org. +# +# GROMACS is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public License +# as published by the Free Software Foundation; either version 2.1 +# of the License, or (at your option) any later version. +# +# GROMACS is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with GROMACS; if not, see +# http://www.gnu.org/licenses, or write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# If you want to redistribute modifications to GROMACS, please +# consider that scientific software is very special. Version +# control is crucial - bugs must be traceable. We will be happy to +# consider code for inclusion in the official distribution, but +# derived work must not be called official GROMACS. Details are found +# in the README & COPYING files - if they are missing, get the +# official version at http://www.gromacs.org. +# +# To help us fund GROMACS development, we humbly ask that you cite +# the research papers on the package. Check out http://www.gromacs.org. + +set(_gmx_cmake_dir ${CMAKE_CURRENT_LIST_DIR}) +get_filename_component(_gmx_root_dir "${_gmx_cmake_dir}" PATH) +get_filename_component(_gmx_root_dir "${_gmx_root_dir}" PATH) +get_filename_component(_gmx_root_dir "${_gmx_root_dir}" PATH) + +# Find the exported targets (file name depends on whether shared or static +# libraries were built to allow both to coexist in the same prefix), and +# import them. +set(_gmx_import_file ${_gmx_cmake_dir}/libgromacs.cmake) +if (GROMACS_PREFER_STATIC OR NOT EXISTS ${_gmx_import_file}) + set(_gmx_import_file_static ${_gmx_cmake_dir}/libgromacs_static.cmake) + if (EXISTS ${_gmx_import_file_static}) + set(_gmx_import_file ${_gmx_import_file_static}) + endif() + unset(_gmx_import_file_static) +endif() +if (NOT EXISTS ${_gmx_import_file}) + message(FATAL_ERROR + "The GROMACS installation at ${_gmx_root_dir} does not contain " + "libgromacs.cmake or libgromacs_static.cmake to define the imported " + "targets.") +endif() +include(${_gmx_import_file}) +unset(_gmx_import_file) + +set(GROMACS_INCLUDE_DIRS) +set(_include_dirs "@INSTALLED_HEADER_INCLUDE_DIRS@") +foreach (_dir ${_include_dirs}) + if (IS_ABSOLUTE ${_dir}) + list(APPEND GROMACS_INCLUDE_DIRS ${_dir}) + else() + list(APPEND GROMACS_INCLUDE_DIRS ${_gmx_root_dir}/${_dir}) + endif() +endforeach() +set(GROMACS_LIBRARIES libgromacs) +set(GROMACS_DEFINITIONS @INSTALLED_HEADER_DEFINITIONS@) +set(GROMACS_IS_DOUBLE @GMX_DOUBLE@) +if (DEFINED GROMACS_SUFFIX AND NOT "${GROMACS_SUFFIX}" STREQUAL "@GMX_LIBS_SUFFIX@") + message(FATAL_ERROR "GROMACS_SUFFIX is set inconsistently, expected '@GMX_LIBS_SUFFIX@'") +endif() +set(GROMACS_SUFFIX "@GMX_LIBS_SUFFIX@") +set(GROMACS_CXX_COMPILER "@GROMACS_CXX_COMPILER@") +set(GROMACS_CXX_COMPILER_ID "@CMAKE_CXX_COMPILER_ID@") +set(GROMACS_CXX_COMPILER_VERSION "@CMAKE_CXX_COMPILER_VERSION@") + +# Produce a message, since find_package() prints nothing on success. +include(FindPackageMessage) +# The version info is set by CMake when it determines whether this file +# is suitable (by calling the version file, which sets PACKAGE_VERSION). +set(_gmx_info "${GROMACS_VERSION}") +if (GROMACS_SUFFIX) + set(_gmx_info "${_gmx_info} (suffix: ${GROMACS_SUFFIX})") +endif() +find_package_message(GROMACS "Found GROMACS: ${_gmx_info}" "${CMAKE_CURRENT_LIST_FILE}") + +unset(_gmx_cmake_dir) +unset(_gmx_root_dir) +unset(_gmx_info) + +##################################################################### +# Macros for use in calling code + +# This does not work as a function if called as gromacs_check_double(GMX_DOUBLE) +# (i.e., with the parameter value equal to the formal parameter name) because +# of scoping rules. +macro (gromacs_check_double GMX_DOUBLE) + if (${GMX_DOUBLE} AND NOT GROMACS_IS_DOUBLE) + message(FATAL_ERROR + "The found GROMACS installation is compiled in mixed precision, " + "but double-precision compilation was requested with ${GMX_DOUBLE}=${${GMX_DOUBLE}}") + elseif (NOT ${GMX_DOUBLE} AND GROMACS_IS_DOUBLE) + message(FATAL_ERROR + "The found GROMACS installation is compiled in double precision, " + "but mixed-precision compilation was requested with ${GMX_DOUBLE}=${${GMX_DOUBLE}}") + endif() +endmacro() + +function (gromacs_check_compiler LANG) + if (NOT LANG STREQUAL CXX) + message(FATAL_ERROR + "gromacs_check_compiler(CXX) is currently the only supported call") + endif() + # Deal with possible symlinks (it is fine if one of the used compilers was + # a symlink to another one). + get_filename_component(_cmake_compiler_realpath ${CMAKE_${LANG}_COMPILER} REALPATH) + if (NOT "${_cmake_compiler_realpath}" STREQUAL "${GROMACS_${LANG}_COMPILER}" OR + NOT "${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "${GROMACS_${LANG}_COMPILER_ID}" OR + NOT "${CMAKE_${LANG}_COMPILER_VERSION}" STREQUAL "${GROMACS_${LANG}_COMPILER_VERSION}") + message(WARNING + "You are compiling with a different C++ compiler than what was used " + "to compile GROMACS. This may lead to linking or runtime problems. " + "GROMACS was compiled with " + "${GROMACS_${LANG}_COMPILER_ID} ${GROMACS_${LANG}_COMPILER_VERSION} " + "(${GROMACS_${LANG}_COMPILER}).") + endif() +endfunction() diff --git a/src/gromacs/libgromacs.pc.cmakein b/src/gromacs/libgromacs.pc.cmakein index 2ef52aa205..a3dc979e09 100644 --- a/src/gromacs/libgromacs.pc.cmakein +++ b/src/gromacs/libgromacs.pc.cmakein @@ -1,5 +1,4 @@ libdir=@CMAKE_INSTALL_PREFIX@/@LIB_INSTALL_DIR@ -includedir=@CMAKE_INSTALL_PREFIX@/@INCL_INSTALL_DIR@ Name: libgromacs@GMX_LIBS_SUFFIX@ Description: Gromacs library @@ -8,5 +7,5 @@ Version: @GMX_VERSION_STRING@ Requires: @PKG_FFT@ @PKG_XML@ Libs.private: @CMAKE_THREAD_LIBS_INIT@ @PKG_DL_LIBS@ @OpenMP_LINKER_FLAGS@ Libs: -L${libdir} -lgromacs@GMX_LIBS_SUFFIX@ @PKG_FFT_LIBS@ -lm -Cflags: -I${includedir} @PKG_CFLAGS@ +Cflags: @PKG_CFLAGS@ -- 2.22.0