cmake_minimum_required (VERSION 3.15...4.0) list (INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_LIST_DIR}/build/cmake") # Defines BUILD_VERSION, which we use throughout: include (BuildVersion) project ( mongo-c-driver LANGUAGES C # BUILD_VERSION_SIMPLE is a CMake-compatible version number that omits suffixes VERSION "${BUILD_VERSION_SIMPLE}" ) # Set MONGOC_MAJOR_VERSION, MONGOC_MINOR_VERSION, etc. include (ParseVersion) ParseVersion ("${BUILD_VERSION}" MONGOC) # Defines additional similar variables: include (LoadVersion) LoadVersion (VERSION_CURRENT MONGOC) # Extended version attributes that CMake doesn't (yet) understand, which include # the prerelease tag. Named here to match the variables generated by project() set(mongo-c-driver_VERSION_PRERELEASE ${MONGOC_PRERELEASE_VERSION}) set(mongo-c-driver_VERSION_FULL ${MONGOC_VERSION}) include(FeatureSummary) include (MongoSettings) include (MongoPlatform) include (GeneratePkgConfig) include (VerifyHeaders) # Subcomponents: mongo_bool_setting(ENABLE_MONGOC "Enable the build of libmongoc libraries (The MongoDB C database driver)") mongo_bool_setting( USE_SYSTEM_LIBBSON [[Use an existing libbson library (via find_package()) instead of building one from source]] DEFAULT VALUE OFF ADVANCED ) # Deprecated option "ENABLE_BSON" is gone, but old caches may rely on SYSTEM to # disable the libbson build. Allow ENABLE_BSON=SYSTEM only if USE_SYSTEM_LIBBSON # is also true, to allow both ENABLE_BSON=SYSTEM and USE_SYSTEM_LIBBSON=TRUE to # simplify downstream build scripts if(ENABLE_BSON STREQUAL "SYSTEM" AND NOT USE_SYSTEM_LIBBSON) # User set ENABLE_BSON=SYSTEM, so they intend for us to build against an external # libbson, but they didn't set USE_SYSTEM_LIBBSON=ON, so they are probably # unaware of this change. Rather than miscompile, stop what we're doing: message(FATAL_ERROR "ENABLE_BSON=SYSTEM is no longer supported. Use USE_SYSTEM_LIBBSON=ON for the same effect.") endif() # Toggle static libraries: mongo_setting( ENABLE_STATIC "Enable building and installing static library archive artifacts" OPTIONS ON OFF BUILD_ONLY DEFAULT VALUE "ON" ) # Toggle dynamic libraries: mongo_bool_setting(ENABLE_SHARED "Enable building and installing dynamic library artifacts") # Toggle PIC if(NOT WIN32) mongo_bool_setting(ENABLE_PIC "Enable position-independent code when building static libraries (Not applicable on Windows)") elseif(DEFINED ENABLE_PIC) # We are on Windows, and ENABLE_PIC is defined. message(STATUS "ENABLE_PIC=“${ENABLE_PIC}” has no effect on Windows (All Windows code is position-independent)") else() # We are on Windows, and ENABLE_PIC is not defined, which is normal endif() # Dev mode checks: mongo_bool_setting( ENABLE_MAINTAINER_FLAGS "Enable stricter build-time checks" DEFAULT VALUE OFF DEVEL EVAL [[ if(MSVC) set(DEFAULT OFF) else() set(DEFAULT ON) endif() ]]) # Toggle instrumentation: mongo_bool_setting(ENABLE_TRACING "Enable runtime tracing output in the built libmongoc (Very noisy!)" DEFAULT VALUE OFF) mongo_bool_setting(ENABLE_COVERAGE "Build code with coverage instrumentation" DEFAULT VALUE OFF DEVEL VALUE ON) mongo_bool_setting(ENABLE_DEBUG_ASSERTIONS "Build library with runtime debug assertions enabled" DEFAULT VALUE OFF DEVEL VALUE ON) # for MONGO_SANITIZE: include(Sanitizers) # Toggle optional components: mongo_bool_setting(ENABLE_TESTS "Enable building MongoDB C Driver tests") mongo_bool_setting(ENABLE_EXAMPLES "Enable building MongoDB C Driver examples") mongo_bool_setting(ENABLE_MAN_PAGES "Enable building the manual pages" DEFAULT VALUE OFF) mongo_bool_setting(ENABLE_HTML_DOCS "Enable building the HTML documentation" DEFAULT VALUE OFF) mongo_bool_setting(ENABLE_UNINSTALL "Generate an 'uninstall' script and an 'uninstall' build target") mongo_bool_setting(ENABLE_SRV "Enable support for mongodb+srv URIs.") # Optional features that are ENABLED when necessary dependencies are found: mongo_setting(ENABLE_SNAPPY "Enable Snappy compression support" OPTIONS ON OFF AUTO DEFAULT VALUE AUTO) mongo_setting(ENABLE_ZSTD "Enable zstd compression support" OPTIONS ON OFF AUTO DEFAULT VALUE AUTO) mongo_setting(ENABLE_ZLIB "Enable zlib compression support" OPTIONS BUNDLED SYSTEM OFF DEFAULT VALUE BUNDLED) mongo_bool_setting(USE_BUNDLED_UTF8PROC "Enable building with utf8proc. Needed for SCRAM-SHA-256 authentication with non-ASCII passwords" ADVANCED) mongo_setting( ENABLE_SSL [[Enable TLS connection and SCRAM authentication.]] OPTIONS WINDOWS DARWIN OPENSSL OFF AUTO DEFAULT VALUE AUTO VALIDATE CODE [[ if(ENABLE_SSL STREQUAL "DARWIN" AND NOT APPLE) message(WARNING "ENABLE_SSL=DARWIN is only supported on Apple platforms") elseif(ENABLE_SSL STREQUAL "WINDOWS" AND NOT WIN32) message(WARNING "ENABLE_SSL=WINDOWS is only supported on Windows platforms") endif() ]] ) mongo_bool_setting( ENABLE_SHM_COUNTERS "Enable memory performance counters" DEFAULT EVAL [[ set(DEFAULT OFF) if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux" OR (APPLE AND CMAKE_SYSTEM_PROCESSOR MATCHES "arm64")) set(DEFAULT ON) endif() ]] VALIDATE CODE [[ if(ENABLE_SHM_COUNTERS AND NOT CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux" AND NOT (APPLE AND CMAKE_SYSTEM_PROCESSOR MATCHES "arm64")) message(WARNING "ENABLE_SHM_COUNTERS=ON is only supported on Linux or ARM Darwin") endif() ]] ) mongo_setting( ENABLE_SASL "Enable SASL authentication (Kerberos)" OPTIONS CYRUS SSPI OFF AUTO DEFAULT VALUE AUTO VALIDATE CODE [[ if(ENABLE_SASL STREQUAL "SSPI" AND NOT WIN32) message(WARNING "ENABLE_SASL=SSPI is only supported on Windows platforms") endif() if(ENABLE_SASL STREQUAL "CYRUS" AND WIN32) message(WARNING "ENABLE_SASL=CYRUS on Windows platforms is unsupported. Use ENABLE_SASL=SSPI or ENABLE_SASL=OFF instead") endif() ]] ) mongo_setting(ENABLE_CLIENT_SIDE_ENCRYPTION "Enable In-Use Encryption support. Requires additional support libraries." OPTIONS ON OFF AUTO DEFAULT VALUE AUTO) mongo_setting(ENABLE_MONGODB_AWS_AUTH "Enable support for the MONGODB-AWS authentication mechanism" OPTIONS ON OFF AUTO DEFAULT VALUE AUTO VALIDATE CODE [[ if(NOT ENABLE_MONGODB_AWS_AUTH STREQUAL "ON") return() endif() if(MSVC AND MSVC_VERSION LESS 1900) message(FATAL_ERROR "Visual Studio 2015 or newer is required for ENABLE_MONGODB_AWS_AUTH=ON") elseif(ENABLE_SSL STREQUAL "OFF") message(FATAL_ERROR "ENABLE_MONGODB_AWS_AUTH=ON requires that ENABLE_SSL not be 'OFF'") endif() ]]) # Optional features that are DISABLED by default: mongo_bool_setting(ENABLE_RDTSCP "Enable fast performance counters using the Intel RDTSCP instruction" DEFAULT VALUE OFF) mongo_bool_setting( ENABLE_CRYPTO_SYSTEM_PROFILE "Use system crypto profile" DEFAULT VALUE OFF VALIDATE CODE [[ if(ENABLE_CRYPTO_SYSTEM_PROFILE AND NOT ENABLE_SSL STREQUAL "OPENSSL") message(WARNING "ENABLE_CRYPTO_SYSTEM_PROFILE=TRUE is only applicable when ENABLE_SSL=OPENSSL") endif() ]] ) # Announce the build configuration. Used by `mlib_build_config_is()` in `mlib/config.h` add_compile_definitions(_MLIB_BUILD_CONFIG=$) if(ENABLE_COVERAGE) mongo_platform_link_options(--coverage) mongo_platform_compile_options($) endif() # Enable multi-threading: set(THREADS_PREFER_PTHREAD_FLAG TRUE) find_package(Threads REQUIRED) mongo_platform_use_target(Threads::Threads) set_property(DIRECTORY APPEND PROPERTY pkg_config_LIBS ${CMAKE_THREAD_LIBS_INIT}) if(WIN32) # Required for gethostbyname on Windows: mongo_platform_link_libraries(ws2_32) endif() # librt needed on linux for clock_gettime find_library(RT_LIBRARY rt PATHS /usr/lib32) if(RT_LIBRARY) mongo_platform_link_libraries(${RT_LIBRARY}) # Set required libraries for CHECK_FUNCTION_EXISTS list(APPEND CMAKE_REQUIRED_LIBRARIES "${RT_LIBRARY}") # Export the rt linkage as a pkg-config property: get_filename_component(rt_dir "${RT_LIBRARY}" DIRECTORY) set_property(DIRECTORY APPEND PROPERTY pkg_config_LIBS "-L${rt_dir}" -lrt) endif() # On macOS Big Sur, libm resolves to the SDK's tbd file, like: # /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib/libm.tbd # Not all consumers can easily link to a tbd file (notably golang will reject a tbd suffix by default) # macOS includes libm as part of libSystem (along with libc). # It does not need to be explicitly linked. if(NOT APPLE) find_library(M_LIBRARY m) if(M_LIBRARY) mongo_platform_link_libraries(${M_LIBRARY}) endif() endif() # Check for an optional C++ compiler. Result included in handshake metadata. Enables optional C++-specific tests. include (CheckLanguage) check_language (CXX) if (CMAKE_CXX_COMPILER) enable_language (CXX) if (NOT CMAKE_CXX_STANDARD) # Default to C++11 for purposes of testing. set (CMAKE_CXX_STANDARD 11) endif () else () message (STATUS "No CXX support") endif () if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) set (CMAKE_BUILD_TYPE "RelWithDebInfo") message ( STATUS "No CMAKE_BUILD_TYPE selected, defaulting to ${CMAKE_BUILD_TYPE}" ) endif () include (InstallRequiredSystemLibraries) include (CMakeDependentOption) # Installation paths include (GNUInstallDirs) # The directory where CMake config packages will be installed, based on the libdir from GNUInstallDirs mongo_setting( MONGO_C_DRIVER_INSTALL_CMAKEDIR "The directory in which CMake package files will be installed" TYPE STRING DEFAULT VALUE "${CMAKE_INSTALL_LIBDIR}/cmake" VALIDATE CODE [[ if(IS_ABSOLUTE "${MONGO_C_DRIVER_INSTALL_CMAKEDIR}") message(SEND_ERROR "The CMake installation directory must be a relative path (Got “${MONGO_C_DRIVER_INSTALL_CMAKEDIR}”)") endif() ]] ) include(MongoC-Warnings) # Enable "maintainer flags," which are supplementary but not mandatory. # (As opposed to MongoC-Warnings.cmake, which defines "the code is broken" warnings) if(ENABLE_MAINTAINER_FLAGS) mongoc_add_warning_options( gnu-like:-Werror gnu-like:-pedantic gnu-like:-Wall gnu-like:-Wempty-body gnu:not-gcc-lt7:-Wexpansion-to-defined gnu-like:-Winit-self gnu-like:-Wmissing-include-dirs gnu-like:-Wredundant-decls gnu-like:-Wshadow gnu-like:lang-c:-Wstrict-prototypes gnu-like:-Wswitch-default gnu-like:-Wswitch-enum gnu-like:-Wundef gnu-like:-Wuninitialized # Disabled, for now: gnu-like:-Wno-strict-aliasing # Sign-comparison-mismatch: gnu-like:-Wsign-compare msvc:/we4018 ) endif() # Link with LLD, if possible if (NOT MSVC) include (LLDLinker) endif () if ( (ENABLE_BUILD_DEPENDECIES STREQUAL OFF) AND (NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) ) set (ENABLE_BUILD_DEPENDECIES ON) endif () mongo_pick(MONGOC_ENABLE_RDTSCP 1 0 ENABLE_RDTSCP) mongo_pick(MONGOC_ENABLE_STATIC_BUILD 1 0 ENABLE_STATIC) mongo_pick(MONGOC_ENABLE_STATIC_INSTALL 1 0 [[ENABLE_STATIC AND NOT ENABLE_STATIC STREQUAL "BUILD_ONLY"]]) if (USE_SYSTEM_LIBBSON) find_package (bson "${PROJECT_VERSION}" REQUIRED) # Disable test-libmongoc since we are using a system libbson set (ENABLE_TESTS OFF) set (USING_SYSTEM_BSON TRUE) if (NOT TARGET bson::shared) message (FATAL_ERROR "System libbson built without shared library target") endif () if (NOT TARGET bson::static) message (FATAL_ERROR "System libbson built without static library target") endif () endif () set (BUILD_SOURCE_DIR ${CMAKE_BINARY_DIR}) # Enable CTest include (CTest) if (BUILD_TESTING) include (TestFixtures) include (src/libmongoc/tests/import-tests.cmake) endif () # Ensure the default behavior: don't ignore RPATH settings. set (CMAKE_SKIP_BUILD_RPATH OFF) # Ensure the default behavior: don't use the final install destination as the # temporary RPATH for executables (ensure we can run tests and programs from # the build directory). set (CMAKE_BUILD_WITH_INSTALL_RPATH OFF) # Include any custom library paths in the final RPATH. set (CMAKE_INSTALL_RPATH_USE_LINK_PATH ON) # Install libs with names like @rpath/libfoo.dylib, not bare names. set (CMAKE_MACOSX_RPATH ON) # Distinguish DLL import libs with a .dll.lib suffix. Also prevents filename collisions # between static libraries and the import libraries if(WIN32) set (CMAKE_IMPORT_LIBRARY_SUFFIX .dll.lib) endif() # By default, ensure conformance with a minimum C standard. # Required extensions to the language (i.e. POSIX) are (re)enabled further below. if (NOT DEFINED CMAKE_C_STANDARD) set (CMAKE_C_STANDARD 99) endif () if (NOT DEFINED CMAKE_C_STANDARD_REQUIRED) set (CMAKE_C_STANDARD_REQUIRED ON) endif () if (NOT DEFINED CMAKE_C_EXTENSIONS) set (CMAKE_C_EXTENSIONS OFF) endif () # https://man7.org/linux/man-pages/man7/feature_test_macros.7.html # https://pubs.opengroup.org/onlinepubs/7908799/xsh/compilation.html # Enable POSIX features up to POSIX.1-2008 plus the XSI extension and BSD-derived definitions. # Both _BSD_SOURCE and _DEFAULT_SOURCE are defined for backwards-compatibility with glibc 2.19 and earlier. # _BSD_SOURCE and _DEFAULT_SOURCE are required by `getpagesize`, `h_errno`, etc. # _XOPEN_SOURCE=700 is required by `strnlen`, `strerror_l`, etc. add_definitions (-D_XOPEN_SOURCE=700 -D_BSD_SOURCE -D_DEFAULT_SOURCE) list (APPEND CMAKE_REQUIRED_DEFINITIONS -D_XOPEN_SOURCE=700 -D_BSD_SOURCE -D_DEFAULT_SOURCE) # Enable non-standard features on FreeBSD with __BSD_VISIBLE=1 if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD") add_definitions (-D__BSD_VISIBLE=1) list (APPEND CMAKE_REQUIRED_DEFINITIONS -D__BSD_VISIBLE=1) endif () # https://opensource.apple.com/source/Libc/Libc-1439.40.11/gen/compat.5.auto.html # Non-POSIX extensions are required by `_SC_NPROCESSORS_ONLN`. if (CMAKE_SYSTEM_NAME MATCHES "Darwin") add_definitions (-D_DARWIN_C_SOURCE) list (APPEND CMAKE_REQUIRED_DEFINITIONS -D_DARWIN_C_SOURCE) endif () # Convenience targets to build all tests or all examples. add_custom_target(mongo_c_driver_tests) add_custom_target(mongo_c_driver_examples) add_subdirectory (src/common) if (NOT USING_SYSTEM_BSON) message (STATUS "Using bundled libbson") add_subdirectory (src/libbson) endif () if (MSVC) add_definitions (-D_CRT_SECURE_NO_WARNINGS) list (APPEND CMAKE_REQUIRED_DEFINITIONS -D_CRT_SECURE_NO_WARNINGS) endif () if (ENABLE_MONGOC) if (ENABLE_TESTS AND NOT MONGOC_ENABLE_STATIC_BUILD) message (FATAL_ERROR "ENABLE_TESTS requires ENABLE_STATIC or ENABLE_STATIC_BUILD") endif () set (CPACK_RESOURCE_FILE_LICENSE "${mongo-c-driver_SOURCE_DIR}/COPYING") include (CPack) # Ensure the default behavior: don't ignore RPATH settings. set (CMAKE_SKIP_BUILD_RPATH OFF) if (NOT ENABLE_MONGODB_AWS_AUTH MATCHES "ON|OFF|AUTO") message (FATAL_ERROR "ENABLE_MONGODB_AWS_AUTH option must be ON, AUTO, or OFF") endif () set (MONGOC_ENABLE_MONGODB_AWS_AUTH 0) if (ENABLE_MONGODB_AWS_AUTH STREQUAL "AUTO") if (MSVC AND MSVC_VERSION LESS 1900) message (WARNING "MS Visual Studio too old for ENABLE_MONGODB_AWS_AUTH") elseif (NOT ENABLE_SSL) message (WARNING "Option ENABLE_MONGODB_AWS_AUTH requires ENABLE_SSL not set to OFF" ) else () set (MONGOC_ENABLE_MONGODB_AWS_AUTH 1) endif () elseif (ENABLE_MONGODB_AWS_AUTH) if (MSVC AND MSVC_VERSION LESS 1900) message (FATAL_ERROR "Use Visual Studio 2015 or higher for ENABLE_MONGODB_AWS_AUTH") endif () if (NOT ENABLE_SSL) message (FATAL_ERROR "Option ENABLE_MONGODB_AWS_AUTH requires ENABLE_SSL not set to OFF" ) endif () set (MONGOC_ENABLE_MONGODB_AWS_AUTH 1) endif () add_subdirectory (src/libmongoc) if (MONGOC_ENABLE_MONGODB_AWS_AUTH) message (STATUS "Building with MONGODB-AWS auth support") endif () if (ENABLE_MAN_PAGES STREQUAL ON OR ENABLE_HTML_DOCS STREQUAL ON) find_package (Sphinx REQUIRED) add_custom_target (doc ALL DEPENDS $<$>:bson-doc> $<$:mongoc-doc> ) endif () # sub-directory 'doc' was already included above add_subdirectory (src) # 'src/libbson' was already included, so 'src' will not include it directly # 'src/kms-message' was already included if appropriate # 'src/libmongoc' was already included, so 'src' will not include it directly endif () install (FILES COPYING NEWS README.rst THIRD_PARTY_NOTICES DESTINATION ${CMAKE_INSTALL_DATADIR}/mongo-c-driver/${PROJECT_VERSION} ) if (ENABLE_UNINSTALL) # Create uninstall program and associated uninstall target # # This needs to be last (after all other add_subdirectory calls) to ensure that # the generated uninstall program is complete and correct if (NOT ENABLE_MONGOC) # Generate a different script name for uninstalling libbson only: set (UNINSTALL_SCRIPT_NAME "uninstall-bson") endif () set (UNINSTALL_PROG_DIR "${CMAKE_INSTALL_DATADIR}/mongo-c-driver/${PROJECT_VERSION}") include (GenerateUninstaller) endif () # Spit out some information regarding the generated build system message (STATUS "Build files generated for:") message (STATUS "\tbuild system: ${CMAKE_GENERATOR}") if (CMAKE_GENERATOR_INSTANCE) message (STATUS "\tinstance: ${CMAKE_GENERATOR_INSTANCE}") endif () if (CMAKE_GENERATOR_PLATFORM) message (STATUS "\tinstance: ${CMAKE_GENERATOR_PLATFORM}") endif () if (CMAKE_GENERATOR_TOOLSET) message (STATUS "\tinstance: ${CMAKE_GENERATOR_TOOLSET}") endif () if (TARGET test-libmongoc) # Generate a file that can be included by CTest to load and enumerate all of the # tests defined by the test-libmongoc executable. Generate one for each # configuration in case of multiconf generators. string (CONFIGURE [=[ set (TEST_LIBMONGOC_EXE [[$]]) set (SRC_ROOT [[@PROJECT_SOURCE_DIR@]]) set (IS_MULTICONF $) if (NOT IS_MULTICONF OR CTEST_CONFIGURATION_TYPE STREQUAL "$") # We are not in multi-conf, or the current config matches our config. include ("${SRC_ROOT}/build/cmake/LoadTests.cmake") elseif (NOT CTEST_CONFIGURATION_TYPE) # We are in multi-conf, but no '-C' config was specified message (WARNING "Specify a --build-config when using CTest with a multi-config build") else () # Do nothing. Not our config. endif () ]=] code @ONLY) file (GENERATE OUTPUT "${PROJECT_BINARY_DIR}/LoadTests-$.cmake" CONTENT "${code}") if (CMAKE_CONFIGURATION_TYPES) foreach (conf IN LISTS CMAKE_CONFIGURATION_TYPES) # Direct the generated CTest code to include() the file that loads the tests: set_property ( DIRECTORY APPEND PROPERTY TEST_INCLUDE_FILES "${PROJECT_BINARY_DIR}/LoadTests-${conf}.cmake") endforeach () else () set_property ( DIRECTORY APPEND PROPERTY TEST_INCLUDE_FILES "${PROJECT_BINARY_DIR}/LoadTests-${CMAKE_BUILD_TYPE}.cmake") endif () endif () if (CMAKE_GENERATOR STREQUAL "Ninja Multi-Config" AND PROJECT_IS_TOP_LEVEL) set (CMAKE_CROSS_CONFIGS "all") endif () feature_summary(WHAT ENABLED_FEATURES DISABLED_FEATURES)