#=============================================================================== # CMake settings #=============================================================================== cmake_minimum_required(VERSION 3.22.1) project(dart) string(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UPPERCASE) # Use MACOSX_RPATH by default on OS X. This was added in CMake 2.8.12 and # became default in CMake 3.0. Explicitly setting this policy is necessary to # suppress a warning in CMake 3.0 and above. if(POLICY CMP0042) cmake_policy(SET CMP0042 NEW) endif() # Simplify variable reference and escape sequence evaluation. This was added in # CMake 3.1. Explicitly setting this policy is necessary to suppress a warning # in CMake 3.1 and above. if(POLICY CMP0053) cmake_policy(SET CMP0053 NEW) endif() # Use DART_SOURCE/BINARY_DIR instead of CMAKE_SOURCE/BINARY_DIR to support the # case that DART is built as a sub-project in another project. set(DART_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(DART_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) include(GNUInstallDirs) # Variables used in Components.cmake set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR}) set(LIBRARY_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}) set(CONFIG_INSTALL_DIR "${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake") # Set relative location to install additional documentation (sample data, # examples, and tutorials) set(DART_ADDITIONAL_DOCUMENTATION_INSTALL_PATH "${CMAKE_INSTALL_DATAROOTDIR}/doc/${PROJECT_NAME}" ) set(DART_EXAMPLES_INSTALL_PATH "${DART_ADDITIONAL_DOCUMENTATION_INSTALL_PATH}" CACHE PATH "Install destination (relative to CMAKE_INSTALL_PREFIX) for DART example sources. Set to an empty string to skip installing example sources." ) mark_as_advanced(DART_EXAMPLES_INSTALL_PATH) set(CMAKE_DEBUG_POSTFIX "d") set(CMAKE_MODULE_PATH "${DART_SOURCE_DIR}/cmake") include(dart_defs) include(compiler_cache) # Initialize CMake component helpers (now part of dart_defs.cmake) # Uses the following variables: # - LIBRARY_INSTALL_DIR # - CONFIG_INSTALL_DIR initialize_component_helpers(${PROJECT_NAME}) if(BUILD_SHARED_LIBS) set(DART_BUILD_SHARED_VALUE 1) else() set(DART_BUILD_SHARED_VALUE 0) endif() #=============================================================================== # Project settings #=============================================================================== # Extract version numbers from package.xml # Supports both release versions (X.Y.Z) and dev versions (X.Y.Z.devN) file(READ package.xml PACKAGE_XML) string( REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+(\\.(dev|alpha|beta|rc)[0-9]+)?" DIRTY_VERSION_STRING "${PACKAGE_XML}" ) # Remove tags to get clean version string string( REGEX REPLACE "^([0-9]+\\.[0-9]+\\.[0-9]+(\\.(dev|alpha|beta|rc)[0-9]+)?)$" "\\1" DART_VERSION_FULL "${DIRTY_VERSION_STRING}" ) # Extract numeric components string( REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)(\\.(dev|alpha|beta|rc)[0-9]+)?$" "\\1" DART_MAJOR_VERSION "${DART_VERSION_FULL}" ) string( REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)(\\.(dev|alpha|beta|rc)[0-9]+)?$" "\\2" DART_MINOR_VERSION "${DART_VERSION_FULL}" ) string( REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)(\\.(dev|alpha|beta|rc)[0-9]+)?$" "\\3" DART_PATCH_VERSION "${DART_VERSION_FULL}" ) # Extract suffix if present (e.g., "dev0" from "7.0.0.dev0") string( REGEX MATCH "\\.(dev|alpha|beta|rc)[0-9]+" DART_VERSION_SUFFIX "${DART_VERSION_FULL}" ) if(DART_VERSION_SUFFIX) string(SUBSTRING "${DART_VERSION_SUFFIX}" 1 -1 DART_VERSION_SUFFIX) # Remove leading dot else() set(DART_VERSION_SUFFIX "") endif() # DART_VERSION: Short version for CMake compatibility (X.Y.Z) set(DART_VERSION "${DART_MAJOR_VERSION}.${DART_MINOR_VERSION}.${DART_PATCH_VERSION}") # DART_VERSION_FULL: Complete version including suffix (X.Y.Z or X.Y.Z.devN) # Already set above set(DART_PKG_DESC "Dynamic Animation and Robotics Toolkit.") set(DART_PKG_EXTERNAL_DEPS "assimp, ccd, eigen3, fcl, octomap") set_property(GLOBAL PROPERTY DART_PKG_LINK_LIBS "") set_property(GLOBAL PROPERTY DART_PUBLIC_INCLUDE_DIRS "") set_property(GLOBAL PROPERTY DART_PUBLIC_SYSTEM_INCLUDE_DIRS "") set_property(GLOBAL PROPERTY DART_EXTRA_LINK_LIBS "") set_property(GLOBAL PROPERTY DART_EXTRA_COMPILE_OPTIONS "") function(_dart_pkgconfig_collect output_var) set(_converted "") set(_expect_framework FALSE) foreach(_lib IN LISTS ARGN) if(NOT _lib) continue() endif() if(_expect_framework) list(APPEND _converted "-framework" "${_lib}") set(_expect_framework FALSE) continue() endif() if(_lib STREQUAL "optimized" OR _lib STREQUAL "debug" OR _lib STREQUAL "general") continue() elseif(_lib STREQUAL "-framework") set(_expect_framework TRUE) continue() elseif(TARGET "${_lib}") get_target_property(_iface "${_lib}" INTERFACE_LINK_LIBRARIES) if(_iface) _dart_pkgconfig_collect(_nested ${_iface}) list(APPEND _converted ${_nested}) endif() get_target_property(_imported "${_lib}" IMPORTED_LOCATION) if(NOT _imported) get_target_property(_imported "${_lib}" IMPORTED_IMPLIB) endif() if(_imported) list(APPEND _converted "${_imported}") endif() elseif(_lib MATCHES "^-.*") list(APPEND _converted "${_lib}") elseif(IS_ABSOLUTE "${_lib}") list(APPEND _converted "${_lib}") else() list(APPEND _converted "-l${_lib}") endif() endforeach() set("${output_var}" "${_converted}" PARENT_SCOPE) endfunction() function(dart_pkgconfig_append_libraries) if(NOT ARGN) return() endif() _dart_pkgconfig_collect(_converted ${ARGN}) if(_converted) set_property(GLOBAL APPEND PROPERTY DART_PKG_LINK_LIBS ${_converted}) endif() endfunction() #=============================================================================== # Build options #=============================================================================== # Simulation-experimental options option(DART_EXPERIMENTAL_VERBOSE "Show detailed simulation-experimental dependency information" OFF) if(MSVC) set(DART_RUNTIME_LIBRARY "/MD" CACHE STRING "BaseName chosen by the user at CMake configure time") set_property(CACHE DART_RUNTIME_LIBRARY PROPERTY STRINGS /MD /MT) dart_option(DART_MSVC_DEFAULT_OPTIONS "Build DART with default Visual Studio options" OFF CATEGORY msvc) # Option to force /MD (Release runtime) for all configurations including Debug. # This is useful when linking against pre-built libraries (e.g., conda-forge packages) # that are built with /MD to avoid LNK2038 runtime library mismatch errors. # Default: ON (recommended for most users using package managers like conda/pixi) # Set to OFF if you're building all dependencies from source with matching runtime libraries. dart_option(DART_MSVC_FORCE_RELEASE_RUNTIME "Force /MD (Release DLL runtime) for all configurations to match pre-built packages (conda-forge, vcpkg, etc.)" ON CATEGORY msvc) if(DART_MSVC_FORCE_RELEASE_RUNTIME AND CMAKE_VERSION VERSION_GREATER_EQUAL "3.15") # Use modern CMake 3.15+ approach with CMAKE_MSVC_RUNTIME_LIBRARY # This sets /MD for all configurations (Debug, Release, RelWithDebInfo, MinSizeRel) set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDLL" CACHE STRING "MSVC runtime library - forced to /MD for all configs" FORCE) message(STATUS "DART_MSVC_FORCE_RELEASE_RUNTIME=ON: Using /MD for all configurations") message(STATUS " This avoids LNK2038 errors when linking pre-built packages built with /MD") message(STATUS " Set -DDART_MSVC_FORCE_RELEASE_RUNTIME=OFF if building all deps from source") endif() else() dart_option(BUILD_SHARED_LIBS "Build shared libraries" ON CATEGORY build) endif() dart_option(DART_BUILD_DARTPY "Build dartpy" OFF CATEGORY build) dart_option(DART_BUILD_GUI "Build GUI library" ON CATEGORY build) set(_dart_user_set_build_gui_raylib FALSE) if(DEFINED DART_BUILD_GUI_RAYLIB) set(_dart_user_set_build_gui_raylib TRUE) endif() dart_option(DART_BUILD_GUI_RAYLIB "Build experimental Raylib GUI backend" OFF CATEGORY build) if(NOT _dart_user_set_build_gui_raylib AND DEFINED DART_BUILD_RAYLIB) message(WARNING "DART_BUILD_RAYLIB is deprecated; use DART_BUILD_GUI_RAYLIB instead.") if(DART_BUILD_RAYLIB) set(_dart_build_gui_raylib_value ON) else() set(_dart_build_gui_raylib_value OFF) endif() set(DART_BUILD_GUI_RAYLIB "${_dart_build_gui_raylib_value}" CACHE BOOL "Build experimental Raylib GUI backend" FORCE) unset(DART_BUILD_RAYLIB CACHE) unset(_dart_build_gui_raylib_value) endif() unset(_dart_user_set_build_gui_raylib) dart_option(DART_BUILD_COLLISION_BULLET "Embed the Bullet collision backend into the core dart target" OFF CATEGORY build) dart_option(DART_BUILD_COLLISION_ODE "Embed the ODE collision backend into the core dart target" OFF CATEGORY build) dart_option(DART_BUILD_EXAMPLES "Build example targets" ON CATEGORY build) dart_option(DART_BUILD_TUTORIALS "Build tutorial targets" ON CATEGORY build) dart_option(DART_BUILD_TESTS "Build C++ tests" ON CATEGORY build) dart_option(DART_BUILD_PROFILE "Build DART with profiling options" OFF CATEGORY performance) dart_option(DART_PROFILE_BUILTIN "Enable built-in text profiling backend" ON CATEGORY performance) dart_option(DART_PROFILE_TRACY "Enable Tracy profiling backend" ON CATEGORY performance) dart_option(DART_CODECOV "Turn on codecov support" OFF CATEGORY performance) # Backward compatibility: accept legacy DART_PROFILE_TEXT if provided. if(NOT DEFINED DART_PROFILE_BUILTIN AND DEFINED DART_PROFILE_TEXT) set(DART_PROFILE_BUILTIN "${DART_PROFILE_TEXT}") endif() # Keep legacy variable names in scope for consumers (macros expect ENABLE_*). set(DART_PROFILE_TEXT "${DART_PROFILE_BUILTIN}") set(DART_PROFILE_ENABLE_TEXT "${DART_PROFILE_BUILTIN}") set(DART_PROFILE_ENABLE_TRACY "${DART_PROFILE_TRACY}") # Warning: DART_ENABLE_SIMD should be ON only when you build DART and the DART # dependent projects on the same machine. If this option is on, then compile # option `-march=native` is added to the target `dart` that enables all # instruction subsets supported by the local machine. If the architecture of # local machines are different then the projects will be built with different # compile options, which may cause runtime errors especially memory alignment # errors. dart_option(DART_ENABLE_SIMD "Build DART with all SIMD instructions on the current local machine" OFF CATEGORY performance) dart_option(DART_SIMD_FORCE_SCALAR "Force dart::simd to use scalar fallback (for testing)" OFF CATEGORY performance) dart_option(DART_FAST_DEBUG "Add -O1 option for DEBUG mode build" OFF CATEGORY performance) dart_option(DART_ENABLE_ASAN "Build DART with AddressSanitizer instrumentation" OFF CATEGORY diagnostics) # GCC and Clang add ANSI-formatted colors when they detect the output medium is a # terminal. However, this doesn't work in some cases such as when the makefile is # invoked by Ninja. DART_FORCE_COLORED_OUTPUT can be used in this case to enforce # to always generate ANSI-formatted colors regardless of the output medium types. # See: https://medium.com/@alasher/colored-c-compiler-output-with-ninja-clang-gcc-10bfe7f2b949 dart_option(DART_FORCE_COLORED_OUTPUT "Always produce ANSI-colored output (GNU/Clang only)." OFF CATEGORY diagnostics) dart_option(DART_USE_SYSTEM_IMGUI "Use system-installed ImGui instead of fetching from GitHub (recommended for package distributions)" OFF CATEGORY system) dart_option(DART_USE_SYSTEM_RAYLIB "Use system-installed Raylib instead of fetching from GitHub (recommended for package distributions)" OFF CATEGORY system) dart_option(DART_USE_SYSTEM_GOOGLEBENCHMARK "Use system GoogleBenchmark" OFF CATEGORY system) dart_option(DART_USE_SYSTEM_GOOGLETEST "Use system GoogleTest" OFF CATEGORY system) dart_option(DART_USE_SYSTEM_NANOBIND "Use system nanobind" OFF CATEGORY system) dart_option(DART_USE_SYSTEM_TRACY "Use system Tracy" OFF CATEGORY system) dart_option(DART_USE_SYSTEM_ODE "Use system-installed ODE instead of fetching from Bitbucket (set OFF only when system ODE is unavailable)" ON CATEGORY system) dart_option(DART_USE_SYSTEM_BULLET "Use system-installed Bullet instead of fetching from GitHub (set OFF only when system Bullet is unavailable)" ON CATEGORY system) dart_option(DART_VERBOSE "Whether print detailed information in CMake process" OFF CATEGORY diagnostics) dart_option( DART_ENABLE_SDFORMAT "Enable sdformat support in dart-utils (disable on platforms without sdformat)" ON CATEGORY build ) dart_option( DART_BUILD_SIMULATION_EXPERIMENTAL "Build experimental simulation module (dart::simulation::experimental)" OFF CATEGORY build ) dart_configure_compiler_cache() #=============================================================================== # Print intro #=============================================================================== message(STATUS "") message(STATUS "============================================") message(STATUS " DART ${DART_VERSION}") message(STATUS "============================================") message(STATUS "") dart_print_options() # Print build tool information message(STATUS "[ Build Tools ]") message(STATUS "- CMake : ${CMAKE_VERSION}") message(STATUS "- C++ : ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}") if(MSVC) message(STATUS "- CMAKE_TOOLCHAIN_FILE: ${CMAKE_TOOLCHAIN_FILE}") endif() message(STATUS "") #=============================================================================== # CodeCov settings #=============================================================================== if(DART_CODECOV) # Set up custom targets for code coverage dart_coverage( INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/dart SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/dart ) # Code Coverage Configuration add_library(coverage_config INTERFACE) # CodeCov can only be enabled in Debug mode if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") message(FATAL_ERROR "CodeCov can only be enabled in Debug mode") endif() # CodeCov can only be enabled with GCC or Clang if(NOT CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") message(FATAL_ERROR "CodeCov can only be enabled with GCC or Clang") endif() # Add required flags (GCC & LLVM/Clang) target_compile_options(coverage_config INTERFACE -O0 # no optimization -g # generate debug info --coverage # sets all required flags ) # Add required flags (GCC & LLVM/Clang) target_link_options(coverage_config INTERFACE --coverage) # Export CodeCov configuration install(TARGETS coverage_config DESTINATION lib EXPORT coverage_config) install(EXPORT coverage_config DESTINATION ${CONFIG_INSTALL_DIR}) endif() #=============================================================================== # Build type settings #=============================================================================== set(_dart_known_build_types Debug Release RelWithDebInfo MinSizeRel None) if(NOT CMAKE_CONFIGURATION_TYPES) if(NOT CMAKE_BUILD_TYPE) set( CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are: Debug | Release | RelWithDebInfo | MinSizeRel | None" FORCE ) message(STATUS "Setting CMAKE_BUILD_TYPE to '${CMAKE_BUILD_TYPE}'.") else() set( CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING "Choose the type of build, options are: Debug | Release | RelWithDebInfo | MinSizeRel | None" FORCE ) endif() set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${_dart_known_build_types}) endif() string(TOUPPER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_UPPERCASE) set(DART_BUILD_MODE_DEBUG FALSE) set(DART_BUILD_MODE_RELEASE FALSE) if("${CMAKE_BUILD_TYPE_UPPERCASE}" STREQUAL "DEBUG") set(DART_BUILD_MODE_DEBUG TRUE) elseif("${CMAKE_BUILD_TYPE_UPPERCASE}" STREQUAL "RELEASE") set(DART_BUILD_MODE_RELEASE TRUE) elseif("${CMAKE_BUILD_TYPE_UPPERCASE}" STREQUAL "RELWITHDEBINFO") set(DART_BUILD_MODE_RELEASE TRUE) elseif("${CMAKE_BUILD_TYPE_UPPERCASE}" STREQUAL "MINSIZEREL") set(DART_BUILD_MODE_RELEASE TRUE) endif() # Active log level: # # - TRACE: To enable log with DART_TRACE() and below # - DEBUG: To enable log with DART_DEBUG() and below # - INFO: To enable log with DART_INFO() and below # - WARN: To enable log with DART_WARN() and below # - ERROR: To enable log with DART_ERROR() and below # - FATAL: To enable log with DART_FATAL() # - OFF: To turn off all the logs if(DART_BUILD_MODE_DEBUG) set(DART_ACTIVE_LOG_LEVEL "DEBUG" CACHE STRING "Compile time active log level to enable") else() set(DART_ACTIVE_LOG_LEVEL "INFO" CACHE STRING "Compile time active log level to enable") endif() set_property(CACHE DART_ACTIVE_LOG_LEVEL PROPERTY STRINGS TRACE DEBUG INFO WARN ERROR FATAL OFF) if(DART_BUILD_MODE_DEBUG) option(DART_TREAT_WARNINGS_AS_ERRORS "Treat warnings as errors" OFF) else() option(DART_TREAT_WARNINGS_AS_ERRORS "Treat warnings as errors" ON) endif() option(DART_BUILD_WHEELS "Indicate building dartpy for wheels" OFF) #=============================================================================== # Uninstall #=============================================================================== # Add an "uninstall" target early so that fetched dependencies (e.g., raylib) # don't create their own conflicting target. # https://gitlab.kitware.com/cmake/community/-/wikis/doc/cmake/recipe/AddUninstallTarget if(NOT TARGET uninstall) file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/cmake") configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/cmake/uninstall_target.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake" IMMEDIATE @ONLY ) add_custom_target(uninstall COMMAND "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake" ) endif() #=============================================================================== # Find dependencies #=============================================================================== include(dart_find_dependencies) #=============================================================================== # Check for non-case-sensitive filesystems #=============================================================================== execute_process(COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/scripts/case_sensitive_filesystem RESULT_VARIABLE FILESYSTEM_CASE_SENSITIVE_RETURN) if(${FILESYSTEM_CASE_SENSITIVE_RETURN} EQUAL 0) set(FILESYSTEM_CASE_SENSITIVE TRUE) else() set(FILESYSTEM_CASE_SENSITIVE FALSE) endif() #=============================================================================== # Compiler flags #=============================================================================== if(MSVC) # Visual Studio 2022 17.10+ required for C++20 support set(msvc_required_version 1940) if(MSVC_VERSION VERSION_LESS ${msvc_required_version} AND ${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC") message(FATAL_ERROR "Visual Studio ${MSVC_VERSION} is detected, but " "${PROJECT_NAME_UPPERCASE} requires ${msvc_required_version} or greater (Visual Studio 2022 17.10+)." ) endif() if(DART_TREAT_WARNINGS_AS_ERRORS) add_compile_options(/WX) endif() # /MP - Multi-processor compilation (uses all available cores) # /FS - Force synchronous PDB writes (prevents PDB conflicts in parallel builds with /MP) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc /permissive- /Zc:twoPhase- /MP /FS") set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/INCREMENTAL:NO") if(NOT DART_MSVC_DEFAULT_OPTIONS) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${DART_RUNTIME_LIBRARY}d /Zi /Gy /W1 /EHsc") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${DART_RUNTIME_LIBRARY} /Zi /GL /Gy /W1 /EHsc") endif() add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_ENABLE_EXTENDED_ALIGNED_STORAGE) add_compile_options(/wd4005) add_compile_options(/wd4099) add_compile_options(/wd4146) # for FCL warnings: https://github.com/dartsim/dart/runs/4568423649?check_suite_focus=true#step:5:407 add_compile_options(/wd4244) add_compile_options(/wd4250) add_compile_options(/wd4267) add_compile_options(/wd4305) add_compile_options(/wd4334) add_compile_options(/wd4838) add_compile_options(/wd4996) add_compile_options(/bigobj) elseif(CMAKE_COMPILER_IS_GNUCXX) # There is a known bug in GCC 12.1 and above that leads to spurious # -Wmaybe-uninitialized warnings from gcc/x86_64-linux-gnu/12/include/avxintrin.h and # -Warray-bounds warnings from gcc/x86_64-linux-gnu/12/include/avx512fintrin.h. # The bug is tracked here: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105593 # The following workaround can be removed once the bug is fixed. if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 12.1) add_compile_options(-Wno-array-bounds) add_compile_options(-Wno-dangling-pointer) add_compile_options(-Wno-maybe-uninitialized) add_compile_options(-Wno-stringop-overflow) add_compile_options(-Wno-uninitialized) endif() add_compile_options(-Wall -Wextra -fPIC) if(DART_TREAT_WARNINGS_AS_ERRORS) add_compile_options(-Werror) # Also treat preprocessor warnings (like #warning directives in deprecated # headers) as errors add_compile_options(-Werror=cpp) endif() execute_process( COMMAND ${CMAKE_CXX_COMPILER} -dumpfullversion -dumpversion OUTPUT_VARIABLE GCC_VERSION) if(DART_BUILD_WHEELS) set(gcc_required_version 10.2.1) # Lowered from 11.2.0 to support older glibc-based wheel builds else() set(gcc_required_version 11.2.0) endif() if(GCC_VERSION VERSION_LESS ${gcc_required_version}) message(FATAL_ERROR "The installed g++ version is ${GCC_VERSION}. ${PROJECT_NAME} requires g++ ${gcc_required_version} or greater.") endif() if(GCC_VERSION VERSION_GREATER_EQUAL 13.2.0) # GCC 13 currently reports noisy diagnostics in upstream dependencies; silence # them until Eigen/FCL updates remove the false positives. add_compile_options(-Wno-overloaded-virtual -Wno-alloc-size-larger-than -Wno-dangling-pointer) endif() if(GCC_VERSION VERSION_GREATER_EQUAL 15.0) # TODO(GCC15): Remove once upstream dependencies (octomap, fcl) stop using # , which is deprecated in C++20. GCC 15 emits a #warning that our # -Werror=cpp flag treats as an error. # Tracking: octomap uses in OcTreeKey.h; fcl pulls it in transitively. add_compile_options(-Wno-error=cpp) endif() set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG") set(CMAKE_CXX_FLAGS_DEBUG "-g -fno-omit-frame-pointer -fno-inline-functions -fno-inline-functions-called-once -fno-optimize-sibling-calls") if(DART_FAST_DEBUG) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O1") endif() set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} ${CMAKE_CXX_FLAGS_DEBUG}") set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_DEBUG} -pg") set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--no-undefined") # Enforce to colorize compilation output if(DART_FORCE_COLORED_OUTPUT) add_compile_options(-fdiagnostics-color=always) endif() elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") add_compile_options(-Wall -Wextra -fPIC) if(DART_TREAT_WARNINGS_AS_ERRORS) add_compile_options(-Werror) # Also treat preprocessor warnings (like #warning directives in deprecated # headers) as errors add_compile_options(-Werror=cpp) endif() execute_process( COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE CLANG_VERSION) if(CLANG_VERSION VERSION_LESS 6.0) message(FATAL_ERROR "The installed Clang version is ${CLANG_VERSION}. ${PROJECT_NAME} requires clang 6.0 or greater.") endif() if("${CMAKE_SYSTEM_NAME}" MATCHES "Darwin") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") endif() set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG") set(CMAKE_CXX_FLAGS_DEBUG "-g -fno-omit-frame-pointer -fno-inline-functions -fno-optimize-sibling-calls") if(DART_FAST_DEBUG) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O1") endif() set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} ${CMAKE_CXX_FLAGS_DEBUG}") set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_DEBUG} -pg") # Enforce to colorize compilation output if(DART_FORCE_COLORED_OUTPUT) add_compile_options(-fcolor-diagnostics) endif() else() message(SEND_ERROR "Compiler[${CMAKE_CXX_COMPILER_ID}] not supported.") endif() if(DART_ENABLE_ASAN) if(NOT (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")) message(FATAL_ERROR "DART_ENABLE_ASAN is only supported with GCC or Clang.") endif() set(_DART_ASAN_FLAGS "-fsanitize=address") add_compile_options(${_DART_ASAN_FLAGS}) add_link_options(${_DART_ASAN_FLAGS}) foreach(link_var CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS) set(${link_var} "${${link_var}} ${_DART_ASAN_FLAGS}") endforeach() foreach(lang C CXX) set(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS} -fno-omit-frame-pointer") endforeach() set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${_DART_ASAN_FLAGS}") set(CMAKE_REQUIRED_LINK_OPTIONS "${CMAKE_REQUIRED_LINK_OPTIONS} ${_DART_ASAN_FLAGS}") # Disable Boost's embedded GDB scripts, which are known to trigger quoting issues # with recent GCC versions when AddressSanitizer instrumentation is enabled. add_compile_definitions(BOOST_ALL_NO_EMBEDDED_GDB_SCRIPTS) endif() if(DART_SIMD_FORCE_SCALAR) add_compile_definitions(DART_SIMD_FORCE_SCALAR=1) endif() #=============================================================================== # Print build summary #=============================================================================== if(DART_VERBOSE) message(STATUS "") message(STATUS "[ Build summary ]") message(STATUS "CMAKE_GENERATOR : ${CMAKE_GENERATOR}") message(STATUS "Compiler ID : ${CMAKE_CXX_COMPILER_ID}") message(STATUS "Compiler version : ${CMAKE_CXX_COMPILER_VERSION}") message(STATUS "Build type : ${CMAKE_BUILD_TYPE}") message(STATUS "BUILD_SHARED_LIBS: ${BUILD_SHARED_LIBS}") message(STATUS "Build gui : ${DART_BUILD_GUI}") message(STATUS "Install path : ${CMAKE_INSTALL_PREFIX}") message(STATUS "CXX_FLAGS : ${CMAKE_CXX_FLAGS}") if(CMAKE_BUILD_TYPE_UPPERCASE STREQUAL "RELEASE") message(STATUS "CXX_FLAGS_RELEASE: ${CMAKE_CXX_FLAGS_RELEASE}") elseif(CMAKE_BUILD_TYPE_UPPERCASE STREQUAL "DEBUG") message(STATUS "CXX_FLAGS_DEBUG : ${CMAKE_CXX_FLAGS_DEBUG}") elseif(CMAKE_BUILD_TYPE_UPPERCASE STREQUAL "RELWITHDEBINFO") message(STATUS "CXX_FLAGS_RELWITHDEBINFO: ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") elseif(CMAKE_BUILD_TYPE_UPPERCASE STREQUAL "PROFILE") message(STATUS "CXX_FLAGS_PROFILE: ${CMAKE_CXX_FLAGS_PROFILE}") endif() message(STATUS "DART_SOURCE_DIR : ${DART_SOURCE_DIR}") message(STATUS "DART_BINARY_DIR : ${DART_BINARY_DIR}") endif() #=============================================================================== # Add sub-directories #=============================================================================== add_subdirectory(dart) if(DART_BUILD_SIMULATION_EXPERIMENTAL) add_subdirectory(dart/simulation/experimental) endif() set(DART_IN_SOURCE_BUILD TRUE) if(TARGET dart) include(CTest) if(DART_BUILD_TESTS AND BUILD_TESTING) # Add a "tests" target to build unit tests. if(MSVC) add_subdirectory(tests) else() add_subdirectory(tests EXCLUDE_FROM_ALL) endif() if(DART_BUILD_SIMULATION_EXPERIMENTAL) if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tests/unit/simulation/experimental/CMakeLists.txt") if(NOT TARGET dart_experimental_tests) add_custom_target(dart_experimental_tests) endif() endif() endif() elseif(NOT DART_BUILD_TESTS) message(STATUS "Skipping tests (DART_BUILD_TESTS == OFF)") else() message(STATUS "Skipping tests (BUILD_TESTING == OFF)") endif() if(DART_BUILD_EXAMPLES) if(TARGET dart-gui) # Add example subdirectories and an "examples" target. if(MSVC) add_subdirectory(examples) else() add_subdirectory(examples EXCLUDE_FROM_ALL) get_property(examples GLOBAL PROPERTY DART_EXAMPLES) add_custom_target(examples DEPENDS ${examples}) endif() if(DART_VERBOSE) message(STATUS "") message(STATUS "[ Examples ]") foreach(example IN LISTS examples) message(STATUS "Adding example: ${example}") endforeach() else() list(LENGTH examples examples_length) message(STATUS "Adding ${examples_length} examples") endif() else() message(STATUS "Skipping examples (requires dart-gui target; enable DART_BUILD_GUI)") endif() else() message(STATUS "Skipping examples (DART_BUILD_EXAMPLES == OFF)") endif() if(DART_BUILD_TUTORIALS) if(TARGET dart-gui) # Add a "tutorials" target to build tutorials. if(MSVC) add_subdirectory(tutorials) else() add_subdirectory(tutorials EXCLUDE_FROM_ALL) get_property(tutorials GLOBAL PROPERTY DART_TUTORIALS) add_custom_target(tutorials DEPENDS ${tutorials}) endif() if(DART_VERBOSE) message(STATUS "") message(STATUS "[ Tutorials ]") foreach(tutorial IN LISTS tutorials) message(STATUS "Adding tutorial: ${tutorial}") endforeach() else() list(LENGTH tutorials tutorials_length) message(STATUS "Adding ${tutorials_length} tutorials") endif() else() message(STATUS "Skipping tutorials (requires dart-gui target; enable DART_BUILD_GUI)") endif() else() message(STATUS "Skipping tutorials (DART_BUILD_TUTORIALS == OFF)") endif() if(DART_BUILD_GUI_RAYLIB) if(MSVC) add_subdirectory(examples/raylib) else() add_subdirectory(examples/raylib EXCLUDE_FROM_ALL) endif() if(TARGET examples AND TARGET dart_raylib) add_dependencies(examples dart_raylib) endif() else() message(STATUS "Skipping Raylib example (DART_BUILD_GUI_RAYLIB == OFF)") endif() endif() add_subdirectory(python) # Add 'ALL' target that builds everything set(all_target_candidates) if(DART_BUILD_DARTPY) list(APPEND all_target_candidates dartpy) endif() if(DART_BUILD_TESTS AND BUILD_TESTING) list(APPEND all_target_candidates tests_and_run pytest) endif() foreach(target_candidate IN LISTS all_target_candidates) if(TARGET ${target_candidate}) list(APPEND all_targets ${target_candidate}) endif() endforeach() foreach(target_candidate IN LISTS examples) if(TARGET ${target_candidate}) list(APPEND all_targets ${target_candidate}) endif() endforeach() foreach(target_candidate IN LISTS tutorials) if(TARGET ${target_candidate}) list(APPEND all_targets ${target_candidate}) endif() endforeach() if(TARGET dart_raylib) list(APPEND all_targets dart_raylib) endif() add_custom_target(ALL DEPENDS ${all_targets}) #=============================================================================== # CMake configuration files for components and targets #=============================================================================== # Generate and install CMake configuration files for each component : # - Component.cmake, which defines: # - dart__DEPENDENCIES: list of component dependencies # - dart__LIBRARIES: list of library targets in this component # - Targets.cmake, which creates IMPORTED targets install_component_exports(${PROJECT_NAME}) #=============================================================================== # Configure files #=============================================================================== if(DART_VERBOSE) message(STATUS "") message(STATUS "[ Configured files ]") endif() # Generate and install a Config.cmake file. This file includes the # Component.cmake and Targets.cmake created above. It also uses the # following variables: # # - PACKAGE_INCLUDE_INSTALL_DIR # - PACKAGE_INCLUDE_DIRS get_property(PACKAGE_INCLUDE_DIRS GLOBAL PROPERTY "${PROJECT_NAME_UPPERCASE}_INCLUDE_DIRS") # Generate the DART CMake Config and version files include(CMakePackageConfigHelpers) set(DART_CONFIG_IN ${DART_SOURCE_DIR}/cmake/${PROJECT_NAME_UPPERCASE}Config.cmake.in) set(DART_CONFIG_OUT ${DART_BINARY_DIR}/${PROJECT_NAME_UPPERCASE}Config.cmake) set(DART_VERSION_OUT ${DART_BINARY_DIR}/cmake/${PROJECT_NAME_UPPERCASE}ConfigVersion.cmake) if(DART_VERBOSE) message(STATUS ${DART_CONFIG_OUT}) message(STATUS ${DART_VERSION_OUT}) endif() configure_package_config_file( ${DART_CONFIG_IN} ${DART_CONFIG_OUT} INSTALL_DESTINATION "${CONFIG_INSTALL_DIR}" PATH_VARS INCLUDE_INSTALL_DIR ) write_basic_config_version_file( ${DART_VERSION_OUT} VERSION ${${PROJECT_NAME_UPPERCASE}_VERSION} COMPATIBILITY SameMajorVersion ) install( FILES ${DART_CONFIG_OUT} ${DART_VERSION_OUT} DESTINATION "${CONFIG_INSTALL_DIR}" ) # Generate the DART pkg-config set(PC_CONFIG_IN ${DART_SOURCE_DIR}/cmake/dart.pc.in) set(PC_CONFIG_OUT ${DART_BINARY_DIR}/cmake/dart.pc) set(DART_PKG_LINK_LIBS "") get_property(_dart_pkg_link_libs GLOBAL PROPERTY DART_PKG_LINK_LIBS) if(_dart_pkg_link_libs) string(JOIN " " DART_PKG_LINK_LIBS ${_dart_pkg_link_libs}) if(DART_PKG_LINK_LIBS) set(DART_PKG_LINK_LIBS " ${DART_PKG_LINK_LIBS}") endif() endif() set(DART_PKG_EXTRA_CFLAGS "") get_property(_dart_pkg_includes GLOBAL PROPERTY DART_PUBLIC_INCLUDE_DIRS) get_property(_dart_pkg_system_includes GLOBAL PROPERTY DART_PUBLIC_SYSTEM_INCLUDE_DIRS) set(_dart_pkg_all_includes ${_dart_pkg_includes} ${_dart_pkg_system_includes}) if(_dart_pkg_all_includes) list(REMOVE_DUPLICATES _dart_pkg_all_includes) foreach(_inc IN LISTS _dart_pkg_all_includes) if(_inc) string(APPEND DART_PKG_EXTRA_CFLAGS " -I${_inc}") endif() endforeach() endif() cmake_path(IS_ABSOLUTE CMAKE_INSTALL_LIBDIR ABSOLUTE_CMAKE_INSTALL_LIBDIR) if(ABSOLUTE_CMAKE_INSTALL_LIBDIR) # Absolute "CMAKE_INSTALL_*DIR" can be provided by user # eg. to install libs and headers in different prefixes # to split the package between propagated runtime dependency package # and buildtime-only -dev package. # In that case, the package can not be relocatable, # and the installed files must not contain any "CMAKE_INSTALL_PREFIX" # concatenated with a "CMAKE_INSTALL_*DIR". Use "CMAKE_INSTALL_FULL_*DIR". set(PC_CONFIG_INSTALL_DIR ${CMAKE_INSTALL_FULL_LIBDIR}/pkgconfig) set(PC_LIBDIR ${CMAKE_INSTALL_FULL_LIBDIR}) set(PC_INCLUDEDIR ${CMAKE_INSTALL_FULL_INCLUDEDIR}) else() # When "CMAKE_INSTALL_*DIR" are relative, we should ensure the installed # files contain relocatable references to install paths. set(PC_CONFIG_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/pkgconfig) set(PC_LIBDIR "\${prefix}/${CMAKE_INSTALL_LIBDIR}") set(PC_INCLUDEDIR "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}") endif() file(RELATIVE_PATH RELATIVE_PATH_TO_INSTALL_PREFIX "${PC_CONFIG_INSTALL_DIR}" "${CMAKE_INSTALL_PREFIX}" ) if(DART_VERBOSE) message(STATUS ${PC_CONFIG_OUT}) endif() configure_file(${PC_CONFIG_IN} ${PC_CONFIG_OUT} @ONLY) install(FILES ${PC_CONFIG_OUT} DESTINATION ${PC_CONFIG_INSTALL_DIR}) # Install a Catkin 'package.xml' file. This is required by REP-136. install(FILES package.xml DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME} ) #=============================================================================== # Install sample data, examples, and tutorials #=============================================================================== # Sample data install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/data" DESTINATION ${DART_ADDITIONAL_DOCUMENTATION_INSTALL_PATH} ) # Examples source if(NOT DART_EXAMPLES_INSTALL_PATH STREQUAL "") install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/examples" DESTINATION "${DART_EXAMPLES_INSTALL_PATH}" ) endif() # Tutorials source install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/tutorials" DESTINATION ${DART_ADDITIONAL_DOCUMENTATION_INSTALL_PATH} ) #=============================================================================== # Code Formatting #=============================================================================== if(DART_VERBOSE) message(STATUS "") message(STATUS "[ Code Formatting ]") endif() find_program( CLANG_FORMAT_EXECUTABLE NAMES clang-format-21 clang-format ) get_property(formatting_files GLOBAL PROPERTY DART_FORMAT_FILES) list(LENGTH formatting_files formatting_files_length) if(CLANG_FORMAT_EXECUTABLE) if(DART_VERBOSE) message(STATUS "Looking for clang-format - found") endif() message(STATUS "Formatting on ${formatting_files_length} source files.") if(formatting_files) add_custom_target( format COMMAND ${CMAKE_COMMAND} -E echo "Formatting ${formatting_files_length} files... " COMMAND ${CLANG_FORMAT_EXECUTABLE} -style=file -i ${formatting_files} COMMAND ${CMAKE_COMMAND} -E echo "Done." DEPENDS ${CLANG_FORMAT_EXECUTABLE} WORKING_DIRECTORY ${DART_SOURCE_DIR}/dart ) add_custom_target( check-format COMMAND ${CMAKE_COMMAND} -E echo "Checking ${formatting_files_length} files... " COMMAND ${DART_SOURCE_DIR}/scripts/check_format.sh ${CLANG_FORMAT_EXECUTABLE} ${formatting_files} COMMAND ${CMAKE_COMMAND} -E echo "Done." DEPENDS ${CLANG_FORMAT_EXECUTABLE} WORKING_DIRECTORY ${DART_SOURCE_DIR}/dart ) else() add_custom_target( format COMMAND ${CMAKE_COMMAND} -E echo "Warning: Not found any source files to format." ) add_custom_target( check-format COMMAND ${CMAKE_COMMAND} -E echo "Warning: Not found any source files to check." ) endif() else() if(DART_VERBOSE) message(WARNING "Looking for clang-format - NOT found, please install clang-format to enable automatic code formatting") endif() endif() #=============================================================================== # API Document using Doxygen # References: # http://mementocodex.wordpress.com/2013/01/19/how-to-generate-code-documentation-with-doxygen-and-cmake-a-slightly-improved-approach/ # http://www.cmake.org/pipermail/cmake/2007-February/012796.html #=============================================================================== if(DOXYGEN_FOUND) set(DOXYGEN_DOXYFILE_IN "${PROJECT_SOURCE_DIR}/docs/doxygen/Doxyfile.in" ) set(DOXYGEN_DOXYFILE "${PROJECT_BINARY_DIR}/docs/doxygen/Doxyfile" ) set(DOXYGEN_HTML_INDEX "${PROJECT_BINARY_DIR}/docs/doxygen/html/index.html") set(DOXYGEN_OUTPUT_ROOT "${PROJECT_BINARY_DIR}/docs/doxygen/html" ) set(DOXYGEN_GENERATE_TAGFILE "${DOXYGEN_OUTPUT_ROOT}/${PROJECT_NAME}.tag" ) set(DOXYGEN_INCLUDE_PATH "${PROJECT_SOURCE_DIR}" ) set(DOXYGEN_INPUT_ROOT "${PROJECT_SOURCE_DIR}/dart" ) set(DOXYGEN_EXTRA_INPUTS "${PROJECT_SOURCE_DIR}/docs/doxygen/mainpage.dox" ) set(DOXYGEN_EXCLUDE "${PROJECT_SOURCE_DIR}/dart/external" ) set(DOXYGEN_STRIP_FROM_PATH "${CMAKE_CURRENT_SOURCE_DIR}" ) # Generate a Doxyfile. This uses the variables: # # - DOXYGEN_OUTPUT_ROOT # - DOXYGEN_GENERATE_TAGFILE # - DOXYGEN_EXTRA_INPUTS # - DOXYGEN_INPUT_ROOT # - DOXYGEN_EXCLUDE # - DOXYGEN_STRIP_FROM_PATH configure_file(${DOXYGEN_DOXYFILE_IN} ${DOXYGEN_DOXYFILE} @ONLY) file( COPY "${PROJECT_SOURCE_DIR}/docs/doxygen/DART logo.png" DESTINATION ${DOXYGEN_OUTPUT_ROOT} ) add_custom_command( OUTPUT ${DOXYGEN_HTML_INDEX} COMMAND ${CMAKE_COMMAND} -E echo_append "Building API Documentation..." COMMAND ${DOXYGEN_EXECUTABLE} -u ${DOXYGEN_DOXYFILE} COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_DOXYFILE} # Strip path prefix from all paths in dart.tag COMMAND ${CMAKE_COMMAND} -E echo "Stripping paths from" "${DOXYGEN_GENERATE_TAGFILE}" COMMAND sed -i s:${DOXYGEN_STRIP_FROM_PATH}::g ${DOXYGEN_GENERATE_TAGFILE} # Strip all doxygen="path" HTML tags COMMAND ${CMAKE_COMMAND} -E echo "Stripping Doxygen HTML tags" COMMAND find "${DOXYGEN_OUTPUT_ROOT}" -type f -name "*.html" -exec sed -i 's: doxygen=\"[^\"]*\"::g' {} \\$ COMMAND ${CMAKE_COMMAND} -E echo "Done." WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/docs/doxygen DEPENDS ${DOXYGEN_DOXYFILE} ) add_custom_target(docs DEPENDS ${DOXYGEN_HTML_INDEX}) add_custom_target( docs_forced COMMAND ${CMAKE_COMMAND} -E echo_append "Building API Documentation..." COMMAND ${DOXYGEN_EXECUTABLE} -u ${DOXYGEN_DOXYFILE} COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_DOXYFILE} COMMAND ${CMAKE_COMMAND} -E echo "Done." WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/docs/doxygen ) # Add the "view_docs" target that opens the generated API documentation. if(APPLE) set(OPEN_COMMAND "open") else() set(OPEN_COMMAND "xdg-open") endif() add_custom_target(view_docs "${OPEN_COMMAND}" "${DOXYGEN_HTML_INDEX}" DEPENDS "${DOXYGEN_HTML_INDEX}" COMMENT "Opening documentation in a web browser.") endif() #=============================================================================== # Build Instructions #=============================================================================== message(STATUS "") set(DART_CMAKE_BUILD_CMD_BASE "cmake --build .") set(DART_CMAKE_BUILD_CMD_SUFFIX "") if(CMAKE_CONFIGURATION_TYPES) if(CMAKE_BUILD_TYPE) set(DART_CMAKE_BUILD_CMD_SUFFIX " --config ${CMAKE_BUILD_TYPE}") else() list(JOIN CMAKE_CONFIGURATION_TYPES ", " DART_CMAKE_KNOWN_CONFIGS) set(DART_CMAKE_BUILD_CMD_SUFFIX " --config ") message(STATUS "Available build configurations: ${DART_CMAKE_KNOWN_CONFIGS}") endif() endif() set(DART_CMAKE_BUILD_CMD "${DART_CMAKE_BUILD_CMD_BASE}${DART_CMAKE_BUILD_CMD_SUFFIX}") message(STATUS "Run '${DART_CMAKE_BUILD_CMD}' to build all the components") if (BUILD_TESTING) message(STATUS "Run '${DART_CMAKE_BUILD_CMD} --target tests' to build all the tests") endif() message(STATUS "Run '${DART_CMAKE_BUILD_CMD} --target examples' to build all the examples") message(STATUS "Run '${DART_CMAKE_BUILD_CMD} --target tutorials' to build all the tutorials") message(STATUS "Run '${DART_CMAKE_BUILD_CMD} --target view_docs' to see the API documentation") message(STATUS "Run '${DART_CMAKE_BUILD_CMD} --target install' to install all the C++ components") if(TARGET dartpy) message(STATUS "Run '${DART_CMAKE_BUILD_CMD} --target dartpy' to build the python bindings") endif() if(TARGET coverage) message(STATUS "- 'coverage' : generate coverage report") message(STATUS "- 'coverage_html': generate coverage report in html") message(STATUS "- 'coverage_view': view generated coverage report in a browser") endif() #=============================================================================== # END #=============================================================================== message(STATUS "")