Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
realm-core/CMakeLists.txt
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
386 lines (327 sloc)
15.3 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| cmake_minimum_required(VERSION 3.15) | |
| set(CMAKE_BUILD_TYPE Debug CACHE STRING "") | |
| project(RealmCore) | |
| list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake") | |
| # Include general CMake modules | |
| include(GNUInstallDirs) | |
| include(CheckIncludeFiles) | |
| include(CheckSymbolExists) | |
| include(GetGitRevisionDescription) | |
| include(Utilities) | |
| include(SpecialtyBuilds) | |
| include(GetVersion) | |
| include(CheckCXXCompilerFlag) | |
| include(CheckCXXSourceRuns) | |
| include(CodeCoverage) | |
| # Get accurate git-describe version | |
| git_describe(REALM_VERSION) | |
| set(PROJECT_VERSION ${DEP_VERSION}) | |
| # Project-wide build flags | |
| set(CMAKE_CXX_STANDARD 17) | |
| set(CMAKE_CXX_STANDARD_REQUIRED ON) | |
| set(CMAKE_CXX_EXTENSIONS OFF) | |
| if(NOT APPLE) | |
| # TODO: Core APIs should always built for internal usage. But there seems to be issues with cocoa. Enable it only for Android for now. | |
| set(CMAKE_CXX_VISIBILITY_PRESET hidden) | |
| elseif(APPLE) | |
| set(CMAKE_VISIBILITY_INLINES_HIDDEN 1) | |
| endif() | |
| function(add_cxx_flag_if_supported flag) | |
| if(flag MATCHES "^-Wno-") | |
| # Compilers ignore unknown -Wno-foo flags, so look for -Wfoo instead. | |
| string(REPLACE "-Wno-" "-W" check_flag ${flag}) | |
| else() | |
| set(check_flag ${flag}) | |
| endif() | |
| check_cxx_compiler_flag(${check_flag} HAVE${check_flag}) | |
| if(HAVE${check_flag}) | |
| add_compile_options($<$<COMPILE_LANGUAGE:CXX>:${flag}>) | |
| endif() | |
| endfunction() | |
| function(use_faster_linker) | |
| # If a linker has already been set, don't override. | |
| if ("${CMAKE_EXE_LINKER_FLAGS}" MATCHES "-fuse-ld=") | |
| return() | |
| endif() | |
| foreach(LINKER lld gold) # lld > gold > default | |
| # there is no link equivalent to check_cxx_compiler_flag() | |
| set(CMAKE_REQUIRED_LINK_OPTIONS "-fuse-ld=${LINKER}") | |
| check_cxx_source_compiles("int main() {}" HAVE_LINKER_${LINKER}) | |
| if(HAVE_LINKER_${LINKER}) | |
| message(STATUS "Using linker ${LINKER}") | |
| add_link_options("-fuse-ld=${LINKER}") | |
| return() | |
| endif() | |
| endforeach() | |
| endfunction() | |
| # Set global warnings settings | |
| if(MSVC) | |
| add_compile_options(/W3 /D_CRT_SECURE_NO_WARNINGS /D_SCL_SECURE_NO_WARNINGS) | |
| # Don't complain about unary minus on unsigned resulting in positive number. | |
| add_compile_options(/wd4146) | |
| # We use these in our AtomicSharedPtr implementation and it can't move | |
| # to atomic<shared_ptr<T>> because NotificationToken relies on movability. | |
| add_compile_options(/D_SILENCE_CXX20_OLD_SHARED_PTR_ATOMIC_SUPPORT_DEPRECATION_WARNING) | |
| else() | |
| add_compile_options(-Wall -Wextra -Wempty-body -Wparentheses -Wunknown-pragmas -Wunreachable-code -Wunused-parameter -Wno-missing-field-initializers) | |
| # TODO: Remove this when fixed | |
| if(ANDROID) | |
| add_compile_options(-Wno-uninitialized) | |
| elseif(${CMAKE_CXX_COMPILER_ID} MATCHES ".*[Cc]lang") | |
| # FIXME: Re-introduce -Wold-style-cast | |
| add_compile_options(-Wunreachable-code -Wshorten-64-to-32 -Wconditional-uninitialized -Wextra-semi -Wno-nested-anon-types -Wdocumentation -Wthread-safety -Wthread-safety-negative) | |
| endif() | |
| if(CMAKE_CXX_STANDARD EQUAL 20) | |
| # std::is_pod was deprecated in c++20, but is still used by 3rd party json parser. | |
| # TODO remove this once we upgrade it. | |
| add_cxx_flag_if_supported(-Wno-deprecated-declarations) | |
| endif() | |
| add_cxx_flag_if_supported(-Wpartial-availability) | |
| # This warning is too agressive. It warns about moves that are not redundant on older | |
| # compilers that we still support. It is also harmless, unlike pessimizing moves. | |
| add_cxx_flag_if_supported(-Wno-redundant-move) | |
| # Ninja buffers output so we need to tell the compiler to use colors even though stdout isn't a tty. | |
| if("${CMAKE_GENERATOR}" STREQUAL "Ninja") | |
| add_cxx_flag_if_supported(-fdiagnostics-color) | |
| endif() | |
| use_faster_linker() | |
| endif() | |
| if(ANDROID) | |
| # Optimize for size vs. performance for Android. The has the following implications: | |
| # - Add `-ffunction-sections` and `-fdata-sections`. This requires that `-Wl,-gc-sections` are used when creating | |
| # the final .so file. | |
| # - `-fstrict-aliasing` is inherited from NDK r10e. | |
| # - `-fomit-frame-pointer` is inherited from NDK r10e. | |
| # - On some architectures char is unsigned by default. Make it signed | |
| # - Compile with -Oz in Release because on Android we favor code size over performance | |
| # | |
| add_compile_options(-fdata-sections -ffunction-sections -fomit-frame-pointer -fsigned-char -fstrict-aliasing -funwind-tables -no-canonical-prefixes $<$<CONFIG:Release>:-Oz>) | |
| endif() | |
| set(OPENSSL_VERSION ${DEP_OPENSSL_VERSION}) | |
| set(CMAKE_DEBUG_POSTFIX "-dbg") | |
| set(CMAKE_MINSIZEDEBUG_POSTFIX "-dbg") | |
| set(CMAKE_POSITION_INDEPENDENT_CODE ON) | |
| if(CMAKE_SYSTEM_NAME MATCHES "^Windows") | |
| add_compile_definitions( | |
| WIN32_LEAN_AND_MEAN # include minimal Windows.h for faster builds | |
| UNICODE # prefer Unicode variants of Windows APIs over ANSI variants | |
| _UNICODE # prefer Unicode variants of C runtime APIs over ANSI variants | |
| ) | |
| if(NOT WINDOWS_STORE) | |
| # for regular Windows target Windows 8.1 as the minimum version | |
| # see https://docs.microsoft.com/en-us/windows/win32/WinProg/using-the-windows-headers | |
| add_compile_definitions( | |
| _WIN32_WINNT=0x0603 | |
| WINVER=0x603 | |
| NTDDI_VERSION=0x06030000 | |
| ) | |
| endif() | |
| endif() | |
| if(MSVC) | |
| add_compile_options( | |
| /MP # Enable multi-processor compilation | |
| ) | |
| if(WINDOWS_STORE) | |
| # Removing LNK4075 warnings for debug UWP builds | |
| # "LNK4075: ignoring '/INCREMENTAL' due to '/OPT:ICF' specification" | |
| # "LNK4075: ignoring '/INCREMENTAL' due to '/OPT:REF' specification" | |
| # Optional verification checks since we don't know existing contents of variables below | |
| string(REPLACE "/OPT:ICF " "/OPT:NOICF " CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG}") | |
| string(REPLACE "/OPT:REF " "/OPT:NOREF " CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG}") | |
| string(REPLACE "/INCREMENTAL:YES " "/INCREMENTAL:NO " CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG}") | |
| string(REPLACE "/INCREMENTAL " "/INCREMENTAL:NO " CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG}") | |
| # Mandatory | |
| set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS_DEBUG} /INCREMENTAL:NO /OPT:NOREF /OPT:NOICF") | |
| set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /INCREMENTAL:NO /OPT:NOREF /OPT:NOICF") | |
| set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /INCREMENTAL:NO /OPT:NOREF /OPT:NOICF") | |
| else() | |
| set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>") | |
| string(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") | |
| endif() | |
| # Let the compiler optimize debug builds ever so slightly. | |
| # /Ob1: This allows the compiler to inline functions marked __inline. | |
| # /Oi: This enables (faster) intrinsic functions. | |
| string(REPLACE "/Ob0" "/Ob1" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") | |
| add_compile_options($<$<CONFIG:Debug>:/Oi>) | |
| # Prevent warnings abount non-existing .pdb files | |
| add_link_options($<$<CONFIG:Debug>:/ignore:4099>) | |
| endif() | |
| if(UNIX) | |
| # Enable access to large file APIs, but don't make them the default. | |
| add_compile_definitions("_LARGEFILE_SOURCE" "_LARGEFILE64_SOURCE") | |
| set(CMAKE_REQUIRED_DEFINITIONS "-D_LARGEFILE_SOURCE" "-D_LARGEFILE64_SOURCE") | |
| # Use readdir64 if available. | |
| check_symbol_exists(readdir64 "dirent.h" REALM_HAVE_READDIR64) | |
| endif() | |
| if (NOT APPLE) | |
| set(REALM_INCLUDE_CERTS_DEFAULT ON) | |
| else() | |
| set(REALM_INCLUDE_CERTS_DEFAULT OFF) | |
| endif() | |
| # Options (passed to CMake) | |
| option(REALM_ENABLE_SYNC "Enable synchronized realms." ON) | |
| option(REALM_BUILD_TEST_CLIENT "Build the test client" OFF) | |
| option(REALM_BUILD_DOGLESS "Build server with support for emitting statsd" OFF) | |
| option(REALM_ENABLE_ASSERTIONS "Enable assertions in release mode." OFF) | |
| option(REALM_ENABLE_ALLOC_SET_ZERO "Zero all allocations." OFF) | |
| option(REALM_ENABLE_ENCRYPTION "Enable encryption." ON) | |
| option(REALM_ENABLE_MEMDEBUG "Add additional memory checks" OFF) | |
| option(REALM_VALGRIND "Tell the test suite we are running with valgrind" OFF) | |
| option(REALM_METRICS "Enable various metric tracking" ON) | |
| option(REALM_INCLUDE_CERTS "Include a list of trust certificates in the build for SSL certificate verification" ${REALM_INCLUDE_CERTS_DEFAULT}) | |
| set(REALM_MAX_BPNODE_SIZE "1000" CACHE STRING "Max B+ tree node size.") | |
| # Find dependencies | |
| set(THREADS_PREFER_PTHREAD_FLAG ON) | |
| find_package(Threads REQUIRED) | |
| find_package(BISON 3.8.2 EXACT) | |
| find_package(FLEX 2.6.4 EXACT) | |
| if(REALM_ENABLE_SYNC) | |
| option(REALM_FORCE_OPENSSL "Always use OpenSSL for SSL needs, regardless of target platform." OFF) | |
| if(CMAKE_SYSTEM_NAME MATCHES "^Windows|Linux|Android") | |
| set(REALM_NEEDS_OPENSSL TRUE) | |
| endif() | |
| elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|Android") | |
| set(REALM_NEEDS_OPENSSL TRUE) | |
| endif() | |
| if(REALM_NEEDS_OPENSSL OR REALM_FORCE_OPENSSL) | |
| set(OPENSSL_USE_STATIC_LIBS ON) | |
| if(VCPKG_TOOLCHAIN) | |
| # If we're building with vcpkg, prefer to find OpenSSL there first | |
| find_package(OpenSSL) | |
| endif() | |
| # We aren't building with vcpkg, or it didn't have OpenSSL | |
| if(NOT OpenSSL_FOUND) | |
| if(ANDROID OR (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")) | |
| # We have prebuilt OpenSSL tarballs for Android and Linux x86_64 | |
| set(_realm_have_prebuilt_openssl ON) | |
| endif() | |
| if(NOT REALM_USE_SYSTEM_OPENSSL AND _realm_have_prebuilt_openssl) | |
| # Use our own prebuilt OpenSSL | |
| if(NOT OpenSSL_DIR) | |
| if(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/openssl/lib/cmake/OpenSSL/OpenSSLConfig.cmake) | |
| if(ANDROID) | |
| set(OPENSSL_URL "http://static.realm.io/downloads/openssl/${OPENSSL_VERSION}/Android/${CMAKE_ANDROID_ARCH_ABI}/openssl.tar.gz") | |
| else() | |
| set(OPENSSL_URL "http://static.realm.io/downloads/openssl/${OPENSSL_VERSION}/Linux/x86_64/openssl.tar.gz") | |
| endif() | |
| message(STATUS "Getting ${OPENSSL_URL}...") | |
| file(DOWNLOAD "${OPENSSL_URL}" "${CMAKE_CURRENT_BINARY_DIR}/openssl/openssl.tar.gz" STATUS download_status) | |
| list(GET download_status 0 status_code) | |
| if (NOT "${status_code}" STREQUAL "0") | |
| message(FATAL_ERROR "Downloading ${url}... Failed. Status: ${download_status}") | |
| endif() | |
| message(STATUS "Uncompressing OpenSSL...") | |
| execute_process( | |
| COMMAND ${CMAKE_COMMAND} -E tar xfz "openssl.tar.gz" | |
| WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/openssl" | |
| ) | |
| endif() | |
| set(OpenSSL_DIR "${CMAKE_CURRENT_BINARY_DIR}/openssl/lib/cmake/OpenSSL") | |
| endif() | |
| find_package(OpenSSL REQUIRED CONFIG) | |
| target_link_libraries(OpenSSL::SSL INTERFACE OpenSSL::Crypto) | |
| else() | |
| # Use whatever OpenSSL CMake finds on the system | |
| find_package(OpenSSL REQUIRED) | |
| endif() | |
| endif() | |
| set(REALM_HAVE_OPENSSL ON) | |
| string(REGEX MATCH "^([0-9]+)\\.([0-9]+)" OPENSSL_VERSION_MAJOR_MINOR ${OPENSSL_VERSION}) | |
| elseif(APPLE) | |
| set(REALM_HAVE_SECURE_TRANSPORT "1") | |
| endif() | |
| # Use Zlib for Sync, but allow integrators to override it | |
| # Don't use find_library(ZLIB) on Apple platforms - it hardcodes the path per platform, | |
| # so for an iOS build it'll use the path from the Device plaform, which is an error on Simulator. | |
| # Just use -lz and let Xcode figure it out | |
| if(NOT APPLE AND NOT TARGET ZLIB::ZLIB) | |
| if(ANDROID) | |
| # On Android FindZLIB chooses the static libz over the dynamic one, but this leads to issues | |
| # (see https://github.com/android/ndk/issues/1179) | |
| # We want to link against the stub library instead of statically linking anyway, | |
| # so we hack find_library to only consider shared object libraries when looking for libz | |
| set(_CMAKE_FIND_LIBRARY_SUFFIXES_orig ${CMAKE_FIND_LIBRARY_SUFFIXES}) | |
| set(CMAKE_FIND_LIBRARY_SUFFIXES .so) | |
| endif() | |
| find_package(ZLIB REQUIRED) | |
| if(ANDROID) | |
| set(CMAKE_FIND_LIBRARY_SUFFIXES ${_CMAKE_FIND_LIBRARY_SUFFIXES_orig}) | |
| endif() | |
| endif() | |
| # Store configuration in header file | |
| configure_file(src/realm/util/config.h.in src/realm/util/config.h) | |
| # Configure source code to use right version number | |
| configure_file(src/realm/version_numbers.hpp.in src/realm/version_numbers.hpp) | |
| set(DEPRECATED_CONFIG_FILE "${RealmCore_SOURCE_DIR}/src/realm/util/config.h") | |
| if(EXISTS "${DEPRECATED_CONFIG_FILE}") | |
| message(FATAL_ERROR "${DEPRECATED_CONFIG_FILE} exists in the source directory, and will take precedence over the generated configuration in the build directory. Please remove this file before continuing. Alternatively, you can also clean your realm-core to remove this and other stale files: git clean -xfd") | |
| endif() | |
| set(CATCH_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/catch/single_include) | |
| set(JSON_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/json) | |
| # Tell the build system where to find the sources (and generated sources) | |
| include_directories(src) | |
| include_directories(${CMAKE_CURRENT_BINARY_DIR}/src) # For generated files (like config.h) | |
| # Include additional CMakeLists | |
| add_subdirectory(src) | |
| if (REALM_BUILD_DOGLESS) | |
| set(REALM_HAVE_DOGLESS ON) | |
| add_subdirectory(src/dogless) | |
| endif() | |
| # Install the licence and changelog files | |
| install(FILES LICENSE CHANGELOG.md DESTINATION "doc/realm" COMPONENT devel) | |
| # Only prepare test/install/package targets if we're not a submodule | |
| if(NOT CMAKE_SOURCE_DIR STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}) | |
| return() | |
| endif() | |
| # Enable CTest and include unit tests | |
| enable_testing() | |
| if(REALM_BUILD_LIB_ONLY OR REALM_NO_TESTS) | |
| set(REALM_EXCLUDE_TESTS EXCLUDE_FROM_ALL) | |
| endif() | |
| add_subdirectory(test ${REALM_EXCLUDE_TESTS}) | |
| if (REALM_BUILD_TEST_CLIENT) | |
| add_subdirectory(test/client) | |
| endif() | |
| # Make the project importable from the build directory | |
| set(REALM_EXPORTED_TARGETS | |
| Storage | |
| QueryParser | |
| ObjectStore | |
| RealmFFI | |
| RealmFFIStatic | |
| ) | |
| if(REALM_ENABLE_SYNC) | |
| list(APPEND REALM_EXPORTED_TARGETS Sync) | |
| endif() | |
| export(TARGETS ${REALM_EXPORTED_TARGETS} NAMESPACE Realm:: FILE RealmTargets.cmake) | |
| configure_file(${CMAKE_CURRENT_LIST_DIR}/tools/cmake/RealmConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/RealmConfig.cmake @ONLY) | |
| # Make the project importable from the install directory | |
| install(EXPORT realm | |
| NAMESPACE Realm:: | |
| FILE RealmTargets.cmake | |
| DESTINATION lib/cmake/Realm | |
| COMPONENT devel | |
| ) | |
| install(FILES ${CMAKE_CURRENT_BINARY_DIR}/RealmConfig.cmake | |
| DESTINATION lib/cmake/Realm | |
| COMPONENT devel | |
| ) | |
| # CPack | |
| set(CPACK_GENERATOR "TGZ") | |
| set(CPACK_PACKAGE_VERSION ${REALM_VERSION}) | |
| set(CPACK_ARCHIVE_COMPONENT_INSTALL ON) | |
| # Generators that don't support build-time configuration selection. | |
| # Others like Xcode and Visual Studio can determine the package name | |
| # based on the build configuration at build-time. | |
| set(_single_config_generators | |
| Ninja | |
| "Unix Makefiles" | |
| ) | |
| if(CMAKE_GENERATOR IN_LIST _single_config_generators) | |
| set(CPACK_PACKAGE_NAME "realm-${CMAKE_BUILD_TYPE}") | |
| else() | |
| set(CPACK_PACKAGE_NAME "realm-\${CPACK_BUILD_CONFIG}") | |
| endif() | |
| include(CPack) | |
| cpack_add_component(runtime DEPENDS runtime) | |
| cpack_add_component(devel DEPENDS devel) |