summaryrefslogtreecommitdiff
blob: ca6e56ce19709fafa7d480a6deb24c75160fdf65 (plain)
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
From 41c4a0869d68d894cbe74a63612df75fd1e93bdf Mon Sep 17 00:00:00 2001
From: Michael Orlitzky <michael@orlitzky.com>
Date: Mon, 19 Apr 2021 16:56:54 -0400
Subject: [PATCH 1/1] CMake/FindGMP.cmake: compile a test program to check the
 gmp version.

The existing GMP version check consists of grepping the contents of
the gmp.h header to parse out a few constants. This test fails, at
least, on Gentoo, where the usual header file is a wrapper that
includes the true header to allow for simultaneous 32/64-bit
support.

This commit updates FindGMP to compile a test program against gmp.h
that compares version constants using the C preprocessor. If GMP is
too old, the test program will fail to compile and CMake will know.
---
 CMake/FindGMP.cmake | 91 +++++++++++++++++++++++----------------------
 1 file changed, 47 insertions(+), 44 deletions(-)

diff --git a/CMake/FindGMP.cmake b/CMake/FindGMP.cmake
index ce4df70f5..951151274 100644
--- a/CMake/FindGMP.cmake
+++ b/CMake/FindGMP.cmake
@@ -2,28 +2,23 @@
 # https://gmplib.org/
 #
 # This module supports requiring a minimum version, e.g. you can do
-#   find_package(GMP 6.0.0)
-# to require version 6.0.0 to newer of GMP.
+#   find_package(GMP 6.2.1)
+# to require version 6.2.1 to newer of GMP.
 #
 # Once done this will define
 #
 #  GMP_FOUND - system has GMP lib with correct version
 #  GMP_INCLUDE_DIRS - the GMP include directory
 #  GMP_LIBRARIES - the GMP library
-#  GMP_VERSION - GMP version
 #
-# Copyright (c) 2016 Jack Poulson, <jack.poulson@gmail.com>
-# Redistribution and use is allowed according to the terms of the BSD license.
 
-find_path(GMP_INCLUDE_DIRS NAMES gmp.h PATHS $ENV{GMPDIR} ${INCLUDE_INSTALL_DIR})
-
-# Set GMP_FIND_VERSION to 5.1.0 if no minimum version is specified
+# Set GMP_FIND_VERSION to 6.0.0 if no minimum version is specified
 if(NOT GMP_FIND_VERSION)
   if(NOT GMP_FIND_VERSION_MAJOR)
-    set(GMP_FIND_VERSION_MAJOR 5)
+    set(GMP_FIND_VERSION_MAJOR 6)
   endif()
   if(NOT GMP_FIND_VERSION_MINOR)
-    set(GMP_FIND_VERSION_MINOR 1)
+    set(GMP_FIND_VERSION_MINOR 0)
   endif()
   if(NOT GMP_FIND_VERSION_PATCH)
     set(GMP_FIND_VERSION_PATCH 0)
@@ -32,43 +27,51 @@ if(NOT GMP_FIND_VERSION)
     "${GMP_FIND_VERSION_MAJOR}.${GMP_FIND_VERSION_MINOR}.${GMP_FIND_VERSION_PATCH}")
 endif()
 
