@@ -484,45 +484,175 @@ endif()
484484# ═══════════════════════════════════════════════════════════════════════════════
485485
486486include (GNUInstallDirs )
487+ option (HC_INSTALL_DEV_KIT "Install CMake dev package (headers/libs)" OFF )
488+
489+ if (HC_INSTALL_DEV_KIT)
490+ # Export HydroChrono as an importable target for other CMake projects
491+ install (TARGETS HydroChrono
492+ EXPORT HydroChronoTargets
493+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
494+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
495+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
496+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
497+ )
487498
488- # Export HydroChrono as an importable target for other CMake projects
489- install (TARGETS HydroChrono
490- EXPORT HydroChronoTargets
491- LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
492- ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
493- RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
494- INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
495- )
496-
497- install (EXPORT HydroChronoTargets
498- FILE HydroChronoTargets.cmake
499- DESTINATION "${CMAKE_INSTALL_DATADIR} /HydroChrono/cmake"
500- NAMESPACE HydroChrono::
501- )
499+ install (EXPORT HydroChronoTargets
500+ FILE HydroChronoTargets.cmake
501+ DESTINATION "${CMAKE_INSTALL_DATADIR} /HydroChrono/cmake"
502+ NAMESPACE HydroChrono::
503+ )
502504
503- # Install public headers
504- install (DIRECTORY include/hydroc
505- DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
506- )
505+ # Install public headers
506+ install (DIRECTORY include/hydroc
507+ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
508+ )
507509
508- # Generate and install package config files for find_package() support
509- include (CMakePackageConfigHelpers )
510- configure_package_config_file (
511- cmake/HydroChronoConfig.cmake.in
512- "${CMAKE_CURRENT_BINARY_DIR} /cmake/HydroChronoConfig.cmake"
513- INSTALL_DESTINATION "${CMAKE_INSTALL_DATADIR} /HydroChrono/cmake"
514- )
510+ # Generate and install package config files for find_package() support
511+ include (CMakePackageConfigHelpers )
512+ configure_package_config_file (
513+ cmake/HydroChronoConfig.cmake.in
514+ "${CMAKE_CURRENT_BINARY_DIR} /cmake/HydroChronoConfig.cmake"
515+ INSTALL_DESTINATION "${CMAKE_INSTALL_DATADIR} /HydroChrono/cmake"
516+ )
515517
516- install (FILES "${CMAKE_CURRENT_BINARY_DIR} /cmake/HydroChronoConfig.cmake"
517- DESTINATION "${CMAKE_INSTALL_DATADIR} /HydroChrono/cmake"
518- )
518+ install (FILES "${CMAKE_CURRENT_BINARY_DIR} /cmake/HydroChronoConfig.cmake"
519+ DESTINATION "${CMAKE_INSTALL_DATADIR} /HydroChrono/cmake"
520+ )
521+ endif ()
519522
520- # Export targets for build tree usage (without installation)
521- export (EXPORT HydroChronoTargets
522- FILE "${CMAKE_CURRENT_BINARY_DIR} /cmake/HydroChronoTargets.cmake"
523- NAMESPACE HydroChrono::
524- )
523+ if (HC_INSTALL_DEV_KIT)
524+ # Export targets for build tree usage (without installation)
525+ export (EXPORT HydroChronoTargets
526+ FILE "${CMAKE_CURRENT_BINARY_DIR} /cmake/HydroChronoTargets.cmake"
527+ NAMESPACE HydroChrono::
528+ )
529+ endif ()
525530
526531# ── Debug Symbols in Release Mode ──
527532# Keep debug symbols in Release builds for better profiling and crash analysis
528533set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi /O2" )
534+
535+ # ──────────────────────────────────────────────────────────────────────────────
536+ # 7.1 Runtime installer and ZIP packaging for releases
537+ # ──────────────────────────────────────────────────────────────────────────────
538+
539+ # Flat install tree for public distribution
540+ option (HC_INSTALL_DEV_DEMOS "Install developer demo executables" OFF )
541+
542+ # Install main CLI only (if built)
543+ if (TARGET run_hydrochrono)
544+ install (TARGETS run_hydrochrono
545+ RUNTIME DESTINATION bin COMPONENT runtime )
546+ endif ()
547+
548+ # Collect runtime DLLs from imported targets when available
549+ set (HC_DLLS)
550+ foreach (tgt IN ITEMS Chrono::Chrono_core Chrono::Chrono_irrlicht Chrono::Chrono_parsers Chrono::ChronoModels_robot yaml-cpp yaml-cpp::yaml-cpp)
551+ if (TARGET ${tgt} )
552+ list (APPEND HC_DLLS "$<TARGET_FILE :${tgt} >" )
553+ endif ()
554+ endforeach ()
555+
556+ # Irrlicht.dll overridable from build system; default derived from Irrlicht_ROOT
557+ set (IRRLICHT_DLL_PATH_DEFAULT "${Irrlicht_ROOT} /bin/Win64-VisualStudio/Irrlicht.dll" )
558+ set (IRRLICHT_DLL_PATH "${IRRLICHT_DLL_PATH_DEFAULT} " CACHE FILEPATH "Path to Irrlicht.dll" )
559+ if (EXISTS "${IRRLICHT_DLL_PATH} " )
560+ list (APPEND HC_DLLS "${IRRLICHT_DLL_PATH} " )
561+ endif ()
562+
563+ # YAML-CPP runtime DLL overridable from build system
564+ set (YAML_CPP_DLL_PATH "" CACHE FILEPATH "Path to yaml-cpp runtime DLL (yaml-cpp.dll)" )
565+ if (EXISTS "${YAML_CPP_DLL_PATH} " )
566+ list (APPEND HC_DLLS "${YAML_CPP_DLL_PATH} " )
567+ endif ()
568+
569+ if (HC_DLLS)
570+ install (FILES ${HC_DLLS} DESTINATION bin COMPONENT runtime )
571+ endif ()
572+
573+ # Ensure yaml-cpp.dll is part of the runtime component in the ZIP (OPTIONAL handles missing paths)
574+ install (FILES
575+ "${Chrono_DIR} /../bin/Release/yaml-cpp.dll"
576+ "${Chrono_DIR} /../bin/RelWithDebInfo/yaml-cpp.dll"
577+ "${Chrono_DIR} /../bin/MinSizeRel/yaml-cpp.dll"
578+ "${Chrono_DIR} /../bin/Debug/yaml-cpp.dll"
579+ "${CMAKE_BINARY_DIR} /bin/Release/yaml-cpp.dll"
580+ "${CMAKE_BINARY_DIR} /bin/RelWithDebInfo/yaml-cpp.dll"
581+ "${CMAKE_BINARY_DIR} /bin/MinSizeRel/yaml-cpp.dll"
582+ "${CMAKE_BINARY_DIR} /bin/Debug/yaml-cpp.dll"
583+ DESTINATION bin COMPONENT runtime OPTIONAL )
584+
585+ # Fallback: copy all Chrono-built DLLs for the active config into bin
586+ install (CODE "
587+ file(GLOB _ALL_DLLS \" ${Chrono_DIR} /../bin/${CMAKE_INSTALL_CONFIG_NAME} /*.dll\" )
588+ foreach(_f IN LISTS _ALL_DLLS)
589+ if(EXISTS \" ${_f} \" )
590+ file(INSTALL DESTINATION \" ${CMAKE_INSTALL_PREFIX} /bin\" TYPE FILE FILES \" ${_f} \" )
591+ endif()
592+ endforeach()
593+ " )
594+
595+ # Also copy any DLLs produced or staged in this project's build bin (e.g., yaml-cpp.dll)
596+ install (CODE "
597+ file(GLOB _HC_DLLS \" ${CMAKE_BINARY_DIR} /bin/${CMAKE_INSTALL_CONFIG_NAME} /*.dll\" )
598+ foreach(_f IN LISTS _HC_DLLS)
599+ if(EXISTS \" ${_f} \" )
600+ file(INSTALL DESTINATION \" ${CMAKE_INSTALL_PREFIX} /bin\" TYPE FILE FILES \" ${_f} \" )
601+ endif()
602+ endforeach()
603+ " )
604+
605+ # Removed fragile fallback DLL copy to avoid install script parse errors. The
606+ # release DLLs should be resolved via imported targets or IRRLICHT_DLL_PATH.
607+
608+ # Optional runtime data folder
609+ if (EXISTS "${PROJECT_SOURCE_DIR} /data" )
610+ install (DIRECTORY ${PROJECT_SOURCE_DIR} /data/ DESTINATION data COMPONENT runtime )
611+ endif ()
612+
613+ # Chrono visual assets (skybox, colormaps) for GUI
614+ if (DEFINED CHRONO_DATA_DIR AND EXISTS "${CHRONO_DATA_DIR} " )
615+ if (EXISTS "${CHRONO_DATA_DIR} /skybox" )
616+ install (DIRECTORY "${CHRONO_DATA_DIR} /skybox" DESTINATION data COMPONENT runtime )
617+ endif ()
618+ if (EXISTS "${CHRONO_DATA_DIR} /colormaps" )
619+ install (DIRECTORY "${CHRONO_DATA_DIR} /colormaps" DESTINATION data COMPONENT runtime )
620+ endif ()
621+ endif ()
622+
623+ # Public, user-facing regression test suite only
624+ install (DIRECTORY ${PROJECT_SOURCE_DIR} /tests/regression/run_hydrochrono
625+ DESTINATION tests COMPONENT python-tests
626+ PATTERN "__pycache__" EXCLUDE
627+ PATTERN "*.pyc" EXCLUDE)
628+
629+ # Simple runner script to execute tests from the installed tree
630+ install (PROGRAMS ${PROJECT_SOURCE_DIR} /scripts/RUN-TESTS.ps1
631+ DESTINATION tests COMPONENT python-tests)
632+
633+ # Optional developer demo executables (OFF by default)
634+ if (HC_INSTALL_DEV_DEMOS)
635+ install (DIRECTORY ${HYDROCHRONO_DEMO_OUTPUT_DIR} /$<CONFIG >/
636+ DESTINATION bin/tests/dev
637+ FILES_MATCHING PATTERN "demo_*.exe" )
638+ endif ()
639+
640+ # MSVC runtime DLLs and ZIP packaging via CPack
641+ include (InstallRequiredSystemLibraries )
642+ set (CPACK_GENERATOR "ZIP" )
643+ set (CPACK_PACKAGE_NAME "HydroChrono" )
644+ set (CPACK_COMPONENTS_ALL runtime python-tests dev-demos)
645+ include (CPack )
646+
647+ # Optionally include Python runtime DLL if Chrono::Parsers depends on it
648+ find_package (Python3 QUIET COMPONENTS Interpreter )
649+ if (Python3_Interpreter_FOUND OR Python3_FOUND)
650+ get_filename_component (_PY_DIR "${Python3_EXECUTABLE} " DIRECTORY )
651+ if (DEFINED Python3_VERSION_MAJOR AND DEFINED Python3_VERSION_MINOR)
652+ set (_PY_DLL_NAME "python${Python3_VERSION_MAJOR}${Python3_VERSION_MINOR} .dll" )
653+ set (_PY_DLL_PATH "${_PY_DIR} /${_PY_DLL_NAME} " )
654+ if (EXISTS "${_PY_DLL_PATH} " )
655+ install (FILES "${_PY_DLL_PATH} " DESTINATION bin COMPONENT runtime )
656+ endif ()
657+ endif ()
658+ endif ()
0 commit comments