From 53f037ed999ea3d26a3ad1958751a99207178222 Mon Sep 17 00:00:00 2001 From: oliver-schick Date: Thu, 10 Sep 2020 05:34:27 +0200 Subject: [PATCH] Added build support for Android platforms --- .gitignore | 2 + CMakeLists.txt | 104 ++++++++--------- cmake/BoostConfig.cmake.in | 5 + cmake/ForwardConfig.cmake.in | 14 +++ cmake/ImportIntoAndroidStudio.cmake.in | 19 +++ cmake/Modules/AddENCRYPTO_utils.cmake | 22 ++++ cmake/Modules/AddRelic.cmake | 24 ++++ cmake/Modules/AndroidCacheVariables.cmake | 45 ++++++++ cmake/Modules/FetchENCRYPTO_utils.cmake | 4 + cmake/Modules/FetchHelper.cmake | 42 +++++++ cmake/Modules/FetchRelic.cmake | 47 ++++++++ cmake/Modules/InstallConfig.cmake | 56 +++++++++ cmake/Modules/OTExtensionCacheVariables.cmake | 108 ++++++++++++++++++ cmake/Modules/PatchRelic.cmake | 5 + cmake/Modules/RelicPatches/cmake/gmp.cmake | 60 ++++++++++ cmake/OTExtensionConfig.cmake.in | 6 +- cmake/RelicConfig.cmake.in | 34 ++++++ 17 files changed, 543 insertions(+), 54 deletions(-) create mode 100644 cmake/BoostConfig.cmake.in create mode 100644 cmake/ForwardConfig.cmake.in create mode 100644 cmake/ImportIntoAndroidStudio.cmake.in create mode 100644 cmake/Modules/AddENCRYPTO_utils.cmake create mode 100644 cmake/Modules/AddRelic.cmake create mode 100644 cmake/Modules/AndroidCacheVariables.cmake create mode 100644 cmake/Modules/FetchENCRYPTO_utils.cmake create mode 100644 cmake/Modules/FetchHelper.cmake create mode 100644 cmake/Modules/FetchRelic.cmake create mode 100644 cmake/Modules/InstallConfig.cmake create mode 100644 cmake/Modules/OTExtensionCacheVariables.cmake create mode 100644 cmake/Modules/PatchRelic.cmake create mode 100644 cmake/Modules/RelicPatches/cmake/gmp.cmake create mode 100644 cmake/RelicConfig.cmake.in diff --git a/.gitignore b/.gitignore index 6f67ea3..154f9f5 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,8 @@ # build directory build*/ +# extern directory +extern/* # CMake CMakeCache.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 6395a71..32e1ac6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,38 +1,49 @@ -cmake_minimum_required(VERSION 3.12) -project(OTExtension LANGUAGES CXX) - -if (CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0) - message(FATAL_ERROR "ENCRYPTO_utils require at least g++-8") +cmake_minimum_required(VERSION 3.13) +list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_LIST_DIR}/cmake/Modules") +include(OTExtensionCacheVariables) +if(ANDROID) + set(CMAKE_CXX_STANDARD 14) +else() + set(CMAKE_CXX_STANDARD 17) endif() - -option(OTEXTENSION_BUILD_EXE "Build executables" OFF) - -find_package(ENCRYPTO_utils QUIET) -if(ENCRYPTO_utils_FOUND) - message(STATUS "Found ENCRYPTO_utils") -elseif(NOT ENCRYPTO_utils_FOUND AND NOT TARGET ENCRYPTO_utils::encrypto_utils) - message("ENCRYPTO_utils was not found: add ENCRYPTO_utils subdirectory") - if(NOT EXISTS "${PROJECT_SOURCE_DIR}/extern/ENCRYPTO_utils/CMakeLists.txt") - find_package(Git REQUIRED) - message("initialize Git submodule: extern/ENCRYPTO_utils") - execute_process(COMMAND git submodule update --init extern/ENCRYPTO_utils - WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}") - endif() - add_subdirectory(extern/ENCRYPTO_utils) +project(OTExtension LANGUAGES C CXX) + +if(ANDROID) + if(ANDROID_ARM_NEON) + set(OTExtension_INSTALL_PREFIX "platforms/${ANDROID_PLATFORM}/arch-${ANDROID_SYSROOT_ABI}/NEON") + else(ANDROID_ARM_NEON) + set(OTExtension_INSTALL_PREFIX "platforms/${ANDROID_PLATFORM}/arch-${ANDROID_SYSROOT_ABI}") + endif(ANDROID_ARM_NEON) + set(OTExtension_INSTALL_INCLUDE "${OTExtension_INSTALL_PREFIX}/include") + set(OTExtension_INSTALL_LIB "${OTExtension_INSTALL_PREFIX}/lib") + set(OTExtension_INSTALL_ARCHIVE "${OTExtension_INSTALL_PREFIX}/lib") + set(OTExtension_INSTALL_CONFIG "") +else(ANDROID) + set(OTExtension_INSTALL_PREFIX "") + set(OTExtension_INSTALL_INCLUDE "include") + set(OTExtension_INSTALL_LIB "lib") + set(OTExtension_INSTALL_ARCHIVE "lib") + set(OTExtension_INSTALL_CONFIG "") +endif(ANDROID) + +if(ANDROID AND CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${ANDROID_NDK}/usr/local" + CACHE PATH "Default install directory for android builds." FORCE) endif() + +include(AddRelic) +include(AddENCRYPTO_utils) find_package(Threads REQUIRED) -add_library(otextension +add_library(otextension ${OTExtension_LIBRARY_TYPE} ot/alsz-ot-ext-rec.cpp ot/alsz-ot-ext-snd.cpp -# ot/asharov-lindell.cpp ot/iknp-ot-ext-rec.cpp ot/iknp-ot-ext-snd.cpp ot/kk-ot-ext-rec.cpp ot/kk-ot-ext-snd.cpp ot/naor-pinkas.cpp -# ot/naor-pinkas_noro.cpp ot/nnob-ot-ext-rec.cpp ot/nnob-ot-ext-snd.cpp ot/ot-ext.cpp @@ -41,55 +52,44 @@ add_library(otextension ot/pvwddh.cpp ot/simpleot.cpp ) +set_target_properties(otextension PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE) + add_library(OTExtension::otextension ALIAS otextension) -target_compile_features(otextension PUBLIC cxx_std_17) target_compile_options(otextension PRIVATE "-Wall" "-Wextra") -#target_compile_options(otextension PUBLIC "-fno-omit-frame-pointer" "-fsanitize=address") -#target_link_options(otextension PUBLIC "-fno-omit-frame-pointer" "-fsanitize=address") target_include_directories(otextension PUBLIC - $ + $ $ ) target_link_libraries(otextension PUBLIC ENCRYPTO_utils::encrypto_utils + PUBLIC Relic::relic PUBLIC Threads::Threads ) +include(InstallConfig) +install_config(OTExtension_INSTALL_LOCATION "OTExtension" OTExtension::otextension) + install(TARGETS otextension EXPORT "${PROJECT_NAME}Targets" - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib - INCLUDES DESTINATION lib -) + ARCHIVE DESTINATION "${OTExtension_INSTALL_ARCHIVE}" + LIBRARY DESTINATION "${OTExtension_INSTALL_LIB}" + INCLUDES DESTINATION "${OTExtension_INSTALL_INCLUDE}") install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/ot" - DESTINATION include - FILES_MATCHING PATTERN "*.h" -) -export(TARGETS otextension NAMESPACE "${PROJECT_NAME}::" FILE "${PROJECT_NAME}Targets.cmake") + DESTINATION "${OTExtension_INSTALL_INCLUDE}" + FILES_MATCHING REGEX ".*\\.h(pp|h)?$" REGEX ".*cmake.*" EXCLUDE) +export(TARGETS otextension ${OTExtension_DEPENDENCIES_TO_EXPORT} + NAMESPACE "${PROJECT_NAME}::" + FILE "${PROJECT_NAME}Targets.cmake") install(EXPORT "${PROJECT_NAME}Targets" NAMESPACE "${PROJECT_NAME}::" - DESTINATION "lib/cmake/${PROJECT_NAME}" -) - - -include(CMakePackageConfigHelpers) - -configure_package_config_file("${CMAKE_CURRENT_LIST_DIR}/cmake/${PROJECT_NAME}Config.cmake.in" - ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake - INSTALL_DESTINATION "lib/cmake/${PROJECT_NAME}" -) - -install(FILES - "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" - DESTINATION "lib/cmake/${PROJECT_NAME}" -) + DESTINATION "${OTExtension_INSTALL_LOCATION}") -if(OTEXTENSION_BUILD_EXE) +if(OTExtension_BUILD_EXE) add_subdirectory(mains) -endif(OTEXTENSION_BUILD_EXE) +endif(OTExtension_BUILD_EXE) diff --git a/cmake/BoostConfig.cmake.in b/cmake/BoostConfig.cmake.in new file mode 100644 index 0000000..832ad04 --- /dev/null +++ b/cmake/BoostConfig.cmake.in @@ -0,0 +1,5 @@ +get_filename_component(Boost_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) + +if(NOT TARGET Boost::boost) + include("${Boost_CMAKE_DIR}/BoostTargets.cmake") +endif() diff --git a/cmake/ForwardConfig.cmake.in b/cmake/ForwardConfig.cmake.in new file mode 100644 index 0000000..ea7270a --- /dev/null +++ b/cmake/ForwardConfig.cmake.in @@ -0,0 +1,14 @@ +include(CMakeFindDependencyMacro) +set(DEPENDENCY_NAME "@DEPENDENCY_NAME@") +if(ANDROID AND ANDROID_ARM_NEON) + set(PREFIX "${DEPENDENCY_NAME}-${ANDROID_PLATFORM}-${ANDROID_SYSROOT_ABI}-NEON") +elseif(ANDROID AND NOT ANDROID_ARM_NEON) + set(PREFIX "${DEPENDENCY_NAME}-${ANDROID_PLATFORM}-${ANDROID_SYSROOT_ABI}") +else() + set(PREFIX "${DEPENDENCY_NAME}") +endif() +if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/${PREFIX}/${PREFIX}Config.cmake") + include("${CMAKE_CURRENT_LIST_DIR}/${PREFIX}/${PREFIX}Config.cmake") +else() + set(${DEPENDENCY_NAME}_FOUND FALSE) +endif() diff --git a/cmake/ImportIntoAndroidStudio.cmake.in b/cmake/ImportIntoAndroidStudio.cmake.in new file mode 100644 index 0000000..f355262 --- /dev/null +++ b/cmake/ImportIntoAndroidStudio.cmake.in @@ -0,0 +1,19 @@ + +set(TARGETS "@DEPENDENCY_TARGETS@") +function(import_into_android_studio IMPORT_LOCATION) + if(ANDROID AND EXISTS "${IMPORT_LOCATION}") + foreach(target ${TARGETS}) + get_target_property(library_type ${target} TYPE) + if("${library_type}" STREQUAL "SHARED_LIBRARY") + get_target_property(lib_location ${target} LOCATION) + file(COPY "${lib_location}" DESTINATION "${IMPORT_LOCATION}") + endif() + endforeach() + endif() +endfunction() + +if(NOT IMPORT_LOCATION) + import_into_android_studio("${PROJECT_SOURCE_DIR}/../jniLibs/${ANDROID_ABI}") +else() + import_into_android_studio("${IMPORT_LOCATION}") +endif() diff --git a/cmake/Modules/AddENCRYPTO_utils.cmake b/cmake/Modules/AddENCRYPTO_utils.cmake new file mode 100644 index 0000000..fcf0aec --- /dev/null +++ b/cmake/Modules/AddENCRYPTO_utils.cmake @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 3.13) + +if(NOT TARGET ENCRYPTO_utils::encrypto_utils) + if(NOT ENCRYPTO_utils_LIBRARY_TYPE) + set(ENCRYPTO_utils_LIBRARY_TYPE ${OTExtension_LIBRARY_TYPE}) + endif() + file(GLOB ENCRYPTO_utils_FILE_LIST "${PROJECT_SOURCE_DIR}/extern/ENCRYPTO_utils/*") + list(LENGTH ENCRYPTO_utils_FILE_LIST ENCRYPTO_utils_NUM_FILES) + #if ENCRYPTO_utils directory is empty + if(ENCRYPTO_utils_NUM_FILES EQUAL 0) + message(STATUS "ENCRYPTO_utils was not found. Fetching ENCRYPTO_utils...") + include(FetchENCRYPTO_utils) + else() + message(STATUS "ENCRYPTO_utils was found in: ${PROJECT_SOURCE_DIR}/extern/ENCRYPTO_utils") + set(ENCRYPTO_utils_SOURCE "${PROJECT_SOURCE_DIR}/extern/ENCRYPTO_utils" + CACHE PATH + "Path to ENCRYPTO_utils source." + FORCE + ) + include(FetchENCRYPTO_utils) + endif() +endif() diff --git a/cmake/Modules/AddRelic.cmake b/cmake/Modules/AddRelic.cmake new file mode 100644 index 0000000..43f3813 --- /dev/null +++ b/cmake/Modules/AddRelic.cmake @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 3.13) + +find_package(Relic QUIET) +if(Relic_FOUND OR TARGET Relic::relic) + message(STATUS "Found Relic.") +elseif(NOT Relic_FOUND AND NOT TARGET Relic::relic) + if("${Relic_SOURCE}" STREQUAL "") + file(GLOB Relic_FILE_LIST "${PROJECT_SOURCE_DIR}/extern/Relic/*") + list(LENGTH Relic_FILE_LIST Relic_NUM_FILES) + #if Relic directory is empty + if(Relic_NUM_FILES EQUAL 0) + message(STATUS "Relic was not found. Fetching Relic...") + else() + message(STATUS "Relic was found in: ${PROJECT_SOURCE_DIR}/extern/Relic") + set(Relic_SOURCE "${PROJECT_SOURCE_DIR}/extern/Relic") + endif() + endif() + include(FetchRelic) + if(ANDROID AND Relic_LIBRARY_TYPE STREQUAL "SHARED") + set(CMAKE_SHARED_LINKER_FLAGS ${TMP}) + endif() + include(ExternalBuildHelper) + install_imported_library(Relic::relic "Relic") +endif() diff --git a/cmake/Modules/AndroidCacheVariables.cmake b/cmake/Modules/AndroidCacheVariables.cmake new file mode 100644 index 0000000..46472fd --- /dev/null +++ b/cmake/Modules/AndroidCacheVariables.cmake @@ -0,0 +1,45 @@ +set(ANDROID_NDK CACHE PATH "Path to Android NDK.") +set(ANDROID_NATIVE_API_LEVEL CACHE STRING "Android API level to compile for. Acceptable values are: [0-9]+ or android-[0-9]+") +set(ANDROID_PLATFORM CACHE STRING "Alternative way to set Android API level. Acceptable values are: latest or android-[0-9]+") +set(ANDROID_TOOLCHAIN_FILE CACHE PATH "Android toolchain file.") +set(ANDROID_ABI CACHE STRING "Target CPU of android device, like e.g. \"armeabi-v7a\".") +set_property(CACHE ANDROID_ABI PROPERTY STRINGS + "armeabi-v7a" + "armeabi-v7a with NEON" + "arm64-v8a" + "x86" + "x86_64" +) + +#Check if user wants to build for Android +if(NOT "${CMAKE_ANDROID_NDK}" STREQUAL "") + set(ANDROID_NDK "${CMAKE_ANDROID_NDK}") +endif() +if(NOT "${ANDROID_NDK}" STREQUAL "") + set(ANDROID ON) +elseif(NOT "${ANDROID_TOOLCHAIN_FILE}" STREQUAL "" AND EXISTS "${ANDROID_TOOLCHAIN_FILE}") + set(ANDROID ON) +elseif(NOT "${CMAKE_TOOLCHAIN_FILE}" STREQUAL "" AND EXISTS "${CMAKE_TOOLCHAIN_FILE}") + set(ANDROID ON) +endif() + +#Set CMAKE_TOOLCHAIN_FILE and CMAKE_INSTALL_PREFIX for Android builds +if(ANDROID) + #CMAKE_TOOLCHAIN_FILE was not set, but ANDROID_TOOLCHAIN_FILE was set + if("${CMAKE_TOOLCHAIN_FILE}" STREQUAL "" AND NOT "${ANDROID_TOOLCHAIN_FILE}" STREQUAL "") + set(CMAKE_TOOLCHAIN_FILE "${ANDROID_TOOLCHAIN_FILE}") + #Neither toolchain file was set, use toolchain in NDK + elseif("${CMAKE_TOOLCHAIN_FILE}" STREQUAL "" AND "${ANDROID_TOOLCHAIN_FILE}" STREQUAL "") + set(CMAKE_TOOLCHAIN_FILE "${ANDROID_NDK}/build/cmake/android.toolchain.cmake") + else() + set(ANDROID_TOOLCHAIN_FILE "${CMAKE_TOOLCHAIN_FILE}") + endif() + if(NOT EXISTS "${CMAKE_TOOLCHAIN_FILE}") + message(FATAL_ERROR + "Could not find file: ${CMAKE_TOOLCHAIN_FILE}. Your NDK might be outdated." + ) + endif() + if(NOT CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${ANDROID_NDK}" CACHE PATH "Default install directory for android builds." FORCE) + endif() +endif(ANDROID) diff --git a/cmake/Modules/FetchENCRYPTO_utils.cmake b/cmake/Modules/FetchENCRYPTO_utils.cmake new file mode 100644 index 0000000..d18a029 --- /dev/null +++ b/cmake/Modules/FetchENCRYPTO_utils.cmake @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.13) + +include(FetchHelper) +fetch_helper(ENCRYPTO_utils) diff --git a/cmake/Modules/FetchHelper.cmake b/cmake/Modules/FetchHelper.cmake new file mode 100644 index 0000000..378952b --- /dev/null +++ b/cmake/Modules/FetchHelper.cmake @@ -0,0 +1,42 @@ +cmake_minimum_required(VERSION 3.13) +macro(fetch_helper content_name) + string(TOLOWER "${content_name}" LOWER_CASE_${content_name}) + if(NOT "${DEPENDENCY_DIR}" STREQUAL "") + set(${content_name}_DOWNLOAD_DIR_COMMAND DOWNLOAD_DIR ${DEPENDENCY_DIR}) + else() + set(${content_name}_DOWNLOAD_DIR_COMMAND "") + endif() + if(NOT "${${content_name}_SOURCE}" STREQUAL "") + set(${content_name}_DOWNLOAD_COMMAND1 URL ${${content_name}_SOURCE}) + set(${content_name}_DOWNLOAD_COMMAND2 "") + else() + set(${content_name}_DOWNLOAD_COMMAND1 GIT_REPOSITORY ${${content_name}_REPOSITORY}) + set(${content_name}_DOWNLOAD_COMMAND2 GIT_TAG ${${content_name}_TAG}) + endif() + include(FetchContent) + FetchContent_Declare(${content_name} + ${${content_name}_DOWNLOAD_COMMAND1} + ${${content_name}_DOWNLOAD_COMMAND2} + ${${content_name}_DOWNLOAD_DIR_COMMAND} + ) + FetchContent_GetProperties(${content_name}) + if(NOT ${LOWER_CASE_${content_name}}_POPULATED) + FetchContent_Populate(${content_name}) + if(NOT "${ARGV1}" STREQUAL "") + message(STATUS "Applying patches to ${content_name}...") + include("Patch${content_name}") + endif() + if(NOT "${ARGV2}" STREQUAL "") + add_subdirectory( + ${${LOWER_CASE_${content_name}}_SOURCE_DIR} + ${${LOWER_CASE_${content_name}}_BINARY_DIR} + EXCLUDE_FROM_ALL + ) + else() + add_subdirectory( + ${${LOWER_CASE_${content_name}}_SOURCE_DIR} + ${${LOWER_CASE_${content_name}}_BINARY_DIR} + ) + endif() + endif() +endmacro() diff --git a/cmake/Modules/FetchRelic.cmake b/cmake/Modules/FetchRelic.cmake new file mode 100644 index 0000000..518cd27 --- /dev/null +++ b/cmake/Modules/FetchRelic.cmake @@ -0,0 +1,47 @@ +cmake_minimum_required(VERSION 3.13) + +set(Relic_SOURCE + CACHE PATH + "Path to Relic source." +) +set(Relic_URL + https://github.com/relic-toolkit/relic/archive/a13dcefef1b81a51f2661910200aa76ab3599273.zip + CACHE STRING + "URL of Relic project." +) +set(Relic_URL_HASH + SHA256=fb327f7350c563433797b5c9ac4e8d08a6989afec5f8f58dbe5d44d621240d65 + CACHE STRING + "Hash of Relic archive." +) + +include(FetchHelper) +#EXCLUDE_FROM_ALL to prevent some rogue config files to be installed +fetch_helper(Relic patch EXCLUDE_FROM_ALL) + +set(Relic_INCLUDE_DIRS "${relic_SOURCE_DIR}/include" "${relic_SOURCE_DIR}/include/low" "${relic_BINARY_DIR}/include") +set(Relic_LIB_DIR "${CMAKE_BINARY_DIR}/lib") +if(Relic_LIBRARY_TYPE STREQUAL "STATIC") + if(LABEL) + set(Relic_TARGET "relic_s_${LABEL}") + else() + set(Relic_TARGET "relic_s") + endif() +elseif(${Relic_LIBRARY_TYPE} STREQUAL "SHARED") + if(LABEL) + set(Relic_TARGET "relic_${LABEL}") + else() + set(Relic_TARGET "relic") + endif() +endif() +set(Relic_LIB_NAME "${Relic_TARGET}") +#Allow relic target to be installed (but keep install deactivated for config files etc.) +set_target_properties(${Relic_TARGET} PROPERTIES EXCLUDE_FROM_ALL 0) +add_library(Relic::relic ${Relic_LIBRARY_TYPE} IMPORTED GLOBAL) +add_dependencies(Relic::relic ${Relic_TARGET}) +target_include_directories(Relic::relic INTERFACE "${Relic_INCLUDE_DIRS}") +set_target_properties(Relic::relic PROPERTIES IMPORTED_LOCATION "${Relic_LIB_DIR}/${CMAKE_${Relic_LIBRARY_TYPE}_LIBRARY_PREFIX}${Relic_TARGET}${CMAKE_${Relic_LIBRARY_TYPE}_LIBRARY_SUFFIX}") +if(ANDROID) + find_library(ANDROID_LOG_LIB log) + target_link_libraries(Relic::relic INTERFACE "${ANDROID_LOG_LIB}") +endif() diff --git a/cmake/Modules/InstallConfig.cmake b/cmake/Modules/InstallConfig.cmake new file mode 100644 index 0000000..414b619 --- /dev/null +++ b/cmake/Modules/InstallConfig.cmake @@ -0,0 +1,56 @@ +#install_config( ) +#Configures and installs a config file with the name ${DEPENDENCY_NAME}Config.cmake.in +#located in ${PROJECT_SOURCE_DIR}/cmake, requiring knowledge about the targets created by the +#config file for correct configuration. +#This function will set the variables #INSTALL_CONFIG_INCLUDE_PATHS to +#${${PROJECT_NAME}_INSTALL_INCLUDE and INSTALL_CONFIG_LIB_PATHS to ${${PROJECT_NAME}_INSTALL_LIB}, +#allowing the config files to be agnostic about the project name they are used in. +#Furthermore, install_config will generate an additional config file for android platforms, +#so that the correct library version is chosen and append additional code to the config file, +#so that required shared libraries are automatically exported together with the executable +#when using Android Studio. +function(install_config RESULT DEPENDENCY_NAME DEPENDENCY_TARGETS) + set(CONFIG_FILE_LOCATION "${PROJECT_SOURCE_DIR}/cmake/${DEPENDENCY_NAME}Config.cmake.in") + if(NOT EXISTS "${CONFIG_FILE_LOCATION}") + message(SEND_ERROR "The corresponding config file to dependency ${DEPENDENCY_NAME} " + "does not exist (absolute file name is assumed to be: " + "${PROJECT_SOURCE_DIR}/cmake/${DEPENDENCY_NAME}Config.cmake.in)") + endif() + set(CONFIG_FILE_COPY_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}Config.cmake.in") + if(NOT DEPENDENCY_TARGETS) + message(SEND_ERROR "DEPENDENCY_TARGETS evaluates to false. At least one valid target name " + "must be exported by the config file") + endif() + if(ANDROID AND ANDROID_ARM_NEON) + set(CONFIG_NAME "${DEPENDENCY_NAME}/${DEPENDENCY_NAME}-${ANDROID_PLATFORM}-${ANDROID_SYSROOT_ABI}-NEON") + set(INSTALL_CONFIG_INCLUDE_PATHS "\${CMAKE_CURRENT_LIST_DIR}/../../${${PROJECT_NAME}_INSTALL_INCLUDE}") + set(INSTALL_CONFIG_LIB_PATHS "\${CMAKE_CURRENT_LIST_DIR}/../../${${PROJECT_NAME}_INSTALL_LIB}") + elseif(ANDROID AND NOT ANDROID_ARM_NEON) + set(CONFIG_NAME "${DEPENDENCY_NAME}/${DEPENDENCY_NAME}-${ANDROID_PLATFORM}-${ANDROID_SYSROOT_ABI}") + set(INSTALL_CONFIG_INCLUDE_PATHS "\${CMAKE_CURRENT_LIST_DIR}/../../${${PROJECT_NAME}_INSTALL_INCLUDE}") + set(INSTALL_CONFIG_LIB_PATHS "\${CMAKE_CURRENT_LIST_DIR}/../../${${PROJECT_NAME}_INSTALL_LIB}") + else() + set(CONFIG_NAME "${DEPENDENCY_NAME}") + set(INSTALL_CONFIG_INCLUDE_PATHS "\${CMAKE_CURRENT_LIST_DIR}/../${${PROJECT_NAME}_INSTALL_INCLUDE}") + set(INSTALL_CONFIG_LIB_PATHS "\${CMAKE_CURRENT_LIST_DIR}/../${${PROJECT_NAME}_INSTALL_LIB}") + endif() + configure_file("${CONFIG_FILE_LOCATION}" "${CONFIG_FILE_COPY_LOCATION}" COPYONLY) + if(ANDROID) + file(READ "${PROJECT_SOURCE_DIR}/cmake/ImportIntoAndroidStudio.cmake.in" IMPORT_INTO_ANDROID_STUDIO) + file(APPEND "${CONFIG_FILE_COPY_LOCATION}" "${IMPORT_INTO_ANDROID_STUDIO}") + endif() + configure_file("${CONFIG_FILE_COPY_LOCATION}" + "${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}Config.cmake" + @ONLY) + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}Config.cmake" DESTINATION "${CONFIG_NAME}") + #We didn't give our config file the expected install name, so we give ForwardConfig.cmake.in that one + #ForwardConfig will then be configured to forward the find_package call to the appropriate config file + if(NOT "${CONFIG_NAME}" STREQUAL "${DEPENDENCY_NAME}") + configure_file("${PROJECT_SOURCE_DIR}/cmake/ForwardConfig.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/${DEPENDENCY_NAME}Config.cmake" + @ONLY) + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${DEPENDENCY_NAME}Config.cmake" DESTINATION "${DEPENDENCY_NAME}") + endif() + #Return relative install location of the "true" config file, i.e. the one that is not ForwardConfig + set(${RESULT} "${CONFIG_NAME}" PARENT_SCOPE) +endfunction(install_config) diff --git a/cmake/Modules/OTExtensionCacheVariables.cmake b/cmake/Modules/OTExtensionCacheVariables.cmake new file mode 100644 index 0000000..a205641 --- /dev/null +++ b/cmake/Modules/OTExtensionCacheVariables.cmake @@ -0,0 +1,108 @@ +set(OTExtension_LIBRARY_TYPE "${OTExtension_LIBRARY_TYPE}" CACHE STRING + [=["[STATIC | SHARED | MODULE] The type of library in which OTExtension will be built." + "Default: STATIC"]=] +) +set_property(CACHE OTExtension_LIBRARY_TYPE PROPERTY STRINGS STATIC SHARED MODULE) +string(TOUPPER "${OTExtension_LIBRARY_TYPE}" OTExtension_LIBRARY_TYPE) +if("${OTExtension_LIBRARY_TYPE}" STREQUAL "") + set(OTExtension_LIBRARY_TYPE "STATIC") +elseif(NOT "${OTExtension_LIBRARY_TYPE}" STREQUAL "STATIC" AND + NOT "${OTExtension_LIBRARY_TYPE}" STREQUAL "SHARED" AND + NOT "${OTExtension_LIBRARY_TYPE}" STREQUAL "MODULE") + message(WARNING + "Unknown library type: ${OTExtension_LIBRARY_TYPE}. " + "Setting OTExtension_LIBRARY_TYPE to default value." + ) + set(OTExtension_LIBRARY_TYPE "SHARED") +endif() + +option(OTExtension_BUILD_EXE "Build executables" OFF) + +set(DEPENDENCY_DIR "${DEPENDENCY_DIR}" CACHE PATH + "Path to directory, where dependencies will be downloaded." +) + +# Set build type to `Release` if none was specified: +# (cf. https://gitlab.kitware.com/cmake/community/wikis/FAQ#how-can-i-change-the-default-build-mode-and-see-it-reflected-in-the-gui) +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release + CACHE STRING "Choose the type of build." FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "None" "Debug" "Release" "RelWithDebInfo" "MinSizeRel") +endif(NOT CMAKE_BUILD_TYPE) + +include(AndroidCacheVariables) + +#Cache Variables related to ENCRYPTO_utils dependency +set(ENCRYPTO_utils_SOURCE + CACHE PATH "Path to ENCRYPTO_utils source.") +set(ENCRYPTO_utils_REPOSITORY https://github.com/oliver-schick/ENCRYPTO_utils.git + CACHE STRING "Git repository of ENCRYPTO_utils project.") +set(ENCRYPTO_utils_TAG origin/master + CACHE STRING "Git tag of downloaded ENCRYPTO_utils project.") + +#Cache Variables related to Relic dependency +set(Relic_SOURCE + CACHE PATH "Path to Relic source.") +set(Relic_LIBRARY_TYPE CACHE STRING "[SHARED | STATIC]: Type of Relic library linked to project.") +set_property(CACHE Relic_LIBRARY_TYPE PROPERTY STRINGS STATIC SHARED) +if(ANDROID) + if(NOT "${Relic_LIBRARY_TYPE}" STREQUAL "" AND NOT "${Relic_LIBRARY_TYPE}" STREQUAL "STATIC") + message(WARNING "${Relic_LIBRARY_TYPE} build for Relic is disabled on Android, " + "setting Relic_LIBRARY_TYPE to STATIC...") + endif() + set(Relic_LIBRARY_TYPE "STATIC") +else() + if("${Relic_LIBRARY_TYPE}" STREQUAL "") + set(Relic_LIBRARY_TYPE "${OTExtension_LIBRARY_TYPE}") + endif() +endif() +set(LABEL "aby" CACHE STRING "Label for relic (empty label not recommended, as this might cause name conflicts at link time)") +set(DEBUG off CACHE BOOL "Build relic with debugging support") +set(PROFL off CACHE BOOL "Build relic with profiling support") +set(CHECK off CACHE BOOL "Build relic with error-checking support") +set(ALIGN "16" CACHE STRING "Relic align") +set(ARITH "curve2251-sse" CACHE STRING "arithmetic utils used in relic") +set(FB_POLYN ${ecclvl} CACHE STRING "security level of the ecc binary curve in relic") +set(FB_METHD "INTEG;INTEG;QUICK;QUICK;QUICK;QUICK;QUICK;SLIDE;QUICK" CACHE STRING "Methods for fb in relic") +set(FB_PRECO on CACHE BOOL "fb preco for relic") +set(FB_SQRTF off CACHE BOOL "sqrtf for relic") +set(EB_METHD "PROJC;LODAH;COMBS;INTER" CACHE STRING "Methods for eb in relic") +set(EC_METHD "CHAR2" CACHE STRING "Methods for ec in relic") +set(TIMER "CYCLE" CACHE STRING "Relic timer") +set(TESTS "0" CACHE STRING "Relic amount of random tests, 0 for disable") +set(BENCH "0" CACHE STRING "Relic amount of benchmarks on random values, 0 for disable") +set(WITH "MD;DV;BN;FB;EB;EC" CACHE STRING "Relic algorithms") +set(COMP "-O3 -funroll-loops -fomit-frame-pointer -march=core2 -msse4.2 -mpclmul" CACHE STRING "Relic compiler options") +set(ARCH "X64" CACHE STRING "Architecture to be used in relic") +set(WSIZE "64" CACHE STRING "Relic word size in bits") +if("${Relic_LIBRARY_TYPE}" STREQUAL "STATIC") + set(SHLIB off CACHE BOOL "Relic shared library") + set(STLIB on CACHE BOOL "Relic static library") +elseif("${Relic_LIBRARY_TYPE}" STREQUAL "SHARED") + set(SHLIB on CACHE BOOL "Relic shared library") + set(STLIB off CACHE BOOL "Relic static library") +endif() +#Overwrite cache entries to be consistent with target android platform +if(ANDROID AND (ANDROID_ABI STREQUAL "armeabi-v7a" OR ANDROID_ABI STREQUAL "x86" OR ANDROID_ABI STREQUAL "mips")) + set(WSIZE "32") +else() + set(WSIZE "64") +endif() +if(ANDROID) + set(COMP "-O3 -funroll-loops -fomit-frame-pointer") + set(OPSYS "DROID") + if(ANDROID_ABI STREQUAL "armeabi-v7a") + set(ARITH "arm-asm-254") + set(ARCH "ARM") + elseif(ANDROID_ABI STREQUAL "arm64-v8a") + set(ARITH "arm-asm-254") + set(ARCH "") + elseif(ANDROID_ABI STREQUAL "x86") + set(ARITH "fiat") + set(ARCH "X86") + elseif(ANDROID_ABI STREQUAL "x86_64") + set(ARITH "fiat") + set(ARCH "X64") + endif() +endif() diff --git a/cmake/Modules/PatchRelic.cmake b/cmake/Modules/PatchRelic.cmake new file mode 100644 index 0000000..46f8078 --- /dev/null +++ b/cmake/Modules/PatchRelic.cmake @@ -0,0 +1,5 @@ +configure_file( + "${CMAKE_CURRENT_LIST_DIR}/RELICPatches/cmake/gmp.cmake" + "${relic_SOURCE_DIR}/cmake/gmp.cmake" + COPYONLY +) diff --git a/cmake/Modules/RelicPatches/cmake/gmp.cmake b/cmake/Modules/RelicPatches/cmake/gmp.cmake new file mode 100644 index 0000000..f001171 --- /dev/null +++ b/cmake/Modules/RelicPatches/cmake/gmp.cmake @@ -0,0 +1,60 @@ +# Copyright (c) 2006, Laurent Montel, +# Copyright (c) 2007, Francesco Biscani, + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# ------------------------------------------------------------------------------------------ + +# Try to find the GMP libraries: +# GMP_FOUND - System has GMP lib +# GMP_INCLUDE_DIR - The GMP include directory +# GMP_LIBRARIES - Libraries needed to use GMP +if(TARGET GMP::GMP) + get_target_property(GMP_INCLUDE_DIR GMP::GMP INTERFACE_INCLUDE_DIRECTORIES) + set(GMP_LIBRARIES GMP::GMP) + set(GMP_FOUND TRUE) +else() + if (GMP_INCLUDE_DIR AND GMP_LIBRARIES) + # Force search at every time, in case configuration changes + unset(GMP_INCLUDE_DIR CACHE) + unset(GMP_LIBRARIES CACHE) + endif (GMP_INCLUDE_DIR AND GMP_LIBRARIES) + + find_path(GMP_INCLUDE_DIR NAMES gmp.h) + if(STBIN) + find_library(GMP_LIBRARIES NAMES libgmp.a gmp) + else(STBIN) + find_library(GMP_LIBRARIES NAMES libgmp.so gmp) + endif(STBIN) + + if(GMP_INCLUDE_DIR AND GMP_LIBRARIES) + set(GMP_FOUND TRUE) + endif(GMP_INCLUDE_DIR AND GMP_LIBRARIES) + + if(GMP_FOUND) + message(STATUS "Configured GMP: ${GMP_LIBRARIES}") + else(GMP_FOUND) + message(STATUS "Could NOT find GMP") + endif(GMP_FOUND) +endif() +mark_as_advanced(GMP_INCLUDE_DIR GMP_LIBRARIES) diff --git a/cmake/OTExtensionConfig.cmake.in b/cmake/OTExtensionConfig.cmake.in index a85e618..c38c877 100644 --- a/cmake/OTExtensionConfig.cmake.in +++ b/cmake/OTExtensionConfig.cmake.in @@ -1,7 +1,5 @@ get_filename_component(OTExtension_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) -list(APPEND CMAKE_MODULE_PATH "${OTExtension_CMAKE_DIR}") - include(CMakeFindDependencyMacro) find_dependency(ENCRYPTO_utils) @@ -9,3 +7,7 @@ find_dependency(ENCRYPTO_utils) if(NOT TARGET OTExtension::otextension) include("${OTExtension_CMAKE_DIR}/OTExtensionTargets.cmake") endif() + +if(TARGET OTExtension::otextension) + set(OTExtension_FOUND TRUE) +endif() diff --git a/cmake/RelicConfig.cmake.in b/cmake/RelicConfig.cmake.in new file mode 100644 index 0000000..3fb1ade --- /dev/null +++ b/cmake/RelicConfig.cmake.in @@ -0,0 +1,34 @@ +set(Relic_NAME @Relic_LIB_NAME@) +if(NOT "${Relic_LIBRARY_TYPE}" STREQUAL "STATIC" AND NOT "${Relic_LIBRARY_TYPE}" STREQUAL "SHARED") + set(Relic_LIBRARY_TYPE "@Relic_LIBRARY_TYPE@") +endif() +set(LIB_PREFIX "${CMAKE_${Relic_LIBRARY_TYPE}_LIBRARY_PREFIX}") +set(LIB_SUFFIX "${CMAKE_${Relic_LIBRARY_TYPE}_LIBRARY_SUFFIX}") + +set(Relic_INCLUDE_PATHS "@INSTALL_CONFIG_INCLUDE_PATHS@") +set(Relic_LIB_PATHS "@INSTALL_CONFIG_LIB_PATHS@") + +unset(Relic_INCLUDE_DIR CACHE) +unset(Relic_LIBRARY CACHE) + +find_path(Relic_INCLUDE_DIR relic.h PATHS ${Relic_INCLUDE_PATHS}) +find_library(Relic_LIBRARY NAMES ${LIB_PREFIX}${Relic_NAME}${LIB_SUFFIX} PATHS ${Relic_LIB_PATHS}) + +if(EXISTS "${Relic_INCLUDE_DIR}" AND EXISTS "${Relic_LIBRARY}") + set(Relic_FOUND TRUE) +else() + set(Relic_LIBRARY ) + set(Relic_FOUND FALSE) +endif() + +if(Relic_FOUND AND NOT TARGET Relic::relic) + add_library(Relic::relic "${Relic_LIBRARY_TYPE}" IMPORTED) + set_target_properties(Relic::relic PROPERTIES + IMPORTED_LOCATION "${Relic_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${Relic_INCLUDE_DIR}") +endif() + +mark_as_advanced( + Relic_INCLUDE_DIR + Relic_LIBRARY +)