2 # This file is part of the GROMACS molecular simulation package.
4 # Copyright (c) 2014, by the GROMACS development team, led by
5 # Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 # and including many others, as listed in the AUTHORS file in the
7 # top-level source directory and at http://www.gromacs.org.
9 # GROMACS is free software; you can redistribute it and/or
10 # modify it under the terms of the GNU Lesser General Public License
11 # as published by the Free Software Foundation; either version 2.1
12 # of the License, or (at your option) any later version.
14 # GROMACS is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 # Lesser General Public License for more details.
19 # You should have received a copy of the GNU Lesser General Public
20 # License along with GROMACS; if not, see
21 # http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 # If you want to redistribute modifications to GROMACS, please
25 # consider that scientific software is very special. Version
26 # control is crucial - bugs must be traceable. We will be happy to
27 # consider code for inclusion in the official distribution, but
28 # derived work must not be called official GROMACS. Details are found
29 # in the README & COPYING files - if they are missing, get the
30 # official version at http://www.gromacs.org.
32 # To help us fund GROMACS development, we humbly ask that you cite
33 # the research papers on the package. Check out http://www.gromacs.org.
35 # Sets version information variables and provides CMake functions for
36 # generating files based on them
38 # This script provides the following basic version variables that need to be
39 # maintained manually:
40 # GMX_VERSION_MAJOR Major version number.
41 # GMX_VERSION_MINOR Minor version number.
42 # GMX_VERSION_PATCH Patch version number.
43 # Should always be defined: zero for, e.g., 5.0.
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.
47 # LIBRARY_SOVERSION so version for the built libraries.
48 # Should be increased for each binary incompatible release (in GROMACS,
49 # the typical policy is to increase it for each major/minor version
50 # change, but not for patch releases, even if the latter may not always
51 # be fully binary compatible).
52 # LIBRARY_VERSION Full library version.
53 # REGRESSIONTEST_BRANCH For builds not from source packages, name of the
54 # regressiontests branch at gerrit.gromacs.org whose HEAD can test this
55 # code, *if* this code is recent enough (i.e., contains all changes from
56 # the corresponding code branch that affects the regression test
58 # They are collected into a single section below.
59 # The following variables are set based on these:
60 # GMX_VERSION String composed from GMX_VERSION_* numeric variables
61 # above. Example: 4.6.1, 5.0
62 # GMX_VERSION_STRING String with GMX_VERSION suffixed with the given
63 # suffix and possibly "-dev" for builds not from a source package.
64 # GMX_VERSION_NUMERIC Numeric version number (e.g., 40601 for 4.6.1).
65 # GMX_API_VERSION Numeric API version.
66 # This is currently set automatically to GMX_VERSION_NUMERIC, but may
67 # become manually maintained in the future if there will be releases
68 # where the API does not change, but programs/libraries do.
69 # In such a case, this should be the first version where the current API
71 # REGRESSIONTEST_VERSION For source packages, version number of the
72 # matching regressiontests tarball. Not used for builds not from source
74 # The latter two are used to generate gromacs/version.h to allow software
75 # written against the GROMACS API to provide some #ifdef'ed code to support
76 # multiple GROMACS versions.
78 # The following variables are defined without manual intervention:
79 # SOURCE_IS_SOURCE_DISTRIBUTION The source tree is from a source tarball.
80 # SOURCE_IS_GIT_REPOSITORY The source tree is a git repository.
81 # Note that both can be false if the tree has been extracted, e.g., as a
82 # tarball directly from git.
84 # This script also declares machinery to generate and obtain version
85 # information from a git repository. This is enabled by default if the source
86 # tree is a git, but can be disabled with
87 # GMX_GIT_VERSION_INFO Advanced CMake variable to disable git
88 # version info generation.
89 # The main interface to this machinery is the gmx_configure_version_file()
90 # CMake function. The signature is
91 # gmx_configure_version_file(<input> <output>
92 # [REMOTE_HASH] [SOURCE_FILE]
94 # [COMMENT <comment>])
95 # <input> Specify the input and output files as for configure_file().
96 # <output> The configuration is done with configure_file(... @ONLY) with
97 # the following variables defined (as well as all the
98 # GMX_VERSION* variables from above):
99 # GMX_VERSION_STRING_FULL
100 # GMX_VERSION_FULL_HASH
101 # GMX_VERSION_CENTRAL_BASE_HASH
102 # The output file is created during build time, so any dependent
103 # targets should specify it as a dependency.
104 # REMOTE_HASH Currently, this has no effect, but it signifies that the
105 # <input> file is using the CENTRAL_BASE_HASH variable.
106 # This variable is much more expensive to initialize than the
107 # others, so this allows local changes in this file to only
108 # compute that value when required if that becomes necessary.
109 # SOURCE_FILE Signals that <output> will be used as a source file.
110 # The function will set properties for the source file
111 # appropriately to signify that it is generated.
112 # TARGET By default, this function uses add_custom_command() to
113 # generate the output file. If TARGET is specified, then
114 # add_custom_target() is used to create a target with the given
115 # name <target> that runs this custom command. Use this if
116 # the same file will be used for multiple downstream targets,
117 # or if the explicit target for the file is otherwise
119 # COMMENT Set a custom comment to be shown when building the rule
120 # (see add_custom_command(... COMMENT <comment>)).
121 # As an alternative to using this script, also the following variables are
122 # provided (can be useful when generating more complex CMake scripts that do
124 # VERSION_INFO_CMAKE_SCRIPT
125 # Absolute path to a CMake script that can be included using include()
126 # to declare the GMX_VERSION_* variables documented for
127 # gmx_configure_version_file().
129 # If a custom command depends on VERSION_INFO_CMAKE_SCRIPT, then it
130 # should add ${VERSION_INFO_DEPS} to its DEPENDS list to get the
131 # appropriate dependencies.
132 # TODO: If someone wants to add a custom target that depends on
133 # VERSION_INFO_CMAKE_SCRIPT, a separate variable may be needed for those
136 # The version string printed by 'gmx -version' (and also printed in the startup
137 # header) can provide useful information for, e.g., diagnosing bug reports and
138 # identifying what exact version the user was using. The following formats are
139 # possible (with examples given for a particular version):
140 # 4.6.1 Plain version number without any suffix signifies a build from
141 # a released source tarball.
142 # 4.6.1-dev '-dev' suffix signifies all other builds. If there is no other
143 # information, either the user built the code outside any git
144 # repository, or disabled the version info generation.
145 # 4.6.1-dev-YYYYMMDD-1234abc
146 # The YYYYMMDD part shows the commit date (not author date) of
147 # the HEAD commit from which the code was built. The abbreviated
148 # hash is the hash of that commit (the full hash is available in
149 # 'gmx -version' output).
150 # If the HEAD hash is not identified as coming from branches in
151 # "authoritative" GROMACS repositories, 'gmx -version' will show
152 # the nearest ancestor commit that is identified as such (but see
153 # the '-local' and '-unknown' suffixes below).
154 # 4.6.1-dev-YYYYMMDD-1234abc-dirty
155 # As above, but there were local modifications in the source tree
156 # when the code was built.
157 # 4.6.1-dev-YYYYMMDD-1234abc-unknown
158 # As above, but there were no remotes in the repository that
159 # could be identified as "authoritative" GROMACS repositories.
160 # This happens if the code is not cloned from git.gromacs.org
161 # or gerrit.gromacs.org.
162 # 4.6.1-dev-YYYYMMDD-1234abc-local
163 # As above, but there were no commits in the recent history of
164 # the branch that could be identified as coming from
165 # "authoritative" GROMACS repositories. This should be
168 # Other variables set here are not intended for use outside this file.
169 # The scripts gmxGenerateVersionInfo.cmake and gmxConfigureVersionInfo.cmake
170 # are used internally by this machinery, as well as VersionInfo.cmake.cmakein.
172 #####################################################################
173 # Basic nature of the source tree
175 set(SOURCE_IS_GIT_REPOSITORY OFF)
176 set(SOURCE_IS_SOURCE_DISTRIBUTION OFF)
177 if (EXISTS "${PROJECT_SOURCE_DIR}/.git")
178 set(SOURCE_IS_GIT_REPOSITORY ON)
180 # This file is excluded from CPack source packages, but part of the repository,
181 # so it should get included everywhere else.
182 if (NOT EXISTS "${PROJECT_SOURCE_DIR}/admin/.isreposource")
183 set(SOURCE_IS_SOURCE_DISTRIBUTION ON)
186 #####################################################################
187 # Manually maintained version info
189 # The GROMACS convention is that these are the version number of the next
190 # release that is going to be made from this branch.
191 set(GMX_VERSION_MAJOR 5)
192 set(GMX_VERSION_MINOR 1)
193 set(GMX_VERSION_PATCH 0)
194 # The suffix, on the other hand, is used mainly for betas and release
195 # candidates, where it signifies the last such release from this branch;
196 # it will be empty before the first such release, as well as after the
197 # final release is out.
198 set(GMX_VERSION_SUFFIX "")
200 set(LIBRARY_SOVERSION 1)
201 set(LIBRARY_VERSION ${LIBRARY_SOVERSION}.0.0)
203 set(REGRESSIONTEST_BRANCH "refs/heads/master")
205 #####################################################################
206 # General version management based on manually set numbers
208 if (GMX_VERSION_PATCH)
209 set(GMX_VERSION "${GMX_VERSION_MAJOR}.${GMX_VERSION_MINOR}.${GMX_VERSION_PATCH}")
211 set(GMX_VERSION "${GMX_VERSION_MAJOR}.${GMX_VERSION_MINOR}")
213 set(GMX_VERSION_STRING "${GMX_VERSION}${GMX_VERSION_SUFFIX}")
214 if (NOT SOURCE_IS_SOURCE_DISTRIBUTION)
215 set(GMX_VERSION_STRING "${GMX_VERSION_STRING}-dev")
218 set(REGRESSIONTEST_VERSION "${GMX_VERSION_STRING}")
220 math(EXPR GMX_VERSION_NUMERIC
221 "${GMX_VERSION_MAJOR}*10000 + ${GMX_VERSION_MINOR}*100 + ${GMX_VERSION_PATCH}")
222 set(GMX_API_VERSION ${NUM_VERSION})
224 #####################################################################
225 # git version info management
227 # There can be clusters where git and CMake can run on nodes where the other is
228 # not available, accessing the same source tree.
229 # Should be unlikely, but doesn't hurt to check.
230 set(_git_info_default OFF)
231 if (SOURCE_IS_GIT_REPOSITORY)
234 set(_git_info_default ON)
237 option(GMX_GIT_VERSION_INFO "Generate git version information" ${_git_info_default})
238 mark_as_advanced(GMX_GIT_VERSION_INFO)
239 # Detect preconditions for version info generation if it is requested.
240 if (GMX_GIT_VERSION_INFO)
241 if (NOT SOURCE_IS_GIT_REPOSITORY)
243 "Cannot generate git version information from source tree not under git. "
244 "Set GMX_GIT_VERSION_INFO=OFF to proceed.")
246 # We need at least git v1.5.3 be able to parse git's date output.
247 if (NOT GIT_FOUND OR GIT_VERSION_STRING VERSION_LESS "1.5.3")
249 "No compatible git version found (>= 1.5.3 required). "
250 "Won't be able to generate development version information. "
251 "Set GMX_GIT_VERSION_INFO=OFF to proceed.")
255 # The first two are also for use outside this file, encapsulating the details
256 # of how to use the generated VersionInfo.cmake.
257 set(VERSION_INFO_CMAKE_FILE ${PROJECT_BINARY_DIR}/VersionInfo.cmake)
258 set(VERSION_INFO_DEPS ${VERSION_INFO_CMAKE_FILE})
259 # Capture the location of the necessary files in internal variables for use in
260 # the function below.
261 set(VERSION_INFO_CMAKEIN_FILE ${CMAKE_CURRENT_LIST_DIR}/VersionInfo.cmake.cmakein)
262 set(VERSION_INFO_CONFIGURE_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/gmxConfigureVersionInfo.cmake)
264 # Rules to create the VersionInfo.cmake file.
265 # For git info, the sequence is:
266 # 1. (configure time) VersionInfo.cmake.cmakein -> VersionInfo-partial.cmake.cmakein
267 # - Set all variables that are known at configure time.
268 # 2. (build time) VersionInfo-partial.cmake.cmakein -> VersionInfo.cmake
269 # - Set variables that may change as result of repository state changes
270 # (i.e., everything that requires running git).
271 # - Runs every time as a git-version-info target, but the output file
272 # timestamp only changes if its contents actually change.
273 # - Depending on the native build system, this may run once per build
274 # or once per each time it is required for step 3.
275 # 3. (build time) VersionInfo.cmake -> other files
276 # - Set variables in files specified with gmx_configure_version_file()
277 # using the values generated in step 2.
278 # - Each file runs as a custom command that depends on the previous
279 # steps, and runs only if the VersionInfo.cmake file is newer than the
281 # Without git info, the sequence is:
282 # 1. (configure time) VersionInfo.cmake.cmakein -> VersionInfo.cmake
283 # - Everything is known at configure time, so the output is generated
284 # immediately with all variables set (git info will be empty).
285 # 2. (build time) VersionInfo.cmake -> other files
286 # - As with git info, processes files from gmx_configure_version_file().
287 # - These are again custom commands that depend on the output from
288 # step 1, so they get regenerated only when the static version info
290 if (GMX_GIT_VERSION_INFO)
291 # Configure information known at this time into a partially filled
293 set(VERSION_INFO_CMAKEIN_FILE_PARTIAL
294 ${PROJECT_BINARY_DIR}/VersionInfo-partial.cmake.cmakein)
295 # Leave these to be substituted by the custom target below.
296 set(GMX_VERSION_STRING_FULL "\@GMX_VERSION_STRING_FULL\@")
297 set(GMX_VERSION_FULL_HASH "\@GMX_VERSION_FULL_HASH\@")
298 set(GMX_VERSION_CENTRAL_BASE_HASH "\@GMX_VERSION_CENTRAL_BASE_HASH\@")
299 configure_file(${VERSION_INFO_CMAKEIN_FILE}
300 ${VERSION_INFO_CMAKEIN_FILE_PARTIAL}
302 # If generating the version info, create a target that runs on every build
303 # and does the actual git calls, storing the results into a CMake script.
304 # This needs to be run at build time to update the version information
305 # properly when the git hash changes, but the build system does not.
306 # All targets added by gmx_configure_version_file() use the information
307 # from this script to get their variables from, removing the need to run
308 # git multiple times and simplifying reuse for other purposes.
310 # Ninja requires all generated files mentioned in dependencies of custom
311 # commands (in gmx_configure_version_info()) to be actually mentioned in
312 # the build system, and luckily add_custom_command() makes that possible.
313 # But it seems impossible to create a robust custom command that would be
314 # always run, so other generators that do not have this constraint simply
315 # use an add_custom_target().
316 if (CMAKE_GENERATOR STREQUAL "Ninja")
317 # The second, phony file is never created, so the rule is always
318 # triggered again. TODO: Figure out why this works, even though ninja
319 # very eagerly complains about missing files.
320 # This unfortunately does not work with the make generator, as
321 # the non-existent second file causes some part of the generated system
322 # erase the first file at the beginning of every build, causing a full
323 # rebuild of the dependencies.
324 add_custom_command(OUTPUT ${VERSION_INFO_CMAKE_FILE} git-version-phony
325 COMMAND ${CMAKE_COMMAND}
326 -D GIT_EXECUTABLE=${GIT_EXECUTABLE}
327 -D PROJECT_VERSION=${GMX_VERSION_STRING}
328 -D PROJECT_SOURCE_DIR=${PROJECT_SOURCE_DIR}
329 -D VERSION_CMAKEIN=${VERSION_INFO_CMAKEIN_FILE_PARTIAL}
330 -D VERSION_OUT=${VERSION_INFO_CMAKE_FILE}
331 -P ${CMAKE_CURRENT_LIST_DIR}/gmxGenerateVersionInfo.cmake
332 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
333 COMMENT "Generating git version information"
335 # The generated Ninja build system would probably work fine even
336 # without this target, but CMake requires all custom commands to belong
337 # to a target in the same CMakeLists.txt to generate anything for them.
338 add_custom_target(git-version-info DEPENDS ${VERSION_INFO_CMAKE_FILE})
340 # For other generators, a target-level dependency on git-version-info
341 # ensures that VERSION_INFO_CMAKE_FILE is created before the dependent
342 # target's dependencies are even evaluated.
343 add_custom_target(git-version-info
344 COMMAND ${CMAKE_COMMAND}
345 -D GIT_EXECUTABLE=${GIT_EXECUTABLE}
346 -D PROJECT_VERSION=${GMX_VERSION_STRING}
347 -D PROJECT_SOURCE_DIR=${PROJECT_SOURCE_DIR}
348 -D VERSION_CMAKEIN=${VERSION_INFO_CMAKEIN_FILE_PARTIAL}
349 -D VERSION_OUT=${VERSION_INFO_CMAKE_FILE}
350 -P ${CMAKE_CURRENT_LIST_DIR}/gmxGenerateVersionInfo.cmake
351 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
352 COMMENT "Generating git version information"
355 list(APPEND VERSION_INFO_DEPS git-version-info)
357 # If the version info is static, just generate the CMake script with the
358 # version variables during the CMake run.
359 set(GMX_VERSION_STRING_FULL ${GMX_VERSION_STRING})
360 set(GMX_VERSION_FULL_HASH "")
361 set(GMX_VERSION_CENTRAL_BASE_HASH "")
362 configure_file(${VERSION_INFO_CMAKEIN_FILE} ${VERSION_INFO_CMAKE_FILE})
364 unset(GMX_VERSION_STRING_FULL)
365 unset(GMX_VERSION_FULL_HASH)
366 unset(GMX_VERSION_CENTRAL_BASE_HASH)
368 # The main user-visible interface to the machinery.
369 # See documentation at the top of the script.
370 function (gmx_configure_version_file INFILE OUTFILE)
371 include(CMakeParseArguments)
372 set(_options REMOTE_HASH SOURCE_FILE)
373 set(_one_value_args COMMENT TARGET)
374 cmake_parse_arguments(ARG "${_options}" "${_one_value_args}" "" ${ARGN})
375 if (ARG_UNPARSED_ARGUMENTS)
376 message(FATAL_ERROR "Unknown arguments: ${ARG_UNPARSED_ARGUMENTS}")
378 # Some callers may pass partial paths that do not really make sense,
379 # so create a default comment that only contains the actual file name.
380 get_filename_component(_basename ${OUTFILE} NAME)
381 set(_comment "Generating ${_basename}")
383 set(_comment ${ARG_COMMENT})
385 # Mimic configure_file()
386 if (NOT IS_ABSOLUTE ${INFILE})
387 set(INFILE ${CMAKE_CURRENT_SOURCE_DIR}/${INFILE})
389 # The touch command is necessary to ensure that after the target is run,
390 # the timestamp is newer than in the input files.
391 add_custom_command(OUTPUT ${OUTFILE}
392 COMMAND ${CMAKE_COMMAND}
393 -D VERSION_VARIABLES=${VERSION_INFO_CMAKE_FILE}
394 -D VERSION_CMAKEIN=${INFILE}
395 -D VERSION_OUT=${OUTFILE}
396 -P ${VERSION_INFO_CONFIGURE_SCRIPT}
397 COMMAND ${CMAKE_COMMAND} -E touch ${OUTFILE}
398 WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
399 DEPENDS ${INFILE} ${VERSION_INFO_DEPS} ${VERSION_INFO_CONFIGURE_SCRIPT}
400 COMMENT "${_comment}"
403 add_custom_target(${ARG_TARGET} DEPENDS ${OUTFILE} VERBATIM)
406 set_source_files_properties(${OUTFILE} PROPERTIES GENERATED true)