## ## CMakeLists.txt for PALISADE ## ## This script will build machine-specific header files for compile ## as it generates the Makefile ## ## Note many user options are handled using an OPTION in CMake ## An option has the value of ON or OFF ## See below for the list of options cmake_minimum_required (VERSION 3.5.1) find_program(CCACHE_PROGRAM ccache) if(CCACHE_PROGRAM) set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}") endif() ### To use gcc/g++ on a Macintosh, you must set the Compilers ### here, not inside the project ##if(APPLE) ## set(CMAKE_C_COMPILER "/usr/local/bin/gcc-7") ## set(CMAKE_CXX_COMPILER "/usr/local/bin/g++-7") ##endif() ### TODO: for now, we use CLang for Mac project (PALISADE C CXX) set(PALISADE_VERSION_MAJOR 1) set(PALISADE_VERSION_MINOR 11) set(PALISADE_VERSION_PATCH 8) set(PALISADE_VERSION ${PALISADE_VERSION_MAJOR}.${PALISADE_VERSION_MINOR}.${PALISADE_VERSION_PATCH}) set(CMAKE_CXX_STANDARD 11) set(CXX_STANDARD_REQUIRED ON) #-------------------------------------------------------------------- # Build options #-------------------------------------------------------------------- if(CMAKE_BUILD_TYPE) set(RELEASE_TYPES Debug Release RelWithDebInfo MinSizeRel) list(FIND RELEASE_TYPES ${CMAKE_BUILD_TYPE} INDEX_FOUND) if(${INDEX_FOUND} EQUAL -1) message( FATAL_ERROR "CMAKE_BUILD_TYPE must be one of Debug, Release, RelWithDebInfo, or MinSizeRel" ) endif() else() # if no build type is chosen, default to Release mode set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are: None, Debug, Release, RelWithDebInfo, or MinSizeRel." FORCE ) endif() message(STATUS "Building in ${CMAKE_BUILD_TYPE} mode" ) if ( EMSCRIPTEN ) set(BUILD_SHARED OFF) message( "Shared library is not supported by Emscripten") option( BUILD_STATIC "Set to ON to build static versions of the library" ON) option( BUILD_UNITTESTS "Set to ON to build unit tests for the library" OFF) option( BUILD_EXAMPLES "Set to ON to build examples for the library" OFF) option( BUILD_BENCHMARKS "Set to ON to build benchmarks for the library" OFF) option( WITH_OPENMP "OpenMP is not supported by Emscripten" OFF) else() option( BUILD_SHARED "Set to ON to build shared versions of the library" ON) option( BUILD_STATIC "Set to ON to build static versions of the library" OFF) option( BUILD_UNITTESTS "Set to ON to build unit tests for the library" ON) option( BUILD_EXAMPLES "Set to ON to build examples for the library" ON) option( BUILD_BENCHMARKS "Set to ON to build benchmarks for the library" ON) option( WITH_OPENMP "Use OpenMP to enable " ON) endif() option( BUILD_EXTRAS "Set to ON to build extras for the library" OFF) option( GIT_SUBMOD_AUTO "Submodules auto-update" ON) option( WITH_BE2 "Include Backend 2 in build by setting WITH_BE2 to ON" ON ) option( WITH_BE4 "Include Backend 4 in build by setting WITH_BE4 to ON" ON ) option( WITH_NTL "Include Backend 6 and NTL in build by setting WITH_NTL to ON" OFF ) option( WITH_TCM "Activate tcmalloc by setting WITH_TCM to ON" OFF ) option( WITH_INTEL_HEXL "Use Intel HEXL library" OFF) option( WITH_NATIVEOPT "Use machine-specific optimizations" OFF) option( WITH_COVTEST "Turn on to enable coverage testing" OFF) option( USE_MACPORTS "Use MacPorts installed packages" OFF) # Set required number of bits for native integer in build by setting NATIVE_SIZE to 64 or 128 if( NOT NATIVE_SIZE ) set( NATIVE_SIZE 64 ) # set( NATIVE_SIZE 128 ) endif() if( NOT CKKS_M_FACTOR ) set( CKKS_M_FACTOR 1 ) endif() ### Print options message( STATUS "BUILD_UNITTESTS: ${BUILD_UNITTESTS}") message( STATUS "BUILD_EXAMPLES: ${BUILD_EXAMPLES}") message( STATUS "BUILD_BENCHMARKS: ${BUILD_BENCHMARKS}") message( STATUS "BUILD_EXTRAS: ${BUILD_EXTRAS}") message( STATUS "BUILD_STATIC: ${BUILD_STATIC}") message( STATUS "BUILD_SHARED: ${BUILD_SHARED}") message( STATUS "GIT_SUBMOD_AUTO: ${GIT_SUBMOD_AUTO}") message( STATUS "WITH_BE2: ${WITH_BE2}") message( STATUS "WITH_BE4: ${WITH_BE4}") message( STATUS "WITH_NTL: ${WITH_NTL}") message( STATUS "WITH_TCM: ${WITH_TCM}") message( STATUS "WITH_INTEL_HEXL: ${WITH_INTEL_HEXL}") message( STATUS "WITH_OPENMP: ${WITH_OPENMP}") message( STATUS "NATIVE_SIZE: ${NATIVE_SIZE}") message( STATUS "CKKS_M_FACTOR: ${CKKS_M_FACTOR}") message( STATUS "WITH_NATIVEOPT: ${WITH_NATIVEOPT}") message( STATUS "WITH_COVTEST: ${WITH_COVTEST}") message( STATUS "USE_MACPORTS: ${USE_MACPORTS}") #-------------------------------------------------------------------- # Compiler logic #-------------------------------------------------------------------- if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") # require at least gcc 6.1 if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.1) message(WARNING "GCC version should be at least 6.1.") endif() elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # require at least clang 6 if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6) message(WARNING "Clang version should be at least 6.") endif() else() message(WARNING "You are using ${CMAKE_CXX_COMPILER_ID} version ${CMAKE_CXX_COMPILER_VERSION}, which is unsupported.") endif() # use, i.e. don't skip the full RPATH for the build tree set(CMAKE_SKIP_BUILD_RPATH FALSE) # when building, don't use the install RPATH already # (but later on when installing) set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) set(CMAKE_INSTALL_RPATH "${LIBINSTALL}") # add the automatically determined parts of the RPATH # which point to directories outside the build tree to the install RPATH set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) # the RPATH to be used when installing, but only if it's not a system directory LIST(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${LIBINSTALL}" isSystemDir) if("${isSystemDir}" STREQUAL "-1") set(CMAKE_INSTALL_RPATH "${LIBINSTALL}") endif("${isSystemDir}" STREQUAL "-1") # Compiler flags # Added -Wno-parentheses for compatibility with g++ if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") set (IGNORE_WARNINGS "-Wno-parentheses") # we can use GNU built-in functions provided by GCC for debugging. ex: __builtin_LINE (), __builtin_FUNCTION (), __builtin_FILE () add_definitions(-DBUILTIN_INFO_AVAILABLE) message (STATUS "BUILTIN_INFO_AVAILABLE is defined") endif() if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") set(IGNORE_WARNINGS "${IGNORE_WARNINGS} -Wno-unused-private-field -Wno-shift-op-parentheses") endif() if( WITH_NATIVEOPT ) set (NATIVE_OPT "-march=native") else() set (NATIVE_OPT "") endif() set(C_COMPILE_FLAGS "-Wall -Werror -O3 ${NATIVE_OPT} -DPALISADE_VERSION=${PALISADE_VERSION}") set(CXX_COMPILE_FLAGS "-Wall -Werror -O3 ${NATIVE_OPT} -DPALISADE_VERSION=${PALISADE_VERSION} ${IGNORE_WARNINGS}") if ( EMSCRIPTEN ) set(EMSCRIPTEN_IGNORE_WARNINGS "-Wno-unused-but-set-variable -Wno-unknown-warning-option") set(C_COMPILE_FLAGS "${C_COMPILE_FLAGS} ${EMSCRIPTEN_IGNORE_WARNINGS}") set(CXX_COMPILE_FLAGS "${CXX_COMPILE_FLAGS} ${EMSCRIPTEN_IGNORE_WARNINGS}") add_compile_options(-fexceptions) add_link_options( -sINITIAL_MEMORY=2047MB -sMAXIMUM_MEMORY=4GB -sALLOW_MEMORY_GROWTH=1 -sMALLOC=emmalloc -sNO_DISABLE_EXCEPTION_CATCHING ) endif() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_COMPILE_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_COMPILE_FLAGS}") if(WITH_COVTEST) #Set flags set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") link_libraries(gcov) set( BUILDDIR ${CMAKE_CURRENT_SOURCE_DIR}/build/) set( COVDIR ${BUILDDIR}coverage/) endif() if(BUILD_STATIC) set(PALISADE_STATIC_LIBS PALISADEcore_static PALISADEpke_static PALISADEbinfhe_static) endif() if(BUILD_SHARED) set(PALISADE_SHARED_LIBS PALISADEcore PALISADEpke PALISADEbinfhe) endif() set(PALISADE_PACKAGE_LIBS ${PALISADE_STATIC_LIBS} ${PALISADE_SHARED_LIBS}) #-------------------------------------------------------------------- # Installation logic #-------------------------------------------------------------------- ### set up for install set(INSTALL_LIB_DIR lib CACHE PATH "Installation directory for libraries") set(INSTALL_INCLUDE_DIR include/palisade CACHE PATH "Installation directory for headers") if(WIN32 AND NOT CYGWIN) set(DEF_INSTALL_CMAKE_DIR CMake) else() set(DEF_INSTALL_CMAKE_DIR lib/Palisade) endif() set(INSTALL_CMAKE_DIR ${DEF_INSTALL_CMAKE_DIR} CACHE PATH "Installation directory for CMake files") foreach(p LIB INCLUDE CMAKE) set(var INSTALL_${p}_DIR) if(NOT IS_ABSOLUTE "${${var}}") set(${var} "${CMAKE_INSTALL_PREFIX}/${${var}}") endif() endforeach() message("***** INSTALL IS AT ${CMAKE_INSTALL_PREFIX}; to change, run cmake with -DCMAKE_INSTALL_PREFIX=/your/path") set (CMAKE_INSTALL_MESSAGE LAZY) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) #-------------------------------------------------------------------- # Uninstall logic #-------------------------------------------------------------------- ## clobber cleans and deletes the third-party stuff add_custom_target( COMMAND make clean WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) add_custom_target("uninstall" COMMENT "Uninstall PALISADE files") add_custom_command( TARGET "uninstall" POST_BUILD COMMENT "Uninstall files within install_manifest.txt" COMMAND ../maint/uninstall_script.sh USES_TERMINAL ) #-------------------------------------------------------------------- # Machine-specific checks #-------------------------------------------------------------------- # determine the architecture on a Linux/Unix/macOS/MinGW system if(CMAKE_HOST_UNIX OR MINGW) EXECUTE_PROCESS( COMMAND uname -m COMMAND tr -d '\n' OUTPUT_VARIABLE ARCHITECTURE ) else() set(ARCHITECTURE "unknown") endif() if(ARCHITECTURE) message(STATUS "Architecture is " ${ARCHITECTURE}) endif() # Size checks include(CheckTypeSize) check_type_size("__int128" INT128) check_type_size("uint64_t" INT64) if (NOT(BUILD_SHARED OR BUILD_STATIC)) message(SEND_ERROR "Either BUILD_SHARED or BUILD_STATIC neeed to be turned on.") endif() if( "${NATIVE_SIZE}" EQUAL 128 ) if( ${HAVE_INT128} ) set( NATIVEINT 128 ) message (STATUS "NATIVEINT is set to " ${NATIVEINT}) else() message(SEND_ERROR "Cannot support NATIVE_SIZE == 128") endif() elseif( "${NATIVE_SIZE}" EQUAL 64 ) if( ${HAVE_INT64} ) set( NATIVEINT 64 ) message (STATUS "NATIVEINT is set to " ${NATIVEINT}) else() message(SEND_ERROR "Cannot support NATIVE_SIZE == 64") endif() elseif( "${NATIVE_SIZE}" EQUAL 32 ) if( ${HAVE_INT64} ) set( NATIVEINT 32 ) set( HAVE_INT128 FALSE) message (STATUS "NATIVEINT is set to " ${NATIVEINT}) else() message(SEND_ERROR "Cannot support NATIVE_SIZE == 32") endif() else() message(SEND_ERROR "NATIVE_SIZE is " ${NATIVE_SIZE}) message(SEND_ERROR "***ERROR*** need a Native implementation") endif() #-------------------------------------------------------------------- # Backend logic #-------------------------------------------------------------------- ## default math backend is 2 for 32-bit and 64-bit integers and 4 for 128-bit integers if( NOT MATHBACKEND AND NOT ${NATIVE_SIZE} EQUAL 128) set( MATHBACKEND 2 ) elseif(NOT MATHBACKEND AND ${NATIVE_SIZE} EQUAL 128) set( MATHBACKEND 4 ) endif() message (STATUS "MATHBACKEND is set to " ${MATHBACKEND}) if( "${MATHBACKEND}" EQUAL 2 ) if( NOT WITH_BE2 ) message(SEND_ERROR "Cannot select backend 2 if WITH_BE2 is disabled") endif() elseif( "${MATHBACKEND}" EQUAL 4 ) if( NOT WITH_BE4 ) message(SEND_ERROR "Cannot select backend 4 if WITH_BE4 is disabled") endif() elseif( "${MATHBACKEND}" EQUAL 6 ) if( NOT WITH_NTL ) message(SEND_ERROR "Cannot select backend 6 if WITH_NTL is disabled") endif() else() message(SEND_ERROR "Backend must be 2, 4 or 6") endif() if( "${MATHBACKEND}" EQUAL 6 AND "${NATIVEINT}" EQUAL 128) set (MATHBACKEND 2) set (WITH_NTL OFF) message (STATUS "BACKEND 6 is not compatible with 128-bit native backend. Resetting multiprecision backend to 2.") endif() set( PALISADE_BACKEND_FLAGS "-DMATHBACKEND=${MATHBACKEND}") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PALISADE_BACKEND_FLAGS}") set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${PALISADE_BACKEND_FLAGS}") if(WITH_TCM) message(STATUS "tcmalloc is turned ON") if(MINGW) message(SEND_ERROR "***ERROR*** tcmalloc is not supported for MinGW") endif() endif() ### build configure_core.h to make options available configure_file(./configure/config_core.in src/core/config_core.h) install(FILES ${CMAKE_BINARY_DIR}/src/core/config_core.h DESTINATION include/palisade/core) find_program(TAR "gtar") find_program(TAR "tar") ### several of the third-party tools use auto-make and autoconf ### we need to make sure that they are installed execute_process(COMMAND autogen --version OUTPUT_VARIABLE AUTOGEN_VER) # execute_process in MINGW by default does not run in a shell if(MINGW) execute_process(COMMAND sh autoconf --version OUTPUT_VARIABLE AUTOCONF_VER) else() execute_process(COMMAND autoconf --version OUTPUT_VARIABLE AUTOCONF_VER) endif() string(LENGTH "${AUTOCONF_VER}" AUTOCONF_VER_LEN) if( ${AUTOCONF_VER_LEN} EQUAL 0 ) message(SEND_ERROR "Autoconf is not installed.") endif() #-------------------------------------------------------------------- # OpenMP logic #-------------------------------------------------------------------- if (WITH_OPENMP) # Used to optionally compile openmp code add_definitions(-DPARALLEL) # Set OpenMP configuration manually for macOS if (APPLE) if (USE_MACPORTS) # Macports-based installation message( STATUS "Using Macports setup") set(OPENMP_LIBRARIES "/opt/local/lib/libomp") set(OPENMP_INCLUDES "/opt/local/include/libomp") if(CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID MATCHES "AppleClang") set(OpenMP_C_FLAGS "-Xpreprocessor -fopenmp -lomp -Wno-unused-command-line-argument") set(OpenMP_C_LIB_NAMES "omp") set(OpenMP_omp_LIBRARY ${OpenMP_C_LIB_NAMES}) endif() if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "AppleClang") set(OpenMP_CXX_FLAGS "-Xpreprocessor -fopenmp -lomp -Wno-unused-command-line-argument") set(OpenMP_CXX_LIB_NAMES "omp") set(OpenMP_omp_LIBRARY ${OpenMP_CXX_LIB_NAMES}) endif() else (USE_MACPORTS) # Homebrew-based installation # Check for Apple M1 Processor if (${ARCHITECTURE} MATCHES "arm64") message( STATUS "Apple M1 detected") set(OPENMP_LIBRARIES "/opt/homebrew/opt/libomp/lib") set(OPENMP_INCLUDES "/opt/homebrew/opt/libomp/include") else() # Apple Intel Processor message( STATUS "Apple Intel detected") set(OPENMP_LIBRARIES "/usr/local/opt/libomp/lib") set(OPENMP_INCLUDES "/usr/local/opt/libomp/include") endif() if(CMAKE_C_COMPILER_ID MATCHES "Clang") set(OpenMP_C_FLAGS "-Xpreprocessor -fopenmp -lomp -Wno-unused-command-line-argument") set(OpenMP_C_LIB_NAMES "libomp") set(OpenMP_libomp_LIBRARY ${OpenMP_C_LIB_NAMES}) endif() if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(OpenMP_CXX_FLAGS "-Xpreprocessor -fopenmp -lomp -Wno-unused-command-line-argument") set(OpenMP_CXX_LIB_NAMES "libomp") set(OpenMP_libomp_LIBRARY ${OpenMP_CXX_LIB_NAMES}) endif() endif (USE_MACPORTS) include_directories("${OPENMP_INCLUDES}") link_directories("${OPENMP_LIBRARIES}") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") message( STATUS "OPENMP_LIBRARIES: " ${OPENMP_LIBRARIES}) message( STATUS "OPENMP_INCLUDES: " ${OPENMP_INCLUDES}) message( STATUS "OpenMP_CXX_FLAGS: " ${OpenMP_CXX_FLAGS}) message( STATUS "OpenMP_CXX_LIB_NAMES: " ${OpenMP_CXX_LIB_NAMES}) endif() find_package (OpenMP) # OpenMP_CXX_FOUND was added in cmake 3.9.x # so we are also checking the OpenMP_FOUND flag if (OpenMP_CXX_FOUND OR OpenMP_FOUND) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") else() message(SEND_ERROR "** ERROR ** OpenMP is not installed. If using macOS/clang, please run 'cmake ..' again.") endif() if (OpenMP_C_FOUND OR OpenMP_FOUND) set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") endif() else() # WITH_OPENMP == OFF find_package (Threads REQUIRED) # Disable unknown #pragma omp warning set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unknown-pragmas") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-pragmas") endif() #-------------------------------------------------------------------- # Pthreads logic (only for Google benchmark) #-------------------------------------------------------------------- # In order to have the Threads_FOUND on some Linux and macOS systems set(CMAKE_THREAD_LIBS_INIT "-lpthread") set(CMAKE_HAVE_THREADS_LIBRARY 1) set(CMAKE_USE_WIN32_THREADS_INIT 0) set(CMAKE_USE_PTHREADS_INIT 1) set(THREADS_PREFER_PTHREAD_FLAG ON) #-------------------------------------------------------------------- # Documentation logic #-------------------------------------------------------------------- find_package (Git REQUIRED) if(GIT_SUBMOD_AUTO AND EXISTS "${PROJECT_SOURCE_DIR}/.git") # Update submodules as needed message(STATUS "Submodule update") if(NOT GIT_SUBMODULE_SYNCED) # "git submodule sync --recursive" should run only once, when CMakeCache.txt doesn't exist' execute_process(COMMAND ${GIT_EXECUTABLE} submodule sync --recursive WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} RESULT_VARIABLE GIT_SUBMODULE_RESULT) if(NOT GIT_SUBMODULE_RESULT EQUAL "0") message(FATAL_ERROR "\"git submodule sync --recursive\" failed with ${GIT_SUBMODULE_RESULT}, please checkout submodules") endif() endif() execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} RESULT_VARIABLE GIT_SUBMODULE_RESULT) if(NOT GIT_SUBMODULE_RESULT EQUAL "0") if(NOT GIT_SUBMODULE_SYNCED) # print this message only if update has never happened message(FATAL_ERROR "\"git submodule update --init\" failed with ${GIT_SUBMODULE_RESULT}, please checkout submodules") else() message(SEND_ERROR "\"git submodule update --init\" failed with ${GIT_SUBMODULE_RESULT}, please checkout submodules or disable autoupdate with -DGIT_SUBMOD_AUTO=OFF") endif() endif() if(NOT GIT_SUBMODULE_SYNCED) set(GIT_SUBMODULE_SYNCED ON CACHE BOOL "" FORCE) endif() endif() find_package (Doxygen QUIET COMPONENTS dot) if (DOXYGEN_FOUND) add_custom_target( apidocs COMMAND sh -c "( cat ${CMAKE_CURRENT_SOURCE_DIR}/lbcrypto-doxy-config && echo PROJECT_NUMBER=${PALISADE_VERSION} ) | ${DOXYGEN_EXECUTABLE} -" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMENT "Generating API documentation with Doxygen" VERBATIM ) message (STATUS "Doxygen and dot are found") else (DOXYGEN_FOUND) message(STATUS "Doxygen and dot (from graphviz) need to be installed to generate the doxygen documentation") endif (DOXYGEN_FOUND) #-------------------------------------------------------------------- # Coverage logic #-------------------------------------------------------------------- if ( WITH_COVTEST ) find_program(LCOV_BIN lcov) if (LCOV_BIN MATCHES "lcov$") #Creates the command make cov add_custom_target( cov DEPENDS core_tests pke_tests binfhe_tests COMMAND cd ${BUILDDIR} && mkdir -p coverage COMMAND cd ${BUILDDIR}/src/core/CMakeFiles/core_tests.dir/unittest/ && gcov *.gcno && lcov --capture --directory . --output-file ${COVDIR}/core.info COMMAND cd ${BUILDDIR}/src/pke/CMakeFiles/pke_tests.dir/unittest/ && gcov *.gcno && lcov --capture --directory . --output-file ${COVDIR}/pke.info COMMAND cd ${BUILDDIR}/src/binfhe/CMakeFiles/binfhe_tests.dir/unittest/ && gcov *.gcno && lcov --capture --directory . --output-file ${COVDIR}/binfhe.info COMMAND cd ${COVDIR} && mkdir -p assets && genhtml -t "Coverage Test" -o ${COVDIR}/assets/ *.info ) message(STATUS "lcov found in ${LCOV_BIN}") else () message(STATUS "lcov needs to be installed to generate a coverage report") endif () endif() #-------------------------------------------------------------------- # Third-party logic #-------------------------------------------------------------------- include (ExternalProject) if (WITH_INTEL_HEXL) include(third-party/intel-hexl/intel-hexl.cmake) endif() # third party directories set( THIRDPARTYDIR ${CMAKE_CURRENT_SOURCE_DIR}/third-party ) include_directories( ${THIRDPARTYDIR}/include ) ### Handle third-party CEREAL include_directories( ${THIRDPARTYDIR}/cereal/include ) install(DIRECTORY ${THIRDPARTYDIR}/cereal/include/ DESTINATION include/palisade) include_directories( ${CMAKE_SOURCE_DIR}/third-party/google-test/googletest ) include_directories( ${CMAKE_SOURCE_DIR}/third-party/google-test/googletest/include ) include_directories( ${CMAKE_SOURCE_DIR}/src/core/include ) include_directories( ${CMAKE_BINARY_DIR}/src/core ) ### Handle third-party gperftools for optional tcmalloc add_custom_target( tcm COMMAND ./autogen.sh COMMAND ./configure --prefix=${CMAKE_CURRENT_BINARY_DIR}/third-party --enable-minimal COMMAND make COMMAND make install WORKING_DIRECTORY ${THIRDPARTYDIR}/gperftools ) add_custom_target( tcm_clean COMMAND rm -rf include/gperftools include/google lib/libtcmalloc_minimal* lib/pkgconfig/libtcmalloc* lib/pkgconfig/libprofiler.pc share/doc/gperftools WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/third-party ) if(BUILD_STATIC) add_library(tcmalloc_static STATIC IMPORTED GLOBAL) set_target_properties(tcmalloc_static PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/third-party/lib/libtcmalloc_minimal${CMAKE_STATIC_LIBRARY_SUFFIX}) endif() if(BUILD_SHARED) add_library(tcmalloc SHARED IMPORTED GLOBAL) set_target_properties(tcmalloc PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/third-party/lib/libtcmalloc_minimal${CMAKE_SHARED_LIBRARY_SUFFIX}) endif() if(WITH_TCM) install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/third-party/lib DESTINATION . FILES_MATCHING PATTERN "libtcmalloc_minimal.*") list(APPEND THIRDPARTYLIBS "tcmalloc") list(APPEND THIRDPARTYSTATICLIBS "tcmalloc_static") install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/third-party/include DESTINATION include/palisade/third-party/) endif() if(WITH_NTL) ### Find gmp and ntl libraries. They must be installed by the user list(APPEND general_paths "/usr" "/usr/local" "/opt" "/opt/local") list(APPEND header_suffixes "include" "include/NTL" "include/${CMAKE_LIBRARY_ARCHITECTURE}") list(APPEND lib_suffixes "lib" "lib/${CMAKE_LIBRARY_ARCHITECTURE}") if (NOT(NTL_INCLUDE_DIR AND NTL_LIBRARIES)) find_path(NTL_INCLUDE_DIR NAMES RR.h PATHS ${general_paths} PATH_SUFFIXES ${header_suffixes} ) find_library(NTL_LIBRARIES NAMES ntl libntl ONLY_CMAKE_FIND_ROOT_PATH PATHS ${general_paths} PATH_SUFFIXES ${lib_suffixes} ) include(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(NTL DEFAULT_MSG NTL_INCLUDE_DIR NTL_LIBRARIES) if(NTL_FOUND) get_filename_component(NTL_LIBRARIES ${NTL_LIBRARIES} DIRECTORY) else() message(FATAL_ERROR "** ERROR ** libntl is not found." "In order to use MATHBACKEND 6, install libntl or pass -DNTL_INCLUDE_DIR= and -DNTL_LIBRARIES= to cmake") endif() endif() if (NOT(GMP_INCLUDE_DIR AND GMP_LIBRARIES)) find_path(GMP_INCLUDE_DIR NAMES gmp.h PATHS ${general_paths} PATH_SUFFIXES ${header_suffixes} ) find_library(GMP_LIBRARIES NAMES gmp libgmp ONLY_CMAKE_FIND_ROOT_PATH PATHS ${general_paths} PATH_SUFFIXES ${lib_suffixes} ) include(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(GMP DEFAULT_MSG GMP_INCLUDE_DIR GMP_LIBRARIES) if(GMP_FOUND) get_filename_component(GMP_LIBRARIES ${GMP_LIBRARIES} DIRECTORY) else() message(FATAL_ERROR "** ERROR ** libgmp is not found." "In order to use MATHBACKEND 6, install libgmp or pass -DGMP_INCLUDE_DIR= and -GMPL_LIBRARIES= to cmake") endif() endif() mark_as_advanced(NTL_INCLUDE_DIR NTL_LIBRARIES) mark_as_advanced(GMP_INCLUDE_DIR GMP_LIBRARIES) include_directories(${NTL_INCLUDE_DIR}) include_directories(${GMP_INCLUDE_DIR}) link_directories(${NTL_LIBRARIES}) link_directories(${GMP_LIBRARIES}) list(APPEND THIRDPARTYLIBS "ntl") list(APPEND THIRDPARTYLIBS "gmp") list(APPEND THIRDPARTYSTATICLIBS "ntl") list(APPEND THIRDPARTYSTATICLIBS "gmp") endif() if (WITH_INTEL_HEXL) list(APPEND THIRDPARTYLIBS HEXL::hexl) endif() set(DEMODATAPATH ${CMAKE_CURRENT_SOURCE_DIR}/demoData) set(BINDEMODATAPATH ${CMAKE_CURRENT_BINARY_DIR}/demoData) # copies demoData folder from the root of the repo to build/demoData if the folder does not exist add_custom_target(third-party ALL COMMAND [ ! -d ${BINDEMODATAPATH} ] && cp -R ${DEMODATAPATH} ${BINDEMODATAPATH} && echo "-- Copied demoData files" || echo "-- demoData folder already exists" ) # when running "make clean", additionally deletes the demoData folder and CMake cache file set(ADDITIONAL_CLEAN_FILES "") LIST(APPEND ADDITIONAL_CLEAN_FILES ${BINDEMODATAPATH}) LIST(APPEND ADDITIONAL_CLEAN_FILES ${CMAKE_CURRENT_BINARY_DIR}/CMakeCache.txt) ## for tests if( BUILD_UNITTESTS ) set(UNITTESTMAIN ${PROJECT_SOURCE_DIR}/test/Main_TestAll.cpp) endif() ### add each of the subdirs of src add_subdirectory(src/core) add_subdirectory(src/pke) add_subdirectory(src/binfhe) ### build the google test handlers ###if( BUILD_UNITTESTS ) ### add_subdirectory(third-party/google-test EXCLUDE_FROM_ALL) ###endif() ### build the google benchmark handlers (just the parts we need) if ( BUILD_BENCHMARKS ) set(BENCHMARK_ENABLE_TESTING OFF CACHE BOOL "Enable testing of the benchmark library." FORCE) set(BENCHMARK_ENABLE_INSTALL OFF CACHE BOOL "Enable installation of benchmark. (Projects embedding benchmark may want to turn this OFF.)" FORCE) set(BENCHMARK_ENABLE_GTEST_TESTS OFF CACHE BOOL "Enable building the unit tests which depend on gtest" FORCE) add_subdirectory(third-party/google-benchmark EXCLUDE_FROM_ALL) add_subdirectory(benchmark) endif() ## clobber cleans AND deletes the third-party stuff add_custom_target( clobber COMMAND make clean WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) if( BUILD_UNITTESTS ) add_custom_target( testall DEPENDS core_tests pke_tests binfhe_tests COMMAND echo core: && unittest/core_tests -t || true COMMAND echo pke: && unittest/pke_tests -t || true COMMAND echo binfhe: && unittest/binfhe_tests -t ) endif() if (BUILD_EXAMPLES) add_custom_target( allexamples DEPENDS allcoreexamples allpkeexamples allbinfheexamples ) endif() if (BUILD_EXTRAS) add_custom_target( allextras DEPENDS allcoreextras allpkeextras ) endif() add_custom_target( allmodules DEPENDS ${PALISADE_PACKAGE_LIBS} ) # Add the additional "make clean" files GET_DIRECTORY_PROPERTY(clean_files ADDITIONAL_MAKE_CLEAN_FILES) LIST(APPEND clean_files ${ADDITIONAL_CLEAN_FILES}) LIST(REMOVE_DUPLICATES clean_files) LIST(REMOVE_ITEM clean_files "") SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${clean_files}") export(EXPORT PalisadeTargets FILE "${PROJECT_BINARY_DIR}/PalisadeTargets.cmake") export(PACKAGE Palisade) # Create the PalisadeConfig.cmake and PalisadeConfigVersion files file(RELATIVE_PATH REL_INCLUDE_DIR "${INSTALL_CMAKE_DIR}" "${INSTALL_INCLUDE_DIR}") # ... for the build tree set(CONF_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}" "${PROJECT_BINARY_DIR}") configure_file(PalisadeConfig.cmake.in "${PROJECT_BINARY_DIR}/PalisadeConfig.cmake" @ONLY) # ... for the install tree set(CONF_INCLUDE_DIRS "\${PALISADE_CMAKE_DIR}/${REL_INCLUDE_DIR}") configure_file(PalisadeConfig.cmake.in "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/PalisadeConfig.cmake" @ONLY) # ... for both configure_file(PalisadeConfigVersion.cmake.in "${PROJECT_BINARY_DIR}/PalisadeConfigVersion.cmake" @ONLY) # Install the PalisadeConfig.cmake and PalisadeConfigVersion.cmake install(FILES "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/PalisadeConfig.cmake" "${PROJECT_BINARY_DIR}/PalisadeConfigVersion.cmake" DESTINATION "${INSTALL_CMAKE_DIR}" COMPONENT dev) # Install the export set for use with the install-tree install(EXPORT PalisadeTargets DESTINATION "${INSTALL_CMAKE_DIR}" COMPONENT dev)