20904e5427f218bfe8b9a55c48a8fe3ca5f31a5c
[alexxy/gromacs.git] / cmake / gmxVersionInfo.cmake
1 #
2 # This file is part of the GROMACS molecular simulation package.
3 #
4 # Copyright (c) 2014,2015,2016,2017,2018 by the GROMACS development team.
5 # Copyright (c) 2019,2020,2021, by the GROMACS development team, led by
6 # Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
7 # and including many others, as listed in the AUTHORS file in the
8 # top-level source directory and at http://www.gromacs.org.
9 #
10 # GROMACS is free software; you can redistribute it and/or
11 # modify it under the terms of the GNU Lesser General Public License
12 # as published by the Free Software Foundation; either version 2.1
13 # of the License, or (at your option) any later version.
14 #
15 # GROMACS is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 # Lesser General Public License for more details.
19 #
20 # You should have received a copy of the GNU Lesser General Public
21 # License along with GROMACS; if not, see
22 # http://www.gnu.org/licenses, or write to the Free Software Foundation,
23 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
24 #
25 # If you want to redistribute modifications to GROMACS, please
26 # consider that scientific software is very special. Version
27 # control is crucial - bugs must be traceable. We will be happy to
28 # consider code for inclusion in the official distribution, but
29 # derived work must not be called official GROMACS. Details are found
30 # in the README & COPYING files - if they are missing, get the
31 # official version at http://www.gromacs.org.
32 #
33 # To help us fund GROMACS development, we humbly ask that you cite
34 # the research papers on the package. Check out http://www.gromacs.org.
35
36 # Sets version information variables and provides CMake functions for
37 # generating files based on them
38 #
39 # This script provides the following basic version variables that need to be
40 # maintained manually:
41 #   GMX_VERSION_MAJOR      Major version number.
42 #   GMX_VERSION_PATCH      Patch version number.
43 #       Should always be defined: zero for, e.g., 2016.
44 #   GMX_VERSION_SUFFIX     String suffix to add to numeric version string.
45 #       "-dev" is automatically added when not building from a source package,
46 #       and does not need to be kept here. This mechanism is not quite enough
47 #       for building a tarball, but setting the CMake cache variable
48 #       GMX_BUILD_TARBALL=on will suppress the addition of "-dev" to the
49 #       version string.
50 #   LIBRARY_SOVERSION_MAJOR so major version for the built libraries.
51 #       Should be increased for each binary incompatible release. In GROMACS,
52 #       the typical policy is to increase it at the start of the development
53 #       cycle for each major/minor version change, but not for patch releases,
54 #       even if the latter may not always be fully binary compatible.
55 #       Table of historical values
56 #         GROMACS     5.0    0
57 #         GROMACS     5.1    1
58 #         GROMACS     2016   2
59 #         GROMACS     2018   3
60 #         GROMACS     2019   4
61 #         GROMACS     2020   5
62 #         GROMACS     2021   6
63 #         GROMACS     2022   7
64 #   LIBRARY_SOVERSION_MINOR so minor version for the built libraries.
65 #       Should be increased for each release that changes only the implementation.
66 #       In GROMACS, the typical policy is to increase it for each patch version
67 #       change, even if they may not always be fully binary compatible.
68 #       If it is somehow clear that the ABI implementation has not changed
69 #       in a patch release, this variable should not increase. Release candidate
70 #       and beta versions will not increase this number, since nobody should
71 #       write code against such versions.
72 #   LIBRARY_VERSION        Full library version.
73 #   REGRESSIONTEST_BRANCH  For builds not from source packages, name of the
74 #       regressiontests branch at gerrit.gromacs.org whose HEAD can test this
75 #       code, *if* this code is recent enough (i.e., contains all changes from
76 #       the corresponding code branch that affects the regression test
77 #       results). Even after a release branch is forked for the source
78 #       repository, the correct regressiontests branch can still be master,
79 #       because we do not fork it until behaviour needs to change.
80 #   REGRESSIONTEST_MD5SUM
81 #       The MD5 checksum of the regressiontest tarball. Only used when building
82 #       from a source package.
83 #   GMX_SOURCE_DOI_ID
84 #       ID collected from Zenodo connected to the doi for a released version
85 #       used to identify the source when building an official released version.
86 #       This ID is used for the source code tarball.
87 #   GMX_MANUAL_DOI_ID
88 #       Same as above, but for the reference manual.
89 # They are collected into a single section below.
90 # The following variables are set based on these:
91 #   GMX_VERSION            String composed from GMX_VERSION_* numeric variables
92 #       above. Example: 4.6.1, 5.0, 2016
93 #   GMX_VERSION_STRING     String with GMX_VERSION suffixed with the given
94 #       suffix and possibly "-dev" for builds not from a source package.
95 #   GMX_VERSION_NUMERIC    Numeric version number (e.g., 40601 for 4.6.1, 20160001 for 2016.1).
96 #   GMX_API_VERSION        Numeric API version.
97 #       This is currently set automatically to GMX_VERSION_NUMERIC, but may
98 #       become manually maintained in the future if there will be releases
99 #       where the API does not change, but programs/libraries do.
100 #       In such a case, this should be the first version where the current API
101 #       appeared.
102 #   REGRESSIONTEST_VERSION For source packages, version number of the
103 #       matching regressiontests tarball.  Not used for builds not from source
104 #       packages.
105 # The latter two are used to generate gromacs/version.h to allow software
106 # written against the GROMACS API to provide some #ifdef'ed code to support
107 # multiple GROMACS versions.
108 #
109 # This script also declares machinery to generate and obtain version
110 # information from a git repository.  This is enabled by default if the source
111 # tree is a git, but can be disabled with
112 #   GMX_GIT_VERSION_INFO           Advanced CMake variable to disable git
113 #                                  version info generation.
114 # If the version generation is disabled, then the source and manual doi
115 # will be based on the stored values for the ID.
116 # The main interface to this machinery is the gmx_configure_version_file()
117 # CMake function.  The signature is
118 #   gmx_configure_version_file(<input> <output>
119 #                              [REMOTE_HASH]
120 #                              [TARGET <target>]
121 #                              [COMMENT <comment>])
122 #   <input>      Specify the input and output files as for configure_file().
123 #   <output>     The configuration is done with configure_file(... @ONLY) with
124 #                the following variables defined (as well as all the
125 #                GMX_VERSION* variables from above):
126 #                  GMX_VERSION_STRING_FULL
127 #                  GMX_VERSION_FULL_HASH
128 #                  GMX_VERSION_CENTRAL_BASE_HASH
129 #                The output file is created during build time, so any dependent
130 #                targets should specify it as a dependency.
131 #   REMOTE_HASH  Currently, this has no effect, but it signifies that the
132 #                <input> file is using the CENTRAL_BASE_HASH variable.
133 #                This variable is much more expensive to initialize than the
134 #                others, so this allows local changes in this file to only
135 #                compute that value when required if that becomes necessary.
136 #   TARGET       By default, this function uses add_custom_command() to
137 #                generate the output file.  If TARGET is specified, then
138 #                add_custom_target() is used to create a target with the given
139 #                name <target> that runs this custom command.  Use this if
140 #                the same file will be used for multiple downstream targets,
141 #                or if the explicit target for the file is otherwise
142 #                necessary.
143 #   COMMENT      Set a custom comment to be shown when building the rule
144 #                (see add_custom_command(... COMMENT <comment>)).
145 # As an alternative to using this script, also the following variables are
146 # provided (can be useful when generating more complex CMake scripts that do
147 # build-time tasks):
148 #   VERSION_INFO_CMAKE_SCRIPT
149 #       Absolute path to a CMake script that can be included using include()
150 #       to declare the GMX_VERSION_* variables documented for
151 #       gmx_configure_version_file().
152 #   VERSION_INFO_DEPS
153 #       If a custom command depends on VERSION_INFO_CMAKE_SCRIPT, then it
154 #       should add ${VERSION_INFO_DEPS} to its DEPENDS list to get the
155 #       appropriate dependencies.
156 # TODO: If someone wants to add a custom target that depends on
157 # VERSION_INFO_CMAKE_SCRIPT, a separate variable may be needed for those
158 # dependencies.
159 #
160 # The version string printed by 'gmx -version' (and also printed in the startup
161 # header) can provide useful information for, e.g., diagnosing bug reports and
162 # identifying what exact version the user was using.  The following formats are
163 # possible (with examples given for a particular version):
164 #   2018.1       Plain version number without any suffix signifies a build from
165 #                a released source tarball.
166 #   2018.1-dev   '-dev' suffix signifies all other builds. If there is no other
167 #                information, either the user built the code outside any git
168 #                repository, or disabled the version info generation.
169 #   2018.1-dev-YYYYMMDD-1234abc
170 #                The YYYYMMDD part shows the commit date (not author date) of
171 #                the HEAD commit from which the code was built.  The abbreviated
172 #                hash is the hash of that commit (the full hash is available in
173 #                'gmx -version' output).
174 #                If the HEAD hash is not identified as coming from branches in
175 #                "authoritative" GROMACS repositories, 'gmx -version' will show
176 #                the nearest ancestor commit that is identified as such (but see
177 #                the '-local' and '-unknown' suffixes below).
178 #   2018.1-dev-YYYYMMDD-1234abc-dirty
179 #                As above, but there were local modifications in the source tree
180 #                when the code was built.
181 #   2018.1-dev-YYYYMMDD-1234abc-unknown
182 #                As above, but there were no remotes in the repository that
183 #                could be identified as "authoritative" GROMACS repositories.
184 #                This happens if the code is not cloned from git.gromacs.org
185 #                or gerrit.gromacs.org.
186 #   2018.1-dev-YYYYMMDD-1234abc-local
187 #                As above, but there were no commits in the recent history of
188 #                the branch that could be identified as coming from
189 #                "authoritative" GROMACS repositories.  This should be
190 #                relatively rare.
191 #
192 # Other variables set here are not intended for use outside this file.
193 # The scripts gmxGenerateVersionInfo.cmake and gmxConfigureVersionInfo.cmake
194 # are used internally by this machinery, as well as VersionInfo.cmake.cmakein.
195
196 #####################################################################
197 # Manually maintained version info
198
199 # The GROMACS convention is that these are the version number of the next
200 # release that is going to be made from this branch.
201 set(GMX_VERSION_MAJOR 2022)
202 set(GMX_VERSION_PATCH 0)
203 # The suffix, on the other hand, is used mainly for betas and release
204 # candidates, where it signifies the most recent such release from
205 # this branch; it will be empty before the first such release, as well
206 # as after the final release is out.
207 set(GMX_VERSION_SUFFIX "-beta1")
208
209 # Conventionally with libtool, any ABI change must change the major
210 # version number, the minor version number should change if it's just
211 # the implementation that has been altered, and the third number
212 # counts the number of old major versions that will still run if
213 # linked to this library (i.e. it is not a patch number). See the
214 # above descriptions of LIBRARY_SOVERSION_* for policy for changes
215 # here. The important thing is to minimize the chance of third-party
216 # code being able to dynamically link with a version of libgromacs
217 # that might not work.
218 set(LIBRARY_SOVERSION_MAJOR 7)
219 set(LIBRARY_SOVERSION_MINOR 0)
220 set(LIBRARY_VERSION ${LIBRARY_SOVERSION_MAJOR}.${LIBRARY_SOVERSION_MINOR}.0)
221
222 #####################################################################
223 # General version management based on manually set numbers
224
225 if (GMX_VERSION_PATCH)
226     set(GMX_VERSION "${GMX_VERSION_MAJOR}.${GMX_VERSION_PATCH}")
227 else()
228     set(GMX_VERSION "${GMX_VERSION_MAJOR}")
229 endif()
230 set(GMX_VERSION_STRING "${GMX_VERSION}${GMX_VERSION_SUFFIX}")
231
232 set(REGRESSIONTEST_VERSION "${GMX_VERSION_STRING}")
233 set(REGRESSIONTEST_BRANCH "master")
234 # Follow the relevant part of the release checklist at
235 # https://gitlab.com/gromacs/gromacs/-/wikis/Release-checklist#how-to-build-a-regressiontests-tarball
236 # in order to have it build the regressiontests tarball with all the
237 # right version naming. The version number and suffix goes into the
238 # directory name within the regressiontests tarball, which affects the
239 # md5sum of the tarball. The matching md5sum has to go here, and if it
240 # isn't right the real release workflow will report a failure.
241 set(REGRESSIONTEST_MD5SUM "9e122010c6e0fea35ec621a8e6561f7f" CACHE INTERNAL "MD5 sum of the regressiontests tarball for this GROMACS version")
242
243 # If you are making a custom fork of GROMACS, please describe your
244 # fork, perhaps with its version number, in the value of
245 # GMX_VERSION_STRING_OF_FORK here. This string will appear in the
246 # header of log files that mdrun writes. This will help you, your
247 # users, your system administrators, your maintainers and the
248 # maintainers of GROMACS core understand how to troubleshoot and
249 # reproduce potential problems.
250 #
251 # If you are distributing a patch to GROMACS, then this change would
252 # be great as part of your patch. Otherwise for personal use, you can
253 # also just set a CMake cache variable.
254 set(GMX_VERSION_STRING_OF_FORK "" CACHE INTERNAL
255     "Version string for forks of GROMACS to set to describe themselves")
256 mark_as_advanced(GMX_VERSION_STRING_OF_FORK)
257 if (GMX_VERSION_STRING_OF_FORK)
258     set(GMX_VERSION_STRING "${GMX_VERSION_STRING}-${GMX_VERSION_STRING_OF_FORK}")
259 endif()
260
261 option(GMX_BUILD_TARBALL "Build tarball without -dev version suffix" OFF)
262 mark_as_advanced(GMX_BUILD_TARBALL)
263 # If run with cmake -P, the -dev suffix is managed elsewhere.
264 if (NOT SOURCE_IS_SOURCE_DISTRIBUTION AND
265     NOT GMX_BUILD_TARBALL AND
266     NOT CMAKE_SCRIPT_MODE_FILE)
267     set(GMX_VERSION_STRING "${GMX_VERSION_STRING}-dev")
268 endif()
269
270 math(EXPR GMX_VERSION_NUMERIC
271      "${GMX_VERSION_MAJOR}*10000 + ${GMX_VERSION_PATCH}")
272 set(GMX_API_VERSION ${GMX_VERSION_NUMERIC})
273
274 # If run with cmake -P from GitLab scripts, print out necessary version info
275 # as JSON.
276 if (CMAKE_SCRIPT_MODE_FILE)
277     message("{ \"version\": \"${GMX_VERSION_STRING}\", \"regressiontest-md5sum\": \"${REGRESSIONTEST_MD5SUM}\" }")
278     return()
279 endif()
280
281 # Set those values only in release versions, after getting the identifiers
282 # from Zenodo for the manual and source code
283 # Has to be done by hand before every final release
284 # Use force to override anything given as a cmake command line input
285 # Actual input depends on the GMX_VERSION_STRING_OF_FORK variable being set or not.
286 # If it is set, we always default to an empty string, otherwise to the value set for the release build.
287 if (GMX_VERSION_STRING_OF_FORK)
288     set(GMX_MANUAL_DOI_INTERNAL "")
289     set(GMX_SOURCE_DOI_INTERNAL "")
290 else()
291     set(GMX_MANUAL_DOI_INTERNAL "") # Set correct doi string here
292     set(GMX_SOURCE_DOI_INTERNAL "") # Set correct doi string here
293 endif()
294 set(GMX_MANUAL_DOI ${GMX_MANUAL_DOI_INTERNAL} CACHE INTERNAL "reserved doi for GROMACS manual" FORCE)
295 set(GMX_SOURCE_DOI ${GMX_SOURCE_DOI_INTERNAL} CACHE INTERNAL "reserved doi for GROMACS source code" FORCE)
296
297 #####################################################################
298 # git version info management
299
300 # There can be clusters where git and CMake can run on nodes where the other is
301 # not available, accessing the same source tree.
302 # Should be unlikely, but doesn't hurt to check.
303 set(_git_info_default OFF)
304 if (SOURCE_IS_GIT_REPOSITORY)
305     find_package(Git)
306     if (GIT_FOUND)
307         set(_git_info_default ON)
308     endif()
309 endif()
310 option(GMX_GIT_VERSION_INFO "Generate git version information" ${_git_info_default})
311 mark_as_advanced(GMX_GIT_VERSION_INFO)
312 # Detect preconditions for version info generation if it is requested.
313 if (GMX_GIT_VERSION_INFO)
314     if (NOT SOURCE_IS_GIT_REPOSITORY)
315         message(FATAL_ERROR
316             "Cannot generate git version information from source tree not under git. "
317             "Set GMX_GIT_VERSION_INFO=OFF to proceed.")
318     endif()
319     # We need at least git v1.5.3 be able to parse git's date output.
320     if (NOT GIT_FOUND OR GIT_VERSION_STRING VERSION_LESS "1.5.3")
321         message(FATAL_ERROR
322             "No compatible git version found (>= 1.5.3 required). "
323             "Won't be able to generate development version information. "
324             "Set GMX_GIT_VERSION_INFO=OFF to proceed.")
325     endif()
326 endif()
327
328 include(gmxCustomCommandUtilities)
329 include(FindPythonModule)
330 # The first two are also for use outside this file, encapsulating the details
331 # of how to use the generated VersionInfo.cmake.
332 set(VERSION_INFO_CMAKE_FILE   ${PROJECT_BINARY_DIR}/VersionInfo.cmake)
333 set(VERSION_INFO_DEPS         ${VERSION_INFO_CMAKE_FILE})
334 # Capture the location of the necessary files in internal variables for use in
335 # the function below.
336 set(VERSION_INFO_CMAKEIN_FILE     ${CMAKE_CURRENT_LIST_DIR}/VersionInfo.cmake.cmakein)
337 set(VERSION_INFO_CONFIGURE_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/gmxConfigureVersionInfo.cmake)
338 # A set of directories to scan for calculating the hash of source files.
339 set(SET_OF_DIRECTORIES_TO_CHECKSUM  "src")
340 list(APPEND SET_OF_DIRECTORIES_TO_CHECKSUM "python_packaging")
341 # Due to the limitations for passing a list as arguments, we make the directories a string here
342 string(REPLACE ";" ":" DIRECTORIES_TO_CHECKSUM_STRING "${SET_OF_DIRECTORIES_TO_CHECKSUM}")
343
344 # Rules to create the VersionInfo.cmake file.
345 # For git info, the sequence is:
346 #   1. (configure time) VersionInfo.cmake.cmakein -> VersionInfo-partial.cmake.cmakein
347 #        - Set all variables that are known at configure time.
348 #   2. (build time)     VersionInfo-partial.cmake.cmakein -> VersionInfo.cmake
349 #        - Set variables that may change as result of repository state changes
350 #          (i.e., everything that requires running git).
351 #        - Runs every time as a git-version-info target, but the output file
352 #          timestamp only changes if its contents actually change.
353 #        - Depending on the native build system, this may run once per build
354 #          or once per each time it is required for step 3.
355 #   3. (build time)     VersionInfo.cmake -> other files
356 #        - Set variables in files specified with gmx_configure_version_file()
357 #          using the values generated in step 2.
358 #        - Each file runs as a custom command that depends on the previous
359 #          steps, and runs only if the VersionInfo.cmake file is newer than the
360 #          output file.
361 # Without git info, the sequence is:
362 #  1. (configure time) VersionInfo.cmake.cmakein -> VersionInfo.cmake
363 #        - Everything is known at configure time, so the output is generated
364 #          immediately with all variables set (git info will be empty).
365 #  2. (build time)     VersionInfo.cmake -> other files
366 #        - As with git info, processes files from gmx_configure_version_file().
367 #        - These are again custom commands that depend on the output from
368 #          step 1, so they get regenerated only when the static version info
369 #          changes.
370
371 # Check if we have all necessary python modules available
372 if (Python3_Interpreter_FOUND)
373     set(HAVE_FULL_FUNCTIONING_PYTHON Python3_Interpreter_FOUND)
374     foreach(module argparse hashlib hmac os stat re) # add further modules if necessary
375         find_python_module(${module} QUIET)
376         string(TOUPPER ${module} module_upper)
377         if(NOT PYTHONMODULE_${module_upper})
378             message(STATUS
379                 "Python module ${module} not found - disabling checksum validation")
380             unset(HAVE_FULL_FUNCTIONING_PYTHON)
381         endif()
382     endforeach()
383 endif()
384
385 # Configure information known at this time into a partially filled
386 # version info file.
387 set(VERSION_INFO_CMAKEIN_FILE_PARTIAL
388     ${PROJECT_BINARY_DIR}/VersionInfo-partial.cmake.cmakein)
389 # Leave these to be substituted by the targets below.
390 set(GMX_VERSION_STRING_FULL       "\@GMX_VERSION_STRING_FULL\@")
391
392 if (GMX_GIT_VERSION_INFO)
393     # Leave these to be substituted by the custom target below.
394     # Specific for building from git.
395     set(GMX_VERSION_FULL_HASH         "\@GMX_VERSION_FULL_HASH\@")
396     set(GMX_VERSION_CENTRAL_BASE_HASH "\@GMX_VERSION_CENTRAL_BASE_HASH\@")
397     # If generating the version info, create a target that runs on every build
398     # and does the actual git calls, storing the results into a CMake script.
399     # This needs to be run at build time to update the version information
400     # properly when the git hash changes, but the build system does not.
401     # All targets added by gmx_configure_version_file() use the information
402     # from this script to get their variables from, removing the need to run
403     # git multiple times and simplifying reuse for other purposes.
404     gmx_add_custom_output_target(git-version-info RUN_ALWAYS
405         OUTPUT ${VERSION_INFO_CMAKE_FILE}
406         COMMAND ${CMAKE_COMMAND}
407             -D GIT_EXECUTABLE=${GIT_EXECUTABLE}
408             -D PROJECT_VERSION=${GMX_VERSION_STRING}
409             -D PROJECT_SOURCE_DIR=${PROJECT_SOURCE_DIR}
410             -D VERSION_CMAKEIN=${VERSION_INFO_CMAKEIN_FILE_PARTIAL}
411             -D VERSION_OUT=${VERSION_INFO_CMAKE_FILE}
412             -P ${CMAKE_CURRENT_LIST_DIR}/gmxGenerateVersionInfo.cmake
413         WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
414         COMMENT "Generating git version information")
415     list(APPEND VERSION_INFO_DEPS git-version-info)
416 else()
417     # Leave these to be substituted by the custom target below.
418     # Specific for building from source tarball.
419     set(GMX_RELEASE_SOURCE_FILE_CHECKSUM "\@GMX_RELEASE_SOURCE_FILE_CHECKSUM\@")
420     set(GMX_CURRENT_SOURCE_FILE_CHECKSUM "\@GMX_CURRENT_SOURCE_FILE_CHECKSUM\@")
421     gmx_add_custom_output_target(release-version-info RUN_ALWAYS
422         OUTPUT ${VERSION_INFO_CMAKE_FILE}
423         COMMAND ${CMAKE_COMMAND}
424             -D PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}
425             -D HAVE_FULL_FUNCTIONING_PYTHON=${HAVE_FULL_FUNCTIONING_PYTHON}
426             -D PROJECT_VERSION=${GMX_VERSION_STRING}
427             -D PROJECT_SOURCE_DIR=${PROJECT_SOURCE_DIR}
428             -D DIRECTORIES_TO_CHECKSUM=${DIRECTORIES_TO_CHECKSUM_STRING}
429             -D VERSION_CMAKEIN=${VERSION_INFO_CMAKEIN_FILE_PARTIAL}
430             -D VERSION_OUT=${VERSION_INFO_CMAKE_FILE}
431             -D VERSION_STRING_OF_FORK=${GMX_VERSION_STRING_OF_FORK}
432             -D SOURCE_IS_SOURCE_DISTRIBUTION=${SOURCE_IS_SOURCE_DISTRIBUTION}
433             -P ${CMAKE_CURRENT_LIST_DIR}/gmxGenerateVersionInfoWithoutGit.cmake
434         WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
435         COMMENT "Generating release version information")
436     list(APPEND VERSION_INFO_DEPS release-version-info)
437 endif()
438 configure_file(${VERSION_INFO_CMAKEIN_FILE}
439                ${VERSION_INFO_CMAKEIN_FILE_PARTIAL}
440                @ONLY)
441 unset(GMX_VERSION_STRING_FULL)
442 unset(GMX_VERSION_FULL_HASH)
443 unset(GMX_VERSION_CENTRAL_BASE_HASH)
444 unset(GMX_RELEASE_SOURCE_FILE_CHECKSUM)
445 unset(GMX_CURRENT_SOURCE_FILE_CHECKSUM)
446
447
448 # What file the checksum should be written to
449 set(CHECKSUM_FILE "${PROJECT_SOURCE_DIR}/src/reference_checksum")
450
451 # Target that allows checksumming a source tree when producing a tarball.
452 # Allows verification of builds from the tarball to make sure the source had
453 # not been tampered with.
454 # Note: The RUN_ALWAYS here is to regenerate the hash file only, it does not
455 # mean that the target is run in all builds
456 if (HAVE_FULL_FUNCTIONING_PYTHON)
457     # We need the full path to the directories after passing it through
458     set(FULL_PATH_DIRECTORIES "")
459     foreach(DIR ${SET_OF_DIRECTORIES_TO_CHECKSUM})
460         list(APPEND FULL_PATH_DIRECTORIES "${PROJECT_SOURCE_DIR}/${DIR}")
461     endforeach()
462     gmx_add_custom_output_target(reference_checksum RUN_ALWAYS
463         OUTPUT ${CHECKSUM_FILE}
464         COMMAND ${PYTHON_EXECUTABLE}
465             ${PROJECT_SOURCE_DIR}/admin/createFileHash.py
466             -s ${FULL_PATH_DIRECTORIES}
467             -o ${CHECKSUM_FILE}
468         WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
469         COMMENT "Generating reference checksum of source files")
470 else()
471     add_custom_target(reference_checksum
472         COMMAND ${CMAKE_COMMAND} -E echo
473         "Can not checksum files without python3 being available"
474         WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
475         COMMENT "Generating reference checksum of source files")
476 endif()
477
478 # The main user-visible interface to the machinery.
479 # See documentation at the top of the script.
480 function (gmx_configure_version_file INFILE OUTFILE)
481     include(CMakeParseArguments)
482     set(_options REMOTE_HASH)
483     set(_one_value_args COMMENT TARGET)
484     set(_multi_value_args EXTRA_VARS)
485     cmake_parse_arguments(
486         ARG "${_options}" "${_one_value_args}" "${_multi_value_args}" ${ARGN})
487     if (ARG_UNPARSED_ARGUMENTS)
488         message(FATAL_ERROR "Unknown arguments: ${ARG_UNPARSED_ARGUMENTS}")
489     endif()
490     # Some callers may pass partial paths that do not really make sense,
491     # so create a default comment that only contains the actual file name.
492     get_filename_component(_basename ${OUTFILE} NAME)
493     set(_comment "Generating ${_basename}")
494     if (ARG_COMMENT)
495         set(_comment ${ARG_COMMENT})
496     endif()
497     # Mimic configure_file()
498     if (NOT IS_ABSOLUTE ${INFILE})
499         set(INFILE ${CMAKE_CURRENT_SOURCE_DIR}/${INFILE})
500     endif()
501     # Create command-line definitions for the requested variables
502     set(_extra_var_defines)
503     foreach(_var ${ARG_EXTRA_VARS})
504         list(APPEND _extra_var_defines -D "${_var}=${${_var}}")
505     endforeach()
506     # The touch command is necessary to ensure that after the target is run,
507     # the timestamp is newer than in the input files.
508     add_custom_command(OUTPUT ${OUTFILE}
509         COMMAND ${CMAKE_COMMAND}
510             -D VERSION_VARIABLES=${VERSION_INFO_CMAKE_FILE}
511             -D VERSION_CMAKEIN=${INFILE}
512             -D VERSION_OUT=${OUTFILE}
513             ${_extra_var_defines}
514             -P ${VERSION_INFO_CONFIGURE_SCRIPT}
515         COMMAND ${CMAKE_COMMAND} -E touch ${OUTFILE}
516         WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
517         DEPENDS ${INFILE} ${VERSION_INFO_DEPS} ${VERSION_INFO_CONFIGURE_SCRIPT}
518         COMMENT "${_comment}"
519         VERBATIM)
520     if (ARG_TARGET)
521         add_custom_target(${ARG_TARGET} DEPENDS ${OUTFILE} VERBATIM)
522         gmx_set_custom_target_output(${ARG_TARGET} ${OUTFILE})
523     endif()
524 endfunction()