-if(GMP_INCLUDE_DIRS)
-  # Since the GMP version macros may be in a file included by gmp.h of the form
-  # gmp-.*[_]?.*.h (e.g., gmp-x86_64.h), we search each of them.
-  file(GLOB GMP_HEADERS "${GMP_INCLUDE_DIRS}/gmp.h" "${GMP_INCLUDE_DIRS}/gmp-*.h"
-	  "${GMP_INCLUDE_DIRS}/x86*/gmp.h")
-  foreach(gmp_header_filename ${GMP_HEADERS})
-    file(READ "${gmp_header_filename}" _gmp_version_header)
-    string(REGEX MATCH
-      "define[ \t]+__GNU_MP_VERSION[ \t]+([0-9]+)" _gmp_major_version_match
-      "${_gmp_version_header}")
-    if(_gmp_major_version_match)
-      set(GMP_MAJOR_VERSION "${CMAKE_MATCH_1}")
-      string(REGEX MATCH "define[ \t]+__GNU_MP_VERSION_MINOR[ \t]+([0-9]+)"
-        _gmp_minor_version_match "${_gmp_version_header}")
-      set(GMP_MINOR_VERSION "${CMAKE_MATCH_1}")
-      string(REGEX MATCH "define[ \t]+__GNU_MP_VERSION_PATCHLEVEL[ \t]+([0-9]+)"
-        _gmp_patchlevel_version_match "${_gmp_version_header}")
-      set(GMP_PATCHLEVEL_VERSION "${CMAKE_MATCH_1}")
-      set(GMP_VERSION
-        ${GMP_MAJOR_VERSION}.${GMP_MINOR_VERSION}.${GMP_PATCHLEVEL_VERSION})
-    endif()
-  endforeach()
+find_path(GMP_INCLUDE_DIRS
+          NAMES gmp.h
+          PATHS $ENV{GMPDIR} ${INCLUDE_INSTALL_DIR})
 
-  # Check whether found version exists and exceeds the minimum requirement
-  if(NOT GMP_VERSION)
-    set(GMP_VERSION_OK FALSE)
-    message(STATUS "GMP version was not detected")
-  elseif(${GMP_VERSION} VERSION_LESS ${GMP_FIND_VERSION})
-    set(GMP_VERSION_OK FALSE)
-    message(STATUS "GMP version ${GMP_VERSION} found in ${GMP_INCLUDE_DIRS}, "
-                   "but at least version ${GMP_FIND_VERSION} is required")
-  else()
-    set(GMP_VERSION_OK TRUE)
-  endif()
+find_library(GMP_LIBRARIES
+             gmp
+             PATHS $ENV{GMPDIR} ${LIB_INSTALL_DIR})
+
+if(GMP_INCLUDE_DIRS AND GMP_LIBRARIES)
+
+  # This program will fail to compile if GMP is too old.
+  # We prefer to perform this "test" at compile-time to
+  # avoid problems with e.g. try_run() during cross-compilation.
+  file(WRITE ${PROJECT_BINARY_DIR}/gmp-version-check.c ""
+  "#include <gmp.h>\n"
+  "\n"
+  "#define GMP_FIND_VERSION_MAJOR ${GMP_FIND_VERSION_MAJOR}\n"
+  "#define GMP_FIND_VERSION_MINOR ${GMP_FIND_VERSION_MINOR}\n"
+  "#define GMP_FIND_VERSION_PATCH ${GMP_FIND_VERSION_PATCH}\n"
+  "\n"
+  "#if __GNU_MP_VERSION < GMP_FIND_VERSION_MAJOR\n"
+  "#error insufficient GMP major version\n"
+  "#elif __GNU_MP_VERSION == GMP_FIND_VERSION_MAJOR\n"
+  "#if __GNU_MP_VERSION_MINOR < GMP_FIND_VERSION_MINOR\n"
+  "#error insufficient GMP minor version\n"
+  "#elif __GNU_MP_VERSION_MINOR == GMP_FIND_VERSION_MINOR\n"
+  "#if __GNU_MP_VERSION_PATCH < GMP_FIND_VERSION_PATCH\n"
+  "#error insufficient GMP patch version\n"
+  "#endif\n"
+  "#endif\n"
+  "#endif\n"
+  "\n"
+  "int main(int argc, char** argv) { return 0; }\n")
+
+  # Try to compile the test program above with the appropriate version
+  # strings substituted in.
+  try_compile(GMP_VERSION_OK
+          "${PROJECT_BINARY_DIR}"
+          "${PROJECT_BINARY_DIR}/gmp-version-check.c"
+          CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${GMP_INCLUDE_DIRS}")
 endif()
 
-find_library(GMP_LIBRARIES gmp PATHS $ENV{GMPDIR} ${LIB_INSTALL_DIR})
+if(NOT GMP_VERSION_OK)
+  message(STATUS "No sufficient GMP version detected")
+endif()
 
 include(FindPackageHandleStandardArgs)
 find_package_handle_standard_args(GMP DEFAULT_MSG
-- 
2.26.3