cmake_minimum_required(VERSION 3.14) # For ARCH_INDEPENDENT in write_basic_package_version_file # Project declaration project( dynamic_bitset VERSION 1.3.2 DESCRIPTION "Simple Useful Libraries: C++17/20 header-only dynamic bitset" HOMEPAGE_URL "https://github.com/pinam45/dynamic_bitset" LANGUAGES CXX ) # Check if dynamic_bitset is being used directly or via add_subdirectory get_directory_property(HAS_PARENT PARENT_DIRECTORY) if(HAS_PARENT) set(DYNAMICBITSET_TOPLEVEL_PROJECT OFF) else() set(DYNAMICBITSET_TOPLEVEL_PROJECT ON) endif() # Options include(CMakeDependentOption) option( DYNAMICBITSET_NO_NAMESPACE "Put the dynamic_bitset class in the global namespace instead of the sul namespace (not recommended)" OFF ) option( DYNAMICBITSET_USE_LIBPOPCNT "Enable using (if available) libpopcnt for bits counting operations" ON ) cmake_dependent_option( DYNAMICBITSET_USE_LIBPOPCNT_SUBMODULE "Enable adding libpopcnt submodule to include paths (disable if your project already include libpopcnt)" ON "DYNAMICBITSET_USE_LIBPOPCNT" OFF ) option( DYNAMICBITSET_USE_STD_BITOPS "Enable using (if available) C++20 binary operations from the bit header" ON ) option( DYNAMICBITSET_USE_COMPILER_BUILTIN "Enable using (if available) compiler builtins (if using C++20 binary operations is disabled or not possible)" ON ) option( DYNAMICBITSET_BUILD_EXAMPLE "Enable building example for dynamic_bitset" ${DYNAMICBITSET_TOPLEVEL_PROJECT} ) option( DYNAMICBITSET_BUILD_TESTS "Enable building tests for dynamic_bitset" ${DYNAMICBITSET_TOPLEVEL_PROJECT} ) option( DYNAMICBITSET_BUILD_DOCS "Enable building documentation for dynamic_bitset" ${DYNAMICBITSET_TOPLEVEL_PROJECT} ) option( DYNAMICBITSET_FORMAT_TARGET "Enable generating a code formating target for dynamic_bitset" ${DYNAMICBITSET_TOPLEVEL_PROJECT} ) option( DYNAMICBITSET_HEADERS_TARGET_IDE "Enable generating a target with headers for ide for dynamic_bitset" ${DYNAMICBITSET_TOPLEVEL_PROJECT} ) option( DYNAMICBITSET_INSTALL "Enable installation for dynamic_bitset" ${DYNAMICBITSET_TOPLEVEL_PROJECT} ) cmake_dependent_option( DYNAMICBITSET_INSTALL_LIBPOPCNT_SUBMODULE "When installing dynamic_bitset, also install libpopcnt from submodule (if available)" ${DYNAMICBITSET_TOPLEVEL_PROJECT} "DYNAMICBITSET_INSTALL;DYNAMICBITSET_USE_LIBPOPCNT;DYNAMICBITSET_USE_LIBPOPCNT_SUBMODULE" OFF ) # Declare dynamic_bitset add_library(dynamic_bitset INTERFACE) add_library(sul::dynamic_bitset ALIAS dynamic_bitset) # If used via add_subdirectory, disable warnings on headers set(MAYBE_SYSTEM) if(NOT DYNAMICBITSET_TOPLEVEL_PROJECT) set(MAYBE_SYSTEM SYSTEM) endif() # Add includes target_include_directories( dynamic_bitset ${MAYBE_SYSTEM} INTERFACE "$" "$" ) # Put the dynamic_bitset class in the global namespace? if(DYNAMICBITSET_NO_NAMESPACE) target_compile_definitions(dynamic_bitset INTERFACE DYNAMIC_BITSET_NO_NAMESPACE) endif() # Set minimum required standard target_compile_features(dynamic_bitset INTERFACE cxx_std_17) # Use libpopcnt? if(DYNAMICBITSET_USE_LIBPOPCNT) message(STATUS "dynamic_bitset: libpopcnt usage enabled") # Use the submodule of the git repository? if(DYNAMICBITSET_USE_LIBPOPCNT_SUBMODULE) get_filename_component(LIBPOPCNT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/extlibs/libpopcnt/libpopcnt.h" ABSOLUTE) if(EXISTS "${LIBPOPCNT_PATH}") message(STATUS "dynamic_bitset: libpopcnt submodule is present and will be used") target_include_directories( dynamic_bitset SYSTEM INTERFACE "$" ) else() message(WARNING "dynamic_bitset: libpopcnt submodule is missing and won't be used, maybe you didn't pull the git submodules") set(DYNAMICBITSET_USE_LIBPOPCNT_SUBMODULE OFF) endif() else() message(STATUS "dynamic_bitset: libpopcnt submodule won't be used") endif() else() target_compile_definitions(dynamic_bitset INTERFACE DYNAMIC_BITSET_NO_LIBPOPCNT) message(STATUS "dynamic_bitset: libpopcnt usage disabled") endif() # Use C++20 binary operations? if(DYNAMICBITSET_USE_STD_BITOPS) message(STATUS "dynamic_bitset: C++20 binary operations usage enabled") else() target_compile_definitions(dynamic_bitset INTERFACE DYNAMIC_BITSET_NO_STD_BITOPS) message(STATUS "dynamic_bitset: C++20 binary operations usage disabled") endif() # Use compiler builtins? if(DYNAMICBITSET_USE_COMPILER_BUILTIN) message(STATUS "dynamic_bitset: compiler builtins usage enabled") else() target_compile_definitions(dynamic_bitset INTERFACE DYNAMIC_BITSET_NO_COMPILER_BUILTIN) message(STATUS "dynamic_bitset: compiler builtins usage disabled") endif() # Global config if top level project if(DYNAMICBITSET_TOPLEVEL_PROJECT) # Disable sources modifications set(CMAKE_DISABLE_SOURCE_CHANGES ON) set(CMAKE_DISABLE_IN_SOURCE_BUILD ON) # Strict C++ standard set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) # IDE folders set_property(GLOBAL PROPERTY USE_FOLDERS ON) set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "_CMake") # Flags include(cmake/flags.cmake) endif() # Create Headers target for IDE? if(DYNAMICBITSET_HEADERS_TARGET_IDE) add_custom_target(dynamic_bitset_headers_for_ide SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/include/sul/dynamic_bitset.hpp") source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" FILES "${CMAKE_CURRENT_SOURCE_DIR}/include/sul/dynamic_bitset.hpp") set_target_properties(dynamic_bitset_headers_for_ide PROPERTIES FOLDER "dynamic_bitset") endif() # Generate format target? if(DYNAMICBITSET_FORMAT_TARGET) find_program(CLANG_FORMAT clang-format) if(${CLANG_FORMAT} STREQUAL CLANG_FORMAT-NOTFOUND) message(WARNING "clang-format not found, format targets not generated") set(DYNAMICBITSET_FORMAT_TARGET OFF) else() message(STATUS "clang-format found: ${CLANG_FORMAT}") add_custom_target( format-dynamic_bitset COMMAND "${CLANG_FORMAT}" -style=file -i "${CMAKE_CURRENT_SOURCE_DIR}/include/sul/dynamic_bitset.hpp" WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" VERBATIM ) set_target_properties(format-dynamic_bitset PROPERTIES FOLDER "dynamic_bitset/format") endif() endif() # Build example? if(DYNAMICBITSET_BUILD_EXAMPLE) add_subdirectory(example) # Set example as startup project for Visual Studio set_property( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT dynamic_bitset_example ) endif() # Build tests? if(DYNAMICBITSET_BUILD_TESTS) enable_testing() # Catch2 get_filename_component(CATCH2_CMAKELISTS_PATH "${CMAKE_CURRENT_SOURCE_DIR}/extlibs/Catch2/CMakeLists.txt" ABSOLUTE) if(NOT EXISTS "${CATCH2_CMAKELISTS_PATH}") message(FATAL_ERROR "Catch2 dependency is missing, maybe you didn't pull the git submodules") endif() if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.25) add_subdirectory(extlibs/Catch2 SYSTEM) else() add_subdirectory(extlibs/Catch2) endif() include(extlibs/Catch2/extras/Catch.cmake) # Disable warnings on Catch2 headers get_target_property(Catch2_include_directories Catch2 INTERFACE_INCLUDE_DIRECTORIES) set_target_properties(Catch2 PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "") target_include_directories(Catch2 SYSTEM INTERFACE ${Catch2_include_directories}) # Tests add_subdirectory(tests) endif() # Build documentation? if(DYNAMICBITSET_BUILD_DOCS) add_subdirectory(docs) endif() # Install the cmake if(DYNAMICBITSET_INSTALL) include(GNUInstallDirs) include(CMakePackageConfigHelpers) install( TARGETS dynamic_bitset EXPORT sul ) # do not use PUBLIC_HEADER property, it flatten include sub-folder, directly install includes install( DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) if(DYNAMICBITSET_INSTALL_LIBPOPCNT_SUBMODULE) get_filename_component(LIBPOPCNT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/extlibs/libpopcnt/libpopcnt.h" ABSOLUTE) if(EXISTS "${LIBPOPCNT_PATH}") install( FILES "${LIBPOPCNT_PATH}" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) else() message(WARNING "dynamic_bitset: libpopcnt submodule is missing and can't be part of the install, maybe you didn't pull the git submodules") endif() endif() install( EXPORT sul DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/sul-dynamic_bitset NAMESPACE sul:: FILE sul-dynamic_bitset.cmake ) install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/sul-dynamic_bitset-config.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/sul-dynamic_bitset ) write_basic_package_version_file( ${CMAKE_CURRENT_BINARY_DIR}/sul-dynamic_bitset-config-version.cmake COMPATIBILITY SameMajorVersion ARCH_INDEPENDENT ) install( FILES ${CMAKE_CURRENT_BINARY_DIR}/sul-dynamic_bitset-config-version.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/sul-dynamic_bitset ) endif()