From 7c246bd12e38f58c788d7c0d3ee24daf08b02a85 Mon Sep 17 00:00:00 2001 From: BadQuanta Date: Sat, 16 May 2026 21:36:45 +0000 Subject: [PATCH] Updated CMake Policies. --- .clang-format | 288 +++++++++++++++++++++++++++++ .gitignore | 1 + CMakeLists.txt | 113 ++++++++++- README.md | 45 ++++- cmake/HDKDependencyPolicy.cmake | 91 +++++++++ cmake/HDKDocumentationPolicy.cmake | 70 +++++++ cmake/HDKExampleAssetsPolicy.cmake | 72 ++++++++ cmake/HDKPackaging.cmake | 49 +++++ examples/CMakeLists.txt | 72 +++++++- examples/is3r-basics.cpp | 6 +- 10 files changed, 798 insertions(+), 9 deletions(-) create mode 100644 .clang-format create mode 100644 .gitignore create mode 100644 cmake/HDKDependencyPolicy.cmake create mode 100644 cmake/HDKDocumentationPolicy.cmake create mode 100644 cmake/HDKExampleAssetsPolicy.cmake create mode 100644 cmake/HDKPackaging.cmake diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..8cb165e --- /dev/null +++ b/.clang-format @@ -0,0 +1,288 @@ +--- +Language: Cpp +AccessModifierOffset: 0 +AlignAfterOpenBracket: DontAlign +AlignArrayOfStructures: None +AlignConsecutiveAssignments: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionDeclarations: false + AlignFunctionPointers: false + PadOperators: true +AlignConsecutiveBitFields: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionDeclarations: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveDeclarations: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionDeclarations: true + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveMacros: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionDeclarations: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveShortCaseStatements: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCaseArrows: false + AlignCaseColons: false +AlignConsecutiveTableGenBreakingDAGArgColons: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionDeclarations: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveTableGenCondOperatorColons: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionDeclarations: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveTableGenDefinitionColons: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionDeclarations: false + AlignFunctionPointers: false + PadOperators: false +AlignEscapedNewlines: Right +AlignOperands: DontAlign +AlignTrailingComments: + Kind: Never + OverEmptyLines: 0 +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowBreakBeforeNoexceptSpecifier: Never +AllowShortBlocksOnASingleLine: Empty +AllowShortCaseExpressionOnASingleLine: true +AllowShortCaseLabelsOnASingleLine: false +AllowShortCompoundRequirementOnASingleLine: true +AllowShortEnumsOnASingleLine: true +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: false +AllowShortNamespacesOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AttributeMacros: + - __capability +BinPackArguments: true +BinPackParameters: BinPack +BitFieldColonSpacing: Both +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterExternBlock: false + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakAdjacentStringLiterals: true +BreakAfterAttributes: Leave +BreakAfterJavaFieldAnnotations: false +BreakAfterReturnType: None +BreakArrays: true +BreakBeforeBinaryOperators: All +BreakBeforeConceptDeclarations: Always +BreakBeforeBraces: Attach +BreakBeforeInlineASMColon: OnlyMultiline +BreakBeforeTernaryOperators: true +BreakBinaryOperations: Never +BreakConstructorInitializers: BeforeComma +BreakFunctionDefinitionParameters: false +BreakInheritanceList: BeforeColon +BreakStringLiterals: true +BreakTemplateDeclarations: MultiLine +ColumnLimit: 120 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerIndentWidth: 2 +ContinuationIndentWidth: 2 +Cpp11BracedListStyle: false +DerivePointerAlignment: false +DisableFormat: false +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: false +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IfMacros: + - KJ_IF_MAYBE +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + CaseSensitive: false + - Regex: '.*' + Priority: 1 + SortPriority: 0 + CaseSensitive: false +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentAccessModifiers: true +IndentCaseBlocks: false +IndentCaseLabels: false +IndentExportBlock: true +IndentExternBlock: AfterExternBlock +IndentGotoLabels: true +IndentPPDirectives: None +IndentRequiresClause: true +IndentWidth: 2 +IndentWrappedFunctionNames: false +InsertBraces: false +InsertNewlineAtEOF: false +InsertTrailingCommas: None +IntegerLiteralSeparator: + Binary: 0 + BinaryMinDigits: 0 + Decimal: 0 + DecimalMinDigits: 0 + Hex: 0 + HexMinDigits: 0 +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLines: + AtEndOfFile: false + AtStartOfBlock: true + AtStartOfFile: true +KeepFormFeed: false +LambdaBodyIndentation: Signature +LineEnding: DeriveLF +MacroBlockBegin: '' +MacroBlockEnd: '' +MainIncludeChar: Quote +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: All +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 4 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: true +ObjCSpaceBeforeProtocolList: true +PackConstructorInitializers: BinPack +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakBeforeMemberAccess: 150 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakOpenParenthesis: 0 +PenaltyBreakScopeResolution: 500 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyIndentedWhitespace: 0 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Left +PPIndentWidth: -1 +QualifierAlignment: Leave +ReferenceAlignment: Pointer +ReflowComments: Always +RemoveBracesLLVM: false +RemoveEmptyLinesInUnwrappedLines: false +RemoveParentheses: Leave +RemoveSemicolon: false +RequiresClausePosition: OwnLine +RequiresExpressionIndentation: OuterScope +SeparateDefinitionBlocks: Leave +ShortNamespaceLines: 1 +SkipMacroDefinitionBody: false +SortIncludes: CaseSensitive +SortJavaStaticImport: Before +SortUsingDeclarations: LexicographicNumeric +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceAroundPointerQualifiers: Default +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: true +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeJsonColon: false +SpaceBeforeParens: ControlStatements +SpaceBeforeParensOptions: + AfterControlStatements: true + AfterForeachMacros: true + AfterFunctionDefinitionName: false + AfterFunctionDeclarationName: false + AfterIfMacros: true + AfterOverloadedOperator: false + AfterPlacementOperator: true + AfterRequiresInClause: false + AfterRequiresInExpression: false + BeforeNonEmptyParentheses: false +SpaceBeforeRangeBasedForLoopColon: true +SpaceBeforeSquareBrackets: false +SpaceInEmptyBlock: true +SpacesBeforeTrailingComments: 1 +SpacesInAngles: Never +SpacesInContainerLiterals: true +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: -1 +SpacesInParens: Never +SpacesInParensOptions: + ExceptDoubleParentheses: false + InCStyleCasts: false + InConditionalStatements: false + InEmptyParentheses: false + Other: false +SpacesInSquareBrackets: false +Standard: Latest +StatementAttributeLikeMacros: + - Q_EMIT +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TableGenBreakInsideDAGArg: DontBreak +TabWidth: 8 +UseTab: Never +VerilogBreakBetweenInstancePorts: true +WhitespaceSensitiveMacros: + - BOOST_PP_STRINGIZE + - CF_SWIFT_NAME + - NS_SWIFT_NAME + - PP_STRINGIZE + - STRINGIZE +WrapNamespaceBodyWithEmptyLines: Leave +... + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d163863 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +build/ \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 0bcd4f7..471f2f1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,50 @@ project(hdk-imgui-sdl-renderer option(HDK_IMGUI_SDL_RENDERER_TESTS "Build hdk-imgui-sdl-renderer tests" ${HDK_TESTS}) option(HDK_IMGUI_SDL_RENDERER_EXAMPLES "Build hdk-imgui-sdl-renderer examples" ${HDK_EXAMPLES}) +if(DEFINED HDK_USE_SYSTEM_DEPS) + set(_hdk_is3r_use_system_default ${HDK_USE_SYSTEM_DEPS}) +else() + set(_hdk_is3r_use_system_default ON) +endif() + +if(DEFINED HDK_CMAKE_POLICY_DIR AND EXISTS "${HDK_CMAKE_POLICY_DIR}/HDKDependencyPolicy.cmake") + include("${HDK_CMAKE_POLICY_DIR}/HDKDependencyPolicy.cmake") +elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/HDKDependencyPolicy.cmake") + include("${CMAKE_CURRENT_SOURCE_DIR}/../cmake/HDKDependencyPolicy.cmake") +elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/HDKDependencyPolicy.cmake") + include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/HDKDependencyPolicy.cmake") +else() + message(FATAL_ERROR "Unable to locate HDKDependencyPolicy.cmake") +endif() + +option(HDK_IS3R_SYSTEM_SDL3 "Prefer system SDL3 before FetchContent fallback" ${_hdk_is3r_use_system_default}) +option(HDK_IS3R_FETCH_SDL3_FALLBACK "Fetch SDL3 when a suitable system package is unavailable" ON) +option(HDK_IS3R_SYSTEM_HDK_SDL "Prefer system hdk-sdl before FetchContent fallback" ${_hdk_is3r_use_system_default}) +option(HDK_IS3R_FETCH_HDK_SDL_FALLBACK "Fetch hdk-sdl when a suitable system package is unavailable" ON) + +if(DEFINED HDK_SDL3_MIN_VERSION) + set(_hdk_is3r_min_sdl3_version_default "${HDK_SDL3_MIN_VERSION}") +else() + set(_hdk_is3r_min_sdl3_version_default "3.4.8") +endif() + +if(DEFINED HDK_SDL_MIN_VERSION) + set(_hdk_is3r_min_sdl_version_default "${HDK_SDL_MIN_VERSION}") +else() + set(_hdk_is3r_min_sdl_version_default "0.0.1") +endif() + +if(DEFINED HDK_SDL_GIT_REPOSITORY) + set(_hdk_is3r_sdl_repo_default "${HDK_SDL_GIT_REPOSITORY}") +else() + set(_hdk_is3r_sdl_repo_default "https://git.ufp.institute/ufp/hdk-sdl.git") +endif() + +set(HDK_IS3R_MIN_SDL3_VERSION "${_hdk_is3r_min_sdl3_version_default}" CACHE STRING "Minimum SDL3 version for system package resolution") +set(HDK_IS3R_MIN_HDK_SDL_VERSION "${_hdk_is3r_min_sdl_version_default}" CACHE STRING "Minimum hdk-sdl version for system package resolution") +set(HDK_IS3R_HDK_SDL_GIT_REPOSITORY "${_hdk_is3r_sdl_repo_default}" CACHE STRING "Git repository used to fetch hdk-sdl when package resolution fails") +set(HDK_IS3R_HDK_SDL_GIT_TAG "v${HDK_IS3R_MIN_HDK_SDL_VERSION}" CACHE STRING "Git tag used to fetch hdk-sdl fallback") + if(HDK_IMGUI_SDL_RENDERER_EXAMPLES) add_subdirectory(examples) endif() @@ -16,7 +60,47 @@ if(HDK_IMGUI_SDL_RENDERER_TESTS) add_subdirectory(tests) endif() -find_package(SDL3 REQUIRED) +hdk_resolve_dependency( + NAME hdk-sdl + TARGETS hdk::hdk-sdl hdk-sdl + PACKAGE_NAMES hdk-sdl + MIN_VERSION ${HDK_IS3R_MIN_HDK_SDL_VERSION} + USE_SYSTEM ${HDK_IS3R_SYSTEM_HDK_SDL} + FETCH_FALLBACK ${HDK_IS3R_FETCH_HDK_SDL_FALLBACK} + GIT_REPOSITORY ${HDK_IS3R_HDK_SDL_GIT_REPOSITORY} + GIT_TAG ${HDK_IS3R_HDK_SDL_GIT_TAG} + FETCHCONTENT_NAME hdk-sdl +) + +if(TARGET hdk-sdl AND NOT TARGET hdk::hdk-sdl) + add_library(hdk::hdk-sdl ALIAS hdk-sdl) +endif() + +set(_hdk_is3r_need_fetch_sdl3 ON) +if(TARGET SDL3::SDL3) + set(_hdk_is3r_need_fetch_sdl3 OFF) +elseif(HDK_IS3R_SYSTEM_SDL3) + find_package(SDL3 ${HDK_IS3R_MIN_SDL3_VERSION} QUIET CONFIG) + if(SDL3_FOUND) + set(_hdk_is3r_need_fetch_sdl3 OFF) + elseif(NOT HDK_IS3R_FETCH_SDL3_FALLBACK) + message(FATAL_ERROR "SDL3 >= ${HDK_IS3R_MIN_SDL3_VERSION} not found and HDK_IS3R_FETCH_SDL3_FALLBACK=OFF") + endif() +endif() + +if(_hdk_is3r_need_fetch_sdl3) + set(SDL_TEST OFF CACHE BOOL "Disable SDL tests" FORCE) + set(SDL_EXAMPLES OFF CACHE BOOL "Disable SDL examples" FORCE) + set(SDL_INSTALL OFF CACHE BOOL "Disable SDL install" FORCE) + + include(FetchContent) + FetchContent_Declare( + SDL3 + GIT_REPOSITORY https://github.com/libsdl-org/SDL.git + GIT_TAG release-${HDK_IS3R_MIN_SDL3_VERSION} + ) + FetchContent_MakeAvailable(SDL3) +endif() include(FetchContent) FetchContent_Declare(imgui @@ -36,7 +120,7 @@ set(HDK_IMGUI_SDL_RENDERER_SOURCES ) add_library(hdk-is3r STATIC ${HDK_IMGUI_SDL_RENDERER_SOURCES}) -target_link_libraries(hdk-is3r PUBLIC hdk-sdl SDL3::SDL3) +target_link_libraries(hdk-is3r PUBLIC hdk::hdk-sdl SDL3::SDL3) target_include_directories(hdk-is3r PUBLIC $ $ @@ -44,4 +128,27 @@ target_include_directories(hdk-is3r PUBLIC $ ) -target_compile_features(hdk-is3r PUBLIC cxx_std_17) \ No newline at end of file +target_compile_features(hdk-is3r PUBLIC cxx_std_17) +include(GNUInstallDirs) + +install(TARGETS hdk-is3r + EXPORT hdk-is3rTargets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + COMPONENT hdk-imgui-sdl-renderer_dev +) + +install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + COMPONENT hdk-imgui-sdl-renderer_dev +) + +# Documentation Policy +include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/HDKDocumentationPolicy.cmake) + +set(hdk-imgui-sdl-renderer_DEBIAN_DEPENDS "hdk-sdl-dev (>= ${HDK_IS3R_MIN_HDK_SDL_VERSION})") + +# CPack Packaging Policy +include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/HDKPackaging.cmake) + diff --git a/README.md b/README.md index 1931c0d..975b92f 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,49 @@ This is the glue library required to have an ImGui renderer implementation for SDL's rendering API. As simple as it sounds but it may get split into three libraries in the future: + - `imgui-sdl-renderer`: Just the SDL Renderer glue for ImGui - `imgui-sdl`: General SDL glue for ImGui (input handling, clipboard, etc.) -- 'imgui': Core ImGUI code that has no dependencies on any backend. +- `imgui`: Core ImGUI code that has no dependencies on any backend. -This will be so that we can very easily add `imgui-sdl-opengl` and `imgui-sdl-vulkan`, etc. in the future without having to duplicate the SDL glue or ImGUI core code. +This will be so that we can very easily add `imgui-sdl-opengl` and `imgui-sdl-vulkan`, etc. +in the future without having to duplicate the SDL glue or ImGUI core code. + +## Dependency Resolution + +`hdk-is3r` resolves SDL3 with the same system-first strategy as other HDK modules: + +1. Try `find_package(SDL3 )`. +2. If unavailable or too old, optionally fall back to `FetchContent`. + +Relevant CMake options: + +- `HDK_IS3R_SYSTEM_SDL3` +- `HDK_IS3R_FETCH_SDL3_FALLBACK` +- `HDK_IS3R_MIN_SDL3_VERSION` + +## Example Assets + +`hdk-is3r` examples follow the shared HDK asset resolution contract and stage assets beside example executables in the build tree. + +Resolution order: + +1. Repository checkout assets (monorepo use) +2. Installed `hdk-assets` package with minimum version +3. `FetchContent` fallback + +Relevant CMake options: + +- `HDK_IS3R_EXAMPLES_FETCH_ASSETS` +- `HDK_IS3R_EXAMPLES_ASSETS_MIN_VERSION` +- `HDK_IS3R_EXAMPLES_ASSETS_GIT_REPOSITORY` +- `HDK_IS3R_EXAMPLES_ASSETS_GIT_TAG` + +## Installation Layout + +When enabled, installed is3r examples and shared assets go under one install prefix. + +- Example binaries: `${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}` +- Shared assets: `${CMAKE_INSTALL_PREFIX}/${HDK_IS3R_EXAMPLES_INSTALL_ASSETSDIR}` + +Default shared assets directory is `assets`, yielding `${CMAKE_INSTALL_PREFIX}/assets`. diff --git a/cmake/HDKDependencyPolicy.cmake b/cmake/HDKDependencyPolicy.cmake new file mode 100644 index 0000000..9b7d05a --- /dev/null +++ b/cmake/HDKDependencyPolicy.cmake @@ -0,0 +1,91 @@ +include(CMakeParseArguments) + +# Resolve a dependency in this order: +# 1) already-defined target(s) +# 2) find_package() system package(s) +# 3) FetchContent fallback +function(hdk_resolve_dependency) + set(_opts "") + set(_one_value NAME MIN_VERSION USE_SYSTEM FETCH_FALLBACK GIT_REPOSITORY GIT_TAG FETCHCONTENT_NAME OUT_VAR) + set(_multi_value TARGETS PACKAGE_NAMES) + cmake_parse_arguments(HDK_DEP "${_opts}" "${_one_value}" "${_multi_value}" ${ARGN}) + + if(NOT HDK_DEP_NAME) + message(FATAL_ERROR "hdk_resolve_dependency requires NAME") + endif() + if(NOT HDK_DEP_TARGETS) + message(FATAL_ERROR "hdk_resolve_dependency(${HDK_DEP_NAME}) requires TARGETS") + endif() + if(NOT HDK_DEP_FETCHCONTENT_NAME) + message(FATAL_ERROR "hdk_resolve_dependency(${HDK_DEP_NAME}) requires FETCHCONTENT_NAME") + endif() + + set(_hdk_dep_resolved_target "") + foreach(_target IN LISTS HDK_DEP_TARGETS) + if(TARGET ${_target}) + set(_hdk_dep_resolved_target ${_target}) + break() + endif() + endforeach() + + if(NOT _hdk_dep_resolved_target AND HDK_DEP_USE_SYSTEM) + foreach(_pkg IN LISTS HDK_DEP_PACKAGE_NAMES) + if(HDK_DEP_MIN_VERSION) + find_package(${_pkg} ${HDK_DEP_MIN_VERSION} QUIET CONFIG) + else() + find_package(${_pkg} QUIET CONFIG) + endif() + + foreach(_target IN LISTS HDK_DEP_TARGETS) + if(TARGET ${_target}) + set(_hdk_dep_resolved_target ${_target}) + break() + endif() + endforeach() + + if(_hdk_dep_resolved_target) + break() + endif() + endforeach() + endif() + + if(NOT _hdk_dep_resolved_target) + if(NOT HDK_DEP_FETCH_FALLBACK) + if(HDK_DEP_MIN_VERSION) + message(FATAL_ERROR "${HDK_DEP_NAME} >= ${HDK_DEP_MIN_VERSION} not found and fallback is disabled") + else() + message(FATAL_ERROR "${HDK_DEP_NAME} not found and fallback is disabled") + endif() + endif() + + if(NOT HDK_DEP_GIT_REPOSITORY) + message(FATAL_ERROR "hdk_resolve_dependency(${HDK_DEP_NAME}) fallback requires GIT_REPOSITORY") + endif() + if(NOT HDK_DEP_GIT_TAG) + message(FATAL_ERROR "hdk_resolve_dependency(${HDK_DEP_NAME}) fallback requires GIT_TAG") + endif() + + include(FetchContent) + FetchContent_Declare( + ${HDK_DEP_FETCHCONTENT_NAME} + GIT_REPOSITORY ${HDK_DEP_GIT_REPOSITORY} + GIT_TAG ${HDK_DEP_GIT_TAG} + ) + FetchContent_MakeAvailable(${HDK_DEP_FETCHCONTENT_NAME}) + + foreach(_target IN LISTS HDK_DEP_TARGETS) + if(TARGET ${_target}) + set(_hdk_dep_resolved_target ${_target}) + break() + endif() + endforeach() + endif() + + if(NOT _hdk_dep_resolved_target) + message(FATAL_ERROR "${HDK_DEP_NAME} could not be resolved to any expected target: ${HDK_DEP_TARGETS}") + endif() + + if(HDK_DEP_OUT_VAR) + set(${HDK_DEP_OUT_VAR} ${_hdk_dep_resolved_target} PARENT_SCOPE) + endif() +endfunction() diff --git a/cmake/HDKDocumentationPolicy.cmake b/cmake/HDKDocumentationPolicy.cmake new file mode 100644 index 0000000..4cca856 --- /dev/null +++ b/cmake/HDKDocumentationPolicy.cmake @@ -0,0 +1,70 @@ +# HDK Documentation Policy +include(GNUInstallDirs) + +option(${PROJECT_NAME}_DOCS "Build documentation for ${PROJECT_NAME}" OFF) + +if(${PROJECT_NAME}_DOCS) + find_package(Doxygen) + if(DOXYGEN_FOUND) + set(DOXYGEN_GENERATE_HTML YES) + set(DOXYGEN_GENERATE_MAN YES) + set(DOXYGEN_GENERATE_LATEX YES) + + set(DOXYGEN_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/docs) + set(DOXYGEN_STRIP_FROM_PATH ${CMAKE_CURRENT_SOURCE_DIR}) + set(DOXYGEN_EXTRACT_ALL YES) + set(DOXYGEN_DIRECTORY_GRAPH YES) + set(DOXYGEN_JAVADOC_BANNER YES) + set(DOXYGEN_JAVADOC_AUTOBRIEF YES) + set(DOXYGEN_DOT_IMAGE_FORMAT svg) + set(DOXYGEN_INTERACTIVE_SVG YES) + set(DOXYGEN_INTERNAL_DOCS YES) + set(DOXYGEN_TIMESTAMP YES) + set(DOXYGEN_RECURSIVE YES) + set(DOXYGEN_TAB_SIZE 2) + set(DOXYGEN_BUILTIN_STL_SUPPORT YES) + set(DOXYGEN_HTML_DYNAMIC_SECTIONS YES) + set(DOXYGEN_GENERATE_TREEVIEW YES) + set(DOXYGEN_FULL_SIDEBAR YES) + set(DOXYGEN_QUIET YES) + set(DOXYGEN_SOURCE_BROWSER YES) + set(DOXYGEN_VERBATIM_HEADERS YES) + set(DOXYGEN_REFERENCED_BY_RELATION YES) + set(DOXYGEN_REFERENCES_RELATION YES) + + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/INDEX.md") + set(DOXYGEN_USE_MDFILE_AS_MAINPAGE INDEX.md) + set(_hdk_doc_mainpage "${CMAKE_CURRENT_SOURCE_DIR}/INDEX.md") + elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/README.md") + set(DOXYGEN_USE_MDFILE_AS_MAINPAGE README.md) + set(_hdk_doc_mainpage "${CMAKE_CURRENT_SOURCE_DIR}/README.md") + endif() + + doxygen_add_docs(docs + ${_hdk_doc_mainpage} + ${CMAKE_CURRENT_SOURCE_DIR}/include/ + ${CMAKE_CURRENT_SOURCE_DIR}/src/ + ${CMAKE_CURRENT_SOURCE_DIR}/*.md + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Generate ${PROJECT_NAME} API Documentation" + ) + + # Automatically install documentation + install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/docs/html/ + DESTINATION ${CMAKE_INSTALL_DOCDIR} + COMPONENT ${PROJECT_NAME}_doc + OPTIONAL) + + install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/docs/man/man3/ + DESTINATION ${CMAKE_INSTALL_MANDIR}/man3 + COMPONENT ${PROJECT_NAME}_doc + OPTIONAL) + + install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/docs/latex/ + DESTINATION ${CMAKE_INSTALL_DOCDIR}/latex + COMPONENT ${PROJECT_NAME}_doc + OPTIONAL) + else() + message(WARNING "Doxygen not found, API documentation will not be generated for ${PROJECT_NAME}.") + endif() +endif() diff --git a/cmake/HDKExampleAssetsPolicy.cmake b/cmake/HDKExampleAssetsPolicy.cmake new file mode 100644 index 0000000..02c987e --- /dev/null +++ b/cmake/HDKExampleAssetsPolicy.cmake @@ -0,0 +1,72 @@ +include(CMakeParseArguments) +include(FetchContent) + +# Resolve hdk-assets for examples only. +function(hdk_resolve_example_assets) + set(_opts "") + set(_one_value OUT_VAR FETCH_OPTION MIN_VERSION GIT_REPOSITORY GIT_TAG CONTEXT) + cmake_parse_arguments(HDK_ASSETS "${_opts}" "${_one_value}" "" ${ARGN}) + + if(NOT HDK_ASSETS_OUT_VAR) + message(FATAL_ERROR "hdk_resolve_example_assets requires OUT_VAR") + endif() + + set(_resolved_assets_dir "") + set(_repo_assets_dir "${CMAKE_CURRENT_SOURCE_DIR}/../../assets") + if(EXISTS "${_repo_assets_dir}/textures") + set(_resolved_assets_dir "${_repo_assets_dir}") + endif() + + if(NOT _resolved_assets_dir) + if(HDK_ASSETS_MIN_VERSION) + find_package(hdk_assets ${HDK_ASSETS_MIN_VERSION} QUIET CONFIG NAMES hdk-assets hdk_assets) + else() + find_package(hdk_assets QUIET CONFIG NAMES hdk-assets hdk_assets) + endif() + + foreach(_candidate_var IN ITEMS HDK_ASSETS_SOURCE_DIR HDK_ASSETS_DIR hdk_assets_SOURCE_DIR hdk_assets_DIR) + if(NOT _resolved_assets_dir AND DEFINED ${_candidate_var}) + set(_candidate_dir "${${_candidate_var}}") + if(EXISTS "${_candidate_dir}/textures") + set(_resolved_assets_dir "${_candidate_dir}") + endif() + endif() + endforeach() + + if(NOT _resolved_assets_dir AND DEFINED hdk_assets_DIR) + get_filename_component(_hdk_assets_prefix "${hdk_assets_DIR}" DIRECTORY) + get_filename_component(_hdk_assets_prefix "${_hdk_assets_prefix}" DIRECTORY) + get_filename_component(_hdk_assets_prefix "${_hdk_assets_prefix}" DIRECTORY) + if(EXISTS "${_hdk_assets_prefix}/assets/textures") + set(_resolved_assets_dir "${_hdk_assets_prefix}/assets") + endif() + endif() + endif() + + if(NOT _resolved_assets_dir) + if(NOT HDK_ASSETS_FETCH_OPTION) + if(HDK_ASSETS_CONTEXT) + message(FATAL_ERROR "No suitable hdk-assets source found for ${HDK_ASSETS_CONTEXT} and fetch fallback is disabled") + else() + message(FATAL_ERROR "No suitable hdk-assets source found and fetch fallback is disabled") + endif() + endif() + + if(NOT HDK_ASSETS_GIT_REPOSITORY) + message(FATAL_ERROR "hdk_resolve_example_assets fallback requires GIT_REPOSITORY") + endif() + if(NOT HDK_ASSETS_GIT_TAG) + message(FATAL_ERROR "hdk_resolve_example_assets fallback requires GIT_TAG") + endif() + + FetchContent_Declare( + hdk_assets + GIT_REPOSITORY ${HDK_ASSETS_GIT_REPOSITORY} + GIT_TAG ${HDK_ASSETS_GIT_TAG} + ) + FetchContent_MakeAvailable(hdk_assets) + set(_resolved_assets_dir "${hdk_assets_SOURCE_DIR}") + endif() + + set(${HDK_ASSETS_OUT_VAR} "${_resolved_assets_dir}" PARENT_SCOPE) +endfunction() diff --git a/cmake/HDKPackaging.cmake b/cmake/HDKPackaging.cmake new file mode 100644 index 0000000..3966434 --- /dev/null +++ b/cmake/HDKPackaging.cmake @@ -0,0 +1,49 @@ +# HDK Packaging Policy + +# Define variables for CPack +set(CPACK_PACKAGE_NAME "${CMAKE_PROJECT_NAME}") +set(CPACK_PACKAGE_VERSION "${CMAKE_PROJECT_VERSION}") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${CMAKE_PROJECT_DESCRIPTION}") + +# We mainly want component-based installations for nice split packages +set(CPACK_DEB_COMPONENT_INSTALL ON CACHE INTERNAL "Enable component install") + +# Setup Debian Generator +set(CPACK_GENERATOR "DEB" CACHE INTERNAL "Deb generator") +set(CPACK_DEBIAN_PACKAGE_MAINTAINER "HDK Team" CACHE INTERNAL "HDK Team") + +# Source package generator +set(CPACK_SOURCE_GENERATOR "TGZ;ZIP" CACHE INTERNAL "Sources") +set(CPACK_SOURCE_IGNORE_FILES + "/.git/" + "/build/" + "/build.*/" + ".*~$" + CACHE INTERNAL "Ignores" +) + +# Component specific configurations +string(TOUPPER "${PROJECT_NAME}" UPPER_PROJ_NAME) + +# CPack explicitly needs UPPERCASE. Hyphens must remain hyphens in modern CMake CPack. +set(COMP_DEV "${UPPER_PROJ_NAME}_DEV") +set(COMP_DOC "${UPPER_PROJ_NAME}_DOC") +set(COMP_EXAMPLES "${UPPER_PROJ_NAME}_EXAMPLES") + +set(CPACK_DEBIAN_${COMP_DEV}_PACKAGE_NAME "${PROJECT_NAME}-dev" CACHE INTERNAL "") +set(CPACK_DEBIAN_${COMP_DOC}_PACKAGE_NAME "${PROJECT_NAME}-doc" CACHE INTERNAL "") +set(CPACK_DEBIAN_${COMP_EXAMPLES}_PACKAGE_NAME "${PROJECT_NAME}-examples" CACHE INTERNAL "") + +set(CPACK_DEBIAN_${COMP_DEV}_FILE_NAME "${PROJECT_NAME}-dev.deb" CACHE INTERNAL "") +set(CPACK_DEBIAN_${COMP_DOC}_FILE_NAME "${PROJECT_NAME}-doc.deb" CACHE INTERNAL "") +set(CPACK_DEBIAN_${COMP_EXAMPLES}_FILE_NAME "${PROJECT_NAME}-examples.deb" CACHE INTERNAL "") + +if(DEFINED ${PROJECT_NAME}_DEBIAN_DEPENDS) + set(CPACK_DEBIAN_${COMP_DEV}_PACKAGE_DEPENDS "${${PROJECT_NAME}_DEBIAN_DEPENDS}" CACHE INTERNAL "") +else() + set(CPACK_DEBIAN_PACKAGE_DEPENDS "" CACHE INTERNAL "No Debian package dependencies") +endif() + +if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + include(CPack) +endif() \ No newline at end of file diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 8f2b822..7601900 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,3 +1,73 @@ +include(FetchContent) +include(GNUInstallDirs) + +if(DEFINED HDK_CMAKE_POLICY_DIR AND EXISTS "${HDK_CMAKE_POLICY_DIR}/HDKExampleAssetsPolicy.cmake") + include("${HDK_CMAKE_POLICY_DIR}/HDKExampleAssetsPolicy.cmake") +elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/HDKExampleAssetsPolicy.cmake") + include("${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/HDKExampleAssetsPolicy.cmake") +elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/HDKExampleAssetsPolicy.cmake") + include("${CMAKE_CURRENT_SOURCE_DIR}/../cmake/HDKExampleAssetsPolicy.cmake") +else() + message(FATAL_ERROR "Unable to locate HDKExampleAssetsPolicy.cmake") +endif() + +option(HDK_IS3R_INSTALL_EXAMPLES "Install hdk-is3r example binaries and assets" OFF) +option(HDK_IS3R_EXAMPLES_FETCH_ASSETS "Fetch hdk-assets when no suitable package is found" ON) + +if(DEFINED HDK_ASSETS_MIN_VERSION) + set(_hdk_is3r_assets_min_version_default "${HDK_ASSETS_MIN_VERSION}") +else() + set(_hdk_is3r_assets_min_version_default "0.0.1") +endif() + +if(DEFINED HDK_ASSETS_GIT_REPOSITORY) + set(_hdk_is3r_assets_repo_default "${HDK_ASSETS_GIT_REPOSITORY}") +else() + set(_hdk_is3r_assets_repo_default "https://git.ufp.institute/ufp/hdk-assets.git") +endif() + +if(DEFINED HDK_INSTALL_ASSETSDIR) + set(_hdk_is3r_install_assetsdir_default "${HDK_INSTALL_ASSETSDIR}") +else() + set(_hdk_is3r_install_assetsdir_default "assets") +endif() + +set(HDK_IS3R_EXAMPLES_ASSETS_MIN_VERSION "${_hdk_is3r_assets_min_version_default}" CACHE STRING "Minimum hdk-assets version used by hdk-is3r examples") +set(HDK_IS3R_EXAMPLES_ASSETS_GIT_REPOSITORY "${_hdk_is3r_assets_repo_default}" CACHE STRING "Git repository for hdk-assets fallback in hdk-is3r examples") +set(HDK_IS3R_EXAMPLES_ASSETS_GIT_TAG "v${HDK_IS3R_EXAMPLES_ASSETS_MIN_VERSION}" CACHE STRING "Git tag used for hdk-assets fallback in hdk-is3r examples") +set(HDK_IS3R_EXAMPLES_INSTALL_ASSETSDIR "${_hdk_is3r_install_assetsdir_default}" CACHE STRING "Install destination for hdk-is3r example assets (relative to CMAKE_INSTALL_PREFIX)") + +hdk_resolve_example_assets( + OUT_VAR HDK_IS3R_EXAMPLES_ASSETS_SOURCE_DIR + FETCH_OPTION ${HDK_IS3R_EXAMPLES_FETCH_ASSETS} + MIN_VERSION ${HDK_IS3R_EXAMPLES_ASSETS_MIN_VERSION} + GIT_REPOSITORY ${HDK_IS3R_EXAMPLES_ASSETS_GIT_REPOSITORY} + GIT_TAG ${HDK_IS3R_EXAMPLES_ASSETS_GIT_TAG} + CONTEXT "hdk-is3r examples" +) +set(HDK_IS3R_EXAMPLES_ASSETS_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/../assets) + add_executable(is3r-basics is3r-basics.cpp) -target_link_libraries(is3r-basics PRIVATE hdk-is3r) \ No newline at end of file +target_link_libraries(is3r-basics PRIVATE hdk-is3r) + +add_custom_command(TARGET is3r-basics POST_BUILD + COMMAND ${CMAKE_COMMAND} -E rm -rf ${HDK_IS3R_EXAMPLES_ASSETS_BUILD_DIR} + COMMAND ${CMAKE_COMMAND} -E copy_directory + ${HDK_IS3R_EXAMPLES_ASSETS_SOURCE_DIR} + ${HDK_IS3R_EXAMPLES_ASSETS_BUILD_DIR} + COMMENT "Staging hdk-is3r example assets" + VERBATIM +) + +if(HDK_IS3R_INSTALL_EXAMPLES) + install(TARGETS is3r-basics + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + COMPONENT hdk-imgui-sdl-renderer_examples + ) + + install(DIRECTORY ${HDK_IS3R_EXAMPLES_ASSETS_SOURCE_DIR}/ + DESTINATION ${HDK_IS3R_EXAMPLES_INSTALL_ASSETSDIR} + COMPONENT hdk-imgui-sdl-renderer_examples + ) +endif() \ No newline at end of file diff --git a/examples/is3r-basics.cpp b/examples/is3r-basics.cpp index de51d91..ddeda72 100644 --- a/examples/is3r-basics.cpp +++ b/examples/is3r-basics.cpp @@ -4,10 +4,10 @@ #include "hdk/is3r.hpp" -namespace simui_example { +namespace is3r_basics { using namespace hdk; - class SimGuiApp : public is3r::Is3rApp { + class BasicApp : public is3r::Is3rApp { public: grid::eps::TapScope taps; const sdl::evt::EventConduit::Callback_t LOG_EVENT = [&](SDL_Event* event) { @@ -102,4 +102,4 @@ namespace simui_example { }; } -HDK_SDL_MAIN_CLASS(simui_example::SimGuiApp) \ No newline at end of file +HDK_SDL_MAIN_CLASS(is3r_basics::BasicApp) \ No newline at end of file