# Based on a project at https://github.com/gx/gmp # Copyright 2019 Free Software Foundation, Inc. # # This file is part of the GNU MP Library. # # The GNU MP Library is free software; you can redistribute it and/or modify # it under the terms of either: # # * the GNU Lesser General Public License as published by the Free # Software Foundation; either version 3 of the License, or (at your # option) any later version. # # or # # * the GNU General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) any # later version. # # or both in parallel, as here. # # The GNU MP Library is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received copies of the GNU General Public License and the # GNU Lesser General Public License along with the GNU MP Library. If not, # see https://www.gnu.org/licenses/. cmake_minimum_required(VERSION 3.12.2) project(GMP VERSION $ENV{PROJECT_VERSION} DESCRIPTION "GNU Multiple Precision Arithmetic Library" HOMEPAGE_URL "https://gmplib.org" LANGUAGES C CXX ASM) # These should be updated per release based on the contents of Makefile.in set(LIBGMP_LT_CURRENT $ENV{LIB_MAJOR_VERSION}) #set(LIBGMP_LT_CURRENT 15) set(LIBGMP_LT_REVISION 0) set(LIBGMP_LT_AGE 5) set(LIBGMPXX_LT_CURRENT $ENV{LIBXX_MAJOR_VERSION}) #set(LIBGMPXX_LT_CURRENT 11) set(LIBGMPXX_LT_REVISION 0) set(LIBGMPXX_LT_AGE 7) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) # Use solution folders for Visual Studio set_property(GLOBAL PROPERTY USE_FOLDERS ON) # Package information # Set the name of this package. set(PACKAGE "gmp") # Set the full name of this package. set(PACKAGE_NAME "GNU MP") # Set the one symbol short name of this package. set(PACKAGE_TARNAME "gmp") # Set the version of this package. set(PACKAGE_VERSION "${GMP_VERSION}") # Set the full name and version of this package. set(PACKAGE_STRING "${PACKAGE_NAME} ${GMP_VERSION}") # Set the home page for this package. set(PACKAGE_URL "http://www.gnu.org/software/gmp/") # Set the address where bug reports for this package should be sent. set(PACKAGE_BUGREPORT "gmp-bugs@gmplib.org, see https://gmplib.org/manual/Reporting-Bugs.html") # Set the return type of signal handlers (`int' or `void'). set(RETSIGTYPE void) # Disable the use of inline assembly. set(NO_ASM 1) set(VERSION ${GMP_VERSION}) include(CheckCSourceCompiles) include(CheckIncludeFile) include(CheckIncludeFiles) include(CheckIncludeFileCXX) include(CheckFunctionExists) include(CheckCXXSymbolExists) include(CheckSymbolExists) include(CheckTypeSize) include(CMakePackageConfigHelpers) include(GNUInstallDirs) option(RUN_TESTS "Enable tests suite" OFF) option(BUILD_DEMOS "Build demonstration applications" OFF) option(WANT_ASSERT "Enable ASSERT checking" OFF) option(WANT_FFT "Enable FFTs for multiplication" ON) option(WANT_OLD_FFT_FULL "Enable old mpn_mul_fft_full for multiplication" OFF) option(WANT_FAKE_CPUID "Enable GMP_CPU_TYPE faking cpuid" OFF) option(WANT_FAT_BINARY "Enable fat binary" OFF) option(WANT_CXX "Enable C++ wrapper" ON) if(SIZEOF_VOID_P EQUAL 8) set(GMP_MPARAM_H_SUGGEST ${CMAKE_SOURCE_DIR}/mpn/x86_64/k8/gmp-mparam.h) else() set(GMP_MPARAM_H_SUGGEST ${CMAKE_SOURCE_DIR}/mpn/x86/gmp-mparam.h) endif() set(WANT_TMP_ALLOCA 1) set(HAVE_HOST_CPU_FAMILY_power 0) set(HAVE_HOST_CPU_FAMILY_powerpc 0) if(CMAKE_SIZEOF_VOID_P EQUAL 8) set(GMP_LIMB_BITS 64) set(DEFN_LONG_LONG_LIMB "#define _LONG_LONG_LIMB 1") set(HOST_DOS64 1) else() set(GMP_LIMB_BITS 32) set(DEFN_LONG_LONG_LIMB "") endif() set(GMP_NAIL_BITS 0 CACHE STRING "Use nails on limbs") set(LIBGMP_DLL 1) set(CC ${CMAKE_C_COMPILER}) set(CFLAG ${CMAKE_C_FLAGS}) # Package config values. set(prefix "$ENV{PREFIX}") set(exec_prefix "${prefix}") set(includedir "${prefix}/include") set(libdir "${exec_prefix}/lib") configure_file(gmp-h.in gmp.h @ONLY) configure_file(gmp.pc.in gmp.pc @ONLY) configure_file(gmpxx.pc.in gmpxx.pc @ONLY) # Check whether gcc __attribute__ ((const)) works. check_c_source_compiles( "int foo(int x) __attribute__((const)); int main() {}" HAVE_ATTRIBUTE_CONST) # Check whether gcc __attribute__ ((malloc)) works. check_c_source_compiles( "void *foo(int x) __attribute ((malloc)); int main() {}" HAVE_ATTRIBUTE_MALLOC) # Check whether gcc __attribute__ ((mode (XX))) works. check_c_source_compiles( "tyedef int SItype __attribute__ ((mode (SI))); int main() {}" HAVE_ATTRIBUTE_MODE) # Check whether gcc __attribute__ ((noreturn)) works. check_c_source_compiles( "void foo(int x) __attribute__ ((noreturn)); int main() {}" HAVE_ATTRIBUTE_NORETURN) # Check header files # Set to 1 if you have the ANSI C header files. set(STDC_HEADERS 1) check_include_file(alloca.h HAVE_ALLOCA_H) check_include_file(dlfcn.h HAVE_DLFCN_H) check_include_file(fcntl.h HAVE_FCNTL_H) check_include_file(float.h HAVE_FLOAT_H) check_include_file(inttypes.h HAVE_INTTYPES_H) check_include_file(invent.h HAVE_INVENT_H) check_include_file(langinfo.h HAVE_LANGINFO_H) check_include_file(locale.h HAVE_LOCALE_H) check_include_file(machine/hal_sysinfo.h HAVE_MACHINE_HAL_SYSINFO_H) check_include_file(memory.h HAVE_MEMORY_H) check_include_file(nl_types.h HAVE_NL_TYPES_H) check_include_file_cxx(sstream HAVE_SSTREAM) check_include_file(stdint.h HAVE_STDINT_H) check_include_file(stdlib.h HAVE_STDLIB_H) check_include_file(strings.h HAVE_STRINGS_H) check_include_file(string.h HAVE_STRING_H) check_include_file(sys/attributes.h HAVE_SYS_ATTRIBUTES_H) check_include_file(sys/iograph.h HAVE_SYS_IOGRAPH_H) check_include_file(sys/mman.h HAVE_SYS_MMAN_H) check_include_file(sys/processor.h HAVE_SYS_PROCESSOR_H) check_include_file(sys/pstat.h HAVE_SYS_PSTAT_H) check_include_file(sys/resource.h HAVE_SYS_RESOURCE_H) check_include_file(sys/stat.h HAVE_SYS_STAT_H) check_include_file(sys/sysctl.h HAVE_SYS_SYSCTRL_H) check_include_file(sys/sysinfo.h HAVE_SYS_SYSINFO_H) check_include_file(sys/syssgi.h HAVE_SYS_SYSSGI_H) check_include_file(sys/systemcfg.h HAVE_SYS_SYSTEMCFG_H) check_include_file(sys/times.h HAVE_SYS_TIMES_H) check_include_file(sys/time.h HAVE_SYS_TIME_H) check_include_file(sys/types.h HAVE_SYS_TYPES_H) check_include_file(unistd.h HAVE_UNISTD_H) check_include_files("sys/time.h;time.h" TIME_WITH_SYS_TIME) # Check functions check_function_exists(alarm HAVE_ALARM) check_function_exists(alloca HAVE_ALLOCA) check_function_exists(attr_get HAVE_ATTR_GET) check_function_exists(clock HAVE_CLOCK) check_function_exists(clock_gettime HAVE_CLOCK_GETTIME) check_function_exists(cputime HAVE_CPUTIME) check_function_exists(getpagesize HAVE_GETPAGESIZE) check_function_exists(getrusage HAVE_GETRUSAGE) check_function_exists(getsysinfo HAVE_GETSYSINFO) check_function_exists(gettimeofday HAVE_GETTIMEOFDAY) check_function_exists(localeconv HAVE_LOCALECONV) check_function_exists(memset HAVE_MEMSET) check_function_exists(mmap HAVE_MMAP) check_function_exists(mprotect HAVE_MPROTECT) check_function_exists(nl_langinfo HAVE_NL_LANGINFO) check_function_exists(obstack_vprintf HAVE_OBSTACK_VPRINTF) check_function_exists(popen HAVE_POPEN) check_function_exists(processor_info HAVE_PROCESSOR_INFO) check_function_exists(pstat_getprocessor HAVE_PSTAT_GETPROCESSOR) check_function_exists(raise HAVE_RAISE) check_function_exists(read_real_time HAVE_READ_REAL_TIME) check_function_exists(sigaction HAVE_SIGACTION) check_function_exists(sigaltstack HAVE_SIGALTSTACK) check_function_exists(sigstack HAVE_SIGSTACK) check_function_exists(strchr HAVE_STRCHR) check_function_exists(strerror HAVE_STRERROR) check_function_exists(strnlen HAVE_STRNLEN) check_function_exists(strtol HAVE_STRTOL) check_function_exists(strtoul HAVE_STRTOUL) check_function_exists(sysctl HAVE_SYSCTL) check_function_exists(sysctlbyname HAVE_SYSCTLBYNAME) check_function_exists(syssgi HAVE_SYSSGI) check_function_exists(times HAVE_TIMES) check_symbol_exists(fgetc stdio.h HAVE_DECL_FGETC) check_symbol_exists(fscanf stdio.h HAVE_DECL_FSCANF) check_symbol_exists(optarg stdio.h HAVE_DECL_OPTARG) check_symbol_exists(sys_errlist stdio.h errno.h HAVE_DECL_SYS_ERRLIST) check_symbol_exists(sys_nerr errno.h HAVE_DECL_SYS_NERR) check_symbol_exists(ungetc stdio.h HAVE_DECL_UNGETC) check_symbol_exists(vfprintf stdio.h HAVE_DECL_VFPRINTF) check_symbol_exists(vsnprintf stdio.h HAVE_VSNPRINTF) check_symbol_exists("struct pst_processor" sys/pstat.h HAVE_PSP_ITICKSPERCLKTICK) check_cxx_symbol_exists("std::locale" locale HAVE_STD__LOCALE) # Check types check_type_size("void *" SIZEOF_VOID_P) check_type_size("unsigned short" SIZEOF_UNSIGNED_SHORT) check_type_size("unsigned" SIZEOF_UNSIGNED) check_type_size("unsigned long" SIZEOF_UNSIGNED_LONG) check_type_size("long double" LONG_DOUBLE) if(HAVE_LONG_DOUBLE) set(SIZEOF_LONG_DOUBLE ${LONG_DOUBLE}) endif() check_type_size("long long" LONG_LONG) if(HAVE_LONG_LONG) set(SIZEOF_LONG_LONG ${LONG_LONG}) endif() check_type_size("ptrdiff_t" SIZEOF_PTRDIFF_T) check_type_size("quad_t" SIZEOF_QUAD_T) check_type_size("uint_least32_t" SIZEOF_UINT_LEAST32_T) check_type_size("intmax_t" INTMAX_T) if(HAVE_INTMAX_T) set(SIZEOF_INTMAX_T ${INTMAX_T}) endif() check_type_size("intptr_t" INTPTR_T) if(HAVE_INTPTR_T) set(SIZEOF_INTPTR_T ${INTPTR_T}) endif() check_type_size("stack_t" SIZEOF_STACK_T) set(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_CURRENT_BINARY_DIR}/gmp.h) check_type_size("mp_limb_t" SIZEOF_MP_LIMB_T) set(CMAKE_EXTRA_INCLUDE_FILES) # CPU Family if(CMAKE_SIZEOF_VOID_P EQUAL 8) set(HAVE_HOST_CPU_FAMILY_x86_64 1) else() set(HAVE_HOST_CPU_FAMILY_x86 1) endif() # Test endian type. include(TestBigEndian) test_big_endian(big_endian) if(big_endian) set(HAVE_DOUBLE_IEEE_BIG_ENDIAN 1) set(HAVE_LIMB_BIG_ENDIAN 1) set(WORDS_BIGENDIAN 1) else() set(HAVE_DOUBLE_IEEE_LITTLE_ENDIAN 1) set(HAVE_LIMB_LITTLE_ENDIAN 1) endif() configure_file(config.h.in config.h @ONLY) if(MSVC) add_compile_options(/wd4018 /wd4146 /wd4244 /wd4267 /wd4996) endif() add_custom_target(bootstrap DEPENDS bootstrap.c) # Generate fac_table.h add_executable(gen-fac gen-fac.c) add_dependencies(gen-fac bootstrap) add_custom_command( OUTPUT fac_table.h COMMAND gen-fac ${GMP_LIMB_BITS} ${GMP_NAIL_BITS} >fac_table.h DEPENDS gen-fac WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Generating fac_table.h ..." ) add_custom_target( gen-fac-table ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/fac_table.h ) # Generate fib_table.h and mpn/fib_table.c add_executable(gen-fib gen-fib.c) add_dependencies(gen-fib bootstrap) add_custom_command( OUTPUT fib_table.h COMMAND gen-fib header ${GMP_LIMB_BITS} ${GMP_NAIL_BITS} >fib_table.h DEPENDS gen-fib WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Generating fib_table.h ..." ) add_custom_command( OUTPUT mpn/fib_table.c COMMAND gen-fib table ${GMP_LIMB_BITS} ${GMP_NAIL_BITS} >mpn/fib_table.c DEPENDS gen-fib WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Generating mpn/fib_table.c ..." ) add_custom_target( gen-fib-table ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/fib_table.h ${CMAKE_CURRENT_BINARY_DIR}/mpn/fib_table.c ) # Generate mp_bases.h and mpn/mp_bases.c add_executable(gen-bases gen-bases.c) add_dependencies(gen-bases bootstrap) add_custom_command( OUTPUT mp_bases.h COMMAND gen-bases header ${GMP_LIMB_BITS} ${GMP_NAIL_BITS} >mp_bases.h DEPENDS gen-bases WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Generating mp_bases.h ..." ) add_custom_command( OUTPUT mpn/mp_bases.c COMMAND gen-bases table ${GMP_LIMB_BITS} ${GMP_NAIL_BITS} >mpn/mp_bases.c DEPENDS gen-bases WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Generating mpn/mp_bases.c ..." ) add_custom_target( gen-mp-bases ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/mp_bases.h ${CMAKE_CURRENT_BINARY_DIR}/mpn/mp_bases.c ) # Generate trialdivtab.h add_executable(gen-trialdivtab gen-trialdivtab.c) add_dependencies(gen-trialdivtab bootstrap) add_custom_command( OUTPUT trialdivtab.h COMMAND gen-trialdivtab ${GMP_LIMB_BITS} 8000 >trialdivtab.h DEPENDS gen-trialdivtab WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Generating trialdivtab.h ..." ) add_custom_target( gen-trialdivtab-h ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/trialdivtab.h ) # Generate mpn/jacobitab.h add_executable(gen-jacobitab gen-jacobitab.c) add_custom_command( OUTPUT mpn/jacobitab.h COMMAND gen-jacobitab >mpn/jacobitab.h DEPENDS gen-jacobitab WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Generating mpn/jacobitab.h ..." ) add_custom_target( gen-mpn-jacobitab ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/mpn/jacobitab.h ) # Generate mpn/perfsqr.h add_executable(gen-psqr gen-psqr.c) add_dependencies(gen-psqr bootstrap) add_custom_command( OUTPUT mpn/perfsqr.h COMMAND gen-psqr ${GMP_LIMB_BITS} ${GMP_NAIL_BITS} >mpn/perfsqr.h WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Generating mpn/perfsqr.h ..." ) add_custom_target( gen-mpn-perfsqr ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/mpn/perfsqr.h ) # Generate sieve_table.h add_executable(gen-sieve gen-sieve.c) add_dependencies(gen-sieve bootstrap) add_custom_command( OUTPUT sieve_table.h COMMAND gen-sieve ${GMP_LIMB_BITS} >sieve_table.h DEPENDS gen-sieve WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Generating sieve_table.h ..." ) add_custom_target( gen-sieve-table ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/sieve_table.h ) include_directories( ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}/mpn ) if(CMAKE_SIZEOF_VOID_P EQUAL 8) include_directories(${CMAKE_SOURCE_DIR}/mpn/x86_64/k8) else() include_directories(${CMAKE_SOURCE_DIR}/mpn/x86) endif() add_subdirectory(mpn) add_subdirectory(mpf) add_subdirectory(mpq) add_subdirectory(mpz) add_subdirectory(printf) add_subdirectory(rand) add_subdirectory(scanf) set( LIBGMP_SOURCES gmp-impl.h longlong.h assert.c compat.c errno.c extract-dbl.c invalid.c memory.c mp_bpl.c mp_clz_tab.c mp_dv_tab.c mp_minv_tab.c mp_get_fns.c mp_set_fns.c version.c nextprime.c primesieve.c ) set( LIBGMP_EXTRA_SOURCES tal-reent.c ) add_library( libgmp SHARED ${LIBGMP_SOURCES} ${LIBGMP_EXTRA_SOURCES} $ $ $ $ $ $ $ ) add_dependencies(libgmp libmpn) target_compile_definitions(libgmp PRIVATE __GMP_WITHIN_GMP) set_target_properties( libgmp PROPERTIES OUTPUT_NAME libgmp$<$:d>-${LIBGMP_LT_CURRENT} VERSION ${GMP_VERSION} SOVERSION ${LIBGMP_LT_CURRENT}) # Install libgmp. install( TARGETS libgmp EXPORT libgmp-export ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) # Install libgmp header file. install( FILES ${CMAKE_CURRENT_BINARY_DIR}/gmp.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT Development) # Install libgmp package config file. install( FILES ${CMAKE_CURRENT_BINARY_DIR}/gmp.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig COMPONENT Development) # Install libgmp PDB files. if(MSVC) install( FILES $ DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Development OPTIONAL) endif() set(GMP_CONFIG_PACKAGE_LOCATION ${CMAKE_INSTALL_LIBDIR}/cmake/gmp) # Create a version file for GMP. write_basic_package_version_file( "${CMAKE_CURRENT_BINARY_DIR}/cmake/GMPConfigVersion.cmake" VERSION ${GMP_VERSION} COMPATIBILITY AnyNewerVersion) export( EXPORT libgmp-export FILE "${CMAKE_CURRENT_BINARY_DIR}/cmake/libgmp.cmake" NAMESPACE GMP::) install(EXPORT libgmp-export FILE libgmp.cmake NAMESPACE GMP:: DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/gmp) # Install GMP config-file package. install( FILES ${CMAKE_SOURCE_DIR}/cmake/GMPConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/cmake/GMPConfigVersion.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/gmp COMPONENT Development) if(WANT_CXX) add_subdirectory(cxx) set(LIBGMPXX_SOURCES cxx/dummy.cc) add_library( libgmpxx SHARED ${LIBGMPXX_SOURCES} $ ) target_compile_definitions(libgmpxx PRIVATE __GMP_WITHIN_GMP) target_link_libraries(libgmpxx PUBLIC libgmp) set_target_properties( libgmpxx PROPERTIES OUTPUT_NAME libgmpxx$<$:d>-${LIBGMPXX_LT_CURRENT}) # Install libgmpxx. install( TARGETS libgmpxx EXPORT libgmpxx-export ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) # Install libgmpxx header file. install( FILES gmpxx.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT Development) # Install libgmpxx package config file. install( FILES ${CMAKE_CURRENT_BINARY_DIR}/gmpxx.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig COMPONENT Development) # Install libgmpxx PDB files. if(MSVC) install( FILES $ DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Development OPTIONAL) endif() # Create a version file for GMP. write_basic_package_version_file( "${CMAKE_CURRENT_BINARY_DIR}/cmake/GMPXXConfigVersion.cmake" VERSION ${GMP_VERSION} COMPATIBILITY AnyNewerVersion) export( EXPORT libgmpxx-export FILE "${CMAKE_CURRENT_BINARY_DIR}/cmake/libgmpxx.cmake" NAMESPACE GMP::) install(EXPORT libgmpxx-export FILE libgmpxx.cmake NAMESPACE GMP:: DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/gmpxx) # Install GMPXX config-file package. install( FILES ${CMAKE_SOURCE_DIR}/cmake/GMPXXConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/cmake/GMPXXConfigVersion.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/gmpxx COMPONENT Development) endif() if(BUILD_DEMOS) add_subdirectory(demos) endif() if(RUN_TESTS) include(CTest) enable_testing() add_subdirectory(tests) endif()