Przeglądaj źródła

Compile GMP and MPFR from source (#1985)

* working x86_64 build on M1 mac

* rm comment debris

* link gmp to mpfr to fix link order issue on linux

* organize gmp and mpfr in _deps with others

* rm gmp + mpfr from workflows
Alec Jacobson 3 lat temu
rodzic
commit
f9547b8e56

+ 1 - 2
.github/workflows/continuous.yml

@@ -49,7 +49,6 @@ jobs:
               libblas-dev \
               libglu1-mesa-dev \
               liblapack-dev \
-              libmpfr-dev \
               xorg-dev \
               ccache
 
@@ -57,7 +56,7 @@ jobs:
         if: runner.os == 'macOS'
         run: |
           brew update
-          brew install gmp mpfr ccache
+          brew install ccache
 
       - name: Cache Build
         id: cache-build

+ 0 - 10
CMakeLists.txt

@@ -53,7 +53,6 @@ endif()
 
 set_property(GLOBAL PROPERTY __igl_module_path ${CMAKE_MODULE_PATH})
 
-# Check for gmp + mpfr and enable cork / cgal modules accordingly
 set(LIBIGL_DEFAULT_CGAL ${LIBIGL_TOPLEVEL_PROJECT})
 set(MATLAB_ADDITIONAL_VERSIONS
     "R2022b=10.3"
@@ -64,15 +63,6 @@ set(MATLAB_ADDITIONAL_VERSIONS
 set(LIBIGL_DEFAULT_MATLAB ${LIBIGL_TOPLEVEL_PROJECT})
 set(LIBIGL_DEFAULT_MOSEK ${LIBIGL_TOPLEVEL_PROJECT})
 if(LIBIGL_TOPLEVEL_PROJECT)
-    if(NOT WIN32)
-        find_package(GMP QUIET)
-        find_package(MPFR QUIET)
-        if(NOT (TARGET gmp::gmp AND TARGET mpfr::mpfr))
-            set(LIBIGL_DEFAULT_CGAL OFF)
-            message(WARNING "Missing dependencies GMP and MPFR. The libigl modules for cork and cgal "
-                            "will be disabled by default.")
-        endif()
-    endif()
     find_package(Matlab QUIET)
     if(NOT Matlab_FOUND)
         set(LIBIGL_DEFAULT_MATLAB OFF)

+ 43 - 4
cmake/recipes/external/gmp.cmake

@@ -3,12 +3,51 @@ if(TARGET gmp::gmp)
 endif()
 
 # Download precompiled .dll on Windows
-include(gmp_mpfr)
+if(WIN32)
+  include(gmp_mpfr)
+  # Find_package will look for our downloaded lib on Windows, and system-wide on Linux/macOS
+  find_package(GMP REQUIRED)
+else()
+  message(STATUS "Third-party: creating target 'gmp::gmp'")
 
-message(STATUS "Third-party: creating target 'gmp::gmp'")
+  include(FetchContent)
+  include(ProcessorCount)
+  ProcessorCount(Ncpu)
+  include(ExternalProject)
+  set(prefix ${FETCHCONTENT_BASE_DIR}/gmp)
+  set(gmp_INSTALL ${prefix}/install)
+  set(gmp_LIB_DIR ${gmp_INSTALL}/lib)
+  set(gmp_LIBRARY ${gmp_LIB_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}gmp${CMAKE_STATIC_LIBRARY_SUFFIX})
+  set(gmp_INCLUDE_DIR ${gmp_INSTALL}/include)
 
-# Find_package will look for our downloaded lib on Windows, and system-wide on Linux/macOS
-find_package(GMP REQUIRED)
+  ExternalProject_Add(gmp
+    PREFIX ${prefix}
+    URL  https://gmplib.org/download/gmp/gmp-6.2.1.tar.xz
+    URL_MD5 0b82665c4a92fd2ade7440c13fcaa42b
+    UPDATE_DISCONNECTED true  # need this to avoid constant rebuild
+    PATCH_COMMAND 
+      curl "https://gmplib.org/repo/gmp/raw-rev/5f32dbc41afc" "|" git apply -v
+    CONFIGURE_HANDLED_BY_BUILD ON  # avoid constant reconfigure
+    CONFIGURE_COMMAND 
+      ${prefix}/src/gmp/configure 
+      --disable-debug --disable-dependency-tracking --enable-cxx --with-pic
+      --prefix=${gmp_INSTALL}
+      --disable-shared
+    BUILD_COMMAND make -j${Ncpu}
+    INSTALL_COMMAND make -j${Ncpu} install
+    INSTALL_DIR ${gmp_INSTALL}
+    TEST_COMMAND ""
+    BUILD_BYPRODUCTS ${gmp_LIBRARY}
+  )
+  ExternalProject_Get_Property(gmp SOURCE_DIR)
+  set(gmp_LIBRARIES ${gmp_LIBRARY})
+  add_library(gmp::gmp INTERFACE IMPORTED GLOBAL)
+  file(MAKE_DIRECTORY ${gmp_INCLUDE_DIR})  # avoid race condition
+  target_include_directories(gmp::gmp INTERFACE ${gmp_INCLUDE_DIR})
+  target_link_libraries(gmp::gmp INTERFACE "${gmp_LIBRARIES}")  # need the quotes to expand list
+  add_dependencies(gmp::gmp gmp)
+
+endif()
 
 if(NOT TARGET gmp::gmp)
     message(FATAL_ERROR "Creation of target 'gmp::gmp' failed")

+ 1 - 1
cmake/recipes/external/gmp_mpfr.cmake

@@ -30,5 +30,5 @@ if(WIN32)
     set(ENV{GMP_DIR} "${gmp_SOURCE_DIR}")
     set(ENV{MPFR_DIR} "${mpfr_SOURCE_DIR}")
 else()
-    # On Linux/macOS, gmp+mpfr should be installed system-wide
+    # On Linux/macOS, gmp+mpfr will be fetched and compiled
 endif()

+ 50 - 4
cmake/recipes/external/mpfr.cmake

@@ -1,14 +1,60 @@
+# Expects
+#   gmp_INCLUDE_DIR
+#   gmp_LIB_DIR
+#   gmp_LIBRARIES
 if(TARGET mpfr::mpfr)
     return()
 endif()
 
 # Download precompiled .dll on Windows
-include(gmp_mpfr)
+if(WIN32)
+  include(gmp_mpfr)
+  # Find_package will look for our downloaded lib on Windows, and system-wide on Linux/macOS
+  find_package(MPFR REQUIRED)
+else()
+  message(STATUS "Third-party: creating target 'mpfr::mpfr'")
 
-message(STATUS "Third-party: creating target 'mpfr::mpfr'")
+  include(FetchContent)
+  include(ProcessorCount)
+  ProcessorCount(Ncpu)
+  include(ExternalProject)
+  set(prefix ${FETCHCONTENT_BASE_DIR}/mpfr)
+  set(mpfr_INSTALL ${prefix}/install)
+  set(mpfr_LIBRARY ${mpfr_INSTALL}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}mpfr${CMAKE_STATIC_LIBRARY_SUFFIX})
+  set(mpfr_INCLUDE_DIR ${mpfr_INSTALL}/include)
 
-# Find_package will look for our downloaded lib on Windows, and system-wide on Linux/macOS
-find_package(MPFR REQUIRED)
+  ExternalProject_Add(mpfr
+    PREFIX ${prefix}
+    DEPENDS gmp
+    URL  https://ftp.gnu.org/gnu/mpfr/mpfr-4.1.0.tar.xz
+    URL_MD5 bdd3d5efba9c17da8d83a35ec552baef
+    UPDATE_DISCONNECTED true  # need this to avoid constant rebuild
+    CONFIGURE_HANDLED_BY_BUILD ON  # avoid constant reconfigure
+    CONFIGURE_COMMAND 
+      ${prefix}/src/mpfr/configure 
+      --disable-debug --disable-dependency-tracking  --disable-silent-rules --enable-cxx --with-pic
+      --with-gmp-include=${gmp_INCLUDE_DIR} --with-gmp-lib=${gmp_LIB_DIR}
+      --disable-shared
+      --prefix=${mpfr_INSTALL}
+      --disable-shared
+    BUILD_COMMAND make -j${Ncpu}
+    INSTALL_COMMAND make -j${Ncpu} install
+    INSTALL_DIR ${mpfr_INSTALL}
+    TEST_COMMAND ""
+    BUILD_BYPRODUCTS ${mpfr_LIBRARY}
+  )
+  #PATCH_COMMAND  curl "https://raw.githubusercontent.com/Homebrew/formula-patches/03cf8088210822aa2c1ab544ed58ea04c897d9c4/libtool/configure-big_sur.diff" "|" sed -e "s/configure.orig/configure/g" "|" git apply -v
+  ExternalProject_Get_Property(mpfr SOURCE_DIR)
+  set(mpfr_LIBRARIES ${mpfr_LIBRARY})
+  add_library(mpfr::mpfr INTERFACE IMPORTED GLOBAL)
+  file(MAKE_DIRECTORY ${mpfr_INCLUDE_DIR})  # avoid race condition
+  target_include_directories(mpfr::mpfr INTERFACE ${mpfr_INCLUDE_DIR})
+  target_link_libraries(mpfr::mpfr INTERFACE "${mpfr_LIBRARIES}")  # need the quotes to expand list
+  # This is necessary to ensure that mpfr appears before gmp in link order.
+  # Otherwise undefined reference errors occur at link time on Linux with gcc
+  target_link_libraries(mpfr::mpfr INTERFACE "${gmp_LIBRARIES}") 
+  add_dependencies(mpfr::mpfr mpfr)
+endif()
 
 if(NOT TARGET mpfr::mpfr)
     message(FATAL_ERROR "Creation of target 'mpfr::mpfr' failed")