Make python check if modules are available for checksumming
[alexxy/gromacs.git] / cmake / gmxGenerateVersionInfoWithoutGit.cmake
1 #
2 # This file is part of the GROMACS molecular simulation package.
3 #
4 # Copyright (c) 2020,2021, 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.
8 #
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.
13 #
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.
18 #
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.
23 #
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.
31 #
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.
34
35 # Generate GROMACS release build version information, as well as build
36 # directory integrity checking.
37
38 # This script generates version information for a build from a release tarball
39 # source tree based on the release information in the released tarball.
40 # It is assumed that by default the script is run in cmake script mode.
41 # If *not* called in script mode but used in generating cache variables,
42 # GEN_VERSION_INFO_INTERNAL has to be set ON.
43 #
44 # The following variables have to be previously defined:
45 # PROJECT_VERSION               - hard-coded version string (generated info is appended)
46 # PROJECT_SOURCE_DIR            - top level source directory
47 # SOURCE_IS_SOURCE_DISTRIBUTION - Whether we are building from source or tarball
48 # DIRECTORIES_TO_CHECKSUM       - List of directories to hash
49 # VERSION_CMAKEIN               - path to an input template file
50 # VERSION_OUT                   - path to the output file
51 # HAVE_FUNCTIONING_PYTHON       - Whether the python used can do the checking.
52 #
53 # The following a possible additional definitions
54 # PYTHON_EXECUTABLE             - Needed to run checking stage of current tree
55 # VERSION_STRING_OF_FORK        - Possibly defined custom version string to override
56 #                                 process of checking source file hashes.
57 # Output:
58 # VERSION_OUT is configured from the input VERSION_CMAKEIN
59 # using the variables listed below.
60 #
61 # GMX_VERSION_STRING_FULL       - version string
62 # GMX_RELEASE_SOURCE_FILE_CHECKSUM - Sha256 hash of source tree files at release
63 # GMX_CURRENT_SOURCE_FILE_CHECKSUM - Sha256 hash of current source tree files
64 #
65 # Paul Bauer (paul.bauer.q@gmail.com)
66 # (authors of git Version of the script that this is based on below)
67 # Szilard Pall (pszilard@cbr.su.se)
68 # Teemu Murtola (teemu.murtola@gmail.com)
69
70 # Check input variables.
71 if("${PROJECT_VERSION}" STREQUAL "")
72     message(FATAL_ERROR "PROJECT_VERSION undefined!")
73 endif()
74 if (NOT EXISTS "${PROJECT_SOURCE_DIR}")
75     message(FATAL_ERROR "Project source directory ${PROJECT_SOURCE_DIR} does not exist")
76 endif()
77 if ("${DIRECTORIES_TO_CHECKSUM}" STREQUAL "")
78     message(FATAL_ERROR "Need list of directories to generate the hash for")
79 endif()
80 if ("${VERSION_CMAKEIN}" STREQUAL "")
81     message(FATAL_ERROR "Missing input parameter VERSION_CMAKEIN!")
82 endif()
83 if ("${VERSION_OUT}" STREQUAL "")
84     message(FATAL_ERROR "Missing input parameter VERSION_OUT!")
85 endif()
86 if ("${SOURCE_IS_SOURCE_DISTRIBUTION}" STREQUAL "")
87     message(FATAL_ERROR "SOURCE_IS_SOURCE_DISTRIBUTION undefined!")
88 endif()
89
90 # Prepare version string to populate
91 set(GMX_VERSION_STRING_FULL          ${PROJECT_VERSION})
92
93 # We had to pass the directory list as a string, so now we convert it back to a list
94 string(REPLACE ":" ";" DIRECTORIES_TO_CHECKSUM_LIST ${DIRECTORIES_TO_CHECKSUM})
95
96 # We need the full path to the directories after passing it through
97 set(FULL_PATH_DIRECTORIES "")
98 foreach(DIR ${DIRECTORIES_TO_CHECKSUM_LIST})
99     list(APPEND FULL_PATH_DIRECTORIES "${PROJECT_SOURCE_DIR}/${DIR}")
100 endforeach()
101
102 # Change path depending on if this is a source distribution (e.g. release tarball)
103 # or just a source directory that is managed by something else, like an IDE.
104 # If the git executable isn't found by CMake, there will not be version info even
105 # if the .git folder is present and SOURCE_IS_GIT_REPOSITORY is true.
106 # Don't issue warnings in this case.
107 if (SOURCE_IS_SOURCE_DISTRIBUTION)
108     # Prepare for checking source tree file hashes.
109     # To notify the user during compilation and at runtime that the build source
110     # has not been modified after unpacking the source tarball, the contents are hashed
111     # to be compared to a hash computed during the release process. If the hash matches
112     # all is fine and the user gets a message in the log file indicating that.
113     # If either the release hash file is missing, or if the hash does not match
114     # a different message is printed to indicate that the source has been changed
115     # compared to the version actually released. This is not needed in case a build
116     # is done in git, as we have the information there already.
117     # This is not done if the user has explicitly set an additional custom version string with
118     # -DGMX_VERSION_STRING_OF_FORK, as this indicates that they are knowing that a custom
119     # version of GROMACS is in use.
120     set(RELEASE_CHECKSUM_FILE "${PROJECT_SOURCE_DIR}/src/reference_checksum")
121     if(NOT VERSION_STRING_OF_FORK OR "${VERSION_STRING_OF_FORK}" STREQUAL "")
122         if(EXISTS ${RELEASE_CHECKSUM_FILE} AND HAVE_FULL_FUNCTIONING_PYTHON)
123             file(READ ${RELEASE_CHECKSUM_FILE} GMX_RELEASE_SOURCE_FILE_CHECKSUM)
124             string(STRIP ${GMX_RELEASE_SOURCE_FILE_CHECKSUM} GMX_RELEASE_SOURCE_FILE_CHECKSUM)
125             set(CHECKSUM_RESULT_FILE "${CMAKE_CURRENT_BINARY_DIR}/computed_checksum")
126             execute_process(COMMAND ${PYTHON_EXECUTABLE}
127                                     ${PROJECT_SOURCE_DIR}/admin/createFileHash.py
128                                     -s ${FULL_PATH_DIRECTORIES}
129                                     -o ${CHECKSUM_RESULT_FILE}
130                             WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
131                             OUTPUT_QUIET)
132                         file(READ ${CHECKSUM_RESULT_FILE} GMX_CURRENT_SOURCE_FILE_CHECKSUM)
133             string(STRIP ${GMX_CURRENT_SOURCE_FILE_CHECKSUM} GMX_CURRENT_SOURCE_FILE_CHECKSUM)
134             if(NOT ${GMX_RELEASE_SOURCE_FILE_CHECKSUM} STREQUAL ${GMX_CURRENT_SOURCE_FILE_CHECKSUM})
135                 set(GMX_VERSION_STRING_FULL "${GMX_VERSION_STRING_FULL}-MODIFIED")
136                 message(STATUS "The source code for this GROMACS installation is different from the officially released version.")
137             endif()
138         elseif(HAVE_FULL_FUNCTIONING_PYTHON)
139             set(GMX_VERSION_STRING_FULL "${GMX_VERSION_STRING_FULL}-UNCHECKED")
140             set(GMX_RELEASE_SOURCE_FILE_CHECKSUM "NoChecksumFile")
141             set(GMX_CURRENT_SOURCE_FILE_CHECKSUM "NoChecksumFile")
142             message(WARNING "Could not valdiate the GROMACS source due to missing reference checksum file.")
143         else()
144             set(GMX_VERSION_STRING_FULL "${GMX_VERSION_STRING_FULL}-UNCHECKED")
145             set(GMX_RELEASE_SOURCE_FILE_CHECKSUM "NoPythonAvailable")
146             set(GMX_CURRENT_SOURCE_FILE_CHECKSUM "NoPythonAvailable")
147             message(STATUS "Could not calculate checksum of source files without functioning Python")
148         endif()
149     endif()
150 else()
151     set(GMX_VERSION_STRING_FULL "${GMX_VERSION_STRING_FULL}-UNCHECKED")
152     set(GMX_RELEASE_SOURCE_FILE_CHECKSUM "NotSourceDistribution")
153     set(GMX_CURRENT_SOURCE_FILE_CHECKSUM "NotSourceDistribution")
154     message(STATUS "Build without git or source information")
155 endif()
156
157 # Generate the output file.
158 configure_file(${VERSION_CMAKEIN} ${VERSION_OUT})