File: CMakeLists.txt

package info (click to toggle)
gromacs 2019.1-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 161,296 kB
  • sloc: cpp: 1,425,236; xml: 218,793; ansic: 40,813; python: 11,629; sh: 2,409; yacc: 644; perl: 620; fortran: 397; makefile: 243; lisp: 215; lex: 129; awk: 68; csh: 33
file content (372 lines) | stat: -rw-r--r-- 17,741 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
#
# This file is part of the GROMACS molecular simulation package.
#
# Copyright (c) 2012,2013,2014,2015,2016,2017,2018, 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(REGRESSIONTEST_PATH "" CACHE PATH "Directory containing regressiontests")
mark_as_advanced(REGRESSIONTEST_PATH)
option(REGRESSIONTEST_DOWNLOAD
    "Automatically download regressiontests. Tests can be run with ctest." OFF)

if(REGRESSIONTEST_DOWNLOAD)
    if (NOT SOURCE_IS_SOURCE_DISTRIBUTION)
        set(REGRESSIONTEST_URL http://gerrit.gromacs.org/snapshot/${REGRESSIONTEST_BRANCH})
        # REGRESSIONTEST_PATH for dev trees is set later based on the dirname found in the tar
    else()
        set(REGRESSIONTEST_URL http://gerrit.gromacs.org/download/regressiontests-${REGRESSIONTEST_VERSION}.tar.gz)
        set(REGRESSIONTEST_PATH
            "${CMAKE_CURRENT_BINARY_DIR}/regressiontests-${REGRESSIONTEST_VERSION}"
            CACHE PATH "Path to auto-downloaded regressiontests" FORCE)
    endif()
    set(REGRESSIONTEST_FILE "${CMAKE_CURRENT_BINARY_DIR}/regressiontests.tgz")
    message("Downloading: ${REGRESSIONTEST_URL}")
    file(DOWNLOAD ${REGRESSIONTEST_URL} "${REGRESSIONTEST_FILE}" SHOW_PROGRESS STATUS status LOG log)
    list(GET status 0 status_code)
    list(GET status 1 status_string)

    if(NOT status_code EQUAL 0)
        message(FATAL_ERROR "error: downloading '${REGRESSIONTEST_URL}' failed
status_code: ${status_code}
status_string: ${status_string}
log: ${log}")
    endif()
    if (SOURCE_IS_SOURCE_DISTRIBUTION)
        file(MD5 ${REGRESSIONTEST_FILE} COMPUTED_MD5SUM)
        if(NOT ${REGRESSIONTEST_MD5SUM} STREQUAL ${COMPUTED_MD5SUM})
            message(FATAL_ERROR "Download of regressiontests failed. Expected MD5 of ${REGRESSIONTEST_MD5SUM} but download has ${COMPUTED_MD5SUM}")
        endif()
    else()
        # Extract the REGRESSIONTEST_PATH from the tar when using dev tree.
        execute_process(COMMAND ${CMAKE_COMMAND} -E tar tf "${REGRESSIONTEST_FILE}"
                RESULT_VARIABLE _tar_tf_res
                OUTPUT_VARIABLE _tar_tf_out)
        if (${_tar_tf_res} EQUAL 0)
            string(REGEX REPLACE "/\n.*$" "" _regressiontest_dir "${_tar_tf_out}")
            set(REGRESSIONTEST_PATH "${CMAKE_CURRENT_BINARY_DIR}/${_regressiontest_dir}"
                CACHE PATH "Path to auto-downloaded regressiontests" FORCE)
        else()
            message(FATAL_ERROR "Failed to list the contents of the downloaded tarball: ${REGRESSIONTEST_FILE}")
        endif()
    endif()

    file(REMOVE_RECURSE "${REGRESSIONTEST_PATH}") #delete potential prior folder
    execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf "${REGRESSIONTEST_FILE}"
        WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
    if(NOT EXISTS ${REGRESSIONTEST_PATH}/gmxtest.pl)
        message(FATAL_ERROR "Download incorrect. Doesn't contain required gmxtest.pl")
    endif()
    set(REGRESSIONTEST_DOWNLOAD OFF CACHE BOOL "Tests already downloaded. Set to yes to download again" FORCE)
endif()

if(REGRESSIONTEST_PATH AND (CMAKE_CROSSCOMPILING OR CMAKE_CONFIGURATION_TYPES OR GMX_BUILD_MDRUN_ONLY))
    # TODO: It would be nicer to do these checks before potentially downloading the tests.
    # Cross-compiling toolchains require us to compile both front-end and
    # back-end binaries to run gmxtest.pl.
    # Testing an mdrun-only builds require supporting binaries from a full build
    message(WARNING
        "With cross-compiling, multi-configuration generators (e.g. Visual Studio), or with mdrun-only builds, running regressiontests from build system is not supported. Please run gmxtest.pl directly.")
    set(REGRESSIONTEST_PATH OFF CACHE BOOL
        "With cross-compiling or multi-configuration generators, running regressiontests from build system is not supported." FORCE)
endif()

if(REGRESSIONTEST_PATH)
    if(NOT EXISTS ${REGRESSIONTEST_PATH}/gmxtest.pl)
        message(FATAL_ERROR
            "REGRESSIONTEST_PATH invalid. The path needs to contain gmxtest.pl.")
    endif()

    # gmxtests target builds all binaries required for running gmxtest
    add_custom_target(gmxtests DEPENDS gmx)
    add_dependencies(run-ctest gmxtests)
    add_dependencies(run-ctest-nophys gmxtests)

    if(GMX_DOUBLE)
        list(APPEND ARGS -double)
    endif()
    if(GMX_LIB_MPI AND NOT MPIEXEC) # find_program failed
        message(WARNING
            "Please set MPIEXEC. Otherwise mpirun is assumed for running tests.")
    endif()
    if(GMX_LIB_MPI)
        set(GMX_TEST_NUMBER_PROCS 8 CACHE STRING "Number of processors used for testing")
        mark_as_advanced(GMX_TEST_NUMBER_PROCS)
        list(APPEND ARGS -np ${GMX_TEST_NUMBER_PROCS})
        if(MPIEXEC)
            list(APPEND ARGS -mpirun ${MPIEXEC})
        endif()
        #We should use MPIEXEC_NUMPROC_FLAG but gmxtest.pl doesn't let us pass it
    endif()
    if(GMX_BINARY_SUFFIX)
        list(APPEND ARGS -suffix ${GMX_BINARY_SUFFIX})
    endif()
    #crosscompile is only used to disable checking whether binaries work
    #given that we know they are there and that mdrun might not be exectuable
    #(e.g. Cray) we enable it.
    list(APPEND ARGS -crosscompile)

    set(REGRESSIONTEST_EXTRA_ARGS "" CACHE STRING 
        "Extra arguments passed to gmxtest")
    mark_as_advanced(REGRESSIONTEST_EXTRA_ARGS)
    list(APPEND ARGS ${REGRESSIONTEST_EXTRA_ARGS})

    list(APPEND ARGS -noverbose -nosuffix)

    if(GMX_NATIVE_WINDOWS)
        set(PATH_SEPARATOR "\\;")
        #replacing \ with / shouldn't be neccessary. But otherwise "..\bin\;c:\.."
        #gets turned into "...\bin\\c:\.." don't know why and don't have a better
        #workaround. This workaround doesn't hurt.
        string(REPLACE "\\" "/" PATH "$ENV{PATH}")
        #protect ; (don't treat as list)
        string(REPLACE ";" "\\;" PATH "${PATH}")
    else()
        set(PATH_SEPARATOR ":")
        set(PATH "$ENV{PATH}")
    endif()

    foreach(FOLDER bin lib) #lib folders might be needed for
        #e.g. DLLs. For GMX paths native ("\") is needed for GMXLIB detection
        file(TO_NATIVE_PATH "${CMAKE_BINARY_DIR}/${FOLDER}" DIR)
        set(PATH "${DIR}${PATH_SEPARATOR}${PATH}")
    endforeach()

    find_program(PERL_EXECUTABLE NAMES "perl")
    mark_as_advanced(PERL_EXECUTABLE)

    if (NOT PERL_EXECUTABLE)
        message(FATAL_ERROR "Perl not found. Install perl, set PERL_EXECUTABLE to the perl location, or unset REGRESSIONTEST_PATH to disable testing.")
    endif()

    #currently not testing tools because they don't contain any useful tests
    foreach(subtest simple complex kernel freeenergy rotation essentialdynamics)
        add_test(NAME regressiontests/${subtest}
            #windows requires the command to be perl and not the script
            COMMAND perl "${REGRESSIONTEST_PATH}/gmxtest.pl" ${subtest} ${ARGS})
        set_tests_properties(regressiontests/${subtest} PROPERTIES
            ENVIRONMENT "PATH=${PATH}")
    endforeach()
else()
    gmx_add_missing_tests_notice("Regression tests have not been run. If you want to run them from the build system, get the correct version of the regression tests package and set REGRESSIONTEST_PATH in CMake to point to it, or set REGRESSIONTEST_DOWNLOAD=ON.")
endif()


#
# Physical validation tests are opt-in via -DGMX_PHYSICAL_VALIDATION=ON
#
if(GMX_PHYSICAL_VALIDATION)
    # physical validation suite is distributed with the source
    set(PHYSVALTEST_SOURCE_PATH
            "${CMAKE_CURRENT_SOURCE_DIR}/physicalvalidation")
    #       CACHE PATH "Source directory containing physical validation tests.")
    if(NOT EXISTS ${PHYSVALTEST_SOURCE_PATH}/gmx_physicalvalidation.py)
        message(FATAL_ERROR
            "GMX_PHYSICAL_VALIDATION set, but physical validation script not found in ${PHYSVALTEST_SOURCE_PATH}.")
    endif()

    if(CMAKE_CROSSCOMPILING OR CMAKE_CONFIGURATION_TYPES OR GMX_BUILD_MDRUN_ONLY)
        # The following comment is copied from regression tests:
        #     Cross-compiling toolchains require us to compile both front-end and
        #     back-end binaries to run gmxtest.pl.
        #     Testing an mdrun-only builds require supporting binaries from a full build
        # TODO: Look into the details of this.
        # For now, turn it off - our python-gmx interface is probably not that stable for special cases anyway
        message(WARNING
                "With cross-compiling, multi-configuration generators (e.g. Visual Studio), or with mdrun-only builds,\
                running physical validation tests from build system is not supported.\
                Please run physicalvalidation.py directly.")
        set(GMX_PHYSICAL_VALIDATION OFF CACHE BOOL
                "With cross-compiling or multi-configuration generators, running physical validation tests from build\
                system is not supported." FORCE)

    else()
        #
        # Making sure gmx is built before running physical validation tests
        #
        add_dependencies(run-ctest-phys gmx)
        add_dependencies(run-ctest gmx)

        #
        # Determine arguments passed to physicalvalidation.py
        #
        set(PARGS "")
        list(APPEND PARGS --wd ${CMAKE_CURRENT_BINARY_DIR}/physicalvalidation)
        list(APPEND PARGS --bindir ${CMAKE_BINARY_DIR}/bin)

        if(GMX_LIB_MPI AND NOT MPIEXEC) # find_program failed
            message(WARNING
                "Please set MPIEXEC. Otherwise mpirun is assumed for running tests.")
        endif()
        if(GMX_LIB_MPI)
            # define number of processors in analogy to regression tests?
            if(MPIEXEC)
                list(APPEND ARGS --mpicmd ${MPIEXEC})
            else()
                list(APPEND ARGS --mpicmd mpirun)
            endif()
        endif()
        if(GMX_LIB_MPI)
            message(FATAL_ERROR
                "Physical validation using MPI not supported.")
        endif()

        if(GMX_BINARY_SUFFIX)
            list(APPEND PARGS --suffix ${GMX_BINARY_SUFFIX})
        endif()

        #
        # Give possibility to add args via cache
        #
        set(PHYSVALTEST_EXTRA_ARGS "" CACHE STRING
            "Extra arguments passed to phystest")
        mark_as_advanced(PHYSVALTEST_EXTRA_ARGS)
        list(APPEND PARGS ${PHYSVALTEST_EXTRA_ARGS})

        #
        # The following lines are directly copied from regression tests.
        # They seem to be applicable to physical validation tests as well.
        #
        if(GMX_NATIVE_WINDOWS)
            set(PATH_SEPARATOR "\\;")
            #replacing \ with / shouldn't be neccessary. But otherwise "..\bin\;c:\.."
            #gets turned into "...\bin\\c:\.." don't know why and don't have a better
            #workaround. This workaround doesn't hurt.
            string(REPLACE "\\" "/" PATH "$ENV{PATH}")
            #protect ; (don't treat as list)
            string(REPLACE ";" "\\;" PATH "${PATH}")
        else()
            set(PATH_SEPARATOR ":")
            set(PATH "$ENV{PATH}")
        endif()

        foreach(FOLDER bin lib) #lib folders might be needed for
                                #e.g. DLLs. For GMX paths native ("\") is needed for GMXLIB detection
            file(TO_NATIVE_PATH "${CMAKE_BINARY_DIR}/${FOLDER}" DIR)
            set(PATH "${DIR}${PATH_SEPARATOR}${PATH}")
        endforeach()
        #
        # End copied from regression tests.
        #

        #
        # TODO: Switch to python >= 3.3. For now, use 2.7 for compatibility with rest of build system.
        #
        # ${PYTHON_EXECUTABLE} can only be set for one version per build system.
        # Currently, the following files set 2.7 explicitly:
        # * cmake/CheckTarget.cmake
        # * docs/CMakeList.txt
        # Parts of the documentation rely on python scripts.
        # These need to be ported to be able to make the move to python 3.
        #
        if (NOT PYTHON_EXECUTABLE)
            message(FATAL_ERROR
                    "Python not found. Physical validation relies on python >= 3.3 (python 2.7 supported, but\
                    deprecated). Install python, set PYTHON_EXECUTABLE to the python location, or set\
                    GMX_PHYSCIAL_VALIDATION=OFF to disable the physical validation tests.")
        endif()
        #
        foreach(module numpy scipy pymbar) # add further modules if necessary
            find_python_module(${module})
            string(TOUPPER ${module} module_upper)
            if(NOT PYTHONMODULE_${module_upper})
                message(WARNING
                        "Python module ${module} not found. Physical validation relies on ${module}. Make sure\
                        ${module} can be found by PYTHON_EXECUTABLE, or set GMX_PHYSCIAL_VALIDATION=OFF to disable\
                        the physical validation tests.")
            endif()
        endforeach()

        #
        # Hook in our own tests
        # Read them from json file to make every system a separate test
        #
        if (GMX_DOUBLE)
            set(PHYSVALTEST_JSON "${PHYSVALTEST_SOURCE_PATH}/systems_d.json")
        else()
            set(PHYSVALTEST_JSON "${PHYSVALTEST_SOURCE_PATH}/systems.json")
        endif()
        file(STRINGS "${PHYSVALTEST_JSON}" json)
        string(REPLACE "\"" "" json ${json})
        string(REPLACE "," "" json ${json})
        string(REPLACE " " "" json ${json})
        string(REPLACE ";" "<<>>" json ${json})
        string(REPLACE "[" "" json ${json})
        string(REPLACE "]" "" json ${json})
        string(REPLACE "{" "" json ${json})
        string(REPLACE "}" "" json ${json})
        string(REPLACE "<<>>" ";" json ${json})
        foreach(line ${json})
            if("${line}" MATCHES "name:")
                string(REPLACE "name:" "" testname ${line})
                add_test(NAME physicalvalidationtests/${testname}
                        COMMAND ${PYTHON_EXECUTABLE} "${PHYSVALTEST_SOURCE_PATH}/gmx_physicalvalidation.py" "${PHYSVALTEST_JSON}" -s ${testname} -a ${PARGS})
                set_tests_properties(physicalvalidationtests/${testname} PROPERTIES
                        ENVIRONMENT "PATH=${PATH}"
                        LABELS "PhysicalValidationTest")
            endif()
        endforeach()

        #
        # Create prepare and run targets while all variables are set
        # Will be referenced in CheckTarget.cmake
        #
        # "check-phys-prepare" prepares the systems needed for physical validation for external running
        add_custom_target(check-phys-prepare
                          COMMAND ${PYTHON_EXECUTABLE} "${PHYSVALTEST_SOURCE_PATH}/gmx_physicalvalidation.py" "${PHYSVALTEST_JSON}" -p ${PARGS}
                          COMMENT "Preparing systems for physical validation"
                          DEPENDS gmx)
        # "run-physval-sims" prepares and runs the systems needed for physical validation
        add_custom_target(run-physval-sims
                          COMMAND ${PYTHON_EXECUTABLE} "${PHYSVALTEST_SOURCE_PATH}/gmx_physicalvalidation.py" "${PHYSVALTEST_JSON}" -r ${PARGS}
                          COMMENT "Preparing and running systems for physical validation"
                          DEPENDS gmx)
    endif()
else()
    #
    # Create dummy prepare and run targets
    # Will be referenced in CheckTarget.cmake
    #
    # "check-phys-prepare" prepares the systems needed for physical validation for external running
    add_custom_target(check-phys-prepare
                      COMMAND ${CMAKE_COMMAND} -E echo "NOTE: You called the target `check-phys-prepare`, but ran cmake with\
 `-DGMX_PHYSICAL_VALIDATION=OFF`. The physical validation tests are therefore unavailable,\
 and this target is not doing anything."
                      COMMENT "No physical validation" VERBATIM)
    # "run-physval-sims" prepares and runs the systems needed for physical validation
    add_custom_target(run-physval-sims
                      COMMAND ${CMAKE_COMMAND} -E echo "NOTE: You called the target `run-physval-sims`, but ran cmake with\
 `-DGMX_PHYSICAL_VALIDATION=OFF`. The physical validation tests are therefore unavailable,\
 and this target is not doing anything."
                      COMMENT "No physical validation" VERBATIM)
endif()

gmx_create_missing_tests_notice_target()