[CMake] Improve FindGMP (#8846)
authorAndres Noetzli <andres.noetzli@gmail.com>
Mon, 6 Jun 2022 22:16:15 +0000 (15:16 -0700)
committerGitHub <noreply@github.com>
Mon, 6 Jun 2022 22:16:15 +0000 (22:16 +0000)
Fixes #8792. This commit fixes issues with/improves our current
implementation of FindGMP:

- Version check that does not rely on regex matches in `gmp.h`. Instead,
  this commit uses a test program that checks at compile-time whether
  the GMP version is recent enough. This is more robust, because on some
  systems (such as Fedora), `gmp.h` includes another file that has that
  version information.
- It now also checks for the `gmpxx.h` header and the `gmpxx` library.
- The commit changes the compile test to use the include directories and
  libraries that were found using `find_path` and `find_library`.

cmake/FindGMP.cmake
cmake/deps-utils/gmp-test.cpp

index f63cf7c2658e4626d89dc18be65b62a6ac9cb881..2e2afb89817524998308409fc8281fb5a9fb7e41 100644 (file)
 
 include(deps-helper)
 
-find_path(GMP_INCLUDE_DIR NAMES gmp.h gmpxx.h)
+find_path(GMP_INCLUDE_DIR NAMES gmp.h)
+find_path(GMPXX_INCLUDE_DIR NAMES gmpxx.h)
 find_library(GMP_LIBRARIES NAMES gmp)
+find_library(GMPXX_LIBRARIES NAMES gmpxx)
 
 set(GMP_FOUND_SYSTEM FALSE)
-if(GMP_INCLUDE_DIR AND GMP_LIBRARIES)
+if(GMP_INCLUDE_DIR AND GMPXX_INCLUDE_DIR AND GMP_LIBRARIES AND GMPXX_LIBRARIES)
   set(GMP_FOUND_SYSTEM TRUE)
 
+  # Attempt to retrieve the version from gmp.h
   function(getversionpart OUTPUT FILENAME DESC)
     file(STRINGS ${FILENAME} RES REGEX "^#define __GNU_MP_${DESC}[ \\t]+.*")
     string(REGEX MATCH "[0-9]+" RES "${RES}")
@@ -35,19 +38,26 @@ if(GMP_INCLUDE_DIR AND GMP_LIBRARIES)
   getversionpart(MAJOR "${GMP_INCLUDE_DIR}/gmp.h" "VERSION")
   getversionpart(MINOR "${GMP_INCLUDE_DIR}/gmp.h" "VERSION_MINOR")
   getversionpart(PATCH "${GMP_INCLUDE_DIR}/gmp.h" "VERSION_PATCHLEVEL")
-  set(GMP_VERSION
-      "${MAJOR}.${MINOR}.${PATCH}"
-  )
 
-  check_system_version("GMP")
+  if(MAJOR AND MINOR AND PATCH)
+    set(GMP_VERSION
+        "${MAJOR}.${MINOR}.${PATCH}"
+    )
+  else()
+    set(GMP_VERSION "(unknown version)")
+  endif()
 
-  TRY_COMPILE(DOES_WORK "${DEPS_BASE}/try_compile/GMP-EP"
+  # This test checks whether GMP is usable and whether the version is new
+  # enough
+  try_compile(GMP_USABLE "${DEPS_BASE}/try_compile/GMP-EP"
     "${CMAKE_CURRENT_LIST_DIR}/deps-utils/gmp-test.cpp"
-    CMAKE_FLAGS -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
-    LINK_LIBRARIES gmpxx gmp
+    CMAKE_FLAGS
+      "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}"
+      "-DINCLUDE_DIRECTORIES=${GMP_INCLUDE_DIR}"
+    LINK_LIBRARIES ${GMP_LIBRARIES} ${GMPXX_LIBRARIES}
   )
-  if(NOT ${DOES_WORK})
-    message(VERBOSE "System version for ${name} does not work in the selected configuration. Maybe we are cross-compiling?")
+  if(NOT GMP_USABLE)
+    message(VERBOSE "System version for GMP does not work in the selected configuration. Maybe we are cross-compiling?")
     set(GMP_FOUND_SYSTEM FALSE)
   endif()
 endif()
index 88d1ca62c92739f44baa5c2eaeff5ae6e8d6fd8e..c845a2587ad078da678249ce85f032153d31b700 100644 (file)
@@ -1,5 +1,9 @@
 #include <gmpxx.h>
 
+#if __GNU_MP_RELEASE < 60100
+#error "GMP version too old (version >= 6.1 required)"
+#endif
+
 int main()
 {
   mpz_class i = 0;