# Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT license. cmake_minimum_required(VERSION 3.13) ################################################### # Project SEAL includes the following components: # # 1. SEAL C++ library # # 2. SEAL C export library # # 3. SEAL C++ examples # # 4. SEAL C++ tests # ################################################### # [option] CMAKE_BUILD_TYPE (default: "Release") # Build in one of the following modes: Release, Debug, MiniSizeRel, or RelWithDebInfo. # Most generators recognize these and can set the compiler flags accordingly. We set # the build type here before creating the project to prevent the CMake generator from # overriding our default of "Release". if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type" FORCE) set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Release" "Debug" "MinSizeRel" "RelWithDebInfo") endif() message(STATUS "Build type (CMAKE_BUILD_TYPE): ${CMAKE_BUILD_TYPE}") project(SEAL VERSION 4.0.0 LANGUAGES CXX C) ######################## # Global configuration # ######################## # CMake modules include(CMakeDependentOption) include(CMakePushCheckState) include(CheckIncludeFiles) include(CheckCXXSourceCompiles) include(CheckCXXSourceRuns) include(CheckTypeSize) include(CheckSymbolExists) # Extra modules list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake) include(SEALMacros) # Always build position-independent-code set(CMAKE_POSITION_INDEPENDENT_CODE ON) # Make the install target depend on the all target (required by vcpkg) set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY OFF) # In Debug mode, define SEAL_DEBUG if(CMAKE_BUILD_TYPE STREQUAL "Debug") set(SEAL_DEBUG ON) # In Debug mode, enable extra compiler flags. include(EnableCXXCompilerFlags) else() set(SEAL_DEBUG OFF) endif() message(STATUS "Microsoft SEAL debug mode: ${SEAL_DEBUG}") # [option] SEAL_USE_CXX17 (default: ON) # Use C++17, use C++14 otherwise. set(SEAL_USE_CXX17_OPTION_STR "Use C++17") option(SEAL_USE_CXX17 ${SEAL_USE_CXX17_OPTION_STR} ON) message(STATUS "SEAL_USE_CXX17: ${SEAL_USE_CXX17}") # Enable features from C++17 if available, disable features if set to OFF. include(EnableCXX17) # Enable security-related compile options (MSVC only) set(SEAL_SECURE_COMPILE_OPTIONS_OPTIONS_STR "Enable Control Flow Guard and Spectre mitigations (MSVC only)") option(SEAL_SECURE_COMPILE_OPTIONS ${SEAL_SECURE_COMPILE_OPTIONS_OPTIONS_STR} OFF) mark_as_advanced(SEAL_SECURE_COMPILE_OPTIONS) # Path for output if(ANDROID_ABI) # Android compiles several targets at the same time. Need to specify # separate directories for separate ABIs. set(OUTLIB_PATH "lib/${ANDROID_ABI}") else() set(OUTLIB_PATH "lib") endif() # Required files and directories include(GNUInstallDirs) # Runtime path setup set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}") set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) # Source Tree set(SEAL_INCLUDES_DIR ${CMAKE_CURRENT_LIST_DIR}/native/src) set(SEAL_CONFIG_IN_FILENAME ${CMAKE_CURRENT_LIST_DIR}/cmake/SEALConfig.cmake.in) set(SEAL_CONFIG_H_IN_FILENAME ${SEAL_INCLUDES_DIR}/seal/util/config.h.in) # Build tree set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${OUTLIB_PATH}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${OUTLIB_PATH}) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin) set(SEAL_TARGETS_FILENAME ${CMAKE_CURRENT_BINARY_DIR}/cmake/SEALTargets.cmake) set(SEAL_CONFIG_FILENAME ${CMAKE_CURRENT_BINARY_DIR}/cmake/SEALConfig.cmake) set(SEAL_CONFIG_VERSION_FILENAME ${CMAKE_CURRENT_BINARY_DIR}/cmake/SEALConfigVersion.cmake) set(SEAL_CONFIG_H_FILENAME ${CMAKE_CURRENT_BINARY_DIR}/native/src/seal/util/config.h) set(SEAL_THIRDPARTY_DIR ${CMAKE_SOURCE_DIR}/thirdparty) # Install set(SEAL_CONFIG_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/SEAL-${SEAL_VERSION_MAJOR}.${SEAL_VERSION_MINOR}) set(SEAL_INCLUDES_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR}/SEAL-${SEAL_VERSION_MAJOR}.${SEAL_VERSION_MINOR}) # pkg-config set(SEAL_PKGCONFIG_IN_DIR ${CMAKE_CURRENT_LIST_DIR}/pkgconfig) set(SEAL_PKGCONFIG_IN_FILENAME ${SEAL_PKGCONFIG_IN_DIR}/seal.pc.in) set(SEAL_PKGCONFIG_SHARED_IN_FILENAME ${SEAL_PKGCONFIG_IN_DIR}/seal_shared.pc.in) set(SEAL_PKGCONFIG_MSGSL_IN_FILENAME ${SEAL_PKGCONFIG_IN_DIR}/seal_msgsl.pc.in) set(SEAL_PKGCONFIG_DIR ${CMAKE_CURRENT_BINARY_DIR}/pkgconfig) set(SEAL_PKGCONFIG_FILENAME ${SEAL_PKGCONFIG_DIR}/seal.pc) set(SEAL_PKGCONFIG_SHARED_FILENAME ${SEAL_PKGCONFIG_DIR}/seal_shared.pc) set(SEAL_PKGCONFIG_MSGSL_FILENAME ${SEAL_PKGCONFIG_DIR}/seal_msgsl.pc) set(SEAL_PKGCONFIG_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/pkgconfig) # Clean up artifacts from previous versions include(CleanArtifacts) ######################### # External dependencies # ######################### # [option] SEAL_BUILD_DEPS (default: ON) # Download and build missing dependencies, throw error if disabled. set(SEAL_BUILD_DEPS_OPTION_STR "Automatically download and build unmet dependencies") option(SEAL_BUILD_DEPS ${SEAL_BUILD_DEPS_OPTION_STR} ON) message(STATUS "SEAL_BUILD_DEPS: ${SEAL_BUILD_DEPS}") if(SEAL_BUILD_DEPS) include(FetchContent) mark_as_advanced(FETCHCONTENT_BASE_DIR) mark_as_advanced(FETCHCONTENT_FULLY_DISCONNECTED) mark_as_advanced(FETCHCONTENT_UPDATES_DISCONNECTED) mark_as_advanced(FETCHCONTENT_QUIET) endif() # [option] SEAL_USE_MSGSL (default: ON) set(SEAL_USE_MSGSL_OPTION_STR "Use Microsoft GSL") option(SEAL_USE_MSGSL ${SEAL_USE_MSGSL_OPTION_STR} ON) message(STATUS "SEAL_USE_MSGSL: ${SEAL_USE_MSGSL}") if(SEAL_USE_MSGSL) if(SEAL_BUILD_DEPS) include(ExternalMSGSL) else() find_package(Microsoft.GSL 3 CONFIG) if(NOT Microsoft.GSL_FOUND) message(FATAL_ERROR "Microsoft GSL: not found") else() message(STATUS "Microsoft GSL: found") endif() endif() endif() # [option] SEAL_USE_ZLIB (default: ON) set(SEAL_USE_ZLIB_OPTION_STR "Use ZLIB for compressed serialization") option(SEAL_USE_ZLIB ${SEAL_USE_ZLIB_OPTION_STR} ON) message(STATUS "SEAL_USE_ZLIB: ${SEAL_USE_ZLIB}") if(SEAL_USE_ZLIB) if(SEAL_BUILD_DEPS) include(ExternalZLIB) set(zlib "zlibstatic") else() find_package(ZLIB 1.2.11) if(NOT ZLIB_FOUND) message(FATAL_ERROR "ZLIB: not found") else() message(STATUS "ZLIB: found") endif() set(zlib "ZLIB::ZLIB") endif() endif() # [option] SEAL_USE_ZSTD (default: ON) set(SEAL_USE_ZSTD_OPTION_STR "Use Zstandard for compressed serialization") option(SEAL_USE_ZSTD ${SEAL_USE_ZSTD_OPTION_STR} ON) message(STATUS "SEAL_USE_ZSTD: ${SEAL_USE_ZSTD}") if(SEAL_USE_ZSTD) if(SEAL_BUILD_DEPS) include(ExternalZSTD) set(zstd_static "libzstd_static") else() find_package(zstd CONFIG) if(NOT zstd_FOUND) message(FATAL_ERROR "Zstandard: not found") else() if(TARGET zstd::libzstd_static) set(zstd_static "zstd::libzstd_static") elseif(TARGET libzstd) get_target_property(libzstd_type libzstd TYPE) if(libzstd_type STREQUAL "STATIC_LIBRARY") set(zstd_static "libzstd") message(STATUS "Zstandard: found") else() message(FATAL_ERROR "Zstandard: must be static") endif() elseif(TARGET zstd::libzstd_shared) message(FATAL_ERROR "Zstandard: must be static") else() message(FATAL_ERROR "Zstandard: not found") endif() endif() endif() endif() # [option] SEAL_USE_INTEL_HEXL (default: OFF) set(SEAL_USE_INTEL_HEXL_OPTION_STR "Use Intel HEXL library") option(SEAL_USE_INTEL_HEXL ${SEAL_USE_INTEL_HEXL_OPTION_STR} OFF) message(STATUS "SEAL_USE_INTEL_HEXL: ${SEAL_USE_INTEL_HEXL}") if(SEAL_USE_INTEL_HEXL) if(SEAL_BUILD_DEPS) include(ExternalIntelHEXL) else() find_package(HEXL 1.2.3) if (NOT TARGET HEXL::hexl) message(FATAL_ERROR "Intel HEXL: not found") endif() endif() endif() #################### # SEAL C++ library # #################### # [option] BUILD_SHARED_LIBS (default: OFF) # Build a shared library if set to ON. Build a static library regardlessly. set(BUILD_SHARED_LIBS_STR "Build shared library") option(BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS_STR} OFF) message(STATUS "BUILD_SHARED_LIBS: ${BUILD_SHARED_LIBS}") if(WIN32 AND BUILD_SHARED_LIBS) message(FATAL_ERROR "On Windows only static build is supported; set `BUILD_SHARED_LIBS=OFF`") endif() # [option] SEAL_THROW_ON_TRANSPARENT_CIPHERTEXT (default: ON) set(SEAL_THROW_ON_TRANSPARENT_CIPHERTEXT_STR "Throw an exception when Evaluator outputs a transparent ciphertext") option(SEAL_THROW_ON_TRANSPARENT_CIPHERTEXT ${SEAL_THROW_ON_TRANSPARENT_CIPHERTEXT_STR} ON) message(STATUS "SEAL_THROW_ON_TRANSPARENT_CIPHERTEXT: ${SEAL_THROW_ON_TRANSPARENT_CIPHERTEXT}") mark_as_advanced(FORCE SEAL_THROW_ON_TRANSPARENT_CIPHERTEXT) # [option] SEAL_USE_GAUSSIAN_NOISE (default: OFF) # Use Gaussian distribution for noise sampling if set to ON, use centered binomial otherwise. set(SEAL_USE_GAUSSIAN_NOISE_STR "Use a rounded Gaussian distribution for noise sampling instead of a Centered Binomial Distribution") option(SEAL_USE_GAUSSIAN_NOISE ${SEAL_USE_GAUSSIAN_NOISE_STR} OFF) message(STATUS "SEAL_USE_GAUSSIAN_NOISE: ${SEAL_USE_GAUSSIAN_NOISE}") mark_as_advanced(FORCE SEAL_USE_GAUSSIAN_NOISE) # [option] SEAL_DEFAULT_PRNG (default: Blake2xb) # Choose either Blake2xb or Shake256 to be the default PRNG. set(SEAL_DEFAULT_PRNG_STR "Choose the default PRNG") set(SEAL_DEFAULT_PRNG "Blake2xb" CACHE STRING ${SEAL_DEFAULT_PRNG_STR} FORCE) message(STATUS "SEAL_DEFAULT_PRNG: ${SEAL_DEFAULT_PRNG}") set_property(CACHE SEAL_DEFAULT_PRNG PROPERTY STRINGS "Blake2xb" "Shake256") mark_as_advanced(FORCE SEAL_DEFAULT_PRNG) # [option] SEAL_AVOID_BRANCHING (default: OFF) # Avoid branching in critical conditional move operations if set to ON, use faster method if set to OFF. set(SEAL_AVOID_BRANCHING_STR "Use an always branching-free conditional move") option(SEAL_AVOID_BRANCHING ${SEAL_AVOID_BRANCHING_STR} OFF) message(STATUS "SEAL_AVOID_BRANCHING: ${SEAL_AVOID_BRANCHING}") mark_as_advanced(FORCE SEAL_AVOID_BRANCHING) # [option] SEAL_USE_INTRIN (default: ON) set(SEAL_USE_INTRIN_OPTION_STR "Use intrinsics") option(SEAL_USE_INTRIN ${SEAL_USE_INTRIN_OPTION_STR} ON) # Look for header files, use intrinsics if available, set to OFF otherwise. include(CheckCXXIntrinsicsHeader) if(NOT SEAL_INTRIN_HEADER_FOUND) set(SEAL_USE_INTRIN OFF CACHE BOOL ${SEAL_USE_INTRIN_OPTION_STR} FORCE) endif() message(STATUS "SEAL_USE_INTRIN: ${SEAL_USE_INTRIN}") # [option] SEAL_USE_${A_SPECIFIC_INTRIN} (default: ON, advanced) # Not available if SEAL_USE_INTRIN is OFF. # Use a specific intrinsic if available, set to OFF otherwise. include(CheckCXXIntrinsicsSpecific) if(MSVC) set(SEAL_USE__UMUL128_OPTION_STR "Use _umul128") cmake_dependent_option(SEAL_USE__UMUL128 ${SEAL_USE__UMUL128_OPTION_STR} ON "SEAL_USE_INTRIN" OFF) mark_as_advanced(FORCE SEAL_USE__UMUL128) if(NOT SEAL__UMUL128_FOUND) set(SEAL_USE__UMUL128 OFF CACHE BOOL ${SEAL_USE__UMUL128_OPTION_STR} FORCE) endif() set(SEAL_USE__BITSCANREVERSE64_OPTION_STR "Use _BitScanReverse64") cmake_dependent_option(SEAL_USE__BITSCANREVERSE64 ${SEAL_USE__BITSCANREVERSE64_OPTION_STR} ON "SEAL_USE_INTRIN" OFF) mark_as_advanced(FORCE SEAL_USE__BITSCANREVERSE64) if(NOT SEAL__BITSCANREVERSE64_FOUND) set(SEAL_USE__BITSCANREVERSE64 OFF CACHE BOOL ${SEAL_USE__BITSCANREVERSE64_OPTION_STR} FORCE) endif() else() set(SEAL_USE___INT128_OPTION_STR "Use __int128") cmake_dependent_option(SEAL_USE___INT128 ${SEAL_USE___INT128_OPTION_STR} ON "SEAL_USE_INTRIN" OFF) mark_as_advanced(FORCE SEAL_USE___INT128) if(NOT SEAL___INT128_FOUND) set(SEAL_USE___INT128 OFF CACHE BOOL ${SEAL_USE___INT128_OPTION_STR} FORCE) endif() set(SEAL_USE___BUILTIN_CLZLL_OPTION_STR "Use __builtin_clzll") cmake_dependent_option(SEAL_USE___BUILTIN_CLZLL ${SEAL_USE___BUILTIN_CLZLL_OPTION_STR} ON "SEAL_USE_INTRIN" OFF) mark_as_advanced(FORCE SEAL_USE___BUILTIN_CLZLL) if(NOT SEAL___BUILTIN_CLZLL_FOUND) set(SEAL_USE___BUILTIN_CLZLL OFF CACHE BOOL ${SEAL_USE___BUILTIN_CLZLL_OPTION_STR} FORCE) endif() endif() set(SEAL_USE__ADDCARRY_U64_OPTION_STR "Use _addcarry_u64") cmake_dependent_option(SEAL_USE__ADDCARRY_U64 ${SEAL_USE__ADDCARRY_U64_OPTION_STR} ON "SEAL_USE_INTRIN" OFF) mark_as_advanced(FORCE SEAL_USE__ADDCARRY_U64) if(NOT SEAL__ADDCARRY_U64_FOUND) set(SEAL_USE__ADDCARRY_U64 OFF CACHE BOOL ${SEAL_USE__ADDCARRY_U64_OPTION_STR} FORCE) endif() set(SEAL_USE__SUBBORROW_U64_OPTION_STR "Use _subborrow_u64") cmake_dependent_option(SEAL_USE__SUBBORROW_U64 ${SEAL_USE__SUBBORROW_U64_OPTION_STR} ON "SEAL_USE_INTRIN" OFF) mark_as_advanced(FORCE SEAL_USE__SUBBORROW_U64) if(NOT SEAL__SUBBORROW_U64_FOUND) set(SEAL_USE__SUBBORROW_U64 OFF CACHE BOOL ${SEAL_USE__SUBBORROW_U64_OPTION_STR} FORCE) endif() # [option] SEAL_USE_${A_SPECIFIC_MEMSET_METHOD} (default: ON, advanced) # Use a specific memset method if available, set to OFF otherwise. include(CheckMemset) set(SEAL_USE_MEMSET_S_OPTION_STR "Use memset_s") option(SEAL_USE_MEMSET_S ${SEAL_USE_MEMSET_S_OPTION_STR} ON) mark_as_advanced(FORCE SEAL_USE_MEMSET_S) if(NOT SEAL_MEMSET_S_FOUND) set(SEAL_USE_MEMSET_S OFF CACHE BOOL ${SEAL_USE_MEMSET_S_OPTION_STR} FORCE) endif() message(STATUS "SEAL_USE_MEMSET_S: ${SEAL_USE_MEMSET_S}") set(SEAL_USE_EXPLICIT_BZERO_OPTION_STR "Use explicit_bzero") option(SEAL_USE_EXPLICIT_BZERO ${SEAL_USE_EXPLICIT_BZERO_OPTION_STR} ON) mark_as_advanced(FORCE SEAL_USE_EXPLICIT_BZERO) if(NOT SEAL_EXPLICIT_BZERO_FOUND) set(SEAL_USE_EXPLICIT_BZERO OFF CACHE BOOL ${SEAL_USE_EXPLICIT_BZERO_OPTION_STR} FORCE) endif() message(STATUS "SEAL_USE_EXPLICIT_BZERO: ${SEAL_USE_EXPLICIT_BZERO}") set(SEAL_USE_EXPLICIT_MEMSET_OPTION_STR "Use explicit_memset") option(SEAL_USE_EXPLICIT_MEMSET ${SEAL_USE_EXPLICIT_MEMSET_OPTION_STR} ON) mark_as_advanced(FORCE SEAL_USE_EXPLICIT_MEMSET) if(NOT SEAL_EXPLICIT_MEMSET_FOUND) set(SEAL_USE_EXPLICIT_MEMSET OFF CACHE BOOL ${SEAL_USE_EXPLICIT_MEMSET_OPTION_STR} FORCE) endif() message(STATUS "SEAL_USE_EXPLICIT_MEMSET: ${SEAL_USE_EXPLICIT_MEMSET}") # [option] SEAL_USE_ALIGNED_ALLOC (default: ON, advanced) # Not available if SEAL_USE_CXX17 is OFF or building for Android. # Use 64-byte aligned malloc if available, set of OFF otherwise if(MSVC) set(SEAL_USE_ALIGNED_ALLOC_OPTION_STR "Use _aligned_malloc") else() set(SEAL_USE_ALIGNED_ALLOC_OPTION_STR "Use ::aligned_alloc") endif() cmake_dependent_option(SEAL_USE_ALIGNED_ALLOC ${SEAL_USE_ALIGNED_ALLOC_OPTION_STR} ON "SEAL_USE_CXX17;NOT ANDROID_ABI" OFF) mark_as_advanced(FORCE SEAL_USE_ALIGNED_ALLOC) # Add source files to library and header files to install set(SEAL_SOURCE_FILES "") add_subdirectory(native/src/seal) # Create the config file configure_file(${SEAL_CONFIG_H_IN_FILENAME} ${SEAL_CONFIG_H_FILENAME}) install( FILES ${SEAL_CONFIG_H_FILENAME} DESTINATION ${SEAL_INCLUDES_INSTALL_DIR}/seal/util) # Build only a static library if(NOT BUILD_SHARED_LIBS) add_library(seal STATIC ${SEAL_SOURCE_FILES}) seal_set_version_filename(seal) seal_set_language(seal) seal_set_include_directories(seal) seal_set_version(seal) seal_link_threads(seal) seal_install_target(seal SEALTargets) if(SEAL_USE_MSGSL) if(SEAL_BUILD_DEPS) target_include_directories(seal PUBLIC $) else() target_link_libraries(seal PUBLIC Microsoft.GSL::GSL) endif() endif() if(SEAL_USE_ZLIB) if(SEAL_BUILD_DEPS) add_dependencies(seal ${zlib}) target_include_directories(seal PRIVATE $) target_include_directories(seal PRIVATE $>) seal_combine_archives(seal ${zlib}) else() target_link_libraries(seal PRIVATE ${zlib}) endif() endif() if(SEAL_USE_ZSTD) if(SEAL_BUILD_DEPS) add_dependencies(seal ${zstd_static}) target_include_directories(seal PRIVATE $) target_include_directories(seal PRIVATE $) seal_combine_archives(seal ${zstd_static}) else() target_link_libraries(seal PRIVATE ${zstd_static}) endif() endif() if(SEAL_USE_INTEL_HEXL) if(SEAL_BUILD_DEPS) add_dependencies(seal HEXL::hexl) target_include_directories(seal PRIVATE $>) target_compile_options(seal PRIVATE $) get_target_property(HEXL_INTERFACE_LINK_OPTIONS HEXL::hexl INTERFACE_LINK_OPTIONS) if (NOT "${HEXL_INTERFACE_LINK_OPTIONS}" STREQUAL "HEXL_INTERFACE_LINK_OPTIONS-NOTFOUND") target_link_libraries(seal INTERFACE ${HEXL_INTERFACE_LINK_OPTIONS}) endif() seal_combine_archives(seal HEXL::hexl) else() target_link_libraries(seal PUBLIC HEXL::hexl) endif() endif() # Set secure compile options if SEAL_SECURE_COMPILE_OPTIONS is ON; only supported on MSVC if(SEAL_SECURE_COMPILE_OPTIONS) seal_set_secure_compile_options(seal PUBLIC) endif() # Build only a shared library else() add_library(seal_shared SHARED ${SEAL_SOURCE_FILES}) seal_set_soversion(seal_shared) set_target_properties(seal_shared PROPERTIES OUTPUT_NAME seal) seal_set_language(seal_shared) seal_set_include_directories(seal_shared) seal_set_version(seal_shared) seal_link_threads(seal_shared) seal_install_target(seal_shared SEALTargets) if(SEAL_USE_MSGSL) if(SEAL_BUILD_DEPS) target_include_directories(seal_shared PUBLIC $) else() target_link_libraries(seal_shared PUBLIC Microsoft.GSL::GSL) endif() endif() if(SEAL_USE_ZLIB) target_link_libraries(seal_shared PRIVATE ${zlib}) target_include_directories(seal_shared PRIVATE $) target_include_directories(seal_shared PRIVATE $>) endif() if(SEAL_USE_ZSTD) target_include_directories(seal_shared PRIVATE $) target_include_directories(seal_shared PRIVATE $) target_link_libraries(seal_shared PRIVATE ${zstd_static}) endif() if(SEAL_USE_INTEL_HEXL) target_link_libraries(seal_shared PRIVATE HEXL::hexl) target_compile_options(seal_shared PRIVATE $) get_target_property(HEXL_INTERFACE_LINK_OPTIONS HEXL::hexl INTERFACE_LINK_OPTIONS) if (NOT "${HEXL_INTERFACE_LINK_OPTIONS}" STREQUAL "HEXL_INTERFACE_LINK_OPTIONS-NOTFOUND") target_link_libraries(seal_shared INTERFACE ${HEXL_INTERFACE_LINK_OPTIONS}) endif() # Install shared HEXL library to installation directory install(DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_LIBRARY_PREFIX} FILES_MATCHING PATTERN "*hexl*" ) endif() endif() # Add standard alias targets for SEAL::seal and SEAL::seal_shared if(TARGET seal) add_library(SEAL::seal ALIAS seal) endif() if(TARGET seal_shared) add_library(SEAL::seal_shared ALIAS seal_shared) endif() ######################### # SEAL C export library # ######################### # [option] SEAL_BUILD_SEAL_C (default: OFF) set(SEAL_BUILD_SEAL_C_OPTION_STR "Build C export library for Microsoft SEAL") option(SEAL_BUILD_SEAL_C ${SEAL_BUILD_SEAL_C_OPTION_STR} OFF) message(STATUS "SEAL_BUILD_SEAL_C: ${SEAL_BUILD_SEAL_C}") set(SEAL_BUILD_STATIC_SEAL_C_OPTION_STR "Build static C library for Microsoft SEAL") cmake_dependent_option(SEAL_BUILD_STATIC_SEAL_C ${SEAL_BUILD_STATIC_SEAL_C_OPTION_STR} OFF "SEAL_BUILD_SEAL_C" OFF) mark_as_advanced(SEAL_BUILD_STATIC_SEAL_C) # Create SEAL_C library but add no source files yet if(SEAL_BUILD_SEAL_C) unset(SIZET CACHE) unset(HAVE_SIZET CACHE) if(BUILD_SHARED_LIBS) message(FATAL_ERROR "SEAL_C (shared or static) requires a static SEAL; set `BUILD_SHARED_LIBS=OFF` and control " "SEAL_C by setting `SEAL_BUILD_STATIC_SEAL_C` to `OFF` (default) or `ON`") endif() if(NOT SEAL_BUILD_DEPS) message(FATAL_ERROR "SEAL_C requires `SEAL_BUILD_DEPS=ON`") endif() if(NOT SEAL_BUILD_STATIC_SEAL_C AND SEAL_USE_INTEL_HEXL AND CMAKE_BUILD_TYPE STREQUAL "Debug" AND UNIX) message(WARNING "SEAL_C (shared) cannot find Address Sanitizer (libasan) enabled by Intel HEXL in Debug mode " "on Unix-like systems. SEALNet does not work. Preload libasan for downstream applications.") endif() if(SEAL_BUILD_STATIC_SEAL_C) add_library(sealc STATIC) else() add_library(sealc SHARED) endif() # Add source files to library and header files to install add_subdirectory(${SEAL_INCLUDES_DIR}/seal/c) seal_set_version(sealc) if(SEAL_BUILD_STATIC_SEAL_C) seal_set_version_filename(sealc) else() seal_set_soversion(sealc) endif() seal_set_language(sealc) seal_set_include_directories(sealc) if (SEAL_USE_INTEL_HEXL) target_include_directories(sealc PRIVATE $) endif() target_link_libraries(sealc PUBLIC seal) seal_install_target(sealc SEALTargets) endif() # Add standard alias target for SEAL::sealc if(TARGET sealc) add_library(SEAL::sealc ALIAS sealc) endif() ################################# # Installation and CMake config # ################################# # Create the CMake config file include(CMakePackageConfigHelpers) configure_package_config_file( ${SEAL_CONFIG_IN_FILENAME} ${SEAL_CONFIG_FILENAME} INSTALL_DESTINATION ${SEAL_CONFIG_INSTALL_DIR}) # Install the export install( EXPORT SEALTargets NAMESPACE SEAL:: DESTINATION ${SEAL_CONFIG_INSTALL_DIR}) # Version file; we require exact version match for downstream write_basic_package_version_file( ${SEAL_CONFIG_VERSION_FILENAME} VERSION ${SEAL_VERSION} COMPATIBILITY SameMinorVersion) # Install config and module files install( FILES ${SEAL_CONFIG_FILENAME} ${SEAL_CONFIG_VERSION_FILENAME} DESTINATION ${SEAL_CONFIG_INSTALL_DIR}) # We export SEALTargets from the build tree so it can be used by other projects # without requiring an install. export( EXPORT SEALTargets NAMESPACE SEAL:: FILE ${SEAL_TARGETS_FILENAME}) # Install header files of dependencies if SEAL_BUILD_DEPS is ON if(SEAL_BUILD_DEPS) # MSGSL if(SEAL_USE_MSGSL) install( DIRECTORY ${msgsl_SOURCE_DIR}/include/gsl DESTINATION ${SEAL_INCLUDES_INSTALL_DIR}) endif() endif() ############## # pkg-config # ############## if(UNIX OR APPLE) # Set the requirements according to the current configuration if SEAL_BUILD_DEPS=OFF if(NOT SEAL_BUILD_DEPS) if(SEAL_USE_MSGSL) # Extract the include directories from Microsoft.GSL::GSL get_target_property( SEAL_PKGCONFIG_MSGSL_INCLUDE_DIR Microsoft.GSL::GSL INTERFACE_INCLUDE_DIRECTORIES) # Create the Microsoft GSL pkg-config file configure_file(${SEAL_PKGCONFIG_MSGSL_IN_FILENAME} ${SEAL_PKGCONFIG_MSGSL_FILENAME} @ONLY) set(SEAL_PKGCONFIG_MSGSL_REQUIRES_STRING "seal_msgsl >= ${Microsoft.GSL_VERSION_MAJOR}") endif() if(SEAL_USE_ZLIB) set(SEAL_PKGCONFIG_ZLIB_REQUIRES_STRING "zlib = ${ZLIB_VERSION_STRING}") endif() if(SEAL_USE_ZSTD) set(SEAL_PKGCONFIG_ZSTD_REQUIRES_STRING "libzstd >= ${zstd_VERSION_MAJOR}") endif() if(SEAL_USE_INTEL_HEXL) set(SEAL_PKGCONFIG_INTEL_HEXL_REQUIRES_STRING "hexl >= ${HEXL_VERSION_MAJOR}") message(STATUS "Intel HEXL does not have a pkg-config file") endif() endif() # Create the pkg-config file if(TARGET seal) configure_file(${SEAL_PKGCONFIG_IN_FILENAME} ${SEAL_PKGCONFIG_FILENAME} @ONLY) endif() if(TARGET seal_shared) configure_file(${SEAL_PKGCONFIG_SHARED_IN_FILENAME} ${SEAL_PKGCONFIG_SHARED_FILENAME} @ONLY) endif() # Install the pkg-config files if(EXISTS ${SEAL_PKGCONFIG_FILENAME}) install( FILES ${SEAL_PKGCONFIG_FILENAME} DESTINATION ${SEAL_PKGCONFIG_INSTALL_DIR}) endif() if(EXISTS ${SEAL_PKGCONFIG_SHARED_FILENAME}) install( FILES ${SEAL_PKGCONFIG_SHARED_FILENAME} DESTINATION ${SEAL_PKGCONFIG_INSTALL_DIR}) endif() if(EXISTS ${SEAL_PKGCONFIG_MSGSL_FILENAME}) install( FILES ${SEAL_PKGCONFIG_MSGSL_FILENAME} DESTINATION ${SEAL_PKGCONFIG_INSTALL_DIR}) endif() endif() ##################### # SEAL C++ examples # ##################### # [option] SEAL_BUILD_EXAMPLES set(SEAL_BUILD_EXAMPLES_OPTION_STR "Build C++ examples for Microsoft SEAL") option(SEAL_BUILD_EXAMPLES ${SEAL_BUILD_EXAMPLES_OPTION_STR} OFF) message(STATUS "SEAL_BUILD_EXAMPLES: ${SEAL_BUILD_EXAMPLES}") if(SEAL_BUILD_EXAMPLES) add_subdirectory(native/examples) endif() ################## # SEAL C++ tests # ################## # [option] SEAL_BUILD_TESTS set(SEAL_BUILD_TESTS_OPTION_STR "Build C++ tests for Microsoft SEAL") option(SEAL_BUILD_TESTS ${SEAL_BUILD_TESTS_OPTION_STR} OFF) message(STATUS "SEAL_BUILD_TESTS: ${SEAL_BUILD_TESTS}") if(SEAL_BUILD_TESTS) add_subdirectory(native/tests) endif() ####################### # SEAL C++ benchmarks # ####################### # [option] SEAL_BUILD_BENCH set(SEAL_BUILD_BENCH_OPTION_STR "Build C++ benchmarks for Microsoft SEAL") option(SEAL_BUILD_BENCH ${SEAL_BUILD_BENCH_OPTION_STR} OFF) message(STATUS "SEAL_BUILD_BENCH: ${SEAL_BUILD_BENCH}") if(SEAL_BUILD_BENCH) add_subdirectory(native/bench) endif() ####################################### # Configure SEALNet and NuGet package # ####################################### # In Windows we will set the SEAL_C library path according to the CMake generator set(SEAL_WINDOWS_SEAL_C_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) get_property(SEAL_IS_MULTI_CONFIG_GENERATOR GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) if(SEAL_IS_MULTI_CONFIG_GENERATOR) # Is this the Visual Studio generator? If so, the output path will contain the configuration. # We shall use CMAKE_BUILD_TYPE here, which by default will be "Release". The user has the # option of changing this by explicitly specifying CMAKE_BUILD_TYPE, which multi-config # generators otherwise ignore. set(SEAL_WINDOWS_SEAL_C_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_BUILD_TYPE}) endif() # Create SEALNet.csproj, SEALNetExamples.csproj, and SEALNetTest.csproj configure_file( ${CMAKE_CURRENT_LIST_DIR}/dotnet/src/SEALNet.csproj.in ${CMAKE_CURRENT_BINARY_DIR}/dotnet/src/SEALNet.csproj @ONLY) configure_file( ${CMAKE_CURRENT_LIST_DIR}/dotnet/tests/SEALNetTest.csproj.in ${CMAKE_CURRENT_BINARY_DIR}/dotnet/tests/SEALNetTest.csproj @ONLY) configure_file( ${CMAKE_CURRENT_LIST_DIR}/dotnet/examples/SEALNetExamples.csproj.in ${CMAKE_CURRENT_BINARY_DIR}/dotnet/examples/SEALNetExamples.csproj @ONLY) # Create SEALNet.sln for Visual Studio to build all dotnet projects configure_file( ${CMAKE_CURRENT_LIST_DIR}/dotnet/SEALNet.sln.in ${CMAKE_CURRENT_BINARY_DIR}/dotnet/SEALNet.sln @ONLY) # Set the sealc dynamic library file names to be included in creating # the NuGet package. When building a multi-platform NuGet package, the # dynamic library paths need to be specified explicitly in the NuGet # command. See dotnet/nuget/SEALNet.nuspec.in. # Create SEALNet-multi.nuspec for a multi-platform NuGet package configure_file( ${CMAKE_CURRENT_LIST_DIR}/dotnet/nuget/SEALNet-multi.nuspec.in ${CMAKE_CURRENT_BINARY_DIR}/dotnet/nuget/SEALNet-multi.nuspec @ONLY) set(NUGET_WINDOWS_SEAL_C_PATH "") set(NUGET_LINUX_SEAL_C_PATH "") set(NUGET_MACOS_SEAL_C_PATH "") # Supporting local building of NuGet package if(WIN32) set(NUGET_WINDOWS_SEAL_C_PATH ${SEAL_WINDOWS_SEAL_C_DIRECTORY}/sealc.dll) elseif(UNIX AND NOT APPLE) set(NUGET_LINUX_SEAL_C_PATH ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libsealc.so) elseif(APPLE) set(NUGET_MACOS_SEAL_C_PATH ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libsealc.dylib) endif() # Create SEALNet.nuspec for a local NuGet pack from SEALNet.nuspec.in configure_file( ${CMAKE_CURRENT_LIST_DIR}/dotnet/nuget/SEALNet.nuspec.in ${CMAKE_CURRENT_BINARY_DIR}/dotnet/nuget/SEALNet.nuspec @ONLY)