# SPDX-License-Identifier: BSD-2-Clause # Copyright (c) 2021 NKI/AVL, Netherlands Cancer Institute # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. cmake_minimum_required(VERSION 3.23) cmake_policy(SET CMP0135 NEW) if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR AND NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE) set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") endif() # set the project name project( libcifpp VERSION 10.0.4 LANGUAGES CXX C) list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") include(FindAtomic) include(CMakePackageConfigHelpers) include(GenerateExportHeader) include(CTest) include(ExternalProject) include(FetchContent) include(VersionString) # When building with ninja-multiconfig, build both debug and release by default if(CMAKE_GENERATOR STREQUAL "Ninja Multi-Config") set(CMAKE_CROSS_CONFIGS "Debug;Release") set(CMAKE_DEFAULT_CONFIGS "Debug;Release") endif() if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers" ) elseif(MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4") endif() # Build documentation? set(BUILD_DOCUMENTATION OFF CACHE BOOL "Build the documentation") # Build examples? set(BUILD_EXAMPLES ON CACHE BOOL "Build the example applications") # Optionally build a version to be installed inside CCP4 set(BUILD_FOR_CCP4 OFF CACHE BOOL "Build a version to be installed in CCP4") # Create the cql/sqlite interface set(BUILD_SQLITE_INTERFACE ON CACHE BOOL "Build the sqlite interface") # Building shared libraries? if(NOT (BUILD_FOR_CCP4 AND WIN32)) set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build a shared library instead of a static one") endif() if(PROJECT_IS_TOP_LEVEL AND NOT BUILD_FOR_CCP4) # Lots of code depend on the availability of the components.cif file set(CIFPP_DOWNLOAD_CCD ON CACHE BOOL "Download the CCD file components.cif during installation") # An optional cron script can be installed to keep the data files up-to-date if(UNIX AND NOT APPLE) set(CIFPP_INSTALL_UPDATE_SCRIPT ON CACHE BOOL "Install the script to update CCD and dictionary files") endif() else() unset(CIFPP_DOWNLOAD_CCD) unset(CIFPP_INSTALL_UPDATE_SCRIPT) endif() # When CCP4 is sourced in the environment, we can recreate the symmetry # operations table if(EXISTS "$ENV{CCP4}/lib/data/syminfo.lib") set(CIFPP_RECREATE_SYMOP_DATA ON CACHE BOOL "Recreate SymOp data table in case it is out of date") endif() # CCP4 build if(BUILD_FOR_CCP4) if("$ENV{CCP4}" STREQUAL "" OR NOT EXISTS $ENV{CCP4}) message(FATAL_ERROR "cifpp: A CCP4 built was requested but CCP4 was not sourced") else() list(PREPEND CMAKE_MODULE_PATH "$ENV{CCP4}") list(PREPEND CMAKE_PREFIX_PATH "$ENV{CCP4}") set(CMAKE_INSTALL_PREFIX "$ENV{CCP4}") if(WIN32) set(BUILD_SHARED_LIBS ON) endif() endif() endif() # Now include the GNUInstallDirs module include(GNUInstallDirs) if(WIN32) if(${CMAKE_SYSTEM_VERSION} GREATER_EQUAL 10) # Windows 10 add_definitions(-D _WIN32_WINNT=0x0A00) elseif(${CMAKE_SYSTEM_VERSION} EQUAL 6.3) # Windows 8.1 add_definitions(-D _WIN32_WINNT=0x0603) elseif(${CMAKE_SYSTEM_VERSION} EQUAL 6.2) # Windows 8 add_definitions(-D _WIN32_WINNT=0x0602) elseif(${CMAKE_SYSTEM_VERSION} EQUAL 6.1) # Windows 7 add_definitions(-D _WIN32_WINNT=0x0601) elseif(${CMAKE_SYSTEM_VERSION} EQUAL 6.0) # Windows Vista add_definitions(-D _WIN32_WINNT=0x0600) else() # Windows XP (5.1) add_definitions(-D _WIN32_WINNT=0x0501) endif() # We do not want to write an export file for all our symbols... set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) endif() if(MSVC) # make msvc standards compliant... add_compile_options(/permissive- /bigobj) add_link_options(/NODEFAULTLIB:library) endif() # Libraries if(MSVC) # Avoid linking the shared library of zlib. Search ZLIB_ROOT first if it is # set. if(ZLIB_ROOT) set(_ZLIB_SEARCH_ROOT PATHS ${ZLIB_ROOT} NO_DEFAULT_PATH) list(APPEND _ZLIB_SEARCHES _ZLIB_SEARCH_ROOT) endif() # Normal search. set(_ZLIB_x86 "(x86)") set(_ZLIB_SEARCH_NORMAL PATHS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\Zlib;InstallPath]" "$ENV{ProgramFiles}/zlib" "$ENV{ProgramFiles${_ZLIB_x86}}/zlib") unset(_ZLIB_x86) list(APPEND _ZLIB_SEARCHES _ZLIB_SEARCH_NORMAL) if(BUILD_FOR_CCP4) list(PREPEND _ZLIB_SEARCHES "$ENV{CCP4}/lib") endif() foreach(search ${_ZLIB_SEARCHES}) find_library( ZLIB_LIBRARY NAMES zlibstatic NAMES_PER_DIR ${${search}} PATH_SUFFIXES lib) endforeach() endif() # Using fast_float for float parsing, but only if needed try_compile(STD_CHARCONV_COMPILING SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/test-charconv.cpp CXX_STANDARD 20 CXX_STANDARD_REQUIRED ON) if(NOT STD_CHARCONV_COMPILING) message(NOTICE "libcifpp: Using fast_float for std::from_chars") find_package(FastFloat 8.0 REQUIRED CONFIG) endif() find_package(Threads) find_package(ZLIB QUIET) if(NOT ZLIB_FOUND) message(FATAL_ERROR "cifpp: The zlib development files were not found you this system, please install them and try again (hint: on debian/ubuntu use apt-get install zlib1g-dev)") endif() include(FindPkgConfig) if(PKG_CONFIG_FOUND) pkg_check_modules(PCRE2 IMPORTED_TARGET libpcre2-8) endif() if(NOT PCRE2_FOUND) add_subdirectory(pcre2-simple) endif() # Using Eigen3 is a bit of a thing. We don't want to build it completely since # we only need a couple of header files. Nothing special. But often, eigen3 is # already installed and then we prefer that. find_package(Eigen3 3.4 QUIET) if(Eigen3_FOUND AND TARGET Eigen3::Eigen) get_target_property(EIGEN_INCLUDE_DIR Eigen3::Eigen INTERFACE_INCLUDE_DIRECTORIES) else() # Use ExternalProject since FetchContent always tries to install the result... ExternalProject_Add(my-eigen3 URL https://gitlab.com/libeigen/eigen/-/archive/3.4.0/eigen-3.4.0.zip DOWNLOAD_EXTRACT_TIMESTAMP TRUE CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "") ExternalProject_Get_Property(my-eigen3 SOURCE_DIR) set(EIGEN_INCLUDE_DIR ${SOURCE_DIR}) endif() # SymOp data table if(CIFPP_RECREATE_SYMOP_DATA) # The tool to create the table add_executable(symop-map-generator "${CMAKE_CURRENT_SOURCE_DIR}/src/symop-map-generator.cpp") target_compile_features(symop-map-generator PUBLIC cxx_std_20) add_custom_command( OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/src/symop_table_data.hpp COMMAND $ $ENV{CLIBD}/syminfo.lib $ENV{CLIBD}/symop.lib ${CMAKE_CURRENT_SOURCE_DIR}/src/symop_table_data.hpp) add_custom_target( OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/src/symop_table_data.hpp DEPENDS symop-map-generator "$ENV{CLIBD}/syminfo.lib" "$ENV{CLIBD}/symop.lib") endif() # Create a revision file, containing the current git version info write_version_header("${CMAKE_CURRENT_SOURCE_DIR}/src/" LIB_NAME "LibCIFPP") add_library(cifpp) add_library(cifpp::cifpp ALIAS cifpp) # Sources list(APPEND project_sources ${CMAKE_CURRENT_SOURCE_DIR}/src/category.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/condition.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/datablock.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/dictionary_parser.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/file.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/item.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/parser.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/row.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/validate.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/text.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/utilities.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/atom_type.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/compound.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/point.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/symmetry.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/model.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/pdb/cif2pdb.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/pdb/pdb2cif.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/pdb/pdb_record.hpp ${CMAKE_CURRENT_SOURCE_DIR}/src/pdb/pdb2cif_remark_3.hpp ${CMAKE_CURRENT_SOURCE_DIR}/src/pdb/pdb2cif_remark_3.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/pdb/reconstruct.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/pdb/validate-pdbx.cpp ) list(APPEND project_headers include/cif++.hpp include/cif++/cif++.hpp include/cif++/atom_type.hpp include/cif++/category.hpp include/cif++/compound.hpp include/cif++/condition.hpp include/cif++/datablock.hpp include/cif++/dictionary_parser.hpp include/cif++/exports.hpp include/cif++/file.hpp include/cif++/format.hpp include/cif++/gzio.hpp include/cif++/item.hpp include/cif++/iterator.hpp include/cif++/matrix.hpp include/cif++/model.hpp include/cif++/parser.hpp include/cif++/pdb.hpp include/cif++/point.hpp include/cif++/row.hpp include/cif++/symmetry.hpp include/cif++/text.hpp include/cif++/utilities.hpp include/cif++/validate.hpp ) if(BUILD_SQLITE_INTERFACE) find_package(SQLite3 QUIET) if(SQLite3_FOUND) target_link_libraries(cifpp PRIVATE SQLite::SQLite3) else() FetchContent_Populate(SQLite3 URL https://sqlite.org/2025/sqlite-amalgamation-3510100.zip URL_HASH SHA3_256=856b52ffe7383d779bb86a0ed1ddc19c41b0e5751fa14ce6312f27534e629b64 EXCLUDE_FROM_ALL) list(APPEND project_sources $/sqlite3.c) target_include_directories(cifpp PRIVATE $) endif() list(APPEND project_sources ${CMAKE_CURRENT_SOURCE_DIR}/src/cql.cpp) list(APPEND project_headers include/cif++/cql.hpp) endif() if(TARGET my-eigen3) add_dependencies(cifpp my-eigen3) endif() target_sources(cifpp PRIVATE ${project_sources} ${CMAKE_CURRENT_SOURCE_DIR}/src/symop_table_data.hpp PUBLIC FILE_SET cifpp_headers TYPE HEADERS BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include FILES ${project_headers} ) # The code now really requires C++20 target_compile_features(cifpp PUBLIC cxx_std_23) generate_export_header(cifpp EXPORT_FILE_NAME ${CMAKE_CURRENT_SOURCE_DIR}/include/cif++/exports.hpp) if(MSVC) target_compile_definitions(cifpp PUBLIC NOMINMAX=1) endif() set_target_properties(cifpp PROPERTIES POSITION_INDEPENDENT_CODE ON) target_include_directories( cifpp PUBLIC "$" "$" PRIVATE "${EIGEN_INCLUDE_DIR}") target_link_libraries(cifpp PUBLIC Threads::Threads ZLIB::ZLIB $<$:std::atomic>) if(PCRE2_FOUND) target_include_directories(cifpp PRIVATE ${PCRE2_INCLUDE_DIRS}) target_link_libraries(cifpp PRIVATE ${PCRE2_LINK_LIBRARIES}) else() target_link_libraries(cifpp PRIVATE $) endif() if(NOT STD_CHARCONV_COMPILING) get_target_property(FF_INC_DIR FastFloat::fast_float INTERFACE_INCLUDE_DIRECTORIES) target_include_directories(cifpp PRIVATE ${FF_INC_DIR}) target_compile_definitions(cifpp PRIVATE USE_FAST_FLOAT) endif() if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") target_link_options(cifpp PRIVATE -undefined dynamic_lookup) endif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") if(CIFPP_DOWNLOAD_CCD) # download the components.cif file from CCD set(COMPONENTS_CIF ${CMAKE_CURRENT_SOURCE_DIR}/rsrc/components.cif) if(EXISTS ${COMPONENTS_CIF}) file(SIZE ${COMPONENTS_CIF} CCD_FILE_SIZE) if(CCD_FILE_SIZE EQUAL 0) message(STATUS "cifpp: Removing empty ${COMPONENTS_CIF} file") file(REMOVE "${COMPONENTS_CIF}") endif() endif() if(NOT EXISTS ${COMPONENTS_CIF}) # Since the file(DOWNLOAD) command in cmake does not use compression, we try # to download the gzipped version and decompress it ourselves. find_program(GUNZIP gunzip) if(WIN32 OR GUNZIP STREQUAL "GUNZIP-NOTFOUND") file( DOWNLOAD https://files.wwpdb.org/pub/pdb/data/monomers/components.cif ${COMPONENTS_CIF} SHOW_PROGRESS STATUS CCD_FETCH_STATUS) else() if(NOT EXISTS "${COMPONENTS_CIF}.gz") file( DOWNLOAD https://files.wwpdb.org/pub/pdb/data/monomers/components.cif.gz ${COMPONENTS_CIF}.gz SHOW_PROGRESS STATUS CCD_FETCH_STATUS) endif() add_custom_command( OUTPUT ${COMPONENTS_CIF} COMMAND "${GUNZIP}" ${COMPONENTS_CIF}.gz WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/rsrc/) add_custom_target(COMPONENTS ALL DEPENDS ${COMPONENTS_CIF}) endif() # Do not continue if downloading went wrong list(POP_FRONT CCD_FETCH_STATUS CCD_FETCH_STATUS_CODE) if(CCD_FETCH_STATUS_CODE) message( FATAL_ERROR "cifpp: Error trying to download CCD file: ${CCD_FETCH_STATUS}") endif() endif() endif() # Installation directories if(BUILD_FOR_CCP4) set(CIFPP_DATA_DIR "$ENV{CCP4}/share/libcifpp" CACHE PATH "Directory where dictionary and other static data is stored") else() set(CIFPP_DATA_DIR "${CMAKE_INSTALL_FULL_DATADIR}/libcifpp" CACHE PATH "Directory where dictionary and other static data is stored") endif() if(CIFPP_DATA_DIR) target_compile_definitions(cifpp PUBLIC DATA_DIR="${CIFPP_DATA_DIR}") set_target_properties(cifpp PROPERTIES CIFPP_DATA_DIR ${CIFPP_DATA_DIR}) endif() if(NOT PROJECT_IS_TOP_LEVEL) set(CIFPP_SHARE_DIR ${CIFPP_DATA_DIR} PARENT_SCOPE) endif() if(UNIX AND NOT BUILD_FOR_CCP4) if("${CMAKE_INSTALL_PREFIX}" STREQUAL "/usr/local") set(CIFPP_CACHE_DIR "/var/cache/libcifpp" CACHE PATH "The directory where downloaded data files are stored") else() set(CIFPP_CACHE_DIR "${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/cache/libcifpp" CACHE PATH "The directory where downloaded data files are stored") endif() target_compile_definitions(cifpp PUBLIC CACHE_DIR="${CIFPP_CACHE_DIR}") set(CIFPP_ETC_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}" CACHE PATH "The directory where the update configuration file is stored") else() unset(CIFPP_CACHE_DIR) endif() # Install rules install(TARGETS cifpp EXPORT cifpp FILE_SET cifpp_headers DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) if(MSVC AND BUILD_SHARED_LIBS) install( FILES $ DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL) endif() # Clean up old config files (with old names) file(GLOB OLD_CONFIG_FILES ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/cifpp/cifppConfig*.cmake ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/cifpp/cifppTargets*.cmake) if(OLD_CONFIG_FILES) message( STATUS "cifpp: Installation will remove old config files: ${OLD_CONFIG_FILES}") install(CODE "file(REMOVE ${OLD_CONFIG_FILES})") endif() install(EXPORT cifpp NAMESPACE cifpp:: FILE "cifpp-targets.cmake" DESTINATION lib/cmake/cifpp) install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/rsrc/mmcif_ddl.dic ${CMAKE_CURRENT_SOURCE_DIR}/rsrc/mmcif_pdbx.dic ${CMAKE_CURRENT_SOURCE_DIR}/rsrc/mmcif_ma.dic DESTINATION ${CMAKE_INSTALL_DATADIR}/libcifpp) if(CIFPP_DATA_DIR AND CIFPP_DOWNLOAD_CCD) install(FILES ${COMPONENTS_CIF} DESTINATION ${CMAKE_INSTALL_DATADIR}/libcifpp) endif() set(CONFIG_TEMPLATE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cifpp-config.cmake.in) configure_package_config_file( ${CONFIG_TEMPLATE_FILE} ${CMAKE_CURRENT_BINARY_DIR}/cifpp/cifpp-config.cmake INSTALL_DESTINATION lib/cmake/cifpp PATH_VARS CIFPP_DATA_DIR) install( FILES "${CMAKE_CURRENT_BINARY_DIR}/cifpp/cifpp-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/cifpp/cifpp-config-version.cmake" DESTINATION lib/cmake/cifpp) set_target_properties( cifpp PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}" INTERFACE_cifpp_MAJOR_VERSION ${PROJECT_VERSION_MAJOR}) set_property( TARGET cifpp APPEND PROPERTY COMPATIBLE_INTERFACE_STRING cifpp_MAJOR_VERSION) write_basic_package_version_file( "${CMAKE_CURRENT_BINARY_DIR}/cifpp/cifpp-config-version.cmake" VERSION ${PROJECT_VERSION} COMPATIBILITY AnyNewerVersion) if(BUILD_TESTING AND PROJECT_IS_TOP_LEVEL) add_subdirectory(test) endif() # Optionally install the update scripts for CCD and dictionary files if(CIFPP_INSTALL_UPDATE_SCRIPT) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/tools/update-libcifpp-data.in update-libcifpp-data @ONLY) if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR ${CMAKE_SYSTEM_NAME} STREQUAL "GNU" OR ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") install( FILES ${CMAKE_CURRENT_BINARY_DIR}/update-libcifpp-data DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/cron.weekly PERMISSIONS OWNER_EXECUTE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ) else() message(FATAL_ERROR "cifpp: Don't know where to install the update script") endif() # a config file, to make it complete # install(DIRECTORY DESTINATION "${CMAKE_INSTALL_LOCALSTATEDIR}/libcifpp") if(NOT EXISTS "${CMAKE_INSTALL_SYSCONFDIR}/libcifpp.conf") file( WRITE ${CMAKE_CURRENT_BINARY_DIR}/libcifpp.conf [[# Uncomment the next line to enable automatic updates # update=true ]]) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libcifpp.conf DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}) install( CODE "message(\"cifpp: A configuration file has been written to ${CIFPP_ETC_DIR}/libcifpp.conf, please edit this file to enable automatic updates\")" ) install(DIRECTORY DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/libcifpp/cache-update.d) endif() target_compile_definitions(cifpp PUBLIC CACHE_DIR="${CIFPP_CACHE_DIR}") endif() if(BUILD_DOCUMENTATION) add_subdirectory(docs) endif() if(BUILD_EXAMPLES) add_subdirectory(examples) endif()