From 689d5e979d81b8ae4e2e40e3126e31c28d33bf01 Mon Sep 17 00:00:00 2001 From: BadQuanta Date: Sat, 16 May 2026 21:37:44 +0000 Subject: [PATCH] CMake Policy Implementation changes. --- .clang-format | 288 +++++++++++++++++++++++++++++ .gitignore | 1 + .gitmodules | 3 + CMakeLists.txt | 97 +++++++++- README.md | 205 +++++--------------- cmake/HDKDependencyPolicy.cmake | 91 +++++++++ cmake/HDKDocumentationPolicy.cmake | 70 +++++++ cmake/HDKExampleAssetsPolicy.cmake | 72 ++++++++ cmake/HDKPackaging.cmake | 49 +++++ examples/CMakeLists.txt | 50 ++++- hdk-cmake | 1 + include/hdk/sdl/video/Window.hpp | 4 + 12 files changed, 765 insertions(+), 166 deletions(-) create mode 100644 .clang-format create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 cmake/HDKDependencyPolicy.cmake create mode 100644 cmake/HDKDocumentationPolicy.cmake create mode 100644 cmake/HDKExampleAssetsPolicy.cmake create mode 100644 cmake/HDKPackaging.cmake create mode 160000 hdk-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/.gitmodules b/.gitmodules new file mode 100644 index 0000000..48b955d --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "hdk-cmake"] + path = hdk-cmake + url = git@ufp.institute:ufp/hdk-cmake.git diff --git a/CMakeLists.txt b/CMakeLists.txt index b00a1b3..65ce08a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,9 +13,52 @@ project(hdk-sdl option(HDK_SDL_TESTS "Build hdk-sdl tests" ${HDK_TESTS}) option(HDK_SDL_EXAMPLES "Build hdk-sdl examples" ${HDK_EXAMPLES}) option(HDK_SDL_INSTALL_TARGETS "Enable hdk-sdl install/export stubs" ON) -option(HDK_SDL_SYSTEM_SDL3 "Use system SDL3 instead of FetchContent for building" OFF) option(HDK_SDL_BUNDLE_SDL3 "Build and bundle SDL3 as a static lib with hdk-sdl install" OFF) +if(DEFINED HDK_USE_SYSTEM_DEPS) + set(_hdk_sdl_use_system_default ${HDK_USE_SYSTEM_DEPS}) +else() + set(_hdk_sdl_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_SDL_SYSTEM_SDL3 "Prefer system SDL3 before FetchContent fallback" ${_hdk_sdl_use_system_default}) +option(HDK_SDL_FETCH_SDL3_FALLBACK "Fetch SDL3 when a suitable system package is unavailable" ON) +option(HDK_SDL_SYSTEM_HDK_GRID "Prefer system hdk-grid before FetchContent fallback" ${_hdk_sdl_use_system_default}) +option(HDK_SDL_FETCH_HDK_GRID_FALLBACK "Fetch hdk-grid when a suitable system package is unavailable" ON) + +if(DEFINED HDK_SDL3_MIN_VERSION) + set(_hdk_sdl_min_sdl3_version_default "${HDK_SDL3_MIN_VERSION}") +else() + set(_hdk_sdl_min_sdl3_version_default "3.4.8") +endif() + +if(DEFINED HDK_GRID_MIN_VERSION) + set(_hdk_sdl_min_grid_version_default "${HDK_GRID_MIN_VERSION}") +else() + set(_hdk_sdl_min_grid_version_default "0.0.1") +endif() + +if(DEFINED HDK_GRID_GIT_REPOSITORY) + set(_hdk_sdl_grid_repo_default "${HDK_GRID_GIT_REPOSITORY}") +else() + set(_hdk_sdl_grid_repo_default "https://git.ufp.institute/ufp/hdk-grid.git") +endif() + +set(HDK_SDL_MIN_SDL3_VERSION "${_hdk_sdl_min_sdl3_version_default}" CACHE STRING "Minimum SDL3 version for system package resolution") +set(HDK_SDL_MIN_HDK_GRID_VERSION "${_hdk_sdl_min_grid_version_default}" CACHE STRING "Minimum hdk-grid version for system package resolution") +set(HDK_SDL_HDK_GRID_GIT_REPOSITORY "${_hdk_sdl_grid_repo_default}" CACHE STRING "Git repository used to fetch hdk-grid when package resolution fails") +set(HDK_SDL_HDK_GRID_GIT_TAG "v${HDK_SDL_MIN_HDK_GRID_VERSION}" CACHE STRING "Git tag used to fetch hdk-grid fallback") + if(HDK_SDL_SYSTEM_SDL3 AND HDK_SDL_BUNDLE_SDL3) message(FATAL_ERROR "HDK_SDL_SYSTEM_SDL3 and HDK_SDL_BUNDLE_SDL3 are mutually exclusive") endif() @@ -24,8 +67,36 @@ if(HDK_SDL_EXAMPLES) add_subdirectory(examples) endif() +hdk_resolve_dependency( + NAME hdk-grid + TARGETS hdk::hdk-grid hdk-grid + PACKAGE_NAMES hdk-grid + MIN_VERSION ${HDK_SDL_MIN_HDK_GRID_VERSION} + USE_SYSTEM ${HDK_SDL_SYSTEM_HDK_GRID} + FETCH_FALLBACK ${HDK_SDL_FETCH_HDK_GRID_FALLBACK} + GIT_REPOSITORY ${HDK_SDL_HDK_GRID_GIT_REPOSITORY} + GIT_TAG ${HDK_SDL_HDK_GRID_GIT_TAG} + FETCHCONTENT_NAME hdk-grid +) + +if(TARGET hdk-grid AND NOT TARGET hdk::hdk-grid) + add_library(hdk::hdk-grid ALIAS hdk-grid) +endif() + # FOR SDL Building -if(NOT HDK_SDL_SYSTEM_SDL3) +set(_hdk_sdl_need_fetch_sdl3 ON) +if(TARGET SDL3::SDL3) + set(_hdk_sdl_need_fetch_sdl3 OFF) +elseif(HDK_SDL_SYSTEM_SDL3) + find_package(SDL3 ${HDK_SDL_MIN_SDL3_VERSION} QUIET CONFIG) + if(SDL3_FOUND) + set(_hdk_sdl_need_fetch_sdl3 OFF) + elseif(NOT HDK_SDL_FETCH_SDL3_FALLBACK) + message(FATAL_ERROR "SDL3 >= ${HDK_SDL_MIN_SDL3_VERSION} not found and HDK_SDL_FETCH_SDL3_FALLBACK=OFF") + endif() +endif() + +if(_hdk_sdl_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) @@ -40,11 +111,9 @@ if(NOT HDK_SDL_SYSTEM_SDL3) FetchContent_Declare( SDL3 GIT_REPOSITORY https://github.com/libsdl-org/SDL.git - GIT_TAG release-3.4.8 + GIT_TAG release-${HDK_SDL_MIN_SDL3_VERSION} ) FetchContent_MakeAvailable(SDL3) -else() - find_package(SDL3 REQUIRED) endif() include(GNUInstallDirs) @@ -52,7 +121,7 @@ include(GNUInstallDirs) add_library(hdk-sdl INTERFACE) target_link_libraries(hdk-sdl INTERFACE $ - $ + $ $ $ ) @@ -67,6 +136,7 @@ if(HDK_SDL_INSTALL_TARGETS) install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + COMPONENT hdk-sdl_dev ) # Choose config file based on bundle mode @@ -93,16 +163,19 @@ if(HDK_SDL_INSTALL_TARGETS) ${CMAKE_CURRENT_BINARY_DIR}/hdk-sdlConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/hdk-sdlConfigVersion.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/hdk-sdl + COMPONENT hdk-sdl_dev ) # Bundled SDL3 install rules if(HDK_SDL_BUNDLE_SDL3) install(FILES $ DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/hdk-sdl/sdl3-static + COMPONENT hdk-sdl_dev ) - install(DIRECTORY ${sdl3_SOURCE_DIR}/include/ + install(DIRECTORY ${SDL3_SOURCE_DIR}/include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + COMPONENT hdk-sdl_dev ) configure_file( @@ -113,6 +186,7 @@ if(HDK_SDL_INSTALL_TARGETS) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/hdk-sdlBundledSDL3Targets.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/hdk-sdl + COMPONENT hdk-sdl_dev ) endif() endif() @@ -121,3 +195,12 @@ if(HDK_SDL_TESTS) add_subdirectory(test) endif() + +# Documentation Policy +include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/HDKDocumentationPolicy.cmake) + +# Set package dependencies for building debian packages correctly +set(hdk-sdl_DEBIAN_DEPENDS "hdk-grid-dev (>= ${HDK_SDL_MIN_HDK_GRID_VERSION}), libsdl3-dev") + +# CPack Packaging Policy +include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/HDKPackaging.cmake) diff --git a/README.md b/README.md index 9a6e3a2..4bb1884 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,25 @@ Use classes without declaring pointers to them, knowing that copying or referenc ## Dependencies -- holodeck-grid +- [hdk-grid](https://git.ufp.institute/ufp/hdk-grid.git) - [SDL3](https://www.libsdl.org/) +## Building + +To build the hdk-sdl, checkout the source, change into the source directory, make a build directory & run the following commands in the root of the repository: + +```bash +git clone https://git.ufp.institute/ufp/hdk-sdl.git +mkdir build-hdk-sdl +cd build-hdk-sdl +cmake ../hdk-sdl +cmake --build . +``` + +This may require the building of SDL if your system does not have the required version installed. +See [SDL3 Build Dependencies](https://wiki.libsdl.org/SDL3/README-linux#build-dependencies) if SDL fails to build on your machine. + + ## Naming Conventions API that is 1 to 1 with SDL with otherwise minimal wrapping will be as close to the original SDL function call as possible: for example, `SDL_CreateWindow` will be wrapped by `hd::sdl::Window::Create`. @@ -29,162 +45,39 @@ Within `include/hdk/sdl` there are folders for each SDL3 header files, and withi With this entirely header-only and inline design, there is no need for a corresponding .cpp and the resulting compiled code should be as efficient as if you were using the raw SDL3 API directly, while still benefiting from the safety and convenience of C++ RAII and wrapper classes. -## SDL API Coverage +## Dependency Resolution -Most links are from Links from [API by Category](https://wiki.libsdl.org/SDL3/APIByCategory), then those respective pages are used to fill in the rest of the checklist. +`hdk-sdl` resolves SDL3 with a system-first policy by default: -In progress/complete: +1. Try `find_package(SDL3 )`. +2. If unavailable or too old, fall back to `FetchContent`. -- By category: -- [ ] BASICS - - [~] [Category Video][] - - [x] `hdk::sdl::Window` - - [x] `hdk::sdl::Display` - - [ ] [Category Surface][] - - [x] `hdk::sdl::Surface` - - [ ] [Category Main][] - - [ ] [Category Init][] - - [ ] [Category Hints][] - - [x] [Category Properties][] - - [ ] [Category Error][] - - [ ] [Category Log][] - - [ ] [Category Assert][] - - [ ] [Category Version][] - - [ ] [Category Events][] - - [ ] [Category Keyboard][] - - [ ] [Category Keycode][] - - [ ] [Category Scancode][] - - [ ] [Category Mouse][] - - [ ] [Category Joystick][] - - [ ] [Category Gamepad][] - - [ ] [Category Touch][] - - [ ] [Category Pen][] - - [ ] [Category Sensor][] - - [ ] [Category HIDAPI][] -- [ ] [Category Render][] -- [ ] [Category Pixels][] -- [ ] [Category Blendmode][] -- [ ] [Category Rect][] -- [ ] [Category Clipboard][] -- [ ] [Category Vulkan][] -- [ ] [Category Metal][] -- [ ] [Category Camera][] -- [ ] HAPTIC - - [ ] [Category Haptic][] -- [ ] AUDIO - - [ ] [Category Audio][] -- [ ] GPU - - [ ] [Category GPU][] -- [ ] Time - - [ ] [Category Timer][] - - [ ] [Category Time][] -- [ ] THREADS - - [ ] [Category Thread][] - - [ ] [Category Mutex][] - - [ ] [Category Atomic][] -- [ ] FILE I/O - - [ ] [Category Filesystem][] - - [ ] [Category Storage][] - - [ ] [Category IOStream][] - - [ ] [Category AsyncIO][] -- [ ] PLATFORM - - [ ] [Category Platform][] - - [ ] [Category CPUInfo][] - - [ ] [Category Intrinsics][] - - [ ] [Category Endian][] - - [ ] [Category Bits][] -- [ ] MISC - - [N] [Category Shared Object][] - - [ ] [Category Process][] - - [ ] [Category Power][] - - [ ] [Category Messagebox][] - - [ ] [Category Dialog][] - - [ ] [Category Tray][] - - [ ] [Category Locale][] - - [ ] [Category System][] - - [ ] [Category Stdinc][] - - [ ] [Category GUID][] - - [ ] [Category Misc][] +Relevant CMake options: - -[Category Shared Object]: -[Category Assert]: https://wiki.libsdl.org/SDL3/CategoryAssert -[Category AsyncIO]: -[Category Atomic]: -[Category Audio]: - -[Category Bits]: -[Category Blendmode]: - -[Category Camera]: -[Category CPUInfo]: - -[Category Dialog]: - -[Category Endian]: -[Category Error]: https://wiki.libsdl.org/SDL3/CategoryError -[Category Events]: - -[Category Filesystem]: - -[Category Gamepad]: -[Category GPU]: -[Category GUID]: - -[Category Haptic]: -[Category HIDAPI]: -[Category Hints]: https://wiki.libsdl.org/SDL3/CategoryHints - -[Category Init]: https://wiki.libsdl.org/SDL3/CategoryInit -[Category Intrinsics]: -[Category IOStream]: - -[Category Joystick]: - -[Category Keyboard]: -[Category Keycode]: - -[Category Locale]: -[Category Log]: https://wiki.libsdl.org/SDL3/CategoryLog - -[Category Main]: https://wiki.libsdl.org/SDL3/CategoryMain -[Category Messagebox]: -[Category Metal]: -[Category Misc]: -[Category Mouse]: -[Category Mutex]: - - - -[Category Pen]: -[Category Pixels]: -[Category Platform]: -[Category Power]: -[Category Process]: -[Category Properties]: https://wiki.libsdl.org/SDL3/CategoryProperties - - -[Category Rect]: -[Category Render]: - -[Category Scancode]: -[Category Sensor]: -[Category Stdinc]: -[Category Storage]: -[Category Surface]: -[Category System]: - -[Category Thread]: -[Category Time]: -[Category Timer]: -[Category Touch]: -[Category Tray]: - - -[Category Version]: https://wiki.libsdl.org/SDL3/CategoryVersion -[Category Video]: https://wiki.libsdl.org/SDL3/CategoryVideo -[Category Vulkan]: - - - - +- `HDK_SDL_SYSTEM_SDL3` +- `HDK_SDL_FETCH_SDL3_FALLBACK` +- `HDK_SDL_MIN_SDL3_VERSION` + +## Example Assets + +When building examples, `hdk-sdl` resolves shared assets in this order: + +1. Repository checkout assets (when building inside the HDK monorepo) +2. Installed `hdk-assets` package with minimum version +3. `FetchContent` fallback from `HDK_SDL_EXAMPLES_ASSETS_GIT_REPOSITORY` + +Relevant CMake options: + +- `HDK_SDL_EXAMPLES_FETCH_ASSETS` +- `HDK_SDL_EXAMPLES_ASSETS_MIN_VERSION` +- `HDK_SDL_EXAMPLES_ASSETS_GIT_REPOSITORY` +- `HDK_SDL_EXAMPLES_ASSETS_GIT_TAG` + +## Installation Layout + +Installed examples and assets are organized under one prefix using GNU install dirs. + +- Example binaries: `${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}` +- Shared assets: `${CMAKE_INSTALL_PREFIX}/${HDK_SDL_EXAMPLES_INSTALL_ASSETSDIR}` + +The default shared assets directory is `assets`, giving `${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 0a4d0e6..b4683ee 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,10 +1,52 @@ # Simple examples for using hdk-sdl. +include(FetchContent) include(GNUInstallDirs) -option(HDK_SDL_INSTALL_EXAMPLES "Install hdk-sdl example binaries and assets" OFF) +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() -set(HDK_SDL_EXAMPLES_ASSETS_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/assets) +option(HDK_SDL_INSTALL_EXAMPLES "Install hdk-sdl example binaries and assets" OFF) +option(HDK_SDL_EXAMPLES_FETCH_ASSETS "Fetch hdk-assets when no suitable package is found" ON) + +if(DEFINED HDK_ASSETS_MIN_VERSION) + set(_hdk_sdl_assets_min_version_default "${HDK_ASSETS_MIN_VERSION}") +else() + set(_hdk_sdl_assets_min_version_default "0.0.1") +endif() + +if(DEFINED HDK_ASSETS_GIT_REPOSITORY) + set(_hdk_sdl_assets_repo_default "${HDK_ASSETS_GIT_REPOSITORY}") +else() + set(_hdk_sdl_assets_repo_default "https://git.ufp.institute/ufp/hdk-assets.git") +endif() + +if(DEFINED HDK_INSTALL_ASSETSDIR) + set(_hdk_sdl_install_assetsdir_default "${HDK_INSTALL_ASSETSDIR}") +else() + set(_hdk_sdl_install_assetsdir_default "assets") +endif() + +set(HDK_SDL_EXAMPLES_ASSETS_MIN_VERSION "${_hdk_sdl_assets_min_version_default}" CACHE STRING "Minimum hdk-assets version used by hdk-sdl examples") +set(HDK_SDL_EXAMPLES_ASSETS_GIT_REPOSITORY "${_hdk_sdl_assets_repo_default}" CACHE STRING "Git repository for hdk-assets fallback in hdk-sdl examples") +set(HDK_SDL_EXAMPLES_ASSETS_GIT_TAG "v${HDK_SDL_EXAMPLES_ASSETS_MIN_VERSION}" CACHE STRING "Git tag used for hdk-assets fallback in hdk-sdl examples") +set(HDK_SDL_EXAMPLES_INSTALL_ASSETSDIR "${_hdk_sdl_install_assetsdir_default}" CACHE STRING "Install destination for hdk-sdl example assets (relative to CMAKE_INSTALL_PREFIX)") + +hdk_resolve_example_assets( + OUT_VAR HDK_SDL_EXAMPLES_ASSETS_SOURCE_DIR + FETCH_OPTION ${HDK_SDL_EXAMPLES_FETCH_ASSETS} + MIN_VERSION ${HDK_SDL_EXAMPLES_ASSETS_MIN_VERSION} + GIT_REPOSITORY ${HDK_SDL_EXAMPLES_ASSETS_GIT_REPOSITORY} + GIT_TAG ${HDK_SDL_EXAMPLES_ASSETS_GIT_TAG} + CONTEXT "hdk-sdl examples" +) set(HDK_SDL_EXAMPLES_ASSETS_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/../assets) add_executable(HelloRenderer2D HelloRenderer2D.cpp) @@ -23,9 +65,11 @@ add_custom_command(TARGET HelloRenderer2D POST_BUILD if(HDK_SDL_INSTALL_EXAMPLES) install(TARGETS HelloRenderer2D RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + COMPONENT hdk-sdl_examples ) install(DIRECTORY ${HDK_SDL_EXAMPLES_ASSETS_SOURCE_DIR}/ - DESTINATION assets + DESTINATION ${HDK_SDL_EXAMPLES_INSTALL_ASSETSDIR} + COMPONENT hdk-sdl_examples ) endif() \ No newline at end of file diff --git a/hdk-cmake b/hdk-cmake new file mode 160000 index 0000000..141681e --- /dev/null +++ b/hdk-cmake @@ -0,0 +1 @@ +Subproject commit 141681e8cfa1d2b7fb8589c6b57a881d7e73c851 diff --git a/include/hdk/sdl/video/Window.hpp b/include/hdk/sdl/video/Window.hpp index 6127c83..9373196 100644 --- a/include/hdk/sdl/video/Window.hpp +++ b/include/hdk/sdl/video/Window.hpp @@ -9,6 +9,10 @@ namespace hdk::sdl { namespace evt { class EventConduit; } + /** + * @todo https://wiki.libsdl.org/SDL3/SDL_SetWindowFillDocument + * + */ class Window : public hdk::grid::SharedPtrWrapper { public: friend class Renderer;