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