diff --git a/.gitignore b/.gitignore index ce50e626..e1ab2df3 100644 --- a/.gitignore +++ b/.gitignore @@ -11,10 +11,12 @@ README.html docs/* *.dump - +*.bak # build directory build*/ +# extern directory +extern/* # CMake CMakeCache.txt diff --git a/.gitmodules b/.gitmodules index 23e01dde..56696216 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "extern/ENCRYPTO_utils"] - path = extern/ENCRYPTO_utils - url = https://github.com/encryptogroup/ENCRYPTO_utils.git -[submodule "extern/OTExtension"] - path = extern/OTExtension - url = https://github.com/encryptogroup/OTExtension.git +[submodule "extern/boost-cmake"] + path = extern/boost-cmake + url = https://github.com/Orphis/boost-cmake.git diff --git a/CMakeLists.txt b/CMakeLists.txt index e42117b6..4d89700a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,22 +1,8 @@ -cmake_minimum_required(VERSION 3.12) -project(ABY LANGUAGES CXX) - -if (CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0) - message(FATAL_ERROR "ABY requires at least g++-8") -endif() - -option(ABY_BUILD_EXE "Build executables" OFF) - -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") - -# Set build type to `Release` if non 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, options are: None Debug Release RelWithDebInfo MinSizeRel." - FORCE) -endif(NOT CMAKE_BUILD_TYPE) - +cmake_minimum_required(VERSION 3.13) +list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_LIST_DIR}/cmake/Modules") +include(ABYCacheVariables) +set(CMAKE_CXX_STANDARD 14) +project(ABY LANGUAGES C CXX) # Write built executables and libraries to bin/ and lib/, respectively. if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin") @@ -27,43 +13,14 @@ endif() if(NOT CMAKE_ARCHIVE_OUTPUT_DIRECTORY) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib") endif() - -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) -endif() - -find_package(OTExtension QUIET) -if(OTExtension_FOUND) - message(STATUS "Found OTExtension") -elseif (NOT OTExtension_FOUND AND NOT TARGET OTExtension::otextension) - message("OTExtension was not found: add OTExtension subdirectory") - if(NOT EXISTS "${PROJECT_SOURCE_DIR}/extern/OTExtension/CMakeLists.txt") - find_package(Git REQUIRED) - message("initialize Git submodule: extern/OTExtension") - execute_process(COMMAND git submodule update --init extern/OTExtension - WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}") - endif() - add_subdirectory(extern/OTExtension) +if(ANDROID) + add_definitions(-DANDROID) endif() -find_package(GMP REQUIRED) -find_package(Threads REQUIRED) -find_package(Boost 1.66.0 REQUIRED COMPONENTS thread system) - add_subdirectory(src/abycore) - if(ABY_BUILD_EXE) add_subdirectory(src/test) add_subdirectory(src/examples) endif(ABY_BUILD_EXE) + diff --git a/README.md b/README.md index 6387e54a..fb9e6a40 100644 --- a/README.md +++ b/README.md @@ -20,13 +20,13 @@ By *Daniel Demmler, Thomas Schneider and Michael Zohner* ([ENCRYPTO](http://www. - [Build Options](#build-options) - [Cleaning the Build Directory](#cleaning-the-build-directory) - [Installation](#installation) - - [Developer Guide and Documentation](#developer-guide-and-documentation) + - [Building for Android](#building-for-android) + - [Developer Guide and Documentation](#developer-guide-and-documentation) - [ABY Applications](#aby-applications) - [Included Example Applications](#included-example-applications) - [Running Applications](#running-applications) - [Creating and Building your own ABY Application](#creating-and-building-your-own-aby-application) - ### Features --- ABY efficiently combines secure computation schemes based on **Arithmetic sharing**, **Boolean sharing**, and **Yao’s garbled circuits** and makes available best-practice solutions in secure two-party computation. @@ -182,12 +182,36 @@ make make install ``` - #### Developer Guide and Documentation We provide an extensive [developer guide](https://www.informatik.tu-darmstadt.de/media/encrypto/encrypto_code/abydevguide.pdf) with many examples and explanations of how to use ABY. Also, see the [online doxygen documentation of ABY](http://encryptogroup.github.io/ABY/docs/index.html) for further information and comments on the code. +## Building for Android + +1. Clone the ABY git repository by running: + ``` + git clone https://github.com/encryptogroup/ABY.git + ``` + +2. Enter the Framework directory: `cd ABY/` + +3. Create and enter the build directory: `mkdir build && cd build` + +4. Use CMake to configure the build and setting android variables: + ``` + cmake -DANDROID_NDK= -DANDROID_NATIVE_API_LEVEL= -DANDROID_ABI= .. + ``` + where `` is a number between 16 and the latest Android API and `` is the target platform (one of armeabi-v7a, arm64-v8a, x86 and x86_64 respectively). + + Please note that when using ABY with Android Studio that `` needs to be the path to the NDK used by Android Studio (often located at $HOME/Android/Sdk/ndk-bundle on Linux). + + +5. Call `make` in the build directory. + You can find the build executables and libraries in the directories `bin/` + and `lib/`, respectively. + +6. Call `make install` after the build has finished. This will install the libraries into the provided NDK. ### ABY Applications --- @@ -234,6 +258,8 @@ Also, see the [online doxygen documentation of ABY](http://encryptogroup.github. add_executable(my_application my_application.cpp) target_link_libraries(my_application ABY::aby) ``` +* If you are using ABY for Android in Android Studio and you encounter the "library libc++_shared.so not found" error, make sure to pass '-DANDROID_STL=c++_shared' as an argument to cmake within the gradle script. Setting ANDROID_STL within the cmake script won't work. + * Otherwise, setup the include path such that the headers of ABY and its dependencies can be found and link your application to the `libaby.a` library and the other dependencies (see above). diff --git a/cmake/ABYConfig.cmake.in b/cmake/ABYConfig.cmake.in index d0008aa1..1548f8d6 100644 --- a/cmake/ABYConfig.cmake.in +++ b/cmake/ABYConfig.cmake.in @@ -1,15 +1,20 @@ get_filename_component(ABY_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) -list(APPEND CMAKE_MODULE_PATH "${ABY_CMAKE_DIR}") - include(CMakeFindDependencyMacro) +find_dependency(Boost) find_dependency(OTExtension) find_dependency(ENCRYPTO_utils) -find_dependency(MIRACL) find_dependency(GMP) find_dependency(Threads) if(NOT TARGET ABY::aby) include("${ABY_CMAKE_DIR}/ABYTargets.cmake") endif() + +if(TARGET ABY::aby) + set(ABY_FOUND TRUE) + set(TARGETS ABY::aby) +endif() + + diff --git a/cmake/BoostConfig.cmake.in b/cmake/BoostConfig.cmake.in new file mode 100644 index 00000000..832ad041 --- /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/FindGMP.cmake b/cmake/FindGMP.cmake deleted file mode 100644 index b4d9e3ac..00000000 --- a/cmake/FindGMP.cmake +++ /dev/null @@ -1,27 +0,0 @@ - -find_path(GMP_INCLUDE_DIR gmp.h) - -# TODO: get version - -find_library(GMP_LIBRARY NAMES gmp) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(GMP - FOUND_VAR GMP_FOUND - REQUIRED_VARS - GMP_LIBRARY - GMP_INCLUDE_DIR -) - -if(GMP_FOUND AND NOT TARGET GMP::GMP) - add_library(GMP::GMP UNKNOWN IMPORTED) - set_target_properties(GMP::GMP PROPERTIES - IMPORTED_LOCATION "${GMP_LIBRARY}" - INTERFACE_INCLUDE_DIRECTORIES "${GMP_INCLUDE_DIR}" - ) -endif() - -mark_as_advanced( - GMP_INCLUDE_DIR - GMP_LIBRARY -) diff --git a/cmake/FindGMPXX.cmake b/cmake/FindGMPXX.cmake deleted file mode 100644 index 81608ccf..00000000 --- a/cmake/FindGMPXX.cmake +++ /dev/null @@ -1,27 +0,0 @@ - -find_path(GMPXX_INCLUDE_DIR gmpxx.h) - -# TODO: get version - -find_library(GMPXX_LIBRARY NAMES gmpxx) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(GMPXX - FOUND_VAR GMPXX_FOUND - REQUIRED_VARS - GMPXX_LIBRARY - GMPXX_INCLUDE_DIR -) - -if(GMPXX_FOUND AND NOT TARGET GMP::GMPXX) - add_library(GMP::GMPXX UNKNOWN IMPORTED) - set_target_properties(GMP::GMPXX PROPERTIES - IMPORTED_LOCATION "${GMPXX_LIBRARY}" - INTERFACE_INCLUDE_DIRECTORIES "${GMPXX_INCLUDE_DIR}" - ) -endif() - -mark_as_advanced( - GMPXX_INCLUDE_DIR - GMPXX_LIBRARY -) diff --git a/cmake/ForwardConfig.cmake.in b/cmake/ForwardConfig.cmake.in new file mode 100644 index 00000000..5d1c4923 --- /dev/null +++ b/cmake/ForwardConfig.cmake.in @@ -0,0 +1,14 @@ +include(CMakeFindDependencyMacro) +set(INSTALL_NAME "@INSTALL_NAME@") +if(ANDROID AND ANDROID_ARM_NEON) + set(PREFIX "${INSTALL_NAME}-${ANDROID_PLATFORM}-${ANDROID_SYSROOT_ABI}-NEON") +elseif(ANDROID AND NOT ANDROID_ARM_NEON) + set(PREFIX "${INSTALL_NAME}-${ANDROID_PLATFORM}-${ANDROID_SYSROOT_ABI}") +else() + set(PREFIX "${INSTALL_NAME}") +endif() +if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/${PREFIX}/${PREFIX}Config.cmake") + include("${CMAKE_CURRENT_LIST_DIR}/${PREFIX}/${PREFIX}Config.cmake") +else() + set(${INSTALL_NAME}_FOUND FALSE) +endif() diff --git a/cmake/GMPConfig.cmake.in b/cmake/GMPConfig.cmake.in new file mode 100644 index 00000000..3c4b9b07 --- /dev/null +++ b/cmake/GMPConfig.cmake.in @@ -0,0 +1,35 @@ +if(NOT "${GMP_LIBRARY_TYPE}" STREQUAL "STATIC" AND NOT "${GMP_LIBRARY_TYPE}" STREQUAL "SHARED") + set(GMP_LIBRARY_TYPE "@GMP_LIBRARY_TYPE@") +endif() +set(LIB_PREFIX "${CMAKE_${GMP_LIBRARY_TYPE}_LIBRARY_PREFIX}") +set(LIB_SUFFIX "${CMAKE_${GMP_LIBRARY_TYPE}_LIBRARY_SUFFIX}") + +set(GMP_INCLUDE_PATHS "@INSTALL_CONFIG_INCLUDE_PATHS@") +set(GMP_LIB_PATHS "@INSTALL_CONFIG_LIB_PATHS@") + +unset(GMP_INCLUDE_DIR CACHE) +unset(GMP_LIBRARY CACHE) + +find_path(GMP_INCLUDE_DIR gmp.h PATHS ${GMP_INCLUDE_PATHS}) +find_library(GMP_LIBRARY NAMES ${LIB_PREFIX}gmp${LIB_SUFFIX} PATHS ${GMP_LIB_PATHS}) + +if(EXISTS "${GMP_INCLUDE_DIR}" AND EXISTS "${GMP_LIBRARY}") + set(GMP_FOUND TRUE) +else() + set(GMP_LIBRARY ) + set(GMP_FOUND FALSE) +endif() + +if(GMP_FOUND AND NOT TARGET GMP::GMP) + add_library(GMP::GMP "${GMP_LIBRARY_TYPE}" IMPORTED) + set_target_properties(GMP::GMP PROPERTIES + IMPORTED_LOCATION "${GMP_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${GMP_INCLUDE_DIR}") +endif() + +mark_as_advanced( + GMP_INCLUDE_DIR + GMP_LIBRARY +) + +set(TARGETS GMP::GMP) diff --git a/cmake/GMPXXConfig.cmake.in b/cmake/GMPXXConfig.cmake.in new file mode 100644 index 00000000..3ed66700 --- /dev/null +++ b/cmake/GMPXXConfig.cmake.in @@ -0,0 +1,35 @@ +if(NOT "${GMP_LIBRARY_TYPE}" STREQUAL "STATIC" AND NOT "${GMP_LIBRARY_TYPE}" STREQUAL "SHARED") + set(GMP_LIBRARY_TYPE "@GMP_LIBRARY_TYPE@") +endif() +set(LIB_PREFIX "${CMAKE_${GMP_LIBRARY_TYPE}_LIBRARY_PREFIX}") +set(LIB_SUFFIX "${CMAKE_${GMP_LIBRARY_TYPE}_LIBRARY_SUFFIX}") + +set(GMPXX_INCLUDE_PATHS "@INSTALL_CONFIG_INCLUDE_PATHS@") +set(GMPXX_LIB_PATHS "@INSTALL_CONFIG_LIB_PATHS@") + +unset(GMPXX_INCLUDE_DIR CACHE) +unset(GMPXX_LIBRARY CACHE) + +find_path(GMPXX_INCLUDE_DIR gmpxx.h PATHS ${GMPXX_INCLUDE_PATHS}) +find_library(GMPXX_LIBRARY NAMES ${LIB_PREFIX}gmpxx${LIB_SUFFIX} PATHS ${GMPXX_LIB_PATHS}) + +if(EXISTS "${GMPXX_INCLUDE_DIR}" AND EXISTS "${GMPXX_LIBRARY}") + set(GMPXX_FOUND TRUE) +else() + set(GMPXX_LIBRARY ) + set(GMPXX_FOUND FALSE) +endif() + +if(GMPXX_FOUND AND NOT TARGET GMP::GMPXX) + add_library(GMP::GMPXX "${GMP_LIBRARY_TYPE}" IMPORTED) + set_target_properties(GMP::GMPXX PROPERTIES + IMPORTED_LOCATION "${GMPXX_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${GMPXX_INCLUDE_DIR}") +endif() + +mark_as_advanced( + GMPXX_INCLUDE_DIR + GMPXX_LIBRARY +) + +set(TARGETS GMP::GMPXX) diff --git a/cmake/ImportIntoAndroidStudio.cmake b/cmake/ImportIntoAndroidStudio.cmake new file mode 100644 index 00000000..73c6fe6d --- /dev/null +++ b/cmake/ImportIntoAndroidStudio.cmake @@ -0,0 +1,18 @@ + +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/ABYCacheVariables.cmake b/cmake/Modules/ABYCacheVariables.cmake new file mode 100644 index 00000000..85ae27af --- /dev/null +++ b/cmake/Modules/ABYCacheVariables.cmake @@ -0,0 +1,38 @@ +option(ABY_BUILD_EXE "Build executables" OFF) +set(ABY_LIBRARY_TYPE "${ABY_LIBRARY_TYPE}" CACHE STRING + "[STATIC | SHARED | MODULE] The type of library in which ABY will be built. Default: STATIC" +) +set_property(CACHE ABY_LIBRARY_TYPE PROPERTY STRINGS "STATIC" "SHARED" "MODULE") +string(TOUPPER "${ABY_LIBRARY_TYPE}" ABY_LIBRARY_TYPE) +if("${ABY_LIBRARY_TYPE}" STREQUAL "") + set(ABY_LIBRARY_TYPE "SHARED") +elseif(NOT "${ABY_LIBRARY_TYPE}" STREQUAL "STATIC" AND + NOT "${ABY_LIBRARY_TYPE}" STREQUAL "SHARED" AND + NOT "${ABY_LIBRARY_TYPE}" STREQUAL "MODULE") + message(WARNING + "Unknown library type: ${ABY_LIBRARY_TYPE}. " + "Setting ABY_LIBRARY_TYPE to default value." + ) + set(ABY_LIBRARY_TYPE "SHARED") +endif() + +set(DEPENDENCY_DIR "${DEPENDENCY_DIR}" CACHE PATH "Path to directory, where dependencies will be downloaded.") +if(DEPENDENCY_DIR STREQUAL "") + if(NOT EXISTS "${CMAKE_SOURCE_DIR}/extern/dependencies") + file(MAKE_DIRECTORY "${CMAKE_SOURCE_DIR}/extern/dependencies") + endif() + set(DEPENDENCY_DIR "${CMAKE_SOURCE_DIR}/extern/dependencies") +endif() + +# 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) diff --git a/cmake/Modules/AddBOOST_CMAKE.cmake b/cmake/Modules/AddBOOST_CMAKE.cmake new file mode 100644 index 00000000..406b08a0 --- /dev/null +++ b/cmake/Modules/AddBOOST_CMAKE.cmake @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.13) + +set(BOOST_CMAKE_SOURCE "${BOOST_CMAKE_SOURCE}" CACHE PATH "Path to boost-cmake source.") +set(BOOST_CMAKE_URL https://github.com/Orphis/boost-cmake/archive/f0f64adda5ac1312549056dab502da55b9c45b7b.zip CACHE STRING "URL to boost-cmake project.") +set(BOOST_CMAKE_URL_HASH SHA256=0be1ccdebe0a4f77dae683273984770937dd5ef4ee1f5a7552bf862e478f81dd CACHE STRING "Hash of boost-cmake archive.") + +set(BOOST_INSTALL_INCLUDE "${${PROJECT_NAME}_INSTALL_INCLUDE}") +set(USE_ANDROID ANDROID) +file(GLOB BOOST_CMAKE_FILE_LIST "${PROJECT_SOURCE_DIR}/extern/boost-cmake/*") +list(LENGTH BOOST_CMAKE_FILE_LIST BOOST_CMAKE_NUM_FILES) +#if boost-cmake directory is empty +if(BOOST_CMAKE_NUM_FILES EQUAL 0) + include(FetchBOOST_CMAKE) +else() + set(BOOST_CMAKE_SOURCE "${PROJECT_SOURCE_DIR}/extern/BOOST_CMAKE" CACHE PATH "Path to boost-cmake source." FORCE) + include(FetchBOOST_CMAKE) +endif() diff --git a/cmake/Modules/AddBoost.cmake b/cmake/Modules/AddBoost.cmake new file mode 100644 index 00000000..4efb79ef --- /dev/null +++ b/cmake/Modules/AddBoost.cmake @@ -0,0 +1,90 @@ +cmake_minimum_required(VERSION 3.13) + +option(DOWNLOAD_BOOST "Set to download boost libraries. " OFF) +set(BOOST_SOURCE CACHE PATH "Path to boost source location.") +set(BOOST_URL https://dl.bintray.com/boostorg/release/1.69.0/source/boost_1_69_0.tar.bz2 CACHE STRING "Boost download URL.") +set(BOOST_URL_HASH SHA256=8f32d4617390d1c2d16f26a27ab60d97807b35440d45891fa340fc2648b04406 CACHE STRING "Boost download URL SHA256 checksum.") + +#Check if all required boost targets already exist. +set(ALL_REQUIRED_BOOST_TARGETS_EXIST TRUE) +set(BOOST_REQUIRED_COMPONENTS) +foreach(boost_target ${BOOST_TARGETS_REQUIRED}) + if(NOT boost_target MATCHES "^Boost::.*") + message(AUTHOR_WARNING "Given required target: ${boost_target} does not begin with Boost:: and will thus be ignored.") + break() + endif() + string(REGEX REPLACE "^Boost::(.*)" "\\1" COMPONENT_NAME ${boost_target}) + #Do not add boost as a required component + if(NOT COMPONENT_NAME STREQUAL "boost") + list(APPEND BOOST_REQUIRED_COMPONENTS ${COMPONENT_NAME}) + endif() + if(NOT TARGET ${boost_target}) + set(ALL_REQUIRED_BOOST_TARGETS_EXIST FALSE) + endif() +endforeach() + +if(NOT TARGET Boost::boost) + set(EXPORTED_BOOST_boost FALSE CACHE INTERNAL "Check if target Boost::boost is already in export set.") +endif() + +if(NOT ALL_REQUIRED_BOOST_TARGETS_EXIST) + if(DOWNLOAD_BOOST) + message(STATUS "Fetching Boost sources. This might take several minutes. " + "No progress is shown, please wait...") + endif() + if(DOWNLOAD_BOOST OR EXISTS "${BOOST_SOURCE}") + include(AddBOOST_CMAKE) + #Since we import from boost-cmake, we need to export the boost libraries with our project. + set(EXPORT_BOOST_TARGETS TRUE CACHE INTERNAL "Variable to decide whether we export boost dependencies along with project.") + elseif(ANDROID) + message(SEND_ERROR "Please provide a valid directory for BOOST_SOURCE (recommended) or automatically download boost libraries by setting DOWNLOAD_BOOST.") + return() + else() + find_package(Boost 1.67 REQUIRED COMPONENTS ${BOOST_REQUIRED_COMPONENTS}) + #We found our libraries through find_package, so we don't export boost alongside our project. + set(EXPORT_BOOST_TARGETS FALSE CACHE INTERNAL "Variable to decide whether we export boost dependencies along with project.") + endif() +endif() + +#Export boost targets, if option is set to export them. +if(EXPORT_BOOST_TARGETS) + include(GetDependencies) + set(BOOST_DEPENDENCIES_TO_EXPORT) + get_dependencies(BOOST_DEPENDENCIES_TO_EXPORT ${BOOST_TARGETS_REQUIRED}) + #Only export dependencies that start with Boost. + list(FILTER BOOST_DEPENDENCIES_TO_EXPORT INCLUDE REGEX "^[bB]oost.*") + #Do not include Boost::boost dependency. It is exported seperately from project + list(REMOVE_ITEM BOOST_DEPENDENCIES_TO_EXPORT Boost::boost) + #Allow boost dependencies to be automatically installed when installing all. + foreach(dependency ${BOOST_DEPENDENCIES_TO_EXPORT}) + #check if target is not interface library, to prevent error. + get_target_property(target_type ${dependency} TYPE) + if(target_type AND NOT "${target_type}" STREQUAL "INTERFACE_LIBRARY") + set_target_properties(${dependency} PROPERTIES EXCLUDE_FROM_ALL 0) + endif() + endforeach() + #Tell current project that these dependencies need to be exported + set(${PROJECT_NAME}_DEPENDENCIES_TO_EXPORT ${BOOST_DEPENDENCIES_TO_EXPORT}) + get_target_property(BOOST_INCLUDE_DIRS Boost::boost INTERFACE_INCLUDE_DIRECTORIES) + #Add a trailing slash behind every directory, to prevent structures like include/include etc. + #Only add a trailing slash to directories not already ending with a slash + list(TRANSFORM BOOST_INCLUDE_DIRS APPEND "/boost/" REGEX ".*[^/]$") + if(NOT EXPORTED_BOOST_boost) + include(InstallConfig) + install_config(Boost_INSTALL_LOCATION "Boost") + #Install boost headers + install(DIRECTORY "${BOOST_INCLUDE_DIRS}" + DESTINATION "${${PROJECT_NAME}_INSTALL_INCLUDE}/boost/" + FILES_MATCHING REGEX ".*\\.h(pp|h)?$") + install(TARGETS Boost::boost + EXPORT "BoostTargets" + ARCHIVE DESTINATION "${${PROJECT_NAME}_INSTALL_ARCHIVE}" + LIBRARY DESTINATION "${${PROJECT_NAME}_INSTALL_LIB}" + INCLUDES DESTINATION "${${PROJECT_NAME}_INSTALL_INCLUDE}") + export(TARGETS Boost::boost + FILE "BoostTargets.cmake") + install(EXPORT "BoostTargets" + DESTINATION "${Boost_INSTALL_LOCATION}") + set(EXPORTED_BOOST_boost TRUE CACHE INTERNAL "Check if target Boost::boost is already in export set.") + endif() +endif() diff --git a/cmake/Modules/AddENCRYPTO_utils.cmake b/cmake/Modules/AddENCRYPTO_utils.cmake new file mode 100644 index 00000000..7887f6ce --- /dev/null +++ b/cmake/Modules/AddENCRYPTO_utils.cmake @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.13) + +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.") +#Specific commit hash. Please regularly update to maintain compatibility with ABY. +set(ENCRYPTO_utils_URL https://github.com/oliver-schick/ENCRYPTO_utils/archive/a1e60a51e23b2b81a7cecf6bfacb24952275a0a7.zip CACHE STRING "URL of ENCRYPTO_utils project.") +#sha256sum of downloaded file. To get it on linux simply type following command line: +#$ wget -O out [URL] && sha256sum out +set(ENCRYPTO_utils_URL_HASH SHA256=b43e0a2626d351bf190931bddf9974860cf298727d23d20c75ef6f83302fb18b CACHE STRING "Hash of ENCRYPTO_utils archive.") +option(DOWNLOAD_ENCRYPTO_utils "Set this option to download a specific commit of ENCRYPTO_utils." OFF) +mark_as_advanced(ENCRYPTO_utils_REPOSITORY ENCRYPTO_utils_TAG ENCRYPTO_utils_URL ENCRYPTO_utils_URL_HASH DOWNLOAD_ENCRYPTO_utils) + +if(NOT TARGET ENCRYPTO_utils::encrypto_utils) + if(NOT ENCRYPTO_utils_LIBRARY_TYPE) + set(ENCRYPTO_utils_LIBRARY_TYPE ${ABY_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/AddGMP.cmake b/cmake/Modules/AddGMP.cmake new file mode 100644 index 00000000..e646c2f5 --- /dev/null +++ b/cmake/Modules/AddGMP.cmake @@ -0,0 +1,79 @@ +cmake_minimum_required(VERSION 3.13) + +option(BUILD_GMP "Build GMP library if none is found." OFF) +option(FORCE_GMP_BUILD "Force building of GMP library (use if installed GMP library is incompatible with build)." OFF) +set(GMP_LIBRARY_DIR "" CACHE PATH "Path to GMP library.") +set(GMP_INCLUDES "" CACHE PATH "Path to GMP include directories.") +set(GMP_SOURCE CACHE PATH "Path to GMP source (If building GMP).") +set(GMP_URL https://gmplib.org/download/gmp/gmp-6.1.2.tar.lz CACHE STRING "URL of GMP source.") +set(GMP_URL_HASH SHA256=12fed0532d440d2dc902e64f016aa89a33af6044b90bd1f7bca7396635105dbb CACHE STRING "Hash of GMP source archive.") +set(GMP_LIBRARY_TYPE "${GMP_LIBRARY_TYPE}" CACHE STRING "[SHARED | STATIC]: Type of GMP library linked to project.") +set_property(CACHE GMP_LIBRARY_TYPE PROPERTY STRINGS STATIC SHARED) + +mark_as_advanced(FORCE_GMP_BUILD) + +#If cache variable is not set, use same library type as project. +if(NOT ANDROID AND "${GMP_LIBRARY_TYPE}" STREQUAL "") + set(GMP_LIBRARY_TYPE "${${PROJECT_NAME}_LIBRARY_TYPE}") +#Emit an info message if library was set to another type than shared for android builds. +elseif(ANDROID AND NOT "${GMP_LIBRARY_TYPE}" STREQUAL "" AND NOT "${GMP_LIBRARY_TYPE}" STREQUAL "SHARED") + set(GMP_LIBRARY_TYPE "SHARED") + message(STATUS "Only shared GMP builds supported for Android.") +#Set GMP to shared without emiting a status message, if cache variable is not set. +elseif(ANDROID) + set(GMP_LIBRARY_TYPE "SHARED") +endif() + +#Try to find GMP and GMPXX, unless user requests that GMP must be built. +if(NOT FORCE_GMP_BUILD) + find_package(GMP QUIET) + find_package(GMPXX QUIET) + if(TARGET GMP::GMP) + set(GMP_FOUND TRUE) + endif() + if(TARGET GMP::GMPXX) + set(GMPXX_FOUND TRUE) + endif() + if(GMP_FOUND AND GMPXX_FOUND) + message(STATUS "Found GMP and GMPXX.") + endif() +endif() + + +if(NOT GMP_FOUND OR NOT GMPXX_FOUND) + set(PFX ${CMAKE_${GMP_LIBRARY_TYPE}_LIBRARY_PREFIX}) + set(SFX ${CMAKE_${GMP_LIBRARY_TYPE}_LIBRARY_SUFFIX}) + set(GMP_LIBRARY_NAME ${PFX}gmp${SFX}) + set(GMPXX_LIBRARY_NAME$ ${PFX}gmpxx${SFX}) + include(ExternalBuildHelper) + #gmp library can be found at user provided locations. + if(EXISTS "${GMP_LIBRARY_DIR}/${GMP_LIBRARY_NAME}" + AND EXISTS "${GMP_LIBRARY_DIR}/${GMPXX_LIBRARY_NAME}" + AND EXISTS "${GMP_INCLUDES}/gmp.h" + AND EXISTS "${GMP_INCLUDES}/gmpxx.h") + message(STATUS "Found GMP and GMPXX at given location.") + add_imported_library(TARGET GMP::GMP ${GMP_LIBRARY_TYPE} + EXTERNAL_LIB_DIR "${GMP_LIBRARY_DIR}" + EXTERNAL_LIB_NAME gmp + EXTERNAL_INCLUDES "${GMP_INCLUDES}") + add_imported_library(TARGET GMP::GMPXX ${GMP_LIBRARY_TYPE} + EXTERNAL_LIB_DIR "${GMP_LIBRARY_DIR}" + EXTERNAL_LIB_NAME gmpxx + EXTERNAL_INCLUDES "${GMP_INCLUDES}") + #If gmp library cannot be found, but is allowed to be build. + elseif(BUILD_GMP OR FORCE_GMP_BUILD) + message(STATUS "Adding GMP and GMPXX library to build.") + set(GMP_ONLY OFF) + include(BuildGMP) + #Emit an error message if gmp library or gmp include directories cannot be found in cached variables + #and either option BUILD_GMP or FORCE_GMP_BUILD is not set. + else() + message(SEND_ERROR "Did not find gmp in standard location." + " Either set GMP_LIBRARY_DIR and GMP_INCLUDES to valid locations" + " or enable GMP build by setting BUILD_GMP. ") + return() + endif() + #Install gmp libraries. + install_imported_library(GMP::GMP "GMP") + install_imported_library(GMP::GMPXX "GMPXX") +endif() diff --git a/cmake/Modules/AddOTExtension.cmake b/cmake/Modules/AddOTExtension.cmake new file mode 100644 index 00000000..cfb74f09 --- /dev/null +++ b/cmake/Modules/AddOTExtension.cmake @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.13) + +set(OTExtension_SOURCE CACHE PATH "Path to OTExtension source.") +set(OTExtension_REPOSITORY https://github.com/oliver-schick/OTExtension.git CACHE STRING "Git repository of OTExtension project.") +set(OTExtension_TAG origin/master CACHE STRING "Git tag of downloaded OTExtension project.") +#Specific commit hash. Please regularly update to maintain compatibility with ABY. +set(OTExtension_URL https://github.com/oliver-schick/OTExtension/archive/75470c035f101d9230c5a4896cd072745b2f7254.zip CACHE STRING "URL of OTExtension project.") +#sha256sum of downloaded file. To get it on linux simply type following command line: +#$ wget -O out [URL] && sha256sum out +set(OTExtension_URL_HASH SHA256=c43ebf6de0276e7f4c75aaa090196d9942d20677a6e9b99cbe629c208aafb424 CACHE STRING "Hash of OTExtension archive.") +option(DOWNLOAD_OTExtension "Set this option to download a specific commit of OTExtension." OFF) +mark_as_advanced(OTExtension_REPOSITORY OTExtension_TAG OTExtension_URL OTExtension_URL_HASH DOWNLOAD_OTExtension) + +if(NOT TARGET OTExtension::otextension) + if(NOT OTExtension_LIBRARY_TYPE) + set(OTExtension_LIBRARY_TYPE ${ABY_LIBRARY_TYPE}) + endif() + file(GLOB OTExtension_FILE_LIST "${PROJECT_SOURCE_DIR}/extern/OTExtension/*") + list(LENGTH OTExtension_FILE_LIST OTExtension_NUM_FILES) + #if OTExtension directory is empty + if(OTExtension_NUM_FILES EQUAL 0) + message(STATUS "OTExtension was not found. Fetching OTExtension...") + include(FetchOTExtension) + else() + message(STATUS "OTExtension was found in: ${PROJECT_SOURCE_DIR}/extern/OTExtension") + set(OTExtension_SOURCE "${PROJECT_SOURCE_DIR}/extern/OTExtension" + CACHE PATH + "Path to OTExtension source." + FORCE + ) + include(FetchOTExtension) + endif() +endif() diff --git a/cmake/Modules/AndroidCacheVariables.cmake b/cmake/Modules/AndroidCacheVariables.cmake new file mode 100644 index 00000000..501626e4 --- /dev/null +++ b/cmake/Modules/AndroidCacheVariables.cmake @@ -0,0 +1,43 @@ +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") + set(ANDROID_TOOLCHAIN_FILE "${CMAKE_TOOLCHAIN_FILE}") + 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() +endif(ANDROID) diff --git a/cmake/Modules/BOOST_CMAKEPatches/libs/header.cmake b/cmake/Modules/BOOST_CMAKEPatches/libs/header.cmake new file mode 100644 index 00000000..9a4b8c10 --- /dev/null +++ b/cmake/Modules/BOOST_CMAKEPatches/libs/header.cmake @@ -0,0 +1,9 @@ +# Define the header-only Boost target +add_library(Boost::boost INTERFACE IMPORTED GLOBAL) +target_include_directories(Boost::boost SYSTEM INTERFACE + $ + $ +) + +# Disable autolink +target_compile_definitions(Boost::boost INTERFACE BOOST_ALL_NO_LIB=1) diff --git a/cmake/Modules/BuildGMP.cmake b/cmake/Modules/BuildGMP.cmake new file mode 100644 index 00000000..83e90333 --- /dev/null +++ b/cmake/Modules/BuildGMP.cmake @@ -0,0 +1,76 @@ +cmake_minimum_required(VERSION 3.13) + +#Set download command according to whether sorce directory is available and if +#a dependency directory is given, in order to cash downloads in dependency directory +if(NOT "${GMP_SOURCE}" STREQUAL "") + set(GMP_DOWNLOAD_COMMANDS URL "${GMP_SOURCE}") +else() + set(GMP_DOWNLOAD_COMMANDS URL "${GMP_URL}" URL_HASH "${GMP_URL_HASH}") + if(NOT "${DEPENDENCY_DIR}" STREQUAL "") + list(APPEND GMP_DOWNLOAD_COMMANDS DOWNLOAD_DIR ${DEPENDENCY_DIR}) + endif() +endif() + +include(ExternalBuildHelper) + +#Set Environment variables and configure flags, depending on whether building for Android or Linux +if(ANDROID) + get_android_target_compiler(GMP_ANDROID_COMPILER_PREFIX GMP_ANDROID_COMPILER_DIR) + set(GMP_CONFIGURE_FLAGS --prefix= --host=${CMAKE_C_COMPILER_TARGET}) + set(GMP_ENVIRONMENT_VARIABLES + "CC=${GMP_ANDROID_COMPILER_DIR}/${GMP_ANDROID_COMPILER_PREFIX}-clang" + "CFLAGS=-Wno-unused-command-line-argument -Wno-unused-value -Wno-shift-op-parentheses" + ) + set(GMPXX_ENVIRONMENT_VARIABLES + "CXX=${GMP_ANDROID_COMPILER_DIR}/${GMP_ANDROID_COMPILER_PREFIX}-clang++" + "CXXFLAGS=-Wno-unused-command-line-argument -Wno-unused-value -Wno-shift-op-parentheses" + ) +else() + set(GMP_CONFIGURE_FLAGS --prefix=) + set(GMP_ENVIRONMENT_VARIABLES "") + set(GMPXX_ENVIRONMENT_VARIABLES "") +endif() + +#Set Environment variables and configure flags, depending on whether building with or without c++ support +if(NOT GMP_ONLY) + list(APPEND GMP_CONFIGURE_FLAGS --enable-cxx) + list(APPEND GMP_ENVIRONMENT_VARIABLES ${GMPXX_ENVIRONMENT_VARIABLES}) +endif() + +#Set Environment variables and configure flags, depending on whether building with or without c++ support +if("${GMP_LIBRARY_TYPE}" STREQUAL "STATIC") + list(APPEND GMP_CONFIGURE_FLAGS --enable-static --disable-shared) +elseif("${GMP_LIBRARY_TYPE}" STREQUAL "SHARED") + list(APPEND GMP_CONFIGURE_FLAGS --enable-shared --disable-static) +endif() + +find_program(MAKE_EXE NAMES gmake nmake make) + +include(ExternalProject) +ExternalProject_Add(GMP + PREFIX GMP_PREFIX + ${GMP_DOWNLOAD_COMMANDS} + UPDATE_DISCONNECTED TRUE + CONFIGURE_COMMAND "${CMAKE_COMMAND}" -E env ${GMP_ENVIRONMENT_VARIABLES} /configure ${GMP_CONFIGURE_FLAGS} + BUILD_COMMAND "${CMAKE_COMMAND}" -E env ${GMP_ENVIRONMENT_VARIABLES} ${MAKE_EXE} + INSTALL_COMMAND "${CMAKE_COMMAND}" -E env ${GMP_ENVIRONMENT_VARIABLES} ${MAKE_EXE} install +) +ExternalProject_Get_Property(GMP INSTALL_DIR) +ExternalProject_Get_Property(GMP BINARY_DIR) + +#Path that will be created upon downloading the GMP library +set(GMP_INCLUDE_DIR "${INSTALL_DIR}/include") +set(GMP_LIB_DIR "${INSTALL_DIR}/lib") + +add_imported_library(TARGET GMP::GMP ${GMP_LIBRARY_TYPE} + EXTERNAL_TARGET GMP + EXTERNAL_LIB_DIR "lib" + EXTERNAL_LIB_NAME gmp + EXTERNAL_INCLUDES "include" +) +add_imported_library(TARGET GMP::GMPXX ${GMP_LIBRARY_TYPE} + EXTERNAL_TARGET GMP + EXTERNAL_LIB_DIR "lib" + EXTERNAL_LIB_NAME gmpxx + EXTERNAL_INCLUDES "include" +) diff --git a/cmake/Modules/ExternalBuildHelper.cmake b/cmake/Modules/ExternalBuildHelper.cmake new file mode 100644 index 00000000..2f3a6e46 --- /dev/null +++ b/cmake/Modules/ExternalBuildHelper.cmake @@ -0,0 +1,278 @@ +cmake_minimum_required(VERSION 3.13) + +#get_android_target_compiler( [out-dir]) +# +#Calculates a target compiler name for android platform specific builds, based on the current +#build parameters set by the android toolchain file. The android toolchain file must set the +#variables ANDROID_ABI, ANDROID_TOOLCHAIN_ROOT and ANDROID_PLATFORM_LEVEL to correct values. +# +#out-var will be set to the appropriate target that can be passed as -target option to clang. +#out-dir is optional and if provided will be set to the directory containing the target specific +#compilers. +#For more information See https://developer.android.com/ndk/guides/other_build_systems +# +#Example 1: get_android_target_compiler(TARGET_COMPILER_NAME) +# set(ENVIRONMENT "CXX=clang++" "CXXFLAGS=-target ${TARGET_COMPILER_NAME}") +# +#Example 2: get_android_target_compiler(COMPILER_PREFIX COMPILER_DIR) +# set(ENVIRONMENT "CXX=${COMPILER_DIR}/${COMPILER_PREFIX}-clang++") +# +function(get_android_target_compiler RESULT_NAME) + #If ANDROID_ABI is empty, there is no target to be found. Emit warning. + if("${ANDROID_ABI}" STREQUAL "" + OR NOT EXISTS "${ANDROID_TOOLCHAIN_ROOT}" + OR "${ANDROID_PLATFORM_LEVEL}" STREQUAL "") + message(SEND_ERROR "ANDROID_ABI, ANDROID_TOOLCHAIN_ROOT or ANDROID_PLATFORM_LEVEL were not set" + " to valid values. Cannot set android target compiler to any valid value.") + return() + endif() + set(RES_DIR "${ANDROID_TOOLCHAIN_ROOT}/bin") + if("${ANDROID_ABI}" STREQUAL "armeabi-v7a" OR "${ANDROID_ABI}" STREQUAL "armeabi-v7a with NEON") + set(RES "armv7a-linux-androideabi${ANDROID_PLATFORM_LEVEL}") + elseif("${ANDROID_ABI}" STREQUAL "arm64-v8a") + set(RES "aarch64-linux-android${ANDROID_PLATFORM_LEVEL}") + elseif("${ANDROID_ABI}" STREQUAL "x86") + set(RES "i686-linux-android${ANDROID_PLATFORM_LEVEL}") + elseif("${ANDROID_ABI}" STREQUAL "x86_64") + set(RES "x86_64-linux-android${ANDROID_PLATFORM_LEVEL}") + else() + message(SEND_ERROR "Unsupported ANDROID_ABI: ${ANDROID_ABI}") + return() + endif() + set(${RESULT_NAME} "${RES}" PARENT_SCOPE) + #User provided second optional argument. Subsequent arguments are ignored. + if(${ARGC} GREATER 1) + set(${ARGV1} "${RES_DIR}" PARENT_SCOPE) + endif() +endfunction() + +#add_imported_library(TARGET [SHARED|STATIC] +# [EXTERNAL_TARGET external_target] +# [EXTERNAL_INCLUDES paths...] +# EXTERNAL_LIB_DIR path +# EXTERNAL_LIB_NAME name +# [EXTERNAL_LIB_NAME_IS_FULL] +# [NO_GLOBAL] [NO_WARN]) +# +#Creates a linkable imported library from a target created with ExternalProject_Add, +#if EXTERNAL_TARGET is passed or simply import a library from a given location. +#TARGET : the name of the created library target +# [SHARED|STATIC]: The type of the imported library. If you don't specify any, UNKNOWN will be used. +#[EXTERNAL_TARGET external_target]: The name of the target added through ExternalProject_Add. +# If it is not provided, no dependecy to any external target will +# be defined. In that case, EXTERNAL_LIB_DIR and EXTERNAL_LIB_NAME +# must be absolute paths. +#EXTERNAL_INCLUDES paths...: Paths to include directories of external target. If no EXTERNAL_TARGET is provided, +# these must be absolute and existing paths. See below for more information. +#EXTERNAL_LIB_DIR path: Path to lib directory or file of external target. If no EXTERNAL_TARGET is provided, +# this must be an absolute and existing paths. See below for more information. +#EXTERNAL_LIB_NAME name: Name of library created by ExternalProject during build. If the library type +# is provided along with TARGET, then name may omit library prefixes and suffixes +#[EXTERNAL_LIB_NAME_IS_FULL]: EXTERNAL_LIB_NAME represent full library name. Prevents performing any +# checks and modification to library name. +#[NO_GLOBAL]: Created target will not be global. +#[NO_WARN]: Suppress all warnings emitted from this function. +# +#The external library and include directories usually do not exist when calling this function. +#However, they will be created by ExternalProject, so the user must provide information about +#the include and lib directories, as they vary between each project. +#If a relative path is given for EXTERNAL_INCLUDES or EXTERNAL_LIB_DIR, the INSTALL_DIR property +#of ExternalProject will be used as root directory. If the paths do not exist, they will be +#created. EXTERNAL_INCLUDES and EXTERNAL_LIB_DIR must point to all directories filled with +#include directories (or libraries in the case of EXTERNAL_LIB_DIR) that are created by the +#external project after the install step of ExternalProject completes. +# +#This function may also be used to create an imported target that does not depend on a target created +#by ExternalProject_Add, by omitting EXTERNAL_TARGET. In this case EXTERNAL_INCLUDES and EXTERNAL_LIB_DIR must +#point to absolute directories that already exist. +# +#Example 1: add_imported_library(TARGET Foo::foo STATIC +# EXTERNAL_TARGET Foo +# EXTERNAL_INCLUDES include fooinclude +# EXTERNAL_LIB_DIR lib +# EXTERNAL_LIB_NAME foo) +# +#Example 2: add_imported_library(TARGET Bar +# EXTERNAL_LIB_DIR /usr/lib +# EXTERNAL_LIB_NAME libbar.a) +# +function(add_imported_library) + #Parse arguments + set(options NO_GLOBAL NO_WARN EXTERNAL_LIB_NAME_IS_FULL) + set(oneValueArgs EXTERNAL_TARGET EXTERNAL_LIB_DIR EXTERNAL_LIB_NAME) + set(multiValueArgs TARGET EXTERNAL_INCLUDES) + cmake_parse_arguments(IMPORT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(NOT "${IMPORT_UNPARSED_ARGUMENTS}" STREQUAL "") + message(AUTHOR_WARNING "Arguments ${IMPORT_UNPARSED_ARGUMENTS} not recognized.") + endif() + + #Handle Arguments passed to function and emit error messages for invalid arguments + if(NOT IMPORT_TARGET) + message(SEND_ERROR "(TARGET ${IMPORT_TARGET}) is not valid.") + return() + endif() + + list(GET IMPORT_TARGET 0 IMPORT_TARGET_NAME) + list(LENGTH IMPORT_TARGET IMPORT_TARGET_LENGTH) + #User did not provide [SHARED|STATIC] + if(${IMPORT_TARGET_LENGTH} EQUAL 1) + set(IMPORT_LIBRARY_TYPE UNKNOWN) + #User provided [SHARED|STATIC] + elseif(${IMPORT_TARGET_LENGTH} EQUAL 2) + list(GET IMPORT_TARGET 1 IMPORT_LIBRARY_TYPE) + #User provided too many arguments for target + elseif(${IMPORT_TARGET_LENGTH} GREATER 2) + if(NOT IMPORT_NO_WARN) + message(AUTHOR_WARNING "Too many arguments provided for TARGET, additional arguments will be ignored") + endif() + list(GET IMPORT_TARGET 1 IMPORT_LIBRARY_TYPE) + endif() + + #User provided library type, but type is not valid + if(NOT "${IMPORT_LIBRARY_TYPE}" STREQUAL "SHARED" + AND NOT "${IMPORT_LIBRARY_TYPE}" STREQUAL "STATIC" + AND NOT "${IMPORT_LIBRARY_TYPE}" STREQUAL "UNKNOWN") + if(NOT IMPORT_NO_WARN) + message(AUTHOR_WARNING "Unrecognized library type: ${IMPORT_LIBRARY_TYPE}. Using UNKNOWN as library type.") + endif() + set(IMPORT_LIBRARY_TYPE UNKNOWN) + endif() + + #User provided non-existent EXTERNAL_TARGET + if(DEFINED IMPORT_EXTERNAL_TARGET AND NOT TARGET "${IMPORT_EXTERNAL_TARGET}") + message(SEND_ERROR "EXTERNAL_TARGET is set to a value that is not a target." + " Please provide a valid target or omit EXTERNAL_TARGET.") + return() + endif() + + #Get INSTALL_DIR of external project, as default root directory + if(DEFINED IMPORT_EXTERNAL_TARGET) + include(ExternalProject) + ExternalProject_Get_Property(${IMPORT_EXTERNAL_TARGET} INSTALL_DIR) + endif() + + #After invocation passed variable name will contain valid and existing path. + #Variable remains unchanged if it already contained an absolute path. + #If the path Variable pointed to did not exist, it will be created + macro(make_valid path_var) + if(NOT IS_ABSOLUTE "${${path_var}}" AND DEFINED IMPORT_EXTERNAL_TARGET) + set(${path_var} "${INSTALL_DIR}/${${path_var}}") + elseif(NOT IS_ABSOLUTE "${${path_var}}" AND NOT DEFINED IMPORT_EXTERNAL_TARGET) + message(SEND_ERROR "Did not provide an absolute path: ${${path_var}}," + " while not importing from external project.") + return() + endif() + if(NOT EXISTS "${${path_var}}") + file(MAKE_DIRECTORY "${${path_var}}") + endif() + endmacro() + + #Make EXTERNAL_INCLUDES and EXTERNAL_LIB_DIR point to valid directories + set(VALID_IMPORT_EXTERNAL_INCLUDES) + foreach(include_dir ${IMPORT_EXTERNAL_INCLUDES}) + make_valid(include_dir) + list(APPEND VALID_IMPORT_EXTERNAL_INCLUDES "${include_dir}") + endforeach() + set(IMPORT_EXTERNAL_INCLUDES ${VALID_IMPORT_EXTERNAL_INCLUDES}) + make_valid(IMPORT_EXTERNAL_LIB_DIR) + + #User did not specify EXTERNAL_LIB_NAME + if("${IMPORT_EXTERNAL_LIB_NAME}" STREQUAL "") + message(SEND_ERROR "No EXTERNAL_LIB_NAME provided.") + return() + endif() + + #User does not say that EXTERNAL_LIB_NAME represents a full library name, + #so checks are made and library prefixes and suffixes may be added or warnings emitted + if(NOT IMPORT_EXTERNAL_LIB_NAME_IS_FULL) + set(IMPORT_DISABLE_WARNING_HINT_MESSAGE + "Set option EXTERNAL_LIB_NAME_IS_FULL if ${IMPORT_EXTERNAL_LIB_NAME} is full library name.") + get_filename_component(IMPORT_EXTERNAL_LIB_NAME_EXT "${IMPORT_EXTERNAL_LIB_NAME}" EXT) + #User did not provide a library name with file extension, but a library type, so we compute full name of library + if("${IMPORT_EXTERNAL_LIB_NAME_EXT}" STREQUAL "" AND NOT "${IMPORT_LIBRARY_TYPE}" STREQUAL "UNKNOWN") + set(PFX "${CMAKE_${IMPORT_LIBRARY_TYPE}_LIBRARY_PREFIX}") + set(SFX "${CMAKE_${IMPORT_LIBRARY_TYPE}_LIBRARY_SUFFIX}") + if(NOT IMPORT_NO_WARN AND NOT "${PFX}" STREQUAL "" AND "${IMPORT_EXTERNAL_LIB_NAME}" MATCHES "^${PFX}.*") + message(AUTHOR_WARNING "Library name ${IMPORT_EXTERNAL_LIB_NAME} begins with ${PFX}." + " Will assume library full name is ${PFX}${IMPORT_EXTERNAL_LIB_NAME}${SFX}." + " ${IMPORT_DISABLE_WARNING_HINT_MESSAGE}") + endif() + set(IMPORT_EXTERNAL_LIB_NAME "${PFX}${IMPORT_EXTERNAL_LIB_NAME}${SFX}") + message(STATUS "Name of external library set to ${IMPORT_EXTERNAL_LIB_NAME}") + #User provided a library name with file extension and library type. + #Emit warnings if inconsistent, but assume correctness. + elseif(NOT "${IMPORT_EXTERNAL_LIB_NAME_EXT}" STREQUAL "" AND NOT "${IMPORT_LIBRARY_TYPE}" STREQUAL "UNKNOWN") + if(NOT IMPORT_NO_WARN) + macro(escape_special_regex_characters output input) + string(REPLACE "." "\\." ${output} "${input}") + endmacro() + escape_special_regex_characters(REGEX_SFX "${CMAKE_SHARED_LIBRARY_SUFFIX}") + set(REGEX_SFX ".*${REGEX_SFX}(\\..*|$)") + #Library suffix is inconsistent with shared and versioned shared library suffixes + if("${IMPORT_LIBRARY_TYPE}" STREQUAL "SHARED" AND NOT "${IMPORT_EXTERNAL_LIB_NAME_EXT}" MATCHES "${REGEX_SFX}") + message(AUTHOR_WARNING "Given suffix: ${IMPORT_EXTERNAL_LIB_NAME_EXT} is inconsistent with ${IMPORT_LIBRARY_TYPE} suffix." + " ${IMPORT_DISABLE_WARNING_HINT_MESSAGE}") + endif() + escape_special_regex_characters(REGEX_SFX "${CMAKE_STATIC_LIBRARY_SUFFIX}") + set(REGEX_SFX ".*${REGEX_SFX}$") + #Library suffix is inconsistent with static library suffixes + if("${IMPORT_LIBRARY_TYPE}" STREQUAL "STATIC" AND NOT "${IMPORT_EXTERNAL_LIB_NAME_EXT}" MATCHES "${REGEX_SFX}") + message(AUTHOR_WARNING "Given suffix: ${IMPORT_EXTERNAL_LIB_NAME_EXT} is inconsistent with ${IMPORT_LIBRARY_TYPE} suffix." + " ${IMPORT_DISABLE_WARNING_HINT_MESSAGE}") + endif() + #Check if library prefix is consistent + set(PFX "${CMAKE_${IMPORT_LIBRARY_TYPE}_LIBRARY_PREFIX}") + if(NOT "${PFX}" STREQUAL "" AND NOT "${IMPORT_EXTERNAL_LIB_NAME}" MATCHES "^${PFX}.*") + message(AUTHOR_WARNING "Library name ${IMPORT_EXTERNAL_LIB_NAME} does not begin with ${PFX}," + " which is inconsistent with ${IMPORT_LIBRARY_TYPE} prefix." + " ${IMPORT_DISABLE_WARNING_HINT_MESSAGE}") + endif() + endif(NOT IMPORT_NO_WARN) + #User provided no library type. We therefore assume that every library name is correct. + elseif("${IMPORT_LIBRARY_TYPE}" STREQUAL "UNKNOWN") + message(STATUS "Name of external library is set to ${IMPORT_EXTERNAL_LIB_NAME}") + endif() + endif(NOT IMPORT_EXTERNAL_LIB_NAME_IS_FULL) + + #Set IMPORT_TARGET_GLOBAL according to option NO_GLOBAL. + if(IMPORT_NO_GLOBAL) + set(IMPORT_TARGET_GLOBAL ) + else() + set(IMPORT_TARGET_GLOBAL GLOBAL) + endif() + + #Add imported library target. + add_library(${IMPORT_TARGET_NAME} ${IMPORT_LIBRARY_TYPE} IMPORTED ${IMPORT_TARGET_GLOBAL}) + #Set dependency to external target, if EXTERNAL_TARGET is provided. + if(DEFINED IMPORT_EXTERNAL_TARGET) + add_dependencies(${IMPORT_TARGET_NAME} ${IMPORT_EXTERNAL_TARGET}) + endif() + target_include_directories(${IMPORT_TARGET_NAME} INTERFACE ${IMPORT_EXTERNAL_INCLUDES}) + set_target_properties(${IMPORT_TARGET_NAME} PROPERTIES + IMPORTED_LOCATION "${IMPORT_EXTERNAL_LIB_DIR}/${IMPORT_EXTERNAL_LIB_NAME}") +endfunction(add_imported_library) + +function(install_imported_library TARGET LIBRARY_NAME) + if(NOT TARGET "${TARGET}") + message(SEND_ERROR "Input: ${TARGET} is not a target.") + return() + endif() + include(InstallConfig) + install_config(IGNORED "${LIBRARY_NAME}") + get_target_property(INSTALL_INCLUDES ${TARGET} INTERFACE_INCLUDE_DIRECTORIES) + get_target_property(INSTALL_IMPORTED_LOCATION ${TARGET} LOCATION) + if(NOT INSTALL_INCLUDES) + message(SEND_ERROR "Target does not have property INTERFACE_INCLUDE_DIRECTORIES") + return() + endif() + if(NOT INSTALL_IMPORTED_LOCATION) + message(SEND_ERROR "Target does not have a location.") + return() + endif() + #Add a trailing slash behind every directory, to prevent structures like include/include etc. + #Only add a trailing slash to directories not already ending with a slash + list(TRANSFORM INSTALL_INCLUDES APPEND "/" REGEX ".*[^/]$") + install(DIRECTORY ${INSTALL_INCLUDES} DESTINATION "${${PROJECT_NAME}_INSTALL_INCLUDE}") + install(FILES "${INSTALL_IMPORTED_LOCATION}" DESTINATION "${${PROJECT_NAME}_INSTALL_LIB}") +endfunction(install_imported_library) diff --git a/cmake/Modules/FetchBOOST_CMAKE.cmake b/cmake/Modules/FetchBOOST_CMAKE.cmake new file mode 100644 index 00000000..de791884 --- /dev/null +++ b/cmake/Modules/FetchBOOST_CMAKE.cmake @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 3.13) +include(FetchContent) + +if(NOT "${BOOST_SOURCE}" STREQUAL "") + set(FETCHCONTENT_SOURCE_DIR_BOOST "${BOOST_SOURCE}") +elseif(NOT "${DEPENDENCY_DIR}" STREQUAL "") + include(FetchContent) + FetchContent_Declare(Boost + URL ${BOOST_URL} + URL_HASH ${BOOST_URL_HASH} + DOWNLOAD_DIR ${DEPENDENCY_DIR} + ) +else() + include(FetchContent) + FetchContent_Declare(Boost + URL ${BOOST_URL} + URL_HASH ${BOOST_URL_HASH} + ) +endif() + +include(FetchHelper) +fetch_helper(BOOST_CMAKE true) diff --git a/cmake/Modules/FetchENCRYPTO_utils.cmake b/cmake/Modules/FetchENCRYPTO_utils.cmake new file mode 100644 index 00000000..d18a029c --- /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 00000000..fb2de5ca --- /dev/null +++ b/cmake/Modules/FetchHelper.cmake @@ -0,0 +1,45 @@ +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 "") + elseif(DOWNLOAD_${content_name} OR "${${content_name}_REPOSITORY}" STREQUAL "") + set(${content_name}_DOWNLOAD_COMMAND1 URL ${${content_name}_URL}) + set(${content_name}_DOWNLOAD_COMMAND2 URL_HASH ${${content_name}_URL_HASH}) + 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/FetchOTExtension.cmake b/cmake/Modules/FetchOTExtension.cmake new file mode 100644 index 00000000..2e38b726 --- /dev/null +++ b/cmake/Modules/FetchOTExtension.cmake @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.13) + +include(FetchHelper) +fetch_helper(OTExtension) diff --git a/cmake/Modules/GetDependencies.cmake b/cmake/Modules/GetDependencies.cmake new file mode 100644 index 00000000..60445e8c --- /dev/null +++ b/cmake/Modules/GetDependencies.cmake @@ -0,0 +1,57 @@ +#get_dependencies( targets...) +# +#Returns a list of all dependencies of targets... including alias-stripped targets... +#The returned list of dependencies contains no duplicates and dependencies are guaranteed +#to not be alias targets. +#Arguments that are not valid targets, will be ignored and won't appear in the returned list. +function(get_dependencies RESULT) + if(${ARGC} EQUAL 1) + return() + endif() + + #TARGET is not an alias target after invoking this function + function(strip_alias TARGET) + set(target ${${TARGET}}) + get_target_property(alias ${target} ALIASED_TARGET) + if(NOT alias) + set(${TARGET} ${target} PARENT_SCOPE) + else() + strip_alias(alias) + set(${TARGET} ${alias} PARENT_SCOPE) + endif() + endfunction() + + #Put all alis-stripped targets in DEPENDENCY_LIST + #DEPENDENCY_LIST will only contain targets + set(DEPENDENCY_LIST) + foreach(target ${ARGN}) + if(TARGET ${target}) + strip_alias(target) + list(APPEND DEPENDENCY_LIST ${target}) + endif() + endforeach() + + #Put all dependencies of the targets in DEPENDENCY_LIST + #in DEPENDENCY_DEPENDENCY_LIST. DEPENDENCY_DEPENDENCY_LIST + #may contain elements that are not a target + set(DEPENDENCY_DEPENDENCY_LIST) + foreach(target ${DEPENDENCY_LIST}) + get_target_property(dependencies ${target} INTERFACE_LINK_LIBRARIES) + if(dependencies) + list(APPEND DEPENDENCY_DEPENDENCY_LIST ${dependencies}) + endif() + endforeach() + + #We remove all duplicates before recursing. + list(REMOVE_DUPLICATES DEPENDENCY_DEPENDENCY_LIST) + + #Now we get all dependencies of the dependencies of our targets + get_dependencies(DEPENDENCY_DEPENDENCY_LIST ${DEPENDENCY_DEPENDENCY_LIST}) + list(APPEND DEPENDENCY_LIST ${DEPENDENCY_DEPENDENCY_LIST}) + #We need to remove all duplicates again, to ensure we fulfill the guarantee to not + #return duplicates. Without it we would return duplicates, if two input targets had + #the same dependency. + list(REMOVE_DUPLICATES DEPENDENCY_LIST) + #return + set(${RESULT} ${DEPENDENCY_LIST} PARENT_SCOPE) +endfunction() diff --git a/cmake/Modules/InstallConfig.cmake b/cmake/Modules/InstallConfig.cmake new file mode 100644 index 00000000..91d4c344 --- /dev/null +++ b/cmake/Modules/InstallConfig.cmake @@ -0,0 +1,34 @@ +function(install_config RESULT INSTALL_NAME) + set(CONFIG_FILE_LOCATION "${PROJECT_SOURCE_DIR}/cmake/${INSTALL_NAME}Config.cmake.in") + if(ANDROID AND ANDROID_ARM_NEON) + set(CONFIG_NAME "${INSTALL_NAME}/${INSTALL_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 "${INSTALL_NAME}/${INSTALL_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 "${INSTALL_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}" + "${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}Config.cmake" + @ONLY) + if(ANDROID) + file(READ "${PROJECT_SOURCE_DIR}/cmake/ImportIntoAndroidStudio.cmake" IMPORT_INTO_ANDROID_STUDIO) + file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}Config.cmake" "${IMPORT_INTO_ANDROID_STUDIO}") + endif() + 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 "${INSTALL_NAME}") + configure_file("${PROJECT_SOURCE_DIR}/cmake/ForwardConfig.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/${INSTALL_NAME}Config.cmake" + @ONLY) + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${INSTALL_NAME}Config.cmake" DESTINATION "${INSTALL_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/PatchBOOST_CMAKE.cmake b/cmake/Modules/PatchBOOST_CMAKE.cmake new file mode 100644 index 00000000..fb1276aa --- /dev/null +++ b/cmake/Modules/PatchBOOST_CMAKE.cmake @@ -0,0 +1,5 @@ +configure_file( + "${CMAKE_CURRENT_LIST_DIR}/BOOST_CMAKEPatches/libs/header.cmake" + "${boost_cmake_SOURCE_DIR}/libs/header.cmake" + COPYONLY +) diff --git a/extern/ENCRYPTO_utils b/extern/ENCRYPTO_utils deleted file mode 160000 index a596166d..00000000 --- a/extern/ENCRYPTO_utils +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a596166d9ebdc506d1ecb2394fac5ee5d598297b diff --git a/extern/OTExtension b/extern/OTExtension deleted file mode 160000 index 2057fb0d..00000000 --- a/extern/OTExtension +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2057fb0d4cfd39674e7813bc98d6d0a863138fc4 diff --git a/src/abycore/CMakeLists.txt b/src/abycore/CMakeLists.txt index d25f5295..5b39ddc0 100644 --- a/src/abycore/CMakeLists.txt +++ b/src/abycore/CMakeLists.txt @@ -1,4 +1,48 @@ -add_library(aby +cmake_minimum_required(VERSION 3.13) + +list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_LIST_DIR}/cmake/Modules") + +#Watch out when changing name of ABY_* variables: +#They are referenced as ${PROJECT_NAME}_* in InstallConfig.cmake, +#ExternalBuildHelper.cmake and AddBOOST_CMAKE.cmake +if(ANDROID) + if(ANDROID_ARM_NEON) + set(ABY_INSTALL_PREFIX "platforms/${ANDROID_PLATFORM}/arch-${ANDROID_SYSROOT_ABI}/NEON") + else(ANDROID_ARM_NEON) + set(ABY_INSTALL_PREFIX "platforms/${ANDROID_PLATFORM}/arch-${ANDROID_SYSROOT_ABI}") + endif(ANDROID_ARM_NEON) + set(ABY_INSTALL_INCLUDE "${ABY_INSTALL_PREFIX}/include") + set(ABY_INSTALL_LIB "${ABY_INSTALL_PREFIX}/lib") + set(ABY_INSTALL_ARCHIVE "${ABY_INSTALL_PREFIX}/lib") + set(ABY_INSTALL_CONFIG "") +else(ANDROID) + set(ABY_INSTALL_PREFIX "") + set(ABY_INSTALL_INCLUDE "include") + set(ABY_INSTALL_LIB "lib") + set(ABY_INSTALL_ARCHIVE "lib") + set(ABY_INSTALL_CONFIG "") +endif(ANDROID) + +#Watch out when changing name of variable ABY_DEPENDENCIES_TO_EXPORT: +#It is referenced as ${PROJECT_NAME}_DEPENDENCIES_TO_EXPORT in AddBoost.cmake +set(ABY_DEPENDENCIES_TO_EXPORT) + +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() + +if(NOT TARGET stdc++fs) + list(APPEND BOOST_TARGETS_REQUIRED Boost::boost Boost::filesystem) +endif() + +include(AddGMP) +include(AddBoost) +include(AddENCRYPTO_utils) +include(AddOTExtension) +find_package(Threads REQUIRED) + +add_library(aby ${ABY_LIBRARY_TYPE} aby/abyparty.cpp aby/abysetup.cpp circuit/abycircuit.cpp @@ -18,57 +62,44 @@ add_library(aby ) add_library(ABY::aby ALIAS aby) -target_compile_features(aby PUBLIC cxx_std_17) #target_compile_options(aby PRIVATE "-Wall" "-Wextra" "-Weffc++") target_compile_options(aby PRIVATE "-Wall" "-Wextra") target_include_directories(aby PUBLIC - $ + $ $ ) - -# This assumes that libstdc++ is used and should not be required for e.g. -# libc++. Linking to libstdc++fs is currently required when using the -# std::filesystem library. -# cf. https://gitlab.kitware.com/cmake/cmake/issues/17834 -target_link_libraries(aby - PRIVATE stdc++fs -) - +#[[ +add_library(filesystem INTERFACE IMPORTED) +if(TARGET stdc++fs) + target_link_libraries(filesystem INTERFACE stdc++fs) +else() + target_link_libraries(filesystem INTERFACE Boost::filesystem) +endif() +]] target_link_libraries(aby PUBLIC OTExtension::otextension PUBLIC ENCRYPTO_utils::encrypto_utils PUBLIC GMP::GMP PUBLIC Threads::Threads + PRIVATE Boost::filesystem ) +include(InstallConfig) +install_config(ABY_INSTALL_LOCATION "${PROJECT_NAME}") -install(TARGETS aby +install(TARGETS aby ${ABY_DEPENDENCIES_TO_EXPORT} EXPORT "${PROJECT_NAME}Targets" - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib - INCLUDES DESTINATION lib -) + ARCHIVE DESTINATION "${ABY_INSTALL_LIB}" + LIBRARY DESTINATION "${ABY_INSTALL_LIB}" + INCLUDES DESTINATION "${ABY_INSTALL_INCLUDE}") install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - DESTINATION include - FILES_MATCHING PATTERN "*.h" -) - -export(TARGETS aby NAMESPACE "${PROJECT_NAME}::" FILE "${PROJECT_NAME}Targets.cmake") + DESTINATION "${ABY_INSTALL_INCLUDE}" + FILES_MATCHING REGEX ".*\\.h(pp|h)?$" REGEX ".*cmake.*" EXCLUDE) +export(TARGETS aby ${ABY_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("${PROJECT_SOURCE_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 "${ABY_INSTALL_LOCATION}") diff --git a/src/abycore/sharing/boolsharing.cpp b/src/abycore/sharing/boolsharing.cpp index 513925d3..81873668 100644 --- a/src/abycore/sharing/boolsharing.cpp +++ b/src/abycore/sharing/boolsharing.cpp @@ -19,7 +19,10 @@ #include "../aby/abysetup.h" #include -#if __has_include() +#if ANDROID +#include +namespace filesystem = boost::filesystem; +#elif __has_include() #include namespace filesystem = std::filesystem; #elif __has_include() diff --git a/src/abycore/sharing/sharing.cpp b/src/abycore/sharing/sharing.cpp index 1b973b7d..ba929c88 100644 --- a/src/abycore/sharing/sharing.cpp +++ b/src/abycore/sharing/sharing.cpp @@ -23,14 +23,20 @@ #include #include -#if __has_include() +#if ANDROID +#include +namespace filesystem = boost::filesystem; +typedef boost::system::error_code error_code; +#elif __has_include() #include namespace filesystem = std::filesystem; +typedef std::error_code error_code; #elif __has_include() #include namespace filesystem = std::experimental::filesystem; +typedef std::error_code error_code; #else -#error "C++17 filesystem library not found" +#error "filesystem library not found" #endif #include @@ -94,7 +100,7 @@ void Sharing::PreCompFileDelete() { } else { truncation_size = filesystem::file_size(filename) - m_nFilePos; - std::error_code ec; + error_code ec; filesystem::resize_file(filename, truncation_size, ec); if(ec) { std::cout << "Error occured in truncate:" << ec.message() << std::endl;