diff --git a/.appveyor.yml b/.appveyor.yml index a81930c63..f40f65d01 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -2,7 +2,7 @@ # # SPDX-License-Identifier: Apache-2.0 -version: 1.0.31.{build} +version: 1.0.32.{build} image: Visual Studio 2017 diff --git a/.azure-pipelines/shared/build_jobs.yml b/.azure-pipelines/shared/build_jobs.yml index 213a40a84..b9c88cabf 100644 --- a/.azure-pipelines/shared/build_jobs.yml +++ b/.azure-pipelines/shared/build_jobs.yml @@ -26,8 +26,9 @@ jobs: presentationBackend: wayland pool: vmImage: "ubuntu-latest" - container: khronosgroup/docker-images:openxr-sdk.20230323 - # container: khronosgroup/docker-images@sha256:20edadbaa6cdec4fed7417c24b18dfb4b93eec940fdf1a27b5f97272dec47032 + # 20230614 + container: khronosgroup/docker-images:openxr-sdk@sha256:fbc5fe29a0787cccc8f66bd9bd03c9dbddf591c7d1aea673108c38c908b280f5 + steps: # First build as debug - template: build_linux.yml diff --git a/.azure-pipelines/shared/build_linux.yml b/.azure-pipelines/shared/build_linux.yml index 498547664..339a18e3a 100644 --- a/.azure-pipelines/shared/build_linux.yml +++ b/.azure-pipelines/shared/build_linux.yml @@ -16,15 +16,15 @@ parameters: default: build steps: - - script: | - rm -rf ${{ parameters.sourceDir }}/${{ parameters.buildDir }} - mkdir -p ${{ parameters.sourceDir }}/${{ parameters.buildDir }} - displayName: "Clean up and create new build directory" + - checkout: self + lfs: true + - script: "rm -rf ${{ parameters.sourceDir }}/${{ parameters.buildDir }}" + displayName: "Clean up build directory" - - script: cmake -G Ninja .. -DCMAKE_BUILD_TYPE=${{ parameters.buildType }} ${{ parameters.cmakeArgs }} - workingDirectory: ${{ parameters.sourceDir }}/${{ parameters.buildDir }} + - script: "cmake -G Ninja -S . -B ${{ parameters.buildDir }} -DCMAKE_BUILD_TYPE=${{ parameters.buildType }} ${{ parameters.cmakeArgs }}" + workingDirectory: "${{ parameters.sourceDir }}" displayName: "Generate build system" - - script: ninja - workingDirectory: ${{ parameters.sourceDir }}/${{ parameters.buildDir }} + - script: "ninja -C ${{ parameters.buildDir }}" + workingDirectory: "${{ parameters.sourceDir }}" displayName: "Compile" diff --git a/.azure-pipelines/shared/build_mingw.yml b/.azure-pipelines/shared/build_mingw.yml index 13c41b172..0d38848a0 100644 --- a/.azure-pipelines/shared/build_mingw.yml +++ b/.azure-pipelines/shared/build_mingw.yml @@ -17,6 +17,9 @@ parameters: default: "true" steps: + - checkout: self + lfs: true + # - script: choco install -y ninja # displayName: 'Install Ninja' diff --git a/.azure-pipelines/shared/build_msvc.yml b/.azure-pipelines/shared/build_msvc.yml index 667c8b30d..6285403a0 100644 --- a/.azure-pipelines/shared/build_msvc.yml +++ b/.azure-pipelines/shared/build_msvc.yml @@ -20,6 +20,9 @@ parameters: default: "true" steps: + - checkout: self + lfs: true + - powershell: ./.azure-pipelines/shared/install_vulkan.ps1 displayName: Install Vulkan SDK workingDirectory: "${{ parameters.sourceDir }}" diff --git a/.azure-pipelines/shared/check_clang_format.yml b/.azure-pipelines/shared/check_clang_format.yml index d6d1cadbb..ac02f8833 100644 --- a/.azure-pipelines/shared/check_clang_format.yml +++ b/.azure-pipelines/shared/check_clang_format.yml @@ -6,9 +6,13 @@ jobs: displayName: "clang-format" pool: vmImage: "ubuntu-latest" - container: khronosgroup/docker-images:openxr-sdk.20230323 - # container: khronosgroup/docker-images@sha256:20edadbaa6cdec4fed7417c24b18dfb4b93eec940fdf1a27b5f97272dec47032 + # 20230614 + container: khronosgroup/docker-images:openxr-sdk@sha256:fbc5fe29a0787cccc8f66bd9bd03c9dbddf591c7d1aea673108c38c908b280f5 + steps: + - checkout: self + lfs: true + - script: ./runClangFormat.sh displayName: Run clang-format diff --git a/.azure-pipelines/shared/check_file_format.yml b/.azure-pipelines/shared/check_file_format.yml index 2c14cbc45..15deefde1 100644 --- a/.azure-pipelines/shared/check_file_format.yml +++ b/.azure-pipelines/shared/check_file_format.yml @@ -1,23 +1,24 @@ # Copyright (c) 2020-2023, The Khronos Group Inc. # SPDX-License-Identifier: Apache-2.0 jobs: -- job: check_file_format - displayName: 'Check file formatting' - pool: - vmImage: 'ubuntu-latest' - container: khronosgroup/docker-images:openxr-sdk.20230323 - # container: khronosgroup/docker-images@sha256:20edadbaa6cdec4fed7417c24b18dfb4b93eec940fdf1a27b5f97272dec47032 - steps: - - script: ./file_format.sh - displayName: File formatting checks (file_format.sh) + - job: check_file_format + displayName: "Check file formatting" + pool: + vmImage: "ubuntu-latest" + # 20230614 + container: khronosgroup/docker-images:openxr-sdk@sha256:fbc5fe29a0787cccc8f66bd9bd03c9dbddf591c7d1aea673108c38c908b280f5 - - script: git diff --patch --exit-code > file_format.patch - displayName: Save changes as diff - - script: echo "The following files need file formatting:"; sed -n -e "s/^diff.* b\///p" file_format.patch - condition: failed() - - task: PublishPipelineArtifact@1 - displayName: Publish diff - condition: failed() - inputs: - path: $(System.DefaultWorkingDirectory)/file_format.patch - artifact: file_format_changes + steps: + - script: ./file_format.sh + displayName: File formatting checks (file_format.sh) + + - script: git diff --patch --exit-code > file_format.patch + displayName: Save changes as diff + - script: echo "The following files need file formatting:"; sed -n -e "s/^diff.* b\///p" file_format.patch + condition: failed() + - task: PublishPipelineArtifact@1 + displayName: Publish diff + condition: failed() + inputs: + path: $(System.DefaultWorkingDirectory)/file_format.patch + artifact: file_format_changes diff --git a/.azure-pipelines/shared/codespell.yml b/.azure-pipelines/shared/codespell.yml index d582e5211..012cb3188 100644 --- a/.azure-pipelines/shared/codespell.yml +++ b/.azure-pipelines/shared/codespell.yml @@ -6,8 +6,12 @@ jobs: displayName: "codespell" pool: vmImage: "ubuntu-latest" - container: khronosgroup/docker-images:openxr-sdk.20230323 - # container: khronosgroup/docker-images@sha256:20edadbaa6cdec4fed7417c24b18dfb4b93eec940fdf1a27b5f97272dec47032 + # 20230614 + container: khronosgroup/docker-images:openxr-sdk@sha256:fbc5fe29a0787cccc8f66bd9bd03c9dbddf591c7d1aea673108c38c908b280f5 + steps: + - checkout: self + lfs: true + - script: ./checkCodespell displayName: Run Codespell script diff --git a/.env b/.env new file mode 100644 index 000000000..e27735275 --- /dev/null +++ b/.env @@ -0,0 +1,6 @@ +# Copyright (c) 2022-2023, The Khronos Group Inc. +# +# SPDX-License-Identifier: Apache-2.0 + +# Improves the Python editing experience with vscode. +PYTHONPATH=specification/scripts:src/scripts:external/python diff --git a/.github/workflows/check_clang_format_and_codespell.yml b/.github/workflows/check_clang_format_and_codespell.yml index 9eb304284..d807b6601 100644 --- a/.github/workflows/check_clang_format_and_codespell.yml +++ b/.github/workflows/check_clang_format_and_codespell.yml @@ -10,9 +10,14 @@ jobs: clang-format: runs-on: ubuntu-latest container: - image: khronosgroup/docker-images:openxr-sdk.20230209 + # 20230614 + image: khronosgroup/docker-images:openxr-sdk@sha256:fbc5fe29a0787cccc8f66bd9bd03c9dbddf591c7d1aea673108c38c908b280f5 + steps: - uses: actions/checkout@v4 + with: + lfs: true + - run: ./runClangFormat.sh name: Run clang-format diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index a020debff..f7579a779 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -1,4 +1,4 @@ -# Copyright 2022, Collabora, Ltd. +# Copyright 2022-2023, Collabora, Ltd. # SPDX-License-Identifier: CC0-1.0 name: Validate Gradle Wrapper @@ -16,4 +16,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + with: + lfs: true - uses: gradle/wrapper-validation-action@v1 diff --git a/.github/workflows/msvc-build-preset.yml b/.github/workflows/msvc-build-preset.yml index 56501d094..4ac2b5836 100644 --- a/.github/workflows/msvc-build-preset.yml +++ b/.github/workflows/msvc-build-preset.yml @@ -30,6 +30,8 @@ jobs: INSTALL_DIR: "${{ github.workspace }}/install" steps: - uses: actions/checkout@v4 + with: + lfs: true - name: Get modern CMake and Ninja uses: lukka/get-cmake@v3.27.7 diff --git a/.gitignore b/.gitignore index 9af0dd0de..3ea0a5d57 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,8 @@ CMakeFiles *.tar.gz *.log pregen/ +sources-jar/ +docs-jar/ generated-includes cmake_install.cmake cmake_uninstall.cmake @@ -60,7 +62,7 @@ local.properties !.azure-pipelines/nuget/NugetTemplate/build !.clang-format !.clang-tidy -!.cmake-format.json +!.cmake-format.py !.editorconfig !.git-blame-ignore-revs !.git-keep @@ -73,11 +75,13 @@ local.properties !.markdownlint.yaml !.proclamation.json !.reuse +!/.env # Output artifact *.aar *.pom clang-format-patches/ +/*.jar # Key stores *.jks diff --git a/.proclamation.json b/.proclamation.json index bb012540f..3514b2245 100644 --- a/.proclamation.json +++ b/.proclamation.json @@ -1,6 +1,6 @@ { - "#": "This is a config file for proclamation, the changelog combiner: https://gitlab.com/ryanpavlik/proclamation", - "$schema": "https://ryanpavlik.gitlab.io/proclamation/proclamation.schema.json", + "#": "This is a config file for proclamation, the changelog combiner: https://gitlab.com/proclamation/proclamation", + "$schema": "https://proclamation.gitlab.io/proclamation/proclamation.schema.json", "projects": [ { "project_name": "OpenXR SDK", diff --git a/CHANGELOG.SDK.md b/CHANGELOG.SDK.md index 864deb5dc..3f275ab1f 100644 --- a/CHANGELOG.SDK.md +++ b/CHANGELOG.SDK.md @@ -19,6 +19,95 @@ along with any public pull requests that have been accepted. In this repository in particular, since it is primarily software, pull requests may be integrated as they are accepted even between periodic updates. +## OpenXR SDK 1.0.32 (2023-11-29) + +This release contains a number of vendor extensions, plus a new ratified +revision to the `XR_KHR_loader_init` extension that specifies forwarding the +init calls to API layers. **Vendors of API layers**, primarily on Android, must +verify they can handle being passed `XR_NULL_HANDLE` for the instance parameter +of `xrGetInstanceProcAddr`, to avoid bugs when using the updated loader. This +release also contains a number of build system cleanups and fixes. Users of the +Android Gradle Plugin and our official loader AAR file can now use the +`OpenXR::headers` target just like on desktop: there is now metadata for the +"prefab" tool to generate for CMake both this header/include-only target and the +normal `OpenXR::openxr_loader` imported library target. The shipped AAR is much +smaller due to stripping debug data from the binaries, which helps in case +application build systems do not automatically strip native binaries. A bug in +the loader Android manifest as shipped in 1.0.31 has also been fixed. + +- Registry + - Extension reservation: Reserve extension id for `XR_KHR_maintenance1` + ([internal MR 3010](https://gitlab.khronos.org/openxr/openxr/merge_requests/3010)) + - Extension reservation: Reserve extension id for `XR_KHR_game_controller` + ([internal MR 3019](https://gitlab.khronos.org/openxr/openxr/merge_requests/3019)) + - New vendor extension: `XR_HTC_anchor` + ([internal MR 2667](https://gitlab.khronos.org/openxr/openxr/merge_requests/2667)) + - New vendor extension: `XR_META_touch_controller_plus` + ([internal MR 2702](https://gitlab.khronos.org/openxr/openxr/merge_requests/2702)) + - New vendor extension: `XR_ML_marker_understanding` + ([internal MR 2750](https://gitlab.khronos.org/openxr/openxr/merge_requests/2750)) + - New vendor extension: `XR_ML_localization_map` + ([internal MR 2802](https://gitlab.khronos.org/openxr/openxr/merge_requests/2802), + [internal MR 3045](https://gitlab.khronos.org/openxr/openxr/merge_requests/3045), + [internal MR 3047](https://gitlab.khronos.org/openxr/openxr/merge_requests/3047)) + - `XR_KHR_loader_init`: New Khronos ratified revision, adds support for + forwarding loader init calls to API layers + ([internal MR 2703](https://gitlab.khronos.org/openxr/openxr/merge_requests/2703)) +- SDK + - Loader: Pass `xrInitializeLoaderKHR` calls to enabled API layers if + `XR_KHR_loader_init` is enabled, per ratified update to that extension. + ([internal MR 2703](https://gitlab.khronos.org/openxr/openxr/merge_requests/2703)) + - Loader: Partial fix for the loader not honoring + `BUILD_LOADER_WITH_EXCEPTION_HANDLING` on Android. + ([internal MR 2870](https://gitlab.khronos.org/openxr/openxr/merge_requests/2870), + [OpenXR-SDK-Source PR 405](https://github.com/KhronosGroup/OpenXR-SDK-Source/pull/405), + [internal issue 1999](https://gitlab.khronos.org/openxr/openxr/issues/1999)) + - Loader Android AAR: Strip binaries before inclusion in AAR, as loader is stable + (and mostly shared with all platforms) and size difference is substantial. + - Loader Android AAR: Expose `OpenXR::headers` prefab imported target just as on + desktop builds + ([internal MR 2886](https://gitlab.khronos.org/openxr/openxr/merge_requests/2886)) + - Loader Android AAR: Generate a source jar file for completeness. + ([internal MR 2886](https://gitlab.khronos.org/openxr/openxr/merge_requests/2886)) + - Loader Android AAR: Add `` elements to Android loader AAR manifest, + to prevent the manifest merger from assuming a version < 4 and adding unneeded + permissions accordingly. + ([internal MR 3029](https://gitlab.khronos.org/openxr/openxr/merge_requests/3029)) + ([internal MR 3032](https://gitlab.khronos.org/openxr/openxr/merge_requests/3032)) + - Clean up our CMake build substantially, correcting dependencies and narrowing + the scope of includes. + ([internal MR 2886](https://gitlab.khronos.org/openxr/openxr/merge_requests/2886), + [OpenXR-SDK-Source issue 344](https://github.com/KhronosGroup/OpenXR-SDK-Source/issues/344), + [internal issue 1872](https://gitlab.khronos.org/openxr/openxr/issues/1872), + [OpenXR-SDK-Source issue 419](https://github.com/KhronosGroup/OpenXR-SDK-Source/issues/419), + [internal issue 2071](https://gitlab.khronos.org/openxr/openxr/issues/2071), + [internal MR 2987](https://gitlab.khronos.org/openxr/openxr/merge_requests/2987)) + - Fix build in directories containing spaces. + ([internal MR 2886](https://gitlab.khronos.org/openxr/openxr/merge_requests/2886), + [OpenXR-SDK-Source issue 344](https://github.com/KhronosGroup/OpenXR-SDK-Source/issues/344), + [internal issue 1872](https://gitlab.khronos.org/openxr/openxr/issues/1872), + [OpenXR-SDK-Source issue 419](https://github.com/KhronosGroup/OpenXR-SDK-Source/issues/419), + [internal issue 2071](https://gitlab.khronos.org/openxr/openxr/issues/2071), + [internal MR 2987](https://gitlab.khronos.org/openxr/openxr/merge_requests/2987)) + - Fix linking to GLX when glvnd is not found on the system + ([internal MR 3000](https://gitlab.khronos.org/openxr/openxr/merge_requests/3000)) + - Fix use of `OpenXR::headers` target when not building the loader. + ([internal MR 2886](https://gitlab.khronos.org/openxr/openxr/merge_requests/2886), + [OpenXR-SDK-Source issue 344](https://github.com/KhronosGroup/OpenXR-SDK-Source/issues/344), + [internal issue 1872](https://gitlab.khronos.org/openxr/openxr/issues/1872), + [OpenXR-SDK-Source issue 419](https://github.com/KhronosGroup/OpenXR-SDK-Source/issues/419), + [internal issue 2071](https://gitlab.khronos.org/openxr/openxr/issues/2071), + [internal MR 2987](https://gitlab.khronos.org/openxr/openxr/merge_requests/2987)) + - scripts: Migrate `namedtuple` usage to dataclass, and expose the definitions + for reuse. + ([internal MR 2183](https://gitlab.khronos.org/openxr/openxr/merge_requests/2183)) + - scripts: Clean up formatting, clean up some issues found by type-aware Python + editors, and improve the experience of editing Python scripts in some editors + by adding a `.env` file. + ([internal MR 2183](https://gitlab.khronos.org/openxr/openxr/merge_requests/2183)) + - scripts: Support base header types with no derived types defined yet. + ([internal MR 2802](https://gitlab.khronos.org/openxr/openxr/merge_requests/2802)) + ## OpenXR SDK 1.0.31 (2023-10-18) This release features two new vendor extensions and minor extension XML diff --git a/CMakeLists.txt b/CMakeLists.txt index f2d5180de..50dbd254c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,15 +13,12 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -# -# Author: -# # Note: This is the top-level CMake file for the OpenXR project. # It should contain only definitions that are applicable to the # entire project and includes for the sub-directories. -cmake_minimum_required(VERSION 3.0...3.16) +cmake_minimum_required(VERSION 3.16) project(OPENXR) find_package(PythonInterp 3) @@ -29,7 +26,9 @@ include(CTest) # Enable IDE GUI folders. "Helper targets" that don't have interesting source code should set their FOLDER property to this set_property(GLOBAL PROPERTY USE_FOLDERS ON) -set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "CMake predefined targets") +set_property( + GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "CMake predefined targets" +) set(LOADER_FOLDER "Loader") set(HELPER_FOLDER "Helpers") set(CODEGEN_FOLDER "Generated") @@ -39,7 +38,11 @@ set(LOADER_TESTS_FOLDER "Loader Tests") set(API_LAYERS_FOLDER "Layers") set(SAMPLES_FOLDER "Samples") -option(BUILD_FORCE_GENERATION "Force re-generation of files even in the presence of pre-generated copies, replacing those copies." OFF) +option( + BUILD_FORCE_GENERATION + "Force re-generation of files even in the presence of pre-generated copies, replacing those copies." + OFF +) if(BUILD_FORCE_GENERATION AND NOT PYTHON_EXECUTABLE) message(FATAL_ERROR "BUILD_FORCE_GENERATION requires Python") @@ -49,7 +52,11 @@ string(TOUPPER "${CMAKE_GENERATOR_PLATFORM}" CMAKE_GENERATOR_PLATFORM_UPPER) # Artifact organization if(WIN32 OR ANDROID) - option(INSTALL_TO_ARCHITECTURE_PREFIXES "Install platform-specific files to architecture-specific directories, for packaging" OFF) + option( + INSTALL_TO_ARCHITECTURE_PREFIXES + "Install platform-specific files to architecture-specific directories, for packaging" + OFF + ) endif() if(WIN32 AND INSTALL_TO_ARCHITECTURE_PREFIXES) @@ -78,16 +85,26 @@ if(WIN32 AND INSTALL_TO_ARCHITECTURE_PREFIXES) elseif(ANDROID AND INSTALL_TO_ARCHITECTURE_PREFIXES) # This organizes things like a prefab module set(PREFAB_INSTALL_DIR prefab) - set(PREFAB_MODULE_INSTALL_DIR ${PREFAB_INSTALL_DIR}/modules/openxr_loader) - set(CMAKE_INSTALL_LIBDIR ${PREFAB_MODULE_INSTALL_DIR}/libs/android.${ANDROID_ABI} CACHE STRING "Where to install libraries") + set(PREFAB_HEADER_MODULE_INSTALL_DIR + "${PREFAB_INSTALL_DIR}/modules/headers" + ) + set(PREFAB_LOADER_MODULE_INSTALL_DIR + "${PREFAB_INSTALL_DIR}/modules/openxr_loader" + ) + set(CMAKE_INSTALL_LIBDIR + "${PREFAB_LOADER_MODULE_INSTALL_DIR}/libs/android.${ANDROID_ABI}" + CACHE STRING "Where to install libraries" + ) set(CMAKE_INSTALL_BINDIR ${CMAKE_INSTALL_LIBDIR}) - set(CMAKE_INSTALL_INCLUDEDIR ${PREFAB_MODULE_INSTALL_DIR}/include) + set(CMAKE_INSTALL_INCLUDEDIR ${PREFAB_HEADER_MODULE_INSTALL_DIR}/include) unset(NDK_MAJOR_VERSION) if(CMAKE_ANDROID_NDK) file(STRINGS "${CMAKE_ANDROID_NDK}/source.properties" NDK_PROPERTIES) foreach(_line ${NDK_PROPERTIES}) - if("${_line}" MATCHES "Pkg.Revision = ([0-9]+)[.]([0-9]+)[.]([0-9]+)") + if("${_line}" MATCHES + "Pkg.Revision = ([0-9]+)[.]([0-9]+)[.]([0-9]+)" + ) set(NDK_MAJOR_VERSION ${CMAKE_MATCH_1}) endif() endforeach() @@ -97,41 +114,78 @@ elseif(ANDROID AND INSTALL_TO_ARCHITECTURE_PREFIXES) if(NDK_MAJOR_VERSION) message(STATUS "Building using NDK major version ${NDK_MAJOR_VERSION}") else() - message(FATAL_ERROR "Could not parse the major version from ${CMAKE_ANDROID_NDK}/source.properties") + message( + FATAL_ERROR + "Could not parse the major version from ${CMAKE_ANDROID_NDK}/source.properties" + ) endif() elseif(NOT ANDROID) include(GNUInstallDirs) endif() +# Path separators ( : or ; ) are not handled well in CMake. +# This seems like a reasonable approach. +if(CMAKE_HOST_SYSTEM_NAME STREQUAL Windows) + set(CODEGEN_PYTHON_PATH + "${PROJECT_SOURCE_DIR}/specification/scripts;${PROJECT_SOURCE_DIR}/src/scripts;$ENV{PYTHONPATH}" + ) +else() + set(CODEGEN_PYTHON_PATH + "${PROJECT_SOURCE_DIR}/specification/scripts:${PROJECT_SOURCE_DIR}/src/scripts:$ENV{PYTHONPATH}" + ) +endif() + add_subdirectory(include) add_subdirectory(src) # uninstall target if(NOT TARGET uninstall) - configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/cmake/cmake_uninstall.cmake.in" - "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" - IMMEDIATE - @ONLY) - add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) + configure_file( + src/cmake/cmake_uninstall.cmake.in + "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" + IMMEDIATE + @ONLY + ) + add_custom_target( + uninstall + COMMAND + ${CMAKE_COMMAND} -P + ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake + ) set_target_properties(uninstall PROPERTIES FOLDER ${HELPER_FOLDER}) endif() find_program(BASH_COMMAND NAMES bash) if(BASH_COMMAND AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/specification/Makefile") - option(BUILD_SPECIFICATION "Run './makeAllExts all' in the specification directory as part of the build - intended for one-step checking of spec changes" OFF) + option( + BUILD_SPECIFICATION + "Run './makeAllExts all' in the specification directory as part of the build - intended for one-step checking of spec changes" + OFF + ) if(BUILD_SPECIFICATION) - add_custom_target(spec-all ALL - ${BASH_COMMAND} ./makeAllExts all + add_custom_target( + spec-all ALL + "${BASH_COMMAND}" ./makeAllExts all WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/specification" VERBATIM COMMENT "Running './makeAllExts all' in the specification directory" - USES_TERMINAL) + USES_TERMINAL + ) endif() endif() if(ANDROID AND INSTALL_TO_ARCHITECTURE_PREFIXES) - install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE" DESTINATION META-INF COMPONENT License) + install( + FILES "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE" + DESTINATION META-INF + COMPONENT License + ) + else() - install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE" DESTINATION share/doc/openxr COMPONENT License) + install( + FILES "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE" + DESTINATION share/doc/openxr + COMPONENT License + ) endif() diff --git a/changes/README.md b/changes/README.md index fb31fb3c3..c87e70753 100644 --- a/changes/README.md +++ b/changes/README.md @@ -8,10 +8,10 @@ If you want to preview the changelog or perform a release, you can run a command like the following to install it locally: ```sh -pip3 install proclamation +pipx install proclamation ``` -See for more details on *proclamation*. +See for more details on *proclamation*. ## Fragments diff --git a/external/include/CMakeLists.txt b/external/include/CMakeLists.txt index dd0a905be..838161470 100644 --- a/external/include/CMakeLists.txt +++ b/external/include/CMakeLists.txt @@ -2,10 +2,9 @@ # # SPDX-License-Identifier: Apache-2.0 -set( INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}" ) +set(INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") -set( GL_HEADERS - ${INCLUDE_DIR}/GL/gl_format.h ) +set(GL_HEADERS ${INCLUDE_DIR}/GL/gl_format.h) # These can be dropped by some subsetted source distributions since # they ought to exist, if required, in your OpenGL SDK package. @@ -15,5 +14,5 @@ foreach(FN ${INCLUDE_DIR}/GL/glext.h ${INCLUDE_DIR}/GL/wglext.h) endif() endforeach() -source_group( GL FILES ${GL_HEADERS} ) -set_property( TARGET include PROPERTY FOLDER external/include ) +source_group(GL FILES ${GL_HEADERS}) +set_property(TARGET include PROPERTY FOLDER external/include) diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 46f615acd..0977a0bf2 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2017 The Khronos Group Inc. +# Copyright (c) 2017-2023, The Khronos Group Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -13,8 +13,5 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -# -# Author: -# add_subdirectory(openxr) diff --git a/include/openxr/CMakeLists.txt b/include/openxr/CMakeLists.txt index b1718f60e..c814df48d 100644 --- a/include/openxr/CMakeLists.txt +++ b/include/openxr/CMakeLists.txt @@ -13,93 +13,116 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -# -# Author: -# - -# Copy the openxr_platform_defines.h file and place it in the binary (build) directory. -configure_file(openxr_platform_defines.h ${CMAKE_CURRENT_BINARY_DIR}/openxr_platform_defines.h COPYONLY) # Generate OpenXR header files. # Get the list of generated headers from the common single-point-of-truth -file(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/../generated_header_list.txt HEADERS LENGTH_MINIMUM 8) +file(STRINGS "../generated_header_list.txt" HEADERS LENGTH_MINIMUM 8) set(HAVE_PREGENERATED TRUE) set(SOURCE_HEADERS) foreach(output ${HEADERS}) - list(APPEND SOURCE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/${output}) - if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${output}) + list(APPEND SOURCE_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/${output}") + if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${output}") set(HAVE_PREGENERATED FALSE) endif() endforeach() -set(XR_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../..) +add_library(headers INTERFACE) +# Create alias so that it can be used the same whether vendored as source or found with CMake. +# Other targets that need the OpenXR headers should specify OpenXR::headers in their target_link_libraries. +add_library(OpenXR::headers ALIAS headers) +target_include_directories( + headers INTERFACE $ +) + if(HAVE_PREGENERATED AND NOT BUILD_FORCE_GENERATION) - add_custom_target(generate_openxr_header - COMMENT "Using found pre-generated OpenXR headers.") + add_custom_target( + generate_openxr_header + COMMENT "Using found pre-generated OpenXR headers." + ) + + set(INSTALL_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/openxr_platform_defines.h" + ${SOURCE_HEADERS} + ) - set(INSTALL_HEADERS - ${CMAKE_CURRENT_SOURCE_DIR}/openxr_platform_defines.h - ${SOURCE_HEADERS}) + # All headers are in the source dir + target_include_directories( + headers INTERFACE $ + ) else() set(GENERATED_HEADERS) set(OUTPUT_STAMPS) # Copy the openxr_platform_defines.h file and place it in the binary (build) directory. - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/openxr_platform_defines.h - ${CMAKE_CURRENT_BINARY_DIR}/openxr_platform_defines.h - COPYONLY) + configure_file( + openxr_platform_defines.h + "${CMAKE_CURRENT_BINARY_DIR}/openxr_platform_defines.h" COPYONLY + ) # Generate the header files and place it in the binary (build) directory. - file(GLOB _templates LIST_DIRECTORIES false CONFIGURE_DEPENDS ${XR_ROOT}/specification/scripts/template_*) + file( + GLOB _templates + LIST_DIRECTORIES false + CONFIGURE_DEPENDS + "${PROJECT_SOURCE_DIR}/specification/scripts/template_*" + ) foreach(output ${HEADERS}) if("${output}" MATCHES "reflection") - set(_extra_deps ${XR_ROOT}/specification/scripts/jinja_helpers.py ${_templates}) + set(_extra_deps + "${PROJECT_SOURCE_DIR}/specification/scripts/jinja_helpers.py" + ${_templates} + ) else() unset(_extra_deps) endif() - add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${output} - COMMAND ${PYTHON_EXECUTABLE} ${XR_ROOT}/specification/scripts/genxr.py - -registry ${XR_ROOT}/specification/registry/xr.xml - -o ${CMAKE_CURRENT_BINARY_DIR} ${output} + add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${output}" + COMMAND + "${CMAKE_COMMAND}" -E env "PYTHONPATH=${CODEGEN_PYTHON_PATH}" + "${PYTHON_EXECUTABLE}" + "${PROJECT_SOURCE_DIR}/specification/scripts/genxr.py" -registry + "${PROJECT_SOURCE_DIR}/specification/registry/xr.xml" -o + "${CMAKE_CURRENT_BINARY_DIR}" ${output} DEPENDS - ${XR_ROOT}/specification/scripts/genxr.py - ${XR_ROOT}/specification/scripts/cgenerator.py - ${XR_ROOT}/specification/scripts/creflectiongenerator.py - ${XR_ROOT}/specification/scripts/generator.py - ${XR_ROOT}/specification/scripts/reg.py - ${XR_ROOT}/specification/registry/xr.xml + "${PROJECT_SOURCE_DIR}/specification/scripts/genxr.py" + "${PROJECT_SOURCE_DIR}/specification/scripts/cgenerator.py" + "${PROJECT_SOURCE_DIR}/specification/scripts/creflectiongenerator.py" + "${PROJECT_SOURCE_DIR}/specification/scripts/generator.py" + "${PROJECT_SOURCE_DIR}/specification/scripts/reg.py" + "${PROJECT_SOURCE_DIR}/specification/registry/xr.xml" ${_extra_deps} COMMENT "Generating ${CMAKE_CURRENT_BINARY_DIR}/${output}" + VERBATIM ) list(APPEND GENERATED_HEADERS "${CMAKE_CURRENT_BINARY_DIR}/${output}") endforeach() - set_source_files_properties( - ${GENERATED_HEADERS} - PROPERTIES GENERATED TRUE - ) - - set(INSTALL_HEADERS - ${CMAKE_CURRENT_BINARY_DIR}/openxr_platform_defines.h - ${GENERATED_HEADERS}) + set_source_files_properties(${GENERATED_HEADERS} PROPERTIES GENERATED TRUE) + set(INSTALL_HEADERS ${CMAKE_CURRENT_BINARY_DIR}/openxr_platform_defines.h + ${GENERATED_HEADERS} + ) # Define generate_openxr_header target to generate the OpenXR header files. - # Other targets that need the OpenXR headers should use generate_openxr_header as a dependency. - add_custom_target(generate_openxr_header - SOURCES ${XR_ROOT}/specification/registry/xr.xml - DEPENDS - ${GENERATED_HEADERS} - ${OUTPUT_STAMPS} + # Not used directly - depended on by OpenXR::headers + add_custom_target( + generate_openxr_header + SOURCES "${PROJECT_SOURCE_DIR}/specification/registry/xr.xml" + DEPENDS ${GENERATED_HEADERS} ${OUTPUT_STAMPS} + ) + # Headers are all in the binary dir + target_include_directories( + headers INTERFACE $ ) endif() -set_target_properties(generate_openxr_header PROPERTIES FOLDER ${CODEGEN_FOLDER}) +set_target_properties( + generate_openxr_header PROPERTIES FOLDER ${CODEGEN_FOLDER} +) -# make cache variables for install destinations -include(GNUInstallDirs) +add_dependencies(headers generate_openxr_header) -INSTALL(FILES ${INSTALL_HEADERS} +install( + FILES ${INSTALL_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openxr COMPONENT Headers ) diff --git a/maintainer-scripts/build-aar.sh b/maintainer-scripts/build-aar.sh index 867407464..452889b00 100755 --- a/maintainer-scripts/build-aar.sh +++ b/maintainer-scripts/build-aar.sh @@ -36,6 +36,11 @@ ANDROID_STL=c++_static CONFIG=Release ANDROID_PLATFORM=24 +if [ -z "$ANDROID_NDK_HOME" ]; then + logMsg "No ANDROID_NDK_HOME defined!" + exit 1 +fi + logMsg "ANDROID_NDK_HOME: ${ANDROID_NDK_HOME}" logMsg "ANDROID_STL: ${ANDROID_STL}" logMsg "CONFIG: ${CONFIG}" @@ -80,9 +85,9 @@ for arch in x86 x86_64 armeabi-v7a arm64-v8a; do logMsg "Installing for arch ${arch}" + # Component-wise install of the build, since we do not want all components for comp in License Headers Loader Prefab; do - # Component-wise install of the build, since we do not want all components - cmake -DCMAKE_INSTALL_COMPONENT=${comp} -P "${BUILD_DIR}/${arch}/cmake_install.cmake" + cmake --install "${BUILD_DIR}/${arch}/" --strip --component "${comp}" done done @@ -90,11 +95,65 @@ done DECORATED=$(cd "${BUILD_DIR}/x86/src/loader" && ls openxr_loader*.pom) cp "${BUILD_DIR}/x86/src/loader/${DECORATED}" . -DIR=$(pwd) +EXTRA_MANIFEST_ENTRIES="${BUILD_DIR}/x86/src/loader/additional_manifest.mf" + ( logMsg "Packing AAR file" cd "$INSTALL_DIR/openxr" - AARFILE="$DIR/${DECORATED%.pom}.aar" - jar --create --file="${AARFILE}" ./* + AARFILE="$ROOT/${DECORATED%.pom}.aar" + jar --create --file="${AARFILE}" "--manifest=${EXTRA_MANIFEST_ENTRIES}" ./* logMsg "AAR file created: ${AARFILE}" ) + +logMsg "Archiving SDK sources" +SOURCES_JAR_ROOT=sources-jar +SOURCES_NAMESPACE_PATH=org/khronos/openxr/openxr_loader_for_android +rm -f OpenXR-SDK.tar.gz +rm -rf ${SOURCES_JAR_ROOT} +mkdir -p ${SOURCES_JAR_ROOT}/${SOURCES_NAMESPACE_PATH} +maintainer-scripts/archive-sdk.sh + +logMsg "Repacking SDK sources as a sources jar" +SOURCESFILE="$ROOT/${DECORATED%.pom}-sources.jar" +( + cd ${SOURCES_JAR_ROOT}/${SOURCES_NAMESPACE_PATH} + tar xf "${ROOT}/OpenXR-SDK.tar.gz" + + # Add files we want, for reproducibility + mkdir -p maintainer-scripts + cp "${ROOT}/maintainer-scripts/build-aar.sh" maintainer-scripts + cp "${ROOT}/maintainer-scripts/archive-sdk.sh" maintainer-scripts + cp "${ROOT}/maintainer-scripts/common.sh" maintainer-scripts + + # Drop files/dirs we don't care about + rm -rf \ + .appveyor.yml \ + .azure-pipelines \ + .editorconfig \ + .git-blame-ignore-revs \ + .gitattributes \ + .github \ + .gitignore \ + doc + + # Drop licenses not actually used in this code, based on `reuse lint` in OpenXR-SDK + rm -f \ + LICENSES/OFL-1.1-RFN.txt \ + LICENSES/Unlicense.txt \ + LICENSES/LicenseRef-Khronos-Free-Use-License-for-Software-and-Documentation.txt \ + LICENSES/ISC.txt \ + LICENSES/LicenseRef-KhronosSpecCopyright-WithNormativeWording-v10.txt \ + LICENSES/Zlib.txt + + # Remove the bare copy of Apache-2.0 named LICENSE since it is confusing. + rm -f LICENSE + + # Move the copying and license files to the jar root + mv COPYING.adoc "$ROOT/${SOURCES_JAR_ROOT}" + mv LICENSES "$ROOT/${SOURCES_JAR_ROOT}" +) +( + cd ${SOURCES_JAR_ROOT} + jar --create --file="${SOURCESFILE}" "--manifest=${EXTRA_MANIFEST_ENTRIES}" ./* + logMsg "Sources JAR file created: ${SOURCESFILE}" +) diff --git a/maintainer-scripts/common.sh b/maintainer-scripts/common.sh index 540578be0..cce5a6f12 100644 --- a/maintainer-scripts/common.sh +++ b/maintainer-scripts/common.sh @@ -110,6 +110,7 @@ getDocsFilenames() { # TODO omitting style guide VUID chapter for now git ls-files \ $COMMON_FILES \ + .env \ .proclamation.json \ .proclamation.json.license \ CHANGELOG.Docs.md \ @@ -145,6 +146,7 @@ getSDKSourceFilenames() { git ls-files \ $COMMON_FILES \ .appveyor.yml \ + .env \ .proclamation.json \ .proclamation.json.license \ BUILDING.md \ @@ -258,9 +260,9 @@ getSDKFilenames() { getConformanceFilenames() { set -e # The src/conformance directory, plus the minimum subset of the other files required. - # TODO need a mention in the spec folder about how it's not under the same license (?) git ls-files \ $COMMON_FILES \ + .env \ .proclamation.json \ .proclamation.json.license \ BUILDING.md \ @@ -272,8 +274,6 @@ getConformanceFilenames() { openxr-codespell.exclude \ runClangFormat.sh \ tox.ini \ - .azure-pipelines/shared \ - .azure-pipelines/openxr-cts.yml \ .github/dependabot.yml \ .github/scripts \ .github/workflows/android-cts-build.yml \ diff --git a/specification/Makefile b/specification/Makefile index 8b33904f4..136324f22 100644 --- a/specification/Makefile +++ b/specification/Makefile @@ -32,7 +32,7 @@ ifneq (,$(strip $(VERY_STRICT))) ASCIIDOC := $(ASCIIDOC) --failure-level WARN endif -SPECREVISION = 1.0.31 +SPECREVISION = 1.0.32 REVISION_COMPONENTS = $(subst ., ,$(SPECREVISION)) MAJORMINORVER = $(word 1,$(REVISION_COMPONENTS)).$(word 2,$(REVISION_COMPONENTS)) diff --git a/specification/registry/xr.xml b/specification/registry/xr.xml index 1a0cd3015..5b574cddd 100644 --- a/specification/registry/xr.xml +++ b/specification/registry/xr.xml @@ -131,7 +131,7 @@ maintained in the default branch of the Khronos OpenXR GitHub project. updates them automatically by processing a line at a time. --> // OpenXR current version number. -#define XR_CURRENT_API_VERSION XR_MAKE_VERSION(1, 0, 31) +#define XR_CURRENT_API_VERSION XR_MAKE_VERSION(1, 0, 32) XR_DEFINE_ATOM(XrRenderModelKeyFB) + + XR_DEFINE_ATOM(XrMarkerML) @@ -378,6 +380,9 @@ maintained in the default branch of the Khronos OpenXR GitHub project. typedef XrFlags64 XrVirtualKeyboardInputStateFlagsMETA; + + typedef XrFlags64 XrLocalizationMapErrorFlagsML; + XR_DEFINE_HANDLE(XrInstance) @@ -430,6 +435,12 @@ maintained in the default branch of the Khronos OpenXR GitHub project. XR_DEFINE_HANDLE(XrVirtualKeyboardMETA) + + XR_DEFINE_HANDLE(XrExportedLocalizationMapML) + + + XR_DEFINE_HANDLE(XrMarkerDetectorML) + @@ -606,6 +617,24 @@ maintained in the default branch of the Khronos OpenXR GitHub project. + + + + + + + + + + + + + + + + + + float x @@ -2773,6 +2802,23 @@ maintained in the default branch of the Khronos OpenXR GitHub project. XrPassthroughColorHTC color + + + XrStructureType type + const void* next + XrSpace space + XrPosef poseInSpace + XrSpatialAnchorNameHTC name + + + char name[XR_MAX_SPATIAL_ANCHOR_NAME_SIZE_HTC] + + + XrStructureType type + void* next + XrBool32 supportsAnchor + + XrStructureType type @@ -3263,6 +3309,111 @@ maintained in the default branch of the Khronos OpenXR GitHub project. XrEyeCalibrationStatusML status + + + XrStructureType type + void* next + char name[XR_MAX_LOCALIZATION_MAP_NAME_LENGTH_ML] + XrUuidEXT mapUuid + XrLocalizationMapTypeML mapType + + + + XrStructureType type + const void* next + XrBool32 enabled + + + + XrStructureType type + const void* next + XrSession session + XrLocalizationMapStateML state + XrLocalizationMapML map + XrLocalizationMapConfidenceML confidence + XrLocalizationMapErrorFlagsML errorFlags + + + + XrStructureType type + const void* next + + + + XrStructureType type + const void* next + XrUuidEXT mapUuid + + + + XrStructureType type + const void* next + uint32_t size + char* data + + + + + + XrStructureType type + void* next + XrBool32 supportsMarkerUnderstanding + + + + XrStructureType type + const void* next + XrMarkerDetectorProfileML profile + XrMarkerTypeML markerType + + + + XrStructureType type + const void* next + XrMarkerArucoDictML arucoDict + + + + XrStructureType type + const void* next + float markerLength + + + + XrStructureType type + const void* next + XrMarkerAprilTagDictML aprilTagDict + + + + XrStructureType type + const void* next + XrMarkerDetectorFpsML fpsHint + XrMarkerDetectorResolutionML resolutionHint + XrMarkerDetectorCameraML cameraHint + XrMarkerDetectorCornerRefineMethodML cornerRefineMethod + XrBool32 useEdgeRefinement + XrMarkerDetectorFullAnalysisIntervalML fullAnalysisIntervalHint + + + + XrStructureType type + const void* next + + + + XrStructureType type + void* next + XrMarkerDetectorStatusML state + + + + XrStructureType type + const void* next + XrMarkerDetectorML markerDetector + XrMarkerML marker + XrPosef poseInMarkerSpace + @@ -3775,6 +3926,80 @@ maintained in the default branch of the Khronos OpenXR GitHub project. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -4332,6 +4557,36 @@ maintained in the default branch of the Khronos OpenXR GitHub project. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -5597,6 +5852,19 @@ maintained in the default branch of the Khronos OpenXR GitHub project. XrPassthroughHTC passthrough + + + XrResult xrCreateSpatialAnchorHTC + XrSession session + const XrSpatialAnchorCreateInfoHTC* createInfo + XrSpace* anchor + + + XrResult xrGetSpatialAnchorNameHTC + XrSpace anchor + XrSpatialAnchorNameHTC* name + + XrResult xrEnumerateViveTrackerPathsHTCX @@ -5814,7 +6082,6 @@ maintained in the default branch of the Khronos OpenXR GitHub project. XrPlaneDetectorPolygonBufferEXT* polygonBuffer - XrResult xrCreateVirtualKeyboardMETA @@ -5888,10 +6155,121 @@ maintained in the default branch of the Khronos OpenXR GitHub project. const XrVirtualKeyboardTextContextChangeInfoMETA* changeInfo + XrResult xrEnableUserCalibrationEventsML - XrInstance instance - const XrUserCalibrationEnableEventsInfoML* enableInfo + XrInstance instance + const XrUserCalibrationEnableEventsInfoML* enableInfo + + + + + XrResult xrEnableLocalizationEventsML + XrSession session + const XrLocalizationEnableEventsInfoML * info + + + + XrResult xrQueryLocalizationMapsML + XrSession session + const XrLocalizationMapQueryInfoBaseHeaderML* queryInfo + uint32_t mapCapacityInput + uint32_t * mapCountOutput + XrLocalizationMapML* maps + + + + XrResult xrRequestMapLocalizationML + XrSession session + const XrMapLocalizationRequestInfoML* requestInfo + + + + XrResult xrImportLocalizationMapML + XrSession session + const XrLocalizationMapImportInfoML* importInfo + XrUuidEXT* mapUuid + + + + XrResult xrCreateExportedLocalizationMapML + XrSession session + const XrUuidEXT* mapUuid + XrExportedLocalizationMapML* map + + + + XrResult xrDestroyExportedLocalizationMapML + XrExportedLocalizationMapML map + + + + XrResult xrGetExportedLocalizationMapDataML + XrExportedLocalizationMapML map + uint32_t bufferCapacityInput + uint32_t* bufferCountOutput + char* buffer + + + + + XrResult xrCreateMarkerDetectorML + XrSession session + const XrMarkerDetectorCreateInfoML* createInfo + XrMarkerDetectorML* markerDetector + + + XrResult xrDestroyMarkerDetectorML + XrMarkerDetectorML markerDetector + + + XrResult xrSnapshotMarkerDetectorML + XrMarkerDetectorML markerDetector + XrMarkerDetectorSnapshotInfoML* snapshotInfo + + + XrResult xrGetMarkerDetectorStateML + XrMarkerDetectorML markerDetector + XrMarkerDetectorStateML* state + + + XrResult xrGetMarkersML + XrMarkerDetectorML markerDetector + uint32_t markerCapacityInput + uint32_t* markerCountOutput + XrMarkerML* markers + + + XrResult xrGetMarkerReprojectionErrorML + XrMarkerDetectorML markerDetector + XrMarkerML marker + float* reprojectionErrorMeters + + + XrResult xrGetMarkerLengthML + XrMarkerDetectorML markerDetector + XrMarkerML marker + float* meters + + + XrResult xrGetMarkerNumberML + XrMarkerDetectorML markerDetector + XrMarkerML marker + uint64_t* number + + + XrResult xrGetMarkerStringML + XrMarkerDetectorML markerDetector + XrMarkerML marker + uint32_t bufferCapacityInput + uint32_t* bufferCountOutput + char* buffer + + + XrResult xrCreateMarkerSpaceML + XrSession session + const XrMarkerSpaceCreateInfoML* createInfo + XrSpace* space @@ -6321,6 +6699,39 @@ maintained in the default branch of the Khronos OpenXR GitHub project. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -7605,7 +8016,7 @@ maintained in the default branch of the Khronos OpenXR GitHub project. - + @@ -8471,17 +8882,114 @@ maintained in the default branch of the Khronos OpenXR GitHub project. - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -9896,10 +10404,11 @@ maintained in the default branch of the Khronos OpenXR GitHub project. - + - - + + + @@ -10223,10 +10732,19 @@ maintained in the default branch of the Khronos OpenXR GitHub project. - + - - + + + + + + + + + + + @@ -13084,6 +13602,21 @@ maintained in the default branch of the Khronos OpenXR GitHub project. + + + + + + + + + + + + + + + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f94dbf957..d055b7a7a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -22,7 +22,7 @@ endif() # Entire project uses C++14 set(CMAKE_CXX_STANDARD 14) set(CMAKE_POSITION_INDEPENDENT_CODE ON) -set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") include(StdFilesystemFlags) @@ -39,23 +39,33 @@ set(OPENGL_INCOMPATIBLE FALSE) set(VULKAN_INCOMPATIBLE FALSE) # CMake will detect OpenGL/Vulkan which are not compatible with UWP and ARM/ARM64 on Windows so skip it in these cases. -if(CMAKE_SYSTEM_NAME STREQUAL "WindowsStore" OR (WIN32 AND CMAKE_GENERATOR_PLATFORM_UPPER MATCHES "ARM.*")) +if(CMAKE_SYSTEM_NAME STREQUAL "WindowsStore" + OR (WIN32 AND CMAKE_GENERATOR_PLATFORM_UPPER MATCHES "ARM.*") +) set(OPENGL_INCOMPATIBLE TRUE) set(VULKAN_INCOMPATIBLE TRUE) message(STATUS "OpenGL/Vulkan disabled due to incompatibility") + elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") set(OPENGL_INCOMPATIBLE TRUE) message(STATUS "OpenGL disabled as no bindings exist for OpenGL on Darwin") + elseif(ANDROID) set(OPENGL_INCOMPATIBLE TRUE) - find_path(ANDROID_NATIVE_APP_GLUE android_native_app_glue.h PATHS ${ANDROID_NDK}/sources/android/native_app_glue) + find_path( + ANDROID_NATIVE_APP_GLUE android_native_app_glue.h + PATHS "${ANDROID_NDK}/sources/android/native_app_glue" + ) if(ANDROID_NATIVE_APP_GLUE) # Needed by gfxwrapper set(OPENGLES_INCOMPATIBLE FALSE) endif() if(ANDROID_PLATFORM_LEVEL LESS 24) set(VULKAN_INCOMPATIBLE TRUE) - message(STATUS "Vulkan disabled due to incompatibility: need to target at least API 24") + message( + STATUS + "Vulkan disabled due to incompatibility: need to target at least API 24" + ) endif() endif() @@ -85,10 +95,8 @@ if(NOT OPENGLES_INCOMPATIBLE) endif() if(NOT VULKAN_INCOMPATIBLE) - if(NOT CMAKE_VERSION VERSION_LESS 3.7.0) - # Find the Vulkan headers - find_package(Vulkan) - endif() + # Find the Vulkan headers + find_package(Vulkan) if(Vulkan_FOUND) set(XR_USE_GRAPHICS_API_VULKAN TRUE) add_definitions(-DXR_USE_GRAPHICS_API_VULKAN) @@ -111,9 +119,15 @@ option( ) if(WIN32) - set(OPENXR_DEBUG_POSTFIX d CACHE STRING "OpenXR loader debug postfix.") + set(OPENXR_DEBUG_POSTFIX + d + CACHE STRING "OpenXR loader debug postfix." + ) else() - set(OPENXR_DEBUG_POSTFIX "" CACHE STRING "OpenXR loader debug postfix.") + set(OPENXR_DEBUG_POSTFIX + "" + CACHE STRING "OpenXR loader debug postfix." + ) endif() if(CMAKE_SYSTEM_NAME STREQUAL "Windows") @@ -133,10 +147,16 @@ endif() include(CMakeDependentOption) cmake_dependent_option( - BUILD_WITH_SYSTEM_JSONCPP "Use system jsoncpp instead of vendored source" ON "JSONCPP_FOUND" OFF + BUILD_WITH_SYSTEM_JSONCPP + "Use system jsoncpp instead of vendored source" + ON + "JSONCPP_FOUND" + OFF ) cmake_dependent_option( - BUILD_WITH_STD_FILESYSTEM "Use std::[experimental::]filesystem." ON + BUILD_WITH_STD_FILESYSTEM + "Use std::[experimental::]filesystem." + ON "HAVE_FILESYSTEM_WITHOUT_LIB OR HAVE_FILESYSTEM_NEEDING_LIBSTDCXXFS OR HAVE_FILESYSTEM_NEEDING_LIBCXXFS" OFF ) @@ -159,9 +179,16 @@ if(MSVC) endif() # This is a little helper library for setting up OpenGL -if((OPENGL_FOUND OR OpenGLES_FOUND) AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/common/gfxwrapper_opengl.c") - add_library(openxr-gfxwrapper STATIC common/gfxwrapper_opengl.c common/gfxwrapper_opengl.h) - target_include_directories(openxr-gfxwrapper PUBLIC ${PROJECT_SOURCE_DIR}/external/include) +if((OPENGL_FOUND OR OpenGLES_FOUND) + AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/common/gfxwrapper_opengl.c" +) + add_library( + openxr-gfxwrapper STATIC common/gfxwrapper_opengl.c + common/gfxwrapper_opengl.h + ) + target_include_directories( + openxr-gfxwrapper PUBLIC "${PROJECT_SOURCE_DIR}/external/include" + ) if(OPENGL_FOUND) if(TARGET OpenGL::OpenGL) target_link_libraries(openxr-gfxwrapper PUBLIC OpenGL::OpenGL) @@ -182,28 +209,35 @@ if((OPENGL_FOUND OR OpenGLES_FOUND) AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/comm target_link_libraries(openxr-gfxwrapper PUBLIC EGL::EGL) endif() if(ANDROID) - target_include_directories(openxr-gfxwrapper PUBLIC ${ANDROID_NATIVE_APP_GLUE}) + target_include_directories( + openxr-gfxwrapper PUBLIC "${ANDROID_NATIVE_APP_GLUE}" + ) # Note: For some reason, just adding this to the gfxwrapper library results in failure at load time. # So, each consuming target must add $ to their sources - add_library(android_native_app_glue OBJECT "${ANDROID_NATIVE_APP_GLUE}/android_native_app_glue.c") - target_include_directories(android_native_app_glue PUBLIC ${ANDROID_NATIVE_APP_GLUE}) - target_compile_options(android_native_app_glue PRIVATE -Wno-unused-parameter) - elseif(APPLE) - set(apple_c_compile_options - -x objective-c++ + add_library( + android_native_app_glue OBJECT + "${ANDROID_NATIVE_APP_GLUE}/android_native_app_glue.c" ) - target_compile_options(openxr-gfxwrapper PRIVATE - ${apple_c_compile_options} + target_include_directories( + android_native_app_glue PUBLIC "${ANDROID_NATIVE_APP_GLUE}" ) - target_link_libraries(openxr-gfxwrapper PUBLIC - "-framework AppKit" - "-framework Foundation" - "-framework CoreGraphics" + target_compile_options( + android_native_app_glue PRIVATE -Wno-unused-parameter + ) + elseif(APPLE) + target_compile_options(openxr-gfxwrapper PRIVATE -x objective-c++) + target_link_libraries( + openxr-gfxwrapper + PUBLIC "-framework AppKit" "-framework Foundation" + "-framework CoreGraphics" ) endif() set_target_properties(openxr-gfxwrapper PROPERTIES FOLDER ${HELPER_FOLDER}) - message(STATUS "Enabling OpenGL support in hello_xr, loader_test, and conformance, if configured") + message( + STATUS + "Enabling OpenGL support in hello_xr, loader_test, and conformance, if configured" + ) endif() # Determine the presentation backend for Linux systems. @@ -225,7 +259,10 @@ elseif(APPLE) endif() elseif(ANDROID) add_definitions(-DXR_USE_PLATFORM_ANDROID) - set(OPENXR_ANDROID_VERSION_SUFFIX "" CACHE STRING "Suffix for generated Android artifacts.") + set(OPENXR_ANDROID_VERSION_SUFFIX + "" + CACHE STRING "Suffix for generated Android artifacts." + ) elseif(PRESENTATION_BACKEND MATCHES "xlib") add_definitions(-DXR_USE_PLATFORM_XLIB) elseif(PRESENTATION_BACKEND MATCHES "xcb") @@ -262,17 +299,37 @@ endif() # Find glslc shader compiler. # On Android, the NDK includes the binary, so no external dependency. if(ANDROID) - file(GLOB glslc_folders ${ANDROID_NDK}/shader-tools/*) + file( + GLOB + glslc_folders + CONFIGURE_DEPENDS + ${ANDROID_NDK}/shader-tools/* + ) find_program( GLSL_COMPILER glslc PATHS ${glslc_folders} NO_DEFAULT_PATH ) else() - file(GLOB glslc_folders $ENV{VULKAN_SDK}/*) - find_program(GLSL_COMPILER glslc PATHS ${glslc_folders} HINTS ${Vulkan_GLSLC_EXECUTABLE}) + if($ENV{VULKAN_SDK}) + file(TO_CMAKE_PATH "$ENV{VULKAN_SDK}" VULKAN_SDK) + file( + GLOB + glslc_folders + CONFIGURE_DEPENDS + ${VULKAN_SDK}/* + ) + endif() + find_program( + GLSL_COMPILER glslc + PATHS ${glslc_folders} + HINTS "${Vulkan_GLSLC_EXECUTABLE}" + ) endif() -find_program(GLSLANG_VALIDATOR glslangValidator HINTS ${Vulkan_GLSLANG_VALIDATOR_EXECUTABLE}) +find_program( + GLSLANG_VALIDATOR glslangValidator + HINTS "${Vulkan_GLSLANG_VALIDATOR_EXECUTABLE}" +) if(GLSL_COMPILER) message(STATUS "Found glslc: ${GLSL_COMPILER}") elseif(GLSLANG_VALIDATOR) @@ -284,30 +341,37 @@ endif() function(compile_glsl run_target_name) set(glsl_output_files "") foreach(in_file IN LISTS ARGN) - get_filename_component(glsl_stage ${in_file} NAME_WE) - set(out_file ${CMAKE_CURRENT_BINARY_DIR}/${glsl_stage}.spv) + get_filename_component(glsl_stage "${in_file}" NAME_WE) + set(out_file "${CMAKE_CURRENT_BINARY_DIR}/${glsl_stage}.spv") if(GLSL_COMPILER) # Run glslc if we can find it add_custom_command( - OUTPUT ${out_file} - COMMAND ${GLSL_COMPILER} -mfmt=c -fshader-stage=${glsl_stage} ${in_file} -o ${out_file} - DEPENDS ${in_file} + OUTPUT "${out_file}" + COMMAND + "${GLSL_COMPILER}" -mfmt=c -fshader-stage=${glsl_stage} + "${in_file}" -o "${out_file}" + DEPENDS "${in_file}" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + VERBATIM ) elseif(GLSLANG_VALIDATOR) # Run glslangValidator if we can find it add_custom_command( - OUTPUT ${out_file} - COMMAND ${GLSLANG_VALIDATOR} -V -S ${glsl_stage} ${in_file} -x -o ${out_file} - DEPENDS ${in_file} + OUTPUT "${out_file}" + COMMAND + "${GLSLANG_VALIDATOR}" -V -S ${glsl_stage} "${in_file}" -x + -o "${out_file}" + DEPENDS "${in_file}" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" VERBATIM ) else() # Use the precompiled .spv files - get_filename_component(glsl_src_dir ${in_file} DIRECTORY) - set(precompiled_file ${glsl_src_dir}/${glsl_stage}.spv) - configure_file(${precompiled_file} ${out_file} COPYONLY) + get_filename_component(glsl_src_dir "${in_file}" DIRECTORY) + set(precompiled_file "${glsl_src_dir}/${glsl_stage}.spv") + configure_file("${precompiled_file}" "${out_file}" COPYONLY) endif() - list(APPEND glsl_output_files ${out_file}) + list(APPEND glsl_output_files "${out_file}") endforeach() add_custom_target(${run_target_name} ALL DEPENDS ${glsl_output_files}) set_target_properties(${run_target_name} PROPERTIES FOLDER ${HELPER_FOLDER}) @@ -327,12 +391,9 @@ include(CheckFunctionExists) check_function_exists(secure_getenv HAVE_SECURE_GETENV) check_function_exists(__secure_getenv HAVE___SECURE_GETENV) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/common_config.h.in ${CMAKE_CURRENT_BINARY_DIR}/common_config.h) +configure_file(common_config.h.in "${CMAKE_CURRENT_BINARY_DIR}/common_config.h") add_definitions(-DOPENXR_HAVE_COMMON_CONFIG) -# Be able to find pre-generated files, if used. -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include ${CMAKE_CURRENT_SOURCE_DIR}) - include(CheckSymbolExists) check_symbol_exists(timespec_get time.h HAVE_TIMESPEC_GET) if(HAVE_TIMESPEC_GET) @@ -342,23 +403,15 @@ endif() # Set up the OpenXR version variables, used by several targets in this project. include(${CMAKE_CURRENT_SOURCE_DIR}/version.cmake) -# Path separators ( : or ; ) are not handled well in CMake. -# This seems like a reasonable approach. -if(CMAKE_HOST_SYSTEM_NAME STREQUAL Windows) - set(CODEGEN_PYTHON_PATH - "${PROJECT_SOURCE_DIR}/specification/scripts;${PROJECT_SOURCE_DIR}/src/scripts;$ENV{PYTHONPATH}" - ) -else() - set(CODEGEN_PYTHON_PATH - "${PROJECT_SOURCE_DIR}/specification/scripts:${PROJECT_SOURCE_DIR}/src/scripts:$ENV{PYTHONPATH}" - ) -endif() - # General code generation macro used by several targets. macro(run_xr_xml_generate dependency output) - if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${output}" AND NOT BUILD_FORCE_GENERATION) + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${output}" + AND NOT BUILD_FORCE_GENERATION + ) # pre-generated found - message(STATUS "Found and will use pre-generated ${output} in source tree") + message( + STATUS "Found and will use pre-generated ${output} in source tree" + ) list(APPEND GENERATED_OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/${output}") else() if(NOT PYTHON_EXECUTABLE) @@ -368,21 +421,24 @@ macro(run_xr_xml_generate dependency output) ) endif() add_custom_command( - OUTPUT ${output} + OUTPUT "${output}" COMMAND - ${CMAKE_COMMAND} -E env "PYTHONPATH=${CODEGEN_PYTHON_PATH}" - ${PYTHON_EXECUTABLE} - ${PROJECT_SOURCE_DIR}/src/scripts/src_genxr.py - -registry ${PROJECT_SOURCE_DIR}/specification/registry/xr.xml - ${output} + "${CMAKE_COMMAND}" -E env "PYTHONPATH=${CODEGEN_PYTHON_PATH}" + "${PYTHON_EXECUTABLE}" + "${PROJECT_SOURCE_DIR}/src/scripts/src_genxr.py" -registry + "${PROJECT_SOURCE_DIR}/specification/registry/xr.xml" + "${output}" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - DEPENDS "${PROJECT_SOURCE_DIR}/specification/registry/xr.xml" - "${PROJECT_SOURCE_DIR}/specification/scripts/generator.py" - "${PROJECT_SOURCE_DIR}/specification/scripts/reg.py" - "${PROJECT_SOURCE_DIR}/src/scripts/${dependency}" - "${PROJECT_SOURCE_DIR}/src/scripts/src_genxr.py" - ${ARGN} - COMMENT "Generating ${output} using ${PYTHON_EXECUTABLE} on ${dependency}" + DEPENDS + "${PROJECT_SOURCE_DIR}/specification/registry/xr.xml" + "${PROJECT_SOURCE_DIR}/specification/scripts/generator.py" + "${PROJECT_SOURCE_DIR}/specification/scripts/reg.py" + "${PROJECT_SOURCE_DIR}/src/scripts/${dependency}" + "${PROJECT_SOURCE_DIR}/src/scripts/src_genxr.py" + ${ARGN} + VERBATIM + COMMENT + "Generating ${output} using ${PYTHON_EXECUTABLE} on ${dependency}" ) set_source_files_properties(${output} PROPERTIES GENERATED TRUE) list(APPEND GENERATED_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${output}") @@ -391,65 +447,96 @@ macro(run_xr_xml_generate dependency output) endmacro() # Layer JSON generation macro used by several targets. -macro(gen_xr_layer_json filename layername libfile version desc genbad) +macro( + gen_xr_layer_json + filename + layername + libfile + version + desc + genbad +) add_custom_command( - OUTPUT ${filename} + OUTPUT "${filename}" COMMAND - ${CMAKE_COMMAND} -E env "PYTHONPATH=${CODEGEN_PYTHON_PATH}" - ${PYTHON_EXECUTABLE} - ${PROJECT_SOURCE_DIR}/src/scripts/generate_api_layer_manifest.py - -f ${filename} - -n ${layername} - -l ${libfile} - -a ${MAJOR}.${MINOR} - -v ${version} - ${genbad} - -d ${desc} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - DEPENDS ${PROJECT_SOURCE_DIR}/src/scripts/generate_api_layer_manifest.py + "${CMAKE_COMMAND}" -E env "PYTHONPATH=${CODEGEN_PYTHON_PATH}" + "${PYTHON_EXECUTABLE}" + "${PROJECT_SOURCE_DIR}/src/scripts/generate_api_layer_manifest.py" + -f "${filename}" -n ${layername} -l ${libfile} -a ${MAJOR}.${MINOR} + -v ${version} ${genbad} -d ${desc} + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + DEPENDS + "${PROJECT_SOURCE_DIR}/src/scripts/generate_api_layer_manifest.py" COMMENT "Generating API Layer JSON ${filename} using -f ${filename} -n ${layername} -l ${libfile} -a ${MAJOR}.${MINOR} -v ${version} ${genbad} -d ${desc}" + VERBATIM ) endmacro() # Custom target for generated dispatch table sources, used by several targets. -set(GENERATED_OUTPUT) -set(GENERATED_DEPENDS) +unset(GENERATED_OUTPUT) +unset(GENERATED_DEPENDS) run_xr_xml_generate(utility_source_generator.py xr_generated_dispatch_table.h) run_xr_xml_generate(utility_source_generator.py xr_generated_dispatch_table.c) set(COMMON_GENERATED_OUTPUT ${GENERATED_OUTPUT}) set(COMMON_GENERATED_DEPENDS ${GENERATED_DEPENDS}) + +if(COMMON_GENERATED_DEPENDS) + add_custom_target( + xr_common_generated_files DEPENDS ${COMMON_GENERATED_DEPENDS} + ) +else() + add_custom_target(xr_common_generated_files) +endif() + +set_target_properties( + xr_common_generated_files PROPERTIES FOLDER ${CODEGEN_FOLDER} +) + unset(GENERATED_OUTPUT) unset(GENERATED_DEPENDS) - -run_xr_xml_generate(utility_source_generator.py xr_generated_dispatch_table_core.h) -run_xr_xml_generate(utility_source_generator.py xr_generated_dispatch_table_core.c) +run_xr_xml_generate( + utility_source_generator.py xr_generated_dispatch_table_core.h +) +run_xr_xml_generate( + utility_source_generator.py xr_generated_dispatch_table_core.c +) set(LOADER_GENERATED_OUTPUT ${GENERATED_OUTPUT}) set(LOADER_GENERATED_DEPENDS ${GENERATED_DEPENDS}) + unset(GENERATED_OUTPUT) unset(GENERATED_DEPENDS) if(LOADER_GENERATED_DEPENDS) - add_custom_target(xr_global_generated_files DEPENDS ${LOADER_GENERATED_DEPENDS}) + add_custom_target( + xr_global_generated_files DEPENDS ${LOADER_GENERATED_DEPENDS} + ) else() add_custom_target(xr_global_generated_files) endif() -set_target_properties(xr_global_generated_files PROPERTIES FOLDER ${CODEGEN_FOLDER}) - -if(COMMON_GENERATED_DEPENDS) - add_custom_target(xr_common_generated_files DEPENDS ${COMMON_GENERATED_DEPENDS}) -else() - add_custom_target(xr_common_generated_files) -endif() - -set_target_properties(xr_common_generated_files PROPERTIES FOLDER ${CODEGEN_FOLDER}) +set_target_properties( + xr_global_generated_files PROPERTIES FOLDER ${CODEGEN_FOLDER} +) if(NOT MSVC) include(CheckCXXCompilerFlag) include(CheckCCompilerFlag) - foreach(FLAG -Wall -Werror=unused-parameter -Werror=unused-argument -Wpointer-arith) - string(REGEX REPLACE "[^A-Za-z0-9]" "" _flagvar "${FLAG}") + foreach( + FLAG + -Wall + -Werror=unused-parameter + -Werror=unused-argument + -Wpointer-arith + ) + string( + REGEX + REPLACE + "[^A-Za-z0-9]" + "" + _flagvar + "${FLAG}" + ) check_cxx_compiler_flag(${FLAG} SUPPORTS_${_flagvar}) if(SUPPORTS_${_flagvar}) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAG}") @@ -460,9 +547,13 @@ if(NOT MSVC) endif() endforeach() if(APPLE) - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-undefined,error") + set(CMAKE_SHARED_LINKER_FLAGS + "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-undefined,error" + ) elseif(NOT WIN32) - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined") + set(CMAKE_SHARED_LINKER_FLAGS + "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined" + ) endif() endif() diff --git a/src/api_layers/CMakeLists.txt b/src/api_layers/CMakeLists.txt index 9bd00b132..25e6948fb 100644 --- a/src/api_layers/CMakeLists.txt +++ b/src/api_layers/CMakeLists.txt @@ -13,9 +13,6 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -# -# Author: -# # Force all compilers to output to binary folder without additional output (like Windows adds "Debug" and "Release" folders) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) @@ -23,15 +20,24 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES}) string(TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG) - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_CURRENT_BINARY_DIR}) - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_CURRENT_BINARY_DIR}) - set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_CURRENT_BINARY_DIR}) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} + ${CMAKE_CURRENT_BINARY_DIR} + ) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} + ${CMAKE_CURRENT_BINARY_DIR} + ) + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} + ${CMAKE_CURRENT_BINARY_DIR} + ) endforeach(OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES) # Copy the api_layer_platform_defines.h file and place it in the binary (build) directory. -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/api_layer_platform_defines.h ${CMAKE_CURRENT_BINARY_DIR} COPYONLY) +configure_file( + api_layer_platform_defines.h ${CMAKE_CURRENT_BINARY_DIR} COPYONLY +) if(WIN32) + # Find the layer library adjacent to the manifest set(LAYER_MANIFEST_PREFIX "./") else() set(LAYER_MANIFEST_PREFIX) @@ -47,9 +53,9 @@ endif() # Basics for api_dump API Layer gen_xr_layer_json( - ${CMAKE_CURRENT_BINARY_DIR}/XrApiLayer_api_dump.json + "${CMAKE_CURRENT_BINARY_DIR}/XrApiLayer_api_dump.json" LUNARG_api_dump - ${LAYER_MANIFEST_PREFIX}$ + "${LAYER_MANIFEST_PREFIX}$" 1 "API Layer to record api calls as they occur" "" @@ -57,65 +63,68 @@ gen_xr_layer_json( # Flag generated files that aren't generated in this directory. set_source_files_properties( - ${COMMON_GENERATED_OUTPUT} - PROPERTIES GENERATED TRUE + ${COMMON_GENERATED_OUTPUT} PROPERTIES GENERATED TRUE ) set(GENERATED_OUTPUT) set(GENERATED_DEPENDS) -run_xr_xml_generate(api_dump_generator.py xr_generated_api_dump.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/../scripts/automatic_source_generator.py) -run_xr_xml_generate(api_dump_generator.py xr_generated_api_dump.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/../scripts/automatic_source_generator.py) +run_xr_xml_generate( + api_dump_generator.py xr_generated_api_dump.hpp + "${PROJECT_SOURCE_DIR}/src/scripts/automatic_source_generator.py" +) +run_xr_xml_generate( + api_dump_generator.py xr_generated_api_dump.cpp + "${PROJECT_SOURCE_DIR}/src/scripts/automatic_source_generator.py" +) set(API_DUMP_GENERATED_OUTPUT ${GENERATED_OUTPUT}) set(API_DUMP_GENERATED_DEPENDS ${GENERATED_DEPENDS}) unset(GENERATED_OUTPUT) unset(GENERATED_DEPENDS) -add_library(XrApiLayer_api_dump SHARED +add_library( + XrApiLayer_api_dump MODULE api_dump.cpp XrApiLayer_api_dump.def - - ${PROJECT_SOURCE_DIR}/src/common/hex_and_handles.h + "${PROJECT_SOURCE_DIR}/src/common/hex_and_handles.h" # target-specific generated files ${API_DUMP_GENERATED_OUTPUT} - # Dispatch table ${COMMON_GENERATED_OUTPUT} - # Included in this list to force generation - ${CMAKE_CURRENT_BINARY_DIR}/XrApiLayer_api_dump.json + "${CMAKE_CURRENT_BINARY_DIR}/XrApiLayer_api_dump.json" +) +set_target_properties( + XrApiLayer_api_dump PROPERTIES FOLDER ${API_LAYERS_FOLDER} ) -set_target_properties(XrApiLayer_api_dump PROPERTIES FOLDER ${API_LAYERS_FOLDER}) -target_link_libraries(XrApiLayer_api_dump PRIVATE Threads::Threads OpenXR::headers) -target_compile_definitions(XrApiLayer_api_dump PRIVATE ${OPENXR_ALL_SUPPORTED_DEFINES}) -add_dependencies(XrApiLayer_api_dump - generate_openxr_header - xr_common_generated_files +target_link_libraries( + XrApiLayer_api_dump PRIVATE Threads::Threads OpenXR::headers +) +target_compile_definitions( + XrApiLayer_api_dump PRIVATE ${OPENXR_ALL_SUPPORTED_DEFINES} ) +add_dependencies(XrApiLayer_api_dump xr_common_generated_files) -target_include_directories(XrApiLayer_api_dump +target_include_directories( + XrApiLayer_api_dump PRIVATE - ${PROJECT_SOURCE_DIR}/src/common - ${CMAKE_CURRENT_SOURCE_DIR} - - # for generated dispatch table - ${CMAKE_CURRENT_SOURCE_DIR}/.. - ${CMAKE_CURRENT_BINARY_DIR}/.. - - # for target-specific generated files - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_BINARY_DIR} + ${PROJECT_SOURCE_DIR}/src/common + # for generated dispatch table + .. + ${CMAKE_CURRENT_BINARY_DIR}/.. + # for target-specific generated files + . + ${CMAKE_CURRENT_BINARY_DIR} ) -if(Vulkan_FOUND) - target_include_directories(XrApiLayer_api_dump - PRIVATE ${Vulkan_INCLUDE_DIRS} +if(XR_USE_GRAPHICS_API_VULKAN) + target_include_directories( + XrApiLayer_api_dump PRIVATE ${Vulkan_INCLUDE_DIRS} ) endif() if(BUILD_WITH_WAYLAND_HEADERS) - target_include_directories(XrApiLayer_api_dump - PRIVATE ${WAYLAND_CLIENT_INCLUDE_DIRS}) + target_include_directories( + XrApiLayer_api_dump PRIVATE ${WAYLAND_CLIENT_INCLUDE_DIRS} + ) endif() # Basics for core_validation API Layer @@ -131,110 +140,148 @@ gen_xr_layer_json( set(GENERATED_OUTPUT) set(GENERATED_DEPENDS) -run_xr_xml_generate(validation_layer_generator.py xr_generated_core_validation.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/../scripts/automatic_source_generator.py) -run_xr_xml_generate(validation_layer_generator.py xr_generated_core_validation.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/../scripts/automatic_source_generator.py) +run_xr_xml_generate( + validation_layer_generator.py xr_generated_core_validation.hpp + "${PROJECT_SOURCE_DIR}/src/scripts/automatic_source_generator.py" +) +run_xr_xml_generate( + validation_layer_generator.py xr_generated_core_validation.cpp + "${PROJECT_SOURCE_DIR}/src/scripts/automatic_source_generator.py" +) set(CORE_VALIDATION_GENERATED_OUTPUT ${GENERATED_OUTPUT}) set(CORE_VALIDATION_GENERATED_DEPENDS ${GENERATED_DEPENDS}) unset(GENERATED_OUTPUT) unset(GENERATED_DEPENDS) -add_library(XrApiLayer_core_validation SHARED +add_library( + XrApiLayer_core_validation MODULE core_validation.cpp XrApiLayer_core_validation.def - ${PROJECT_SOURCE_DIR}/src/common/hex_and_handles.h ${PROJECT_SOURCE_DIR}/src/common/object_info.cpp ${PROJECT_SOURCE_DIR}/src/common/object_info.h - # target-specific generated files ${CORE_VALIDATION_GENERATED_OUTPUT} - # Dispatch table ${COMMON_GENERATED_OUTPUT} - # Included in this list to force generation ${CMAKE_CURRENT_BINARY_DIR}/XrApiLayer_core_validation.json ) -set_target_properties(XrApiLayer_core_validation PROPERTIES FOLDER ${API_LAYERS_FOLDER}) +set_target_properties( + XrApiLayer_core_validation PROPERTIES FOLDER ${API_LAYERS_FOLDER} +) -target_link_libraries(XrApiLayer_core_validation PRIVATE Threads::Threads OpenXR::headers) -target_compile_definitions(XrApiLayer_core_validation PRIVATE ${OPENXR_ALL_SUPPORTED_DEFINES}) -add_dependencies(XrApiLayer_core_validation - generate_openxr_header - xr_common_generated_files +target_link_libraries( + XrApiLayer_core_validation PRIVATE Threads::Threads OpenXR::headers +) +target_compile_definitions( + XrApiLayer_core_validation PRIVATE ${OPENXR_ALL_SUPPORTED_DEFINES} ) -target_include_directories(XrApiLayer_core_validation +add_dependencies(XrApiLayer_core_validation xr_common_generated_files) +target_include_directories( + XrApiLayer_core_validation PRIVATE - ${PROJECT_SOURCE_DIR}/src/common - - # for generated dispatch table - ${CMAKE_CURRENT_SOURCE_DIR}/.. - ${CMAKE_CURRENT_BINARY_DIR}/.. - - # for target-specific generated files - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_BINARY_DIR} - + ${PROJECT_SOURCE_DIR}/src/common + # for generated dispatch table + .. + ${CMAKE_CURRENT_BINARY_DIR}/.. + # for target-specific generated files + . + ${CMAKE_CURRENT_BINARY_DIR} ) -if(Vulkan_FOUND) - target_include_directories(XrApiLayer_core_validation - PRIVATE ${Vulkan_INCLUDE_DIRS} +if(XR_USE_GRAPHICS_API_VULKAN) + target_include_directories( + XrApiLayer_core_validation PRIVATE ${Vulkan_INCLUDE_DIRS} ) endif() if(BUILD_WITH_WAYLAND_HEADERS) - target_include_directories(XrApiLayer_core_validation - PRIVATE ${WAYLAND_CLIENT_INCLUDE_DIRS}) + target_include_directories( + XrApiLayer_core_validation PRIVATE ${WAYLAND_CLIENT_INCLUDE_DIRS} + ) endif() if(WIN32) # Windows api_dump-specific information - target_compile_definitions(XrApiLayer_api_dump PRIVATE _CRT_SECURE_NO_WARNINGS) + target_compile_definitions( + XrApiLayer_api_dump PRIVATE _CRT_SECURE_NO_WARNINGS + ) # Turn off transitional "changed behavior" warning message for Visual Studio versions prior to 2015. # The changed behavior is that constructor initializers are now fixed to clear the struct members. - target_compile_options(XrApiLayer_api_dump PRIVATE "$<$,$,19>>:/wd4351>") + target_compile_options( + XrApiLayer_api_dump + PRIVATE + "$<$,$,19>>:/wd4351>" + ) # Windows core_validation-specific information - target_compile_definitions(XrApiLayer_core_validation PRIVATE _CRT_SECURE_NO_WARNINGS) + target_compile_definitions( + XrApiLayer_core_validation PRIVATE _CRT_SECURE_NO_WARNINGS + ) # Turn off transitional "changed behavior" warning message for Visual Studio versions prior to 2015. # The changed behavior is that constructor initializers are now fixed to clear the struct members. - target_compile_options(XrApiLayer_core_validation PRIVATE "$<$,$,19>>:/wd4351>") + target_compile_options( + XrApiLayer_core_validation + PRIVATE + "$<$,$,19>>:/wd4351>" + ) elseif(APPLE) # Apple api_dump-specific information - set_target_properties(XrApiLayer_api_dump PROPERTIES LINK_FLAGS "-Wl,-exported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/XrApiLayer_api_dump.expsym") + set_target_properties( + XrApiLayer_api_dump + PROPERTIES + LINK_FLAGS + "-Wl,-exported_symbols_list,\"${CMAKE_CURRENT_SOURCE_DIR}/XrApiLayer_api_dump.expsym\"" + ) # Apple core_validation-specific information - set_target_properties(XrApiLayer_core_validation PROPERTIES LINK_FLAGS "-Wl,-exported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/XrApiLayer_core_validation.expsym") + set_target_properties( + XrApiLayer_core_validation + PROPERTIES + LINK_FLAGS + "-Wl,-exported_symbols_list,\"${CMAKE_CURRENT_SOURCE_DIR}/XrApiLayer_core_validation.expsym\"" + ) else() # Linux api_dump-specific information - set_target_properties(XrApiLayer_api_dump PROPERTIES LINK_FLAGS "-Wl,-Bsymbolic,--exclude-libs,ALL") + set_target_properties( + XrApiLayer_api_dump PROPERTIES LINK_FLAGS + "-Wl,-Bsymbolic,--exclude-libs,ALL" + ) # Linux core_validation-specific information - set_target_properties(XrApiLayer_core_validation PROPERTIES LINK_FLAGS "-Wl,-Bsymbolic,--exclude-libs,ALL") + set_target_properties( + XrApiLayer_core_validation + PROPERTIES LINK_FLAGS "-Wl,-Bsymbolic,--exclude-libs,ALL" + ) endif() # Install explicit layers -set(TARGET_NAMES - XrApiLayer_api_dump - XrApiLayer_core_validation) +set(TARGET_NAMES XrApiLayer_api_dump XrApiLayer_core_validation) if(CMAKE_SYSTEM_NAME STREQUAL "Linux") foreach(TARGET_NAME ${TARGET_NAMES}) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}.json - DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/openxr/${MAJOR}/api_layers/explicit.d - COMPONENT Layers) - install(TARGETS ${TARGET_NAME} + install( + FILES "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}.json" + DESTINATION + "${CMAKE_INSTALL_DATAROOTDIR}/openxr/${MAJOR}/api_layers/explicit.d" + COMPONENT Layers + ) + install( + TARGETS ${TARGET_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} - COMPONENT Layers) + COMPONENT Layers + ) endforeach() elseif(WIN32) foreach(TARGET_NAME ${TARGET_NAMES}) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}.json - DESTINATION ${CMAKE_INSTALL_BINDIR}/api_layers - COMPONENT Layers) - install(TARGETS ${TARGET_NAME} - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}/api_layers - COMPONENT Layers) + install( + FILES "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}.json" + DESTINATION "${CMAKE_INSTALL_BINDIR}/api_layers" + COMPONENT Layers + ) + install( + TARGETS ${TARGET_NAME} + DESTINATION "${CMAKE_INSTALL_BINDIR}/api_layers" + COMPONENT Layers + ) endforeach() endif() diff --git a/src/cmake/FindEGL.cmake b/src/cmake/FindEGL.cmake index 160009277..c4f6c8b47 100644 --- a/src/cmake/FindEGL.cmake +++ b/src/cmake/FindEGL.cmake @@ -33,10 +33,14 @@ # Since pre-1.0.0. # SPDX-License-Identifier: BSD-3-Clause +# +# Note: This module is originally from the KDE "Extra CMake Modules" repo, +# adapted to work standalone. Original source: +# https://github.com/KDE/extra-cmake-modules/blob/3b0bf71a72789eb2b79310b4f67602115e347f56/find-modules/FindEGL.cmake #============================================================================= # Copyright 2014 Alex Merry # Copyright 2014 Martin Gräßlin -# Copyright 2019 Ryan Pavlik +# Copyright 2019, 2021 Ryan Pavlik # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -67,8 +71,12 @@ include(CMakePushCheckState) # Use pkg-config to get the directories and then use these values # in the FIND_PATH() and FIND_LIBRARY() calls -find_package(PkgConfig) -pkg_check_modules(PKG_EGL QUIET egl) +if(NOT ANDROID) + find_package(PkgConfig QUIET) + if(PKGCONFIG_FOUND) + pkg_check_modules(PKG_EGL QUIET egl) + endif() +endif() set(EGL_DEFINITIONS ${PKG_EGL_CFLAGS_OTHER}) @@ -167,5 +175,5 @@ set(EGL_VERSION_STRING ${EGL_VERSION}) include(FeatureSummary) set_package_properties(EGL PROPERTIES URL "https://www.khronos.org/egl/" - DESCRIPTION "A platform-agnostic mechanism for creating rendering surfaces for use with other graphics libraries, such as OpenGL|ES and OpenVG." + DESCRIPTION "A platform-independent mechanism for creating rendering surfaces for use with other graphics libraries, such as OpenGL|ES and OpenVG." ) diff --git a/src/cmake/FindJsonCpp.cmake b/src/cmake/FindJsonCpp.cmake index 9cd868472..e10100564 100644 --- a/src/cmake/FindJsonCpp.cmake +++ b/src/cmake/FindJsonCpp.cmake @@ -26,8 +26,8 @@ # Incorporates work from the module contributed to VRPN under the same license: # 2011 Philippe Crassous (ENSAM ParisTech / Institut Image) p.crassous _at_ free.fr # -# Copyright Philippe Crassous 2011. -# Copyright Sensics, Inc. 2016. +# Copyright 2011, Philippe Crassous +# Copyright 2016, Sensics, Inc. # # SPDX-License-Identifier: BSL-1.0 # diff --git a/src/cmake/FindOpenGLES.cmake b/src/cmake/FindOpenGLES.cmake index fc8aeb56c..e024df8ff 100644 --- a/src/cmake/FindOpenGLES.cmake +++ b/src/cmake/FindOpenGLES.cmake @@ -1,11 +1,11 @@ -# Copyright 2020 Collabora, Ltd. +# Copyright 2020-2021 Collabora, Ltd. # SPDX-License-Identifier: BSL-1.0 # Distributed under the Boost Software License, Version 1.0. # (See accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) # # Original Author: -# 2020 Ryan Pavlik +# 2020-2021, Ryan Pavlik #[[.rst: FindOpenGLES @@ -53,18 +53,22 @@ set(OpenGLES_ROOT_DIR if(NOT OpenGLES_FIND_COMPONENTS) set(OpenGLES_FIND_COMPONENTS V2) endif() -find_package(PkgConfig QUIET) -if(PKG_CONFIG_FOUND) - set(_old_prefix_path "${CMAKE_PREFIX_PATH}") - # So pkg-config uses OpenGLES_ROOT_DIR too. - if(OpenGLES_ROOT_DIR) - list(APPEND CMAKE_PREFIX_PATH ${OpenGLES_ROOT_DIR}) + +if(NOT ANDROID) + find_package(PkgConfig QUIET) + if(PKG_CONFIG_FOUND) + set(_old_prefix_path "${CMAKE_PREFIX_PATH}") + # So pkg-config uses OpenGLES_ROOT_DIR too. + if(OpenGLES_ROOT_DIR) + list(APPEND CMAKE_PREFIX_PATH ${OpenGLES_ROOT_DIR}) + endif() + pkg_check_modules(PC_glesv1_cm QUIET glesv1_cm) + pkg_check_modules(PC_glesv2 QUIET glesv2) + # Restore + set(CMAKE_PREFIX_PATH "${_old_prefix_path}") endif() - pkg_check_modules(PC_glesv1_cm QUIET glesv1_cm) - pkg_check_modules(PC_glesv2 QUIET glesv2) - # Restore - set(CMAKE_PREFIX_PATH "${_old_prefix_path}") endif() + find_path( OpenGLES_V1_INCLUDE_DIR NAMES GLES/gl.h diff --git a/src/cmake/FindVulkanHeaders.cmake b/src/cmake/FindVulkanHeaders.cmake deleted file mode 100644 index 85f5bcd22..000000000 --- a/src/cmake/FindVulkanHeaders.cmake +++ /dev/null @@ -1,88 +0,0 @@ -# ~~~ -# Copyright (c) 2018-2019 Valve Corporation -# Copyright (c) 2018-2019 LunarG, Inc. -# -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ~~~ - -#.rst: -# FindVulkanHeaders -# ----------------- -# -# Try to find Vulkan Headers and Registry. -# -# This module is intended to be used by projects that build Vulkan -# "system" components such as the loader and layers. -# Vulkan applications should instead use the FindVulkan (or similar) -# find module that locates the headers and the loader library. -# -# When using this find module to locate the headers and registry -# in a Vulkan-Headers repository, the Vulkan-Headers repository -# should be built with 'install' target and the following environment -# or CMake variable set to the location of the install directory. -# -# VULKAN_HEADERS_INSTALL_DIR -# -# IMPORTED Targets -# ^^^^^^^^^^^^^^^^ -# -# This module defines no IMPORTED targets -# -# Result Variables -# ^^^^^^^^^^^^^^^^ -# -# This module defines the following variables:: -# -# VulkanHeaders_FOUND - True if VulkanHeaders was found -# VulkanHeaders_INCLUDE_DIRS - include directories for VulkanHeaders -# -# VulkanRegistry_FOUND - True if VulkanRegistry was found -# VulkanRegistry_DIRS - directories for VulkanRegistry -# -# The module will also define two cache variables:: -# -# VulkanHeaders_INCLUDE_DIR - the VulkanHeaders include directory -# VulkanRegistry_DIR - the VulkanRegistry directory -# - -# Use HINTS instead of PATH to search these locations before -# searching system environment variables like $PATH that may -# contain SDK directories. -find_path(VulkanHeaders_INCLUDE_DIR - NAMES vulkan/vulkan.h - HINTS - ${VULKAN_HEADERS_INSTALL_DIR}/include - "$ENV{VULKAN_HEADERS_INSTALL_DIR}/include" - "$ENV{VULKAN_SDK}/include") - -if(VulkanHeaders_INCLUDE_DIR) - get_filename_component(VULKAN_REGISTRY_PATH_HINT ${VulkanHeaders_INCLUDE_DIR} DIRECTORY) - find_path(VulkanRegistry_DIR - NAMES vk.xml - HINTS "${VULKAN_REGISTRY_PATH_HINT}/share/vulkan/registry") -endif() - -set(VulkanHeaders_INCLUDE_DIRS ${VulkanHeaders_INCLUDE_DIR}) -set(VulkanRegistry_DIRS ${VulkanRegistry_DIR}) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(VulkanHeaders - DEFAULT_MSG - VulkanHeaders_INCLUDE_DIR) -find_package_handle_standard_args(VulkanRegistry - DEFAULT_MSG - VulkanRegistry_DIR) - -mark_as_advanced(VulkanHeaders_INCLUDE_DIR VulkanRegistry_DIR) diff --git a/src/cmake/metaconfig.cmake.in b/src/cmake/metaconfig.cmake.in index 462b0cc20..0353e58a5 100644 --- a/src/cmake/metaconfig.cmake.in +++ b/src/cmake/metaconfig.cmake.in @@ -1,4 +1,4 @@ -# Copyright (c) 2017 The Khronos Group Inc. +# Copyright (c) 2017-2023, The Khronos Group Inc. # # SPDX-License-Identifier: Apache-2.0 # diff --git a/src/cmake/presentation.cmake b/src/cmake/presentation.cmake index 50c41803a..263638569 100644 --- a/src/cmake/presentation.cmake +++ b/src/cmake/presentation.cmake @@ -57,11 +57,14 @@ if(PRESENTATION_BACKEND MATCHES "xlib") target_compile_definitions(openxr-gfxwrapper PUBLIC OS_LINUX_XLIB) target_link_libraries(openxr-gfxwrapper PRIVATE ${X11_X11_LIB} ${X11_Xxf86vm_LIB} ${X11_Xrandr_LIB}) - if(TARGET OpenGL::OpenGL AND TARGET OpenGL::GLX) - # OpenGL::OpenGL already linked, we just need to add GLX. + # OpenGL::OpenGL already linked, we just need to add GLX. + if(TARGET OpenGL::GLX) target_link_libraries(openxr-gfxwrapper PUBLIC OpenGL::GLX) else() - target_link_libraries(openxr-gfxwrapper PUBLIC ${OPENGL_LIBRARIES} ${OPENGL_glx_LIBRARY}) + if(${OPENGL_glx_LIBRARY}) + target_link_libraries(openxr-gfxwrapper PUBLIC ${OPENGL_glx_LIBRARY}) + endif() + target_link_libraries(openxr-gfxwrapper PUBLIC ${OPENGL_LIBRARIES}) endif() endif() elseif(PRESENTATION_BACKEND MATCHES "xcb") @@ -143,10 +146,13 @@ endif() if(TARGET openxr-gfxwrapper AND NOT (PRESENTATION_BACKEND MATCHES "wayland")) - if(TARGET OpenGL::OpenGL AND TARGET OpenGL::GLX) + if(TARGET OpenGL::GLX) # OpenGL::OpenGL already linked, we just need to add GLX. target_link_libraries(openxr-gfxwrapper PUBLIC OpenGL::GLX) else() - target_link_libraries(openxr-gfxwrapper PUBLIC ${OPENGL_LIBRARIES} ${OPENGL_glx_LIBRARY}) + if(${OPENGL_glx_LIBRARY}) + target_link_libraries(openxr-gfxwrapper PUBLIC ${OPENGL_glx_LIBRARY}) + endif() + target_link_libraries(openxr-gfxwrapper PUBLIC ${OPENGL_LIBRARIES}) endif() endif() diff --git a/src/loader/AndroidManifest.xml b/src/loader/AndroidManifest.xml deleted file mode 100644 index 0c151c63b..000000000 --- a/src/loader/AndroidManifest.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/src/loader/AndroidManifest.xml.in b/src/loader/AndroidManifest.xml.in index 291a1e2d5..33a45153e 100644 --- a/src/loader/AndroidManifest.xml.in +++ b/src/loader/AndroidManifest.xml.in @@ -7,6 +7,9 @@ SPDX-License-Identifier: Apache-2.0 OR MIT --> + + + diff --git a/src/loader/CMakeLists.txt b/src/loader/CMakeLists.txt index c6905f0bf..e8237adb3 100644 --- a/src/loader/CMakeLists.txt +++ b/src/loader/CMakeLists.txt @@ -15,20 +15,11 @@ # limitations under the License. # -if(WIN32) - # Pass version fields as preprocessor for .rc resource version on Windows. - add_definitions(-DXR_CURRENT_API_MAJOR_VERSION=${MAJOR} -DXR_CURRENT_API_MINOR_VERSION=${MINOR} -DXR_CURRENT_API_PATCH_VERSION=${PATCH}) - set(openxr_loader_RESOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/loader.rc) -endif() - if(NOT MSVC) set(CMAKE_C_VISIBILITY_PRESET hidden) set(CMAKE_CXX_VISIBILITY_PRESET hidden) endif() -# make cache variables for install destinations -include(GNUInstallDirs) - # List of all files externally generated outside of the loader that the loader # needs to build with. set(LOADER_EXTERNAL_GEN_FILES ${LOADER_GENERATED_OUTPUT}) @@ -39,19 +30,21 @@ run_xr_xml_generate(loader_source_generator.py xr_generated_loader.cpp) if(DYNAMIC_LOADER) add_definitions(-DXRAPI_DLL_EXPORT) set(LIBRARY_TYPE SHARED) - if(MSVC) - list(APPEND openxr_loader_RESOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/openxr-loader.def) - endif() -else() # build static lib +else() + # build static lib set(LIBRARY_TYPE STATIC) endif() -add_library(openxr_loader ${LIBRARY_TYPE} +add_library( + openxr_loader + ${LIBRARY_TYPE} android_utilities.cpp android_utilities.h api_layer_interface.cpp api_layer_interface.hpp loader_core.cpp + loader_init_data.cpp + loader_init_data.hpp loader_instance.cpp loader_instance.hpp loader_logger.cpp @@ -62,87 +55,104 @@ add_library(openxr_loader ${LIBRARY_TYPE} manifest_file.hpp runtime_interface.cpp runtime_interface.hpp + "${PROJECT_SOURCE_DIR}/src/common/hex_and_handles.h" + "${PROJECT_SOURCE_DIR}/src/common/object_info.cpp" + "${PROJECT_SOURCE_DIR}/src/common/object_info.h" + "${PROJECT_SOURCE_DIR}/src/common/platform_utils.hpp" ${GENERATED_OUTPUT} - ${PROJECT_SOURCE_DIR}/src/common/hex_and_handles.h - ${PROJECT_SOURCE_DIR}/src/common/object_info.cpp - ${PROJECT_SOURCE_DIR}/src/common/object_info.h - ${PROJECT_SOURCE_DIR}/src/common/platform_utils.hpp ${LOADER_EXTERNAL_GEN_FILES} - ${openxr_loader_RESOURCE_FILE} ) +set_target_properties(openxr_loader PROPERTIES FOLDER ${LOADER_FOLDER}) + +target_include_directories( + openxr_loader + # for OpenXR headers + PUBLIC $ + $ + PRIVATE + "${PROJECT_SOURCE_DIR}/src/common" + # for generated dispatch table, common_config.h + .. + "${CMAKE_CURRENT_BINARY_DIR}/.." + # for target-specific generated files + . + "${CMAKE_CURRENT_BINARY_DIR}" + INTERFACE $ +) +add_dependencies(openxr_loader xr_global_generated_files) + +target_link_libraries( + openxr_loader + PRIVATE ${CMAKE_DL_LIBS} + PUBLIC Threads::Threads OpenXR::headers +) +target_compile_definitions( + openxr_loader PRIVATE ${OPENXR_ALL_SUPPORTED_DEFINES} +) +openxr_add_filesystem_utils(openxr_loader) + +set_target_properties( + openxr_loader PROPERTIES DEBUG_POSTFIX "${OPENXR_DEBUG_POSTFIX}" +) +# TODO remove once we get rid of add_definitions() +if(Vulkan_FOUND) + target_include_directories(openxr_loader PRIVATE ${Vulkan_INCLUDE_DIR}) +endif() + +# Get jsoncpp externally or internally if(BUILD_WITH_SYSTEM_JSONCPP) target_link_libraries(openxr_loader PRIVATE JsonCpp::JsonCpp) else() - target_sources(openxr_loader + if(NOT BUILD_LOADER_WITH_EXCEPTION_HANDLING) + target_compile_definitions(openxr_loader PRIVATE JSON_USE_EXCEPTION=0) + endif() + + target_sources( + openxr_loader PRIVATE - ${PROJECT_SOURCE_DIR}/src/external/jsoncpp/src/lib_json/json_reader.cpp - ${PROJECT_SOURCE_DIR}/src/external/jsoncpp/src/lib_json/json_value.cpp - ${PROJECT_SOURCE_DIR}/src/external/jsoncpp/src/lib_json/json_writer.cpp + "${PROJECT_SOURCE_DIR}/src/external/jsoncpp/src/lib_json/json_reader.cpp" + "${PROJECT_SOURCE_DIR}/src/external/jsoncpp/src/lib_json/json_value.cpp" + "${PROJECT_SOURCE_DIR}/src/external/jsoncpp/src/lib_json/json_writer.cpp" ) - target_include_directories(openxr_loader - PRIVATE - ${PROJECT_SOURCE_DIR}/src/external/jsoncpp/include + target_include_directories( + openxr_loader + PRIVATE "${PROJECT_SOURCE_DIR}/src/external/jsoncpp/include" ) if(SUPPORTS_Werrorunusedparameter) # Don't error on this - triggered by jsoncpp target_compile_options(openxr_loader PRIVATE -Wno-unused-parameter) endif() endif() -if(BUILD_WITH_WAYLAND_HEADERS) - target_include_directories(openxr_loader PRIVATE ${WAYLAND_CLIENT_INCLUDE_DIRS}) -endif() - -set_target_properties(openxr_loader PROPERTIES FOLDER ${LOADER_FOLDER}) if(LOADER_EXTERNAL_GEN_DEPENDS) - set_source_files_properties(${LOADER_EXTERNAL_GEN_DEPENDS} PROPERTIES GENERATED TRUE) + set_source_files_properties( + ${LOADER_EXTERNAL_GEN_DEPENDS} PROPERTIES GENERATED TRUE + ) endif() -add_dependencies(openxr_loader generate_openxr_header xr_global_generated_files) -target_include_directories( - openxr_loader - # for OpenXR headers - PUBLIC $ - $ - PRIVATE ${PROJECT_SOURCE_DIR}/src/common +if(NOT BUILD_LOADER_WITH_EXCEPTION_HANDLING) + target_compile_definitions( + openxr_loader PRIVATE XRLOADER_DISABLE_EXCEPTION_HANDLING + ) - # for generated dispatch table, common_config.h - ${CMAKE_CURRENT_SOURCE_DIR}/.. - ${CMAKE_CURRENT_BINARY_DIR}/.. + # TODO: uncomment this once jnipp starts supporting -fno-exceptions + # if(ANDROID AND (CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")) + # target_compile_options(openxr_loader + # PRIVATE + # -fno-exceptions + # ) + # endif() - # for target-specific generated files - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_BINARY_DIR} - INTERFACE $ -) - -if(Vulkan_FOUND) - target_include_directories(openxr_loader PRIVATE ${Vulkan_INCLUDE_DIRS}) -endif() -if(NOT BUILD_LOADER_WITH_EXCEPTION_HANDLING) - target_compile_definitions(openxr_loader PRIVATE XRLOADER_DISABLE_EXCEPTION_HANDLING) endif() -target_link_libraries( - openxr_loader - PRIVATE ${CMAKE_DL_LIBS} - PUBLIC Threads::Threads -) -target_compile_definitions(openxr_loader PRIVATE ${OPENXR_ALL_SUPPORTED_DEFINES}) +# Platform details + if(ANDROID) target_link_libraries( - openxr_loader - PRIVATE - ${ANDROID_LOG_LIBRARY} - ${ANDROID_LIBRARY}) -endif() - -target_compile_definitions(openxr_loader PRIVATE API_NAME="OpenXR") -openxr_add_filesystem_utils(openxr_loader) - -set_target_properties(openxr_loader PROPERTIES DEBUG_POSTFIX "${OPENXR_DEBUG_POSTFIX}") + openxr_loader PRIVATE ${ANDROID_LOG_LIBRARY} ${ANDROID_LIBRARY} + ) -if(CMAKE_SYSTEM_NAME STREQUAL "Linux") +elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") set(FALLBACK_CONFIG_DIRS "/etc/xdg" CACHE @@ -158,105 +168,165 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux") target_compile_definitions( openxr_loader PRIVATE - FALLBACK_CONFIG_DIRS="${FALLBACK_CONFIG_DIRS}" - FALLBACK_DATA_DIRS="${FALLBACK_DATA_DIRS}" - SYSCONFDIR="${CMAKE_INSTALL_FULL_SYSCONFDIR}" + FALLBACK_CONFIG_DIRS="${FALLBACK_CONFIG_DIRS}" + FALLBACK_DATA_DIRS="${FALLBACK_DATA_DIRS}" + SYSCONFDIR="${CMAKE_INSTALL_FULL_SYSCONFDIR}" ) if(NOT (CMAKE_INSTALL_FULL_SYSCONFDIR STREQUAL "/etc")) target_compile_definitions(openxr_loader PRIVATE EXTRASYSCONFDIR="/etc") endif() - set_target_properties(openxr_loader PROPERTIES SOVERSION "${MAJOR}" VERSION "${OPENXR_FULL_VERSION}") + set_target_properties( + openxr_loader PROPERTIES SOVERSION "${MAJOR}" VERSION + "${OPENXR_FULL_VERSION}" + ) add_custom_target( libopenxr_loader.so.${MAJOR}.${MINOR} ALL - COMMAND ${CMAKE_COMMAND} -E create_symlink libopenxr_loader.so.${OPENXR_FULL_VERSION} - libopenxr_loader.so.${MAJOR}.${MINOR} + COMMAND + "${CMAKE_COMMAND}" -E create_symlink + libopenxr_loader.so.${OPENXR_FULL_VERSION} + libopenxr_loader.so.${MAJOR}.${MINOR} ) + elseif(WIN32) + + # Pass version fields as preprocessor for .rc resource version on Windows. + target_compile_definitions( + openxr_loader + PRIVATE + XR_CURRENT_API_MAJOR_VERSION=${MAJOR} + XR_CURRENT_API_MINOR_VERSION=${MINOR} + XR_CURRENT_API_PATCH_VERSION=${PATCH} + ) + + target_sources( + openxr_loader PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/loader.rc" + ) + if(MSVC) - # WindowsStore (UWP) apps must be compiled with dynamic CRT linkage (default) - if(NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsStore") - foreach(configuration in CMAKE_C_FLAGS_DEBUG - CMAKE_C_FLAGS_RELEASE - CMAKE_C_FLAGS_RELWITHDEBINFO - CMAKE_CXX_FLAGS_DEBUG - CMAKE_CXX_FLAGS_RELEASE - CMAKE_CXX_FLAGS_RELWITHDEBINFO) - # If building DLLs, force static CRT linkage - if(DYNAMIC_LOADER) - if(${configuration} MATCHES "/MD") - string(REGEX REPLACE "/MD" "/MT" ${configuration} "${${configuration}}") - endif() - else() # Otherwise for static libs, link the CRT dynamically - if(${configuration} MATCHES "/MT") - string(REGEX REPLACE "/MT" "/MD" ${configuration} "${${configuration}}") - endif() - endif() - endforeach() + if(DYNAMIC_LOADER AND NOT (CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")) + # If building DLLs, force static CRT linkage + set_target_properties( + openxr_loader + PROPERTIES MSVC_RUNTIME_LIBRARY + "MultiThreaded$<$:Debug>" + ) + target_sources( + openxr_loader + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/openxr-loader.def" + ) + else() + # WindowsStore (UWP) apps must be compiled with dynamic CRT linkage (default) + # Otherwise for static libs, link the CRT dynamically + set_target_properties( + openxr_loader + PROPERTIES MSVC_RUNTIME_LIBRARY + "MultiThreaded$<$:Debug>DLL" + ) endif() - target_compile_options(openxr_loader PRIVATE /wd6386) endif() target_link_libraries(openxr_loader PUBLIC advapi32) +endif() - # Need to copy DLL to client directories so clients can easily load it. - if(DYNAMIC_LOADER AND (CMAKE_GENERATOR MATCHES "^Visual Studio.*")) - file(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/$/openxr_loader$<$:${OPENXR_DEBUG_POSTFIX}>.dll COPY_DLL_SRC_PATH) - file(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/$/openxr_loader$<$:${OPENXR_DEBUG_POSTFIX}>.pdb COPY_PDB_SRC_PATH) - file(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/../tests/hello_xr/$/ - COPY_DST_HELLO_XR_PATH - ) - file(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/../tests/loader_test/$/ - COPY_DST_LOADER_TEST_PATH - ) - file(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/../conformance/conformance_test/$/ - COPY_DST_CONFORMANCE_TEST_PATH - ) - add_custom_command( - TARGET openxr_loader POST_BUILD - COMMAND xcopy /Y /I ${COPY_DLL_SRC_PATH} ${COPY_DST_HELLO_XR_PATH} - COMMAND if exist ${COPY_PDB_SRC_PATH} xcopy /Y /I ${COPY_PDB_SRC_PATH} ${COPY_DST_HELLO_XR_PATH} - COMMAND xcopy /Y /I ${COPY_DLL_SRC_PATH} ${COPY_DST_LOADER_TEST_PATH} - COMMAND if exist ${COPY_PDB_SRC_PATH} xcopy /Y /I ${COPY_PDB_SRC_PATH} ${COPY_DST_LOADER_TEST_PATH} - COMMAND xcopy /Y /I ${COPY_DLL_SRC_PATH} ${COPY_DST_CONFORMANCE_TEST_PATH} - COMMAND if exist ${COPY_PDB_SRC_PATH} xcopy /Y /I ${COPY_PDB_SRC_PATH} ${COPY_DST_CONFORMANCE_TEST_PATH} - ) - endif() -elseif(ANDROID) - set(JNIPP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../external/jnipp) - set(JNIWRAPPER_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../external/android-jni-wrappers) - file(GLOB ANDROID_WRAP_SOURCES ${JNIWRAPPER_ROOT}/wrap/*.cpp) - set_target_properties(openxr_loader - PROPERTIES - CXX_STANDARD 17 - CXX_STANDARD_REQUIRED TRUE) - target_sources(openxr_loader - PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/android_utilities.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/android_utilities.h - ${ANDROID_WRAP_SOURCES} - ${JNIPP_ROOT}/jnipp.cpp +# Need to copy DLL to client directories so clients can easily load it. +if(DYNAMIC_LOADER AND (CMAKE_GENERATOR MATCHES "^Visual Studio.*")) + file( + TO_NATIVE_PATH + ${CMAKE_CURRENT_BINARY_DIR}/$/openxr_loader$<$:${OPENXR_DEBUG_POSTFIX}>.dll + COPY_DLL_SRC_PATH + ) + file( + TO_NATIVE_PATH + ${CMAKE_CURRENT_BINARY_DIR}/$/openxr_loader$<$:${OPENXR_DEBUG_POSTFIX}>.pdb + COPY_PDB_SRC_PATH + ) + file( + TO_NATIVE_PATH + ${CMAKE_CURRENT_BINARY_DIR}/../tests/hello_xr/$/ + COPY_DST_HELLO_XR_PATH + ) + file( + TO_NATIVE_PATH + ${CMAKE_CURRENT_BINARY_DIR}/../tests/loader_test/$/ + COPY_DST_LOADER_TEST_PATH + ) + file( + TO_NATIVE_PATH + ${CMAKE_CURRENT_BINARY_DIR}/../conformance/conformance_test/$/ + COPY_DST_CONFORMANCE_TEST_PATH ) - target_include_directories(openxr_loader + add_custom_command( + TARGET openxr_loader + POST_BUILD + COMMAND xcopy /Y /I ${COPY_DLL_SRC_PATH} ${COPY_DST_HELLO_XR_PATH} + COMMAND + if exist ${COPY_PDB_SRC_PATH} xcopy /Y /I ${COPY_PDB_SRC_PATH} + ${COPY_DST_HELLO_XR_PATH} + COMMAND xcopy /Y /I ${COPY_DLL_SRC_PATH} ${COPY_DST_LOADER_TEST_PATH} + COMMAND + if exist ${COPY_PDB_SRC_PATH} xcopy /Y /I ${COPY_PDB_SRC_PATH} + ${COPY_DST_LOADER_TEST_PATH} + COMMAND + xcopy /Y /I ${COPY_DLL_SRC_PATH} ${COPY_DST_CONFORMANCE_TEST_PATH} + COMMAND + if exist ${COPY_PDB_SRC_PATH} xcopy /Y /I ${COPY_PDB_SRC_PATH} + ${COPY_DST_CONFORMANCE_TEST_PATH} + ) +endif() + +# jnipp - android only +if(ANDROID) + set(JNIPP_ROOT "${PROJECT_SOURCE_DIR}/src/external/jnipp") + set(JNIWRAPPER_ROOT + "${PROJECT_SOURCE_DIR}/src/external/android-jni-wrappers" + ) + file( + GLOB + ANDROID_WRAP_SOURCES + CONFIGURE_DEPENDS + ${JNIWRAPPER_ROOT}/wrap/*.cpp + ) + set_target_properties( + openxr_loader PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED TRUE + ) + target_sources( + openxr_loader PRIVATE - ${JNIPP_ROOT} - ${JNIWRAPPER_ROOT} + ${CMAKE_CURRENT_SOURCE_DIR}/android_utilities.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/android_utilities.h + ${ANDROID_WRAP_SOURCES} + ${JNIPP_ROOT}/jnipp.cpp + ) + target_include_directories( + openxr_loader PRIVATE ${JNIPP_ROOT} ${JNIWRAPPER_ROOT} + ) + target_compile_definitions( + openxr_loader PRIVATE XR_KHR_LOADER_INIT_SUPPORT=1 ) endif() +# Make pkg-config file if(NOT MSVC) set(XR_API_VERSION "${MAJOR}.${MINOR}") set(EXTRA_LIBS ${CMAKE_THREAD_LIBS_INIT}) configure_file(openxr.pc.in openxr.pc @ONLY) - install(FILES "${CMAKE_CURRENT_BINARY_DIR}/openxr.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") + install( + FILES "${CMAKE_CURRENT_BINARY_DIR}/openxr.pc" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig" + ) endif() # Copy loader to conformance_cli binary folder if built as dynamic if(DYNAMIC_LOADER AND BUILD_CONFORMANCE_CLI) - add_custom_command(TARGET openxr_loader POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy $ $ + add_custom_command( + TARGET openxr_loader + POST_BUILD + COMMAND + ${CMAKE_COMMAND} -E copy $ + $ ) endif() @@ -264,25 +334,37 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") if(NOT MSVC) # Do not do this for clang-cl target_compile_options( - openxr_loader - PRIVATE "$<$:-fno-rtti>" - -ffunction-sections - -fdata-sections + openxr_loader PRIVATE "$<$:-fno-rtti>" + -ffunction-sections -fdata-sections ) endif() target_compile_options( - openxr_loader - PRIVATE -Wextra - -fno-strict-aliasing - -fno-builtin-memcmp + openxr_loader PRIVATE -Wextra -fno-strict-aliasing -fno-builtin-memcmp ) - # Make build depend on the version script/export map - target_sources(openxr_loader PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/openxr-loader.map) - # Add the linker flag. + + # Add the linker flag, and make build depend on the version script/export map if(APPLE) - set_target_properties(openxr_loader PROPERTIES LINK_FLAGS "-Wl,-exported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/openxr-loader.expsym") + set_target_properties( + openxr_loader + PROPERTIES + LINK_FLAGS + "-Wl,-exported_symbols_list,\"${CMAKE_CURRENT_SOURCE_DIR}/openxr-loader.expsym\"" + ) + target_sources( + openxr_loader + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/openxr-loader.expsym" + ) else() - set_target_properties(openxr_loader PROPERTIES LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/openxr-loader.map") + set_target_properties( + openxr_loader + PROPERTIES + LINK_FLAGS + "-Wl,--version-script=\"${CMAKE_CURRENT_SOURCE_DIR}/openxr-loader.map\"" + ) + target_sources( + openxr_loader + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/openxr-loader.map" + ) endif() # For GCC version 7.1 or greater, we need to disable the implicit fallthrough warning since # there's no consistent way to satisfy all compilers until they all accept the C++17 standard @@ -291,12 +373,6 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") endif() endif() -add_library(headers INTERFACE) -target_include_directories(headers INTERFACE - $ - $ - $) - # We will never actually install here, but it's easier to set something than block all install code. if(ANDROID AND NOT INSTALL_TO_ARCHITECTURE_PREFIXES) set(CMAKE_INSTALL_BINDIR bin) @@ -304,7 +380,8 @@ if(ANDROID AND NOT INSTALL_TO_ARCHITECTURE_PREFIXES) endif() install( - TARGETS openxr_loader headers EXPORT openxr_loader_export + TARGETS openxr_loader headers + EXPORT openxr_loader_export RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT Loader LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT Loader ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT Loader @@ -316,9 +393,8 @@ export( NAMESPACE OpenXR:: ) -# Create aliases so that it can be used the same whether vendored as source or found with CMake. +# Create alias so that it can be used the same whether vendored as source or found with CMake. add_library(OpenXR::openxr_loader ALIAS openxr_loader) -add_library(OpenXR::headers ALIAS headers) if(WIN32 AND NOT INSTALL_TO_ARCHITECTURE_PREFIXES) set(TARGET_DESTINATION cmake) @@ -337,8 +413,7 @@ install( include(CMakePackageConfigHelpers) set(INCLUDE_INSTALL_DIR include/) configure_package_config_file( - OpenXRConfig.cmake.in - ${CMAKE_CURRENT_BINARY_DIR}/OpenXRConfig.cmake + OpenXRConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/OpenXRConfig.cmake INSTALL_DESTINATION ${TARGET_DESTINATION} PATH_VARS INCLUDE_INSTALL_DIR ) @@ -354,8 +429,15 @@ install( COMPONENT CMakeConfigs ) -if(WIN32 AND NOT MINGW AND DYNAMIC_LOADER) - install(FILES $ DESTINATION ${CMAKE_INSTALL_BINDIR} OPTIONAL) +if(WIN32 + AND NOT MINGW + AND DYNAMIC_LOADER +) + install( + FILES $ + DESTINATION ${CMAKE_INSTALL_BINDIR} + OPTIONAL + ) endif() # Make the "meta" cmake config/version file to redirect to the right arch/build @@ -363,49 +445,68 @@ if(WIN32 AND INSTALL_TO_ARCHITECTURE_PREFIXES) set(TARGET_SUBDIR cmake/openxr) set(WARNING "This is a generated file - do not edit!") set(FN OpenXRConfig) - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/metaconfig.cmake.in - ${CMAKE_CURRENT_BINARY_DIR}/metaconfig.cmake - @ONLY) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/metaconfig.cmake + configure_file( + ../cmake/metaconfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/metaconfig.cmake @ONLY + ) + install( + FILES ${CMAKE_CURRENT_BINARY_DIR}/metaconfig.cmake DESTINATION . RENAME OpenXRConfig.cmake COMPONENT CMakeConfigs ) set(FN OpenXRConfigVersion) - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/metaconfig.cmake.in - ${CMAKE_CURRENT_BINARY_DIR}/metaconfigversion.cmake - @ONLY) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/metaconfigversion.cmake + configure_file( + ../cmake/metaconfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/metaconfigversion.cmake @ONLY + ) + install( + FILES ${CMAKE_CURRENT_BINARY_DIR}/metaconfigversion.cmake DESTINATION . RENAME OpenXRConfigVersion.cmake COMPONENT CMakeConfigs ) elseif(ANDROID AND INSTALL_TO_ARCHITECTURE_PREFIXES) - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/abi.json - ${CMAKE_CURRENT_BINARY_DIR}/abi.json - @ONLY) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/abi.json + + # json data files for a "prefab" AAR + configure_file(abi.json "${CMAKE_CURRENT_BINARY_DIR}/abi.json" @ONLY) + install( + FILES "${CMAKE_CURRENT_BINARY_DIR}/abi.json" DESTINATION ${CMAKE_INSTALL_LIBDIR} - COMPONENT Prefab) + COMPONENT Prefab + ) - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/prefab.json - ${CMAKE_CURRENT_BINARY_DIR}/prefab.json - @ONLY) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/prefab.json + configure_file(prefab.json "${CMAKE_CURRENT_BINARY_DIR}/prefab.json" @ONLY) + install( + FILES "${CMAKE_CURRENT_BINARY_DIR}/prefab.json" DESTINATION ${PREFAB_INSTALL_DIR} - COMPONENT Prefab) + COMPONENT Prefab + ) - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/AndroidManifest.xml.in - ${CMAKE_CURRENT_BINARY_DIR}/AndroidManifest.xml) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/AndroidManifest.xml + configure_file( + AndroidManifest.xml.in + "${CMAKE_CURRENT_BINARY_DIR}/AndroidManifest.xml" + ) + install( + FILES "${CMAKE_CURRENT_BINARY_DIR}/AndroidManifest.xml" DESTINATION . - COMPONENT Prefab) - install(FILES module.json - DESTINATION ${PREFAB_MODULE_INSTALL_DIR} - COMPONENT Prefab) - - # This gets used directly by build-aar.sh - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/openxr_loader_for_android.pom - ${CMAKE_CURRENT_BINARY_DIR}/openxr_loader_for_android-${OPENXR_FULL_VERSION}${OPENXR_ANDROID_VERSION_SUFFIX}.pom) + COMPONENT Prefab + ) + install( + FILES module.json + DESTINATION ${PREFAB_LOADER_MODULE_INSTALL_DIR} + COMPONENT Prefab + ) + + # These get used directly by build-aar.sh + configure_file( + openxr_loader_for_android.pom + "${CMAKE_CURRENT_BINARY_DIR}/openxr_loader_for_android-${OPENXR_FULL_VERSION}${OPENXR_ANDROID_VERSION_SUFFIX}.pom" + ) + + configure_file( + additional_manifest.mf.in + "${CMAKE_CURRENT_BINARY_DIR}/additional_manifest.mf" + ) endif() diff --git a/src/loader/additional_manifest.mf.in b/src/loader/additional_manifest.mf.in new file mode 100644 index 000000000..a34f865f6 --- /dev/null +++ b/src/loader/additional_manifest.mf.in @@ -0,0 +1,7 @@ +Name: org/khronos/openxr/openxr_loader_for_android +Specification-Title: OpenXR Loader for Android +Specification-Version: ${OPENXR_FULL_VERSION} +Specification-Vendor: The Khronos Group Inc. +Implementation-Title: OpenXR standard cross-vendor loader for Android +Implementation-Version: ${OPENXR_FULL_VERSION} +Implementation-Vendor: The Khronos Group Inc. diff --git a/src/loader/additional_manifest.mf.in.license b/src/loader/additional_manifest.mf.in.license new file mode 100644 index 000000000..4f1338245 --- /dev/null +++ b/src/loader/additional_manifest.mf.in.license @@ -0,0 +1,2 @@ +Copyright (c) 2023, The Khronos Group Inc. +SPDX-License-Identifier: Apache-2.0 OR MIT diff --git a/src/loader/android_utilities.cpp b/src/loader/android_utilities.cpp index 9a3ad76ce..68512d4a3 100644 --- a/src/loader/android_utilities.cpp +++ b/src/loader/android_utilities.cpp @@ -245,18 +245,38 @@ static int populateFunctions(wrap::android::content::Context const &context, boo return 0; } +// The current file relies on android-jni-wrappers and jnipp, which may throw on failure. +// This is problematic when the loader is compiled with exception handling disabled - the consumers can reasonably +// expect that the compilation with -fno-exceptions will succeed, but the compiler will not accept the code that +// uses `try` & `catch` keywords. We cannot use the `exception_handling.hpp` here since we're not at an ABI boundary, +// so we define helper macros here. This is fine for now since the only occurrence of exception-handling code is in this file. +#ifdef XRLOADER_DISABLE_EXCEPTION_HANDLING + +#define ANDROID_UTILITIES_TRY +#define ANDROID_UTILITIES_CATCH_FALLBACK(...) + +#else + +#define ANDROID_UTILITIES_TRY try +#define ANDROID_UTILITIES_CATCH_FALLBACK(...) \ + catch (const std::exception &e) { \ + __VA_ARGS__ \ + } + +#endif // XRLOADER_DISABLE_EXCEPTION_HANDLING + /// Get cursor for active runtime, parameterized by whether or not we use the system broker static bool getActiveRuntimeCursor(wrap::android::content::Context const &context, jni::Array const &projection, bool systemBroker, Cursor &cursor) { auto uri = active_runtime::makeContentUri(systemBroker, XR_VERSION_MAJOR(XR_CURRENT_API_VERSION), ABI); ALOGI("getActiveRuntimeCursor: Querying URI: %s", uri.toString().c_str()); - try { - cursor = context.getContentResolver().query(uri, projection); - } catch (const std::exception &e) { + + ANDROID_UTILITIES_TRY { cursor = context.getContentResolver().query(uri, projection); } + ANDROID_UTILITIES_CATCH_FALLBACK({ ALOGW("Exception when querying %s content resolver: %s", getBrokerTypeName(systemBroker), e.what()); cursor = {}; return false; - } + }) if (cursor.isNull()) { ALOGW("Null cursor when querying %s content resolver.", getBrokerTypeName(systemBroker)); diff --git a/src/loader/api_layer_interface.cpp b/src/loader/api_layer_interface.cpp index c9e24ec40..e8f6a401f 100644 --- a/src/loader/api_layer_interface.cpp +++ b/src/loader/api_layer_interface.cpp @@ -10,6 +10,7 @@ #include "api_layer_interface.hpp" #include "loader_interfaces.h" +#include "loader_init_data.hpp" #include "loader_logger.hpp" #include "loader_platform.hpp" #include "manifest_file.hpp" @@ -282,6 +283,38 @@ XrResult ApiLayerInterface::LoadApiLayers(const std::string& openxr_command, uin LoaderLogger::LogWarningMessage(openxr_command, warning_message); continue; } +#ifdef XR_KHR_LOADER_INIT_SUPPORT + if (!LoaderInitData::instance().initialized()) { + LoaderLogger::LogErrorMessage(openxr_command, "ApiLayerInterface::LoadApiLayers skipping manifest file " + + manifest_file->Filename() + + " because xrInitializeLoaderKHR was not yet called."); + + LoaderPlatformLibraryClose(layer_library); + return XR_ERROR_VALIDATION_FAILURE; + } + bool forwardedInitLoader = false; + { + // If we have xrInitializeLoaderKHR exposed as an export, forward call to it. + const auto function_name = manifest_file->GetFunctionName("xrInitializeLoaderKHR"); + auto initLoader = + reinterpret_cast(LoaderPlatformLibraryGetProcAddr(layer_library, function_name)); + if (initLoader != nullptr) { + // we found the entry point one way or another. + LoaderLogger::LogInfoMessage(openxr_command, + "ApiLayerInterface::LoadApiLayers forwarding xrInitializeLoaderKHR call to API layer " + "before calling xrNegotiateLoaderApiLayerInterface."); + XrResult res = initLoader(LoaderInitData::instance().getParam()); + if (!XR_SUCCEEDED(res)) { + LoaderLogger::LogErrorMessage( + openxr_command, "ApiLayerInterface::LoadApiLayers forwarded call to xrInitializeLoaderKHR failed."); + + LoaderPlatformLibraryClose(layer_library); + return res; + } + forwardedInitLoader = true; + } + } +#endif // Get and settle on an layer interface version (using any provided name if required). std::string function_name = manifest_file->GetFunctionName("xrNegotiateLoaderApiLayerInterface"); @@ -324,6 +357,38 @@ XrResult ApiLayerInterface::LoadApiLayers(const std::string& openxr_command, uin LoaderLogger::LogWarningMessage(openxr_command, warning_message); res = XR_ERROR_FILE_CONTENTS_INVALID; } + +#ifdef XR_KHR_LOADER_INIT_SUPPORT + if (XR_SUCCEEDED(res) && !forwardedInitLoader) { + // Forward initialize loader call, where possible and if we did not do so before. + PFN_xrVoidFunction initializeVoid = nullptr; + PFN_xrInitializeLoaderKHR initialize = nullptr; + + // Now we may try asking xrGetInstanceProcAddr on the API layer + if (XR_SUCCEEDED(api_layer_info.getInstanceProcAddr(XR_NULL_HANDLE, "xrInitializeLoaderKHR", &initializeVoid))) { + if (initializeVoid == nullptr) { + LoaderLogger::LogErrorMessage(openxr_command, + "ApiLayerInterface::LoadApiLayers got success from xrGetInstanceProcAddr " + "for xrInitializeLoaderKHR, but output a null pointer."); + res = XR_ERROR_RUNTIME_FAILURE; + } else { + initialize = reinterpret_cast(initializeVoid); + } + } + if (initialize != nullptr) { + // we found the entry point one way or another. + LoaderLogger::LogInfoMessage(openxr_command, + "ApiLayerInterface::LoadApiLayers forwarding xrInitializeLoaderKHR call to API layer " + "after calling xrNegotiateLoaderApiLayerInterface."); + res = initialize(LoaderInitData::instance().getParam()); + if (!XR_SUCCEEDED(res)) { + LoaderLogger::LogErrorMessage( + openxr_command, "ApiLayerInterface::LoadApiLayers forwarded call to xrInitializeLoaderKHR failed."); + } + } + } +#endif + if (XR_FAILED(res)) { if (!any_loaded) { last_error = res; diff --git a/src/loader/loader_core.cpp b/src/loader/loader_core.cpp index 06e687005..f173142c1 100644 --- a/src/loader/loader_core.cpp +++ b/src/loader/loader_core.cpp @@ -14,6 +14,7 @@ #include "api_layer_interface.hpp" #include "exception_handling.hpp" #include "hex_and_handles.h" +#include "loader_init_data.hpp" #include "loader_instance.hpp" #include "loader_logger_recorders.hpp" #include "loader_logger.hpp" @@ -77,7 +78,7 @@ inline bool IsMissingNullTerminator(const char (&str)[max_length]) { #ifdef XR_KHR_LOADER_INIT_SUPPORT // platforms that support XR_KHR_loader_init. XRAPI_ATTR XrResult XRAPI_CALL LoaderXrInitializeLoaderKHR(const XrLoaderInitInfoBaseHeaderKHR *loaderInitInfo) XRLOADER_ABI_TRY { LoaderLogger::LogVerboseMessage("xrInitializeLoaderKHR", "Entering loader trampoline"); - return InitializeLoader(loaderInitInfo); + return InitializeLoaderInitData(loaderInitInfo); } XRLOADER_ABI_CATCH_FALLBACK #endif diff --git a/src/loader/loader_init_data.cpp b/src/loader/loader_init_data.cpp new file mode 100644 index 000000000..16b753041 --- /dev/null +++ b/src/loader/loader_init_data.cpp @@ -0,0 +1,59 @@ +// Copyright (c) 2017-2023, The Khronos Group Inc. +// Copyright (c) 2017-2019 Valve Corporation +// Copyright (c) 2017-2019 LunarG, Inc. +// +// SPDX-License-Identifier: Apache-2.0 OR MIT +// +// Initial Author: Mark Young +// + +#include "loader_init_data.hpp" + +#ifdef XR_KHR_LOADER_INIT_SUPPORT + +#ifdef XR_USE_PLATFORM_ANDROID +// Check and copy the Android-specific init data. +XrResult LoaderInitData::initialize(const XrLoaderInitInfoBaseHeaderKHR* info) { + if (info->type != XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR) { + return XR_ERROR_VALIDATION_FAILURE; + } + auto cast_info = reinterpret_cast(info); + + if (cast_info->applicationVM == nullptr) { + return XR_ERROR_VALIDATION_FAILURE; + } + if (cast_info->applicationContext == nullptr) { + return XR_ERROR_VALIDATION_FAILURE; + } + + // Copy and store the JVM pointer and Android Context, ensuring the JVM is initialised. + _data = *cast_info; + _data.next = nullptr; + jni::init(static_cast(_data.applicationVM)); + const jni::Object context = jni::Object{static_cast(_data.applicationContext)}; + + // Retrieve a reference to the Android AssetManager. + const auto assetManager = context.call("getAssets()Landroid/content/res/AssetManager;"); + _android_asset_manager = AAssetManager_fromJava(jni::env(), assetManager.getHandle()); + + // Retrieve the path to the native libraries. + const auto applicationContext = context.call("getApplicationContext()Landroid/content/Context;"); + const auto applicationInfo = context.call("getApplicationInfo()Landroid/content/pm/ApplicationInfo;"); + _native_library_path = applicationInfo.get("nativeLibraryDir"); + + _initialized = true; + return XR_SUCCESS; +} +#endif // XR_USE_PLATFORM_ANDROID + +XrResult InitializeLoaderInitData(const XrLoaderInitInfoBaseHeaderKHR* loaderInitInfo) { + return LoaderInitData::instance().initialize(loaderInitInfo); +} + +#ifdef XR_USE_PLATFORM_ANDROID +std::string GetAndroidNativeLibraryDir() { return LoaderInitData::instance()._native_library_path; } + +void* Android_Get_Asset_Manager() { return LoaderInitData::instance()._android_asset_manager; } +#endif // XR_USE_PLATFORM_ANDROID + +#endif // XR_KHR_LOADER_INIT_SUPPORT diff --git a/src/loader/loader_init_data.hpp b/src/loader/loader_init_data.hpp new file mode 100644 index 000000000..7c6579cce --- /dev/null +++ b/src/loader/loader_init_data.hpp @@ -0,0 +1,92 @@ +// Copyright (c) 2017-2023, The Khronos Group Inc. +// Copyright (c) 2017-2019 Valve Corporation +// Copyright (c) 2017-2019 LunarG, Inc. +// +// SPDX-License-Identifier: Apache-2.0 OR MIT +// +// Initial Author: Mark Young +// + +#pragma once + +#include +#include + +#ifdef XR_USE_PLATFORM_ANDROID +#include +#include +#include "android_utilities.h" +#endif // XR_USE_PLATFORM_ANDROID + +#ifdef XR_KHR_LOADER_INIT_SUPPORT + +/*! + * Stores a copy of the data passed to the xrInitializeLoaderKHR function in a singleton. + */ +class LoaderInitData { + public: + /*! + * Singleton accessor. + */ + static LoaderInitData& instance() { + static LoaderInitData obj; + return obj; + } + +#ifdef XR_USE_PLATFORM_ANDROID + /*! + * Type alias for the platform-specific structure type. + */ + using StructType = XrLoaderInitInfoAndroidKHR; + /*! + * Native library path. + */ + std::string _native_library_path; + /*! + * Android asset manager. + */ + AAssetManager* _android_asset_manager; +#else +#error "Platform specific XR_KHR_loader_init structure is not defined for this platform." +#endif + + /*! + * Get our copy of the data, casted to pass to the runtime's matching method. + */ + const XrLoaderInitInfoBaseHeaderKHR* getParam() const { return reinterpret_cast(&_data); } + + /*! + * Get the data via its real structure type. + */ + const StructType& getData() const { return _data; } + + /*! + * Has this been correctly initialized? + */ + bool initialized() const noexcept { return _initialized; } + + /*! + * Initialize loader data - called by InitializeLoaderInitData() and thus ultimately by the loader's xrInitializeLoaderKHR + * implementation. Each platform that needs this extension will provide an implementation of this. + */ + XrResult initialize(const XrLoaderInitInfoBaseHeaderKHR* info); + + private: + //! Private constructor, forces use of singleton accessor. + LoaderInitData() = default; + //! Platform-specific init data + StructType _data = {}; + //! Flag for indicating whether _data is valid. + bool _initialized = false; +}; + +//! Initialize loader init data, where required. +XrResult InitializeLoaderInitData(const XrLoaderInitInfoBaseHeaderKHR* loaderInitInfo); + +#ifdef XR_USE_PLATFORM_ANDROID +XrResult GetPlatformRuntimeVirtualManifest(Json::Value& out_manifest); +std::string GetAndroidNativeLibraryDir(); +void* Android_Get_Asset_Manager(); +#endif // XR_USE_PLATFORM_ANDROID + +#endif // XR_KHR_LOADER_INIT_SUPPORT diff --git a/src/loader/manifest_file.cpp b/src/loader/manifest_file.cpp index 0683bc166..da96845e6 100644 --- a/src/loader/manifest_file.cpp +++ b/src/loader/manifest_file.cpp @@ -18,6 +18,7 @@ #endif // OPENXR_HAVE_COMMON_CONFIG #include "filesystem_utils.hpp" +#include "loader_init_data.hpp" #include "loader_platform.hpp" #include "platform_utils.hpp" #include "loader_logger.hpp" @@ -666,14 +667,14 @@ XrResult RuntimeManifestFile::FindManifestFiles(std::vector #ifdef XR_USE_PLATFORM_ANDROID -#include "android_utilities.h" -#include #include // Needed for the loader init struct @@ -35,112 +34,6 @@ #include #endif // XR_USE_PLATFORM_ANDROID -#ifdef XR_KHR_LOADER_INIT_SUPPORT -namespace { -/*! - * Stores a copy of the data passed to the xrInitializeLoaderKHR function in a singleton. - */ -class LoaderInitData { - public: - /*! - * Singleton accessor. - */ - static LoaderInitData& instance() { - static LoaderInitData obj; - return obj; - } - -#ifdef XR_USE_PLATFORM_ANDROID - /*! - * Type alias for the platform-specific structure type. - */ - using StructType = XrLoaderInitInfoAndroidKHR; - /*! - * Native library path. - */ - std::string _native_library_path; - /*! - * Android asset manager. - */ - AAssetManager* _android_asset_manager; -#endif - - /*! - * Get our copy of the data, casted to pass to the runtime's matching method. - */ - const XrLoaderInitInfoBaseHeaderKHR* getParam() const { return reinterpret_cast(&_data); } - - /*! - * Get the data via its real structure type. - */ - const StructType& getData() const { return _data; } - - /*! - * Has this been correctly initialized? - */ - bool initialized() const noexcept { return _initialized; } - - /*! - * Initialize loader data - called by InitializeLoader() and thus ultimately by the loader's xrInitializeLoaderKHR - * implementation. Each platform that needs this extension will provide an implementation of this. - */ - XrResult initialize(const XrLoaderInitInfoBaseHeaderKHR* info); - - private: - //! Private constructor, forces use of singleton accessor. - LoaderInitData() = default; - //! Platform-specific init data - StructType _data = {}; - //! Flag for indicating whether _data is valid. - bool _initialized = false; -}; - -#ifdef XR_USE_PLATFORM_ANDROID -// Check and copy the Android-specific init data. -XrResult LoaderInitData::initialize(const XrLoaderInitInfoBaseHeaderKHR* info) { - if (info->type != XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR) { - return XR_ERROR_VALIDATION_FAILURE; - } - auto cast_info = reinterpret_cast(info); - - if (cast_info->applicationVM == nullptr) { - return XR_ERROR_VALIDATION_FAILURE; - } - if (cast_info->applicationContext == nullptr) { - return XR_ERROR_VALIDATION_FAILURE; - } - - // Copy and store the JVM pointer and Android Context, ensuring the JVM is initialised. - _data = *cast_info; - _data.next = nullptr; - jni::init(static_cast(_data.applicationVM)); - const jni::Object context = jni::Object{static_cast(_data.applicationContext)}; - - // Retrieve a reference to the Android AssetManager. - const auto assetManager = context.call("getAssets()Landroid/content/res/AssetManager;"); - _android_asset_manager = AAssetManager_fromJava(jni::env(), assetManager.getHandle()); - - // Retrieve the path to the native libraries. - const auto applicationContext = context.call("getApplicationContext()Landroid/content/Context;"); - const auto applicationInfo = context.call("getApplicationInfo()Landroid/content/pm/ApplicationInfo;"); - _native_library_path = applicationInfo.get("nativeLibraryDir"); - - _initialized = true; - return XR_SUCCESS; -} -#endif // XR_USE_PLATFORM_ANDROID -} // namespace - -XrResult InitializeLoader(const XrLoaderInitInfoBaseHeaderKHR* loaderInitInfo) { - return LoaderInitData::instance().initialize(loaderInitInfo); -} - -std::string GetAndroidNativeLibraryDir() { return LoaderInitData::instance()._native_library_path; } - -void* Android_Get_Asset_Manager() { return LoaderInitData::instance()._android_asset_manager; } - -#endif // XR_KHR_LOADER_INIT_SUPPORT - #ifdef XR_USE_PLATFORM_ANDROID XrResult GetPlatformRuntimeVirtualManifest(Json::Value& out_manifest) { using wrap::android::content::Context; diff --git a/src/loader/runtime_interface.hpp b/src/loader/runtime_interface.hpp index 8d55ec674..8f8278f52 100644 --- a/src/loader/runtime_interface.hpp +++ b/src/loader/runtime_interface.hpp @@ -19,22 +19,10 @@ #include #include -#ifdef XR_USE_PLATFORM_ANDROID -#define XR_KHR_LOADER_INIT_SUPPORT -#endif - namespace Json { class Value; } -#ifdef XR_KHR_LOADER_INIT_SUPPORT -//! Initialize loader, where required. -XrResult InitializeLoader(const XrLoaderInitInfoBaseHeaderKHR* loaderInitInfo); -XrResult GetPlatformRuntimeVirtualManifest(Json::Value& out_manifest); -std::string GetAndroidNativeLibraryDir(); -void* Android_Get_Asset_Manager(); -#endif - class RuntimeManifestFile; struct XrGeneratedDispatchTable; diff --git a/src/scripts/api_dump_generator.py b/src/scripts/api_dump_generator.py index 5b409c33b..d396560d2 100755 --- a/src/scripts/api_dump_generator.py +++ b/src/scripts/api_dump_generator.py @@ -24,6 +24,8 @@ # automatic_source_generator.py class to produce the # generated source code for the API Dump layer. +import dataclasses + from automatic_source_generator import (AutomaticSourceOutputGenerator, undecorate) from generator import write @@ -604,25 +606,9 @@ def writeExpandedMember(self, base_type, is_pointer, pointer_count, member_param valid_extension_structs = member_param.valid_extension_structs member_string += prefix_string - tmp_member_param = self.MemberOrParam(type=member_param.type, - name=member_param.name, - is_const=member_param.is_const, - is_handle=member_param.is_handle, - is_bool=member_param.is_bool, - is_optional=member_param.is_optional, - no_auto_validity=member_param.no_auto_validity, - valid_extension_structs=valid_extension_structs, - is_array=member_param.is_array, - is_static_array=member_param.is_static_array, - static_array_sizes=member_param.static_array_sizes, - array_dimen=member_param.array_dimen, - array_count_var=member_param.array_count_var, - array_length_for=member_param.array_length_for, - pointer_count=pointer_count, - is_null_terminated=member_param.is_null_terminated, - pointer_count_var=member_param.pointer_count_var, - cdecl=member_param.cdecl, - values=member_param.values) + tmp_member_param = dataclasses.replace(member_param, + valid_extension_structs=valid_extension_structs, + pointer_count=pointer_count,) if member_param.is_optional and member_param.is_const and member_param.pointer_count > 0: member_string += self.writeIndent(indent) @@ -728,25 +714,15 @@ def writeExpandedArray(self, base_type, is_pointer, pointer_count, member_param, else: static_array_sizes = member_param.static_array_sizes[1:] - tmp_member_param = self.MemberOrParam(type=member_param.type, - name=member_param.name, - is_const=member_param.is_const, - is_handle=member_param.is_handle, - is_bool=member_param.is_bool, - is_optional=member_param.is_optional, - no_auto_validity=member_param.no_auto_validity, - valid_extension_structs=member_param.valid_extension_structs, - is_array=is_array, - is_static_array=is_static_array, - static_array_sizes=static_array_sizes, - array_dimen=array_dimen, - array_count_var=array_count_var, - array_length_for=array_length_for, - pointer_count=pointer_count, - is_null_terminated=member_param.is_null_terminated, - pointer_count_var=pointer_count_var, - cdecl=member_param.cdecl, - values=member_param.values) + tmp_member_param = dataclasses.replace(member_param, + is_array=is_array, + is_static_array=is_static_array, + static_array_sizes=static_array_sizes, + array_dimen=array_dimen, + array_count_var=array_count_var, + array_length_for=array_length_for, + pointer_count=pointer_count, + pointer_count_var=pointer_count_var,) member_array_string += self.writeExpandedMember(base_type, is_pointer, pointer_count, tmp_member_param, member_param_prefix, member_param_name, True, prefix_string1, prefix_string2, True, indent) diff --git a/src/scripts/automatic_source_generator.py b/src/scripts/automatic_source_generator.py index 2d6b6b394..b470bb43c 100755 --- a/src/scripts/automatic_source_generator.py +++ b/src/scripts/automatic_source_generator.py @@ -25,13 +25,15 @@ # way for the rest of the automatic source generation scripts. import re -from collections import namedtuple +from dataclasses import dataclass from inspect import currentframe, getframeinfo from typing import List, Optional, Tuple, Union +from xml.etree import ElementTree as et from generator import (GeneratorOptions, MissingRegistryError, OutputGenerator, noneStr, regSortFeatures, write) -from spec_tools.attributes import LengthEntry, parse_optional_from_param +from spec_tools.attributes import (LengthEntry, has_any_optional_in_param, + parse_optional_from_param) from spec_tools.util import getElemName @@ -102,7 +104,340 @@ def __init__(self, self.alignFuncParam = alignFuncParam self.genEnumBeginEndRange = genEnumBeginEndRange -# AutomaticSourceOutputGenerator - subclass of OutputGenerator. + +@dataclass +class LengthMember: + """Length Member data""" + + array_name: str + """The name of the array""" + + length_name: str + """The name of the length parameter""" + + +@dataclass +class HandleData: + """Handle data""" + + name: str + """The name of the handle""" + + parent: Optional[str] + """The name of the handle's direct parent""" + + ancestors: List[str] + """A list of all the handle's ancestors""" + + protect_value: Optional[str] + """None or a comma-delimited list indicating #define values to use around this handle""" + + protect_string: str + """Empty string or string to use after #if to protect this handle""" + + ext_name: Optional[str] + """Name of extension this handle is associated with (or None)""" + + +@dataclass +class FlagBits: + """Flag data""" + + name: str + """The name of the flag""" + + type: str + """The base type of the flag (for example uint64_t)""" + + valid_flags: str + """The list of valid flag values""" + + protect_value: Optional[str] + """None or a comma-delimited list indicating #define values to use around this flag""" + + protect_string: str + """Empty string or string to use after #if to protect this flag""" + + ext_name: Optional[str] + """Name of extension this command is associated with (or None)""" + + +@dataclass +class EnumBitValue: + """Individual Enum bit value""" + + name: str + """Name of an individual enum bit""" + + protect_value: Optional[str] + """None or a comma-delimited list indicating #define values to use around this value""" + + protect_string: str + """Empty string or string to use after #if to protect this value""" + + ext_name: Optional[str] + """Name of extension this command is associated with (or None)""" + + alias: Optional[str] + """None or the name of the type this is an alias for""" + + +@dataclass +class EnumData: + """Enum type data""" + + name: str + """The name of the enum""" + + values: List[EnumBitValue] + """List of possible EnumBitValue for this enum.""" + + protect_value: Optional[str] + """None or a comma-delimited list indicating #define values to use around this enum""" + + protect_string: str + """Empty string or string to use after #if to protect this enum""" + + ext_name: Optional[str] + """Name of extension this command is associated with (or None)""" + + +@dataclass +class MemberOrParam: + """Struct/Union member or Command parameter data""" + + type: str + """The type of this parameter""" + + is_handle: bool + """Boolean indicating if this type is a handle""" + + is_const: bool + """Boolean indicating if this has a const identifier""" + + is_bool: bool + """Boolean indicating if this is a boolean type""" + + is_optional: bool + """Boolean indicating if this is optional (pointers may be NULL, etc)""" + + is_array: bool + """Boolean indicating if this is an array""" + + array_dimen: int + """Number of dimensions for this array""" + + is_static_array: bool + """Boolean indicating if this is a statically sized array""" + + static_array_sizes: Optional[List[int]] + """List of static array sizes for each dimension""" + + array_count_var: str + """Name of array count if this is a value, and not a number""" + + array_length_for: str + """Indicates the array parameter that this is a length for""" + + pointer_count: int + """Depth of pointers for this type (* = 1, ** == 2)""" + + pointer_count_var: str + """If this is a pointer, and an array, it's the max size of that array""" + + is_null_terminated: bool + """Is this parameter null-terminated""" + + no_auto_validity: bool + """Boolean indicating if this should not have any automatic validation performed""" + + name: str + """The parameter name""" + + valid_extension_structs: Optional[str] + """Name of valid extension structs for this param (usually for 'next')""" + + cdecl: str + """The complete C-declaration for this parameter.""" + + values: Optional[str] + """None or comma-separated list of valid values""" + + +@dataclass +class StructUnionData: + """Information regarding a structure or union""" + + name: str + """Name of the structure or union""" + + ext_name: Optional[str] + """Name of extension this struct/union is associated with (or None)""" + + required_exts: List[str] + """Additional extensions required for this struct/union to be valid""" + + returned_only: bool + """Boolean indicating that this struct/union is only for returning information""" + + members: List[MemberOrParam] + """List of MemberOrParam for each member in this struct/union""" + + protect_value: Optional[str] + """None or a comma-delimited list indicating #define values to use around this structure/union""" + + protect_string: str + """Empty string or string to use after #if to protect this structure/union""" + + +@dataclass +class CommandData: + """Command data""" + + name: str + """Name of command""" + + is_create_connect: bool + """Boolean indicating this is a create/connect command""" + + is_destroy_disconnect: bool + """Boolean indicating this is a destroy/disconnect command""" + + ext_name: Optional[str] + """Name of extension this command is associated with (or None)""" + + ext_type: str + """Type of extension (instance, device)""" + + required_exts: List[str] + """Additional extensions required for this command to be valid""" + + handle_type: str + """Type of handle used as the primary type for this command""" + + handle: str + """Base handle for this command""" + + has_instance: bool + """True if an instance is used somewhere in the command""" + + return_type: Optional[et.Element] + """Type of return (or None)""" + + return_values: str + """Documented return values (core only)""" + + params: List[MemberOrParam] + """List of MemberOrParam for each parameter in this command""" + + protect_value: Optional[str] + """None or a comma-delimited list indicating #define values to use around this command""" + + protect_string: str + """Empty string or string to use after #if to protect this command""" + + begins_state: bool + """Boolean indicating this command begins some kind of state""" + + ends_state: bool + """Boolean indicating this command ends some kind of state""" + + checks_state: bool + """Boolean indicating this command checks for some kind of state""" + + cdecl: str + """The complete C-declaration for this command""" + + +@dataclass +class ExtensionData: + """Information on a given extension""" + + name: str + """Name of this extension (ex. XR_EXT_foo)""" + + vendor_tag: str + """Vendor tag associated with this extension""" + + type: str + """Type of extension (instance, device, ...)""" + + define: str + """Define containing a string version of the extension name""" + + num_commands: int + """Number of commands in the extension""" + + required_exts: List[str] + """List of required extensions for using this extension's functionality""" + + protect_value: Optional[str] + """None or a comma-delimited list indicating #define values to use around this extension""" + + protect_string: str + """Empty string or string to use after #if to protect this extension""" + + +@dataclass +class BaseTypeData: + """Base type listing (converts from a type into a name which is used as a type somewhere else).""" + + type: str + """The base type""" + + name: str + """The name of the derived type""" + + +@dataclass +class TypeData: + """Type listing""" + + name: str + """The name of the type""" + + protect_value: Optional[str] + """None or a comma-delimited list indicating #define values to use around this type""" + + protect_string: str + """Empty string or string to use after #if to protect this type""" + + alias: Optional[str] + """None or the name of the type this is an alias for""" + + +@dataclass +class StructRelationGroup: + """Structure relation group data""" + + generic_struct_name: str + """The name of the generic structure defining the common elements""" + + child_struct_names: List[str] + """Children of the base structure""" + + +@dataclass +class ApiState: + """API state listing""" + + state: str + """The name of the state""" + + type: str + """The type that is associated with the state (handle/struct/...)""" + + variable: str + """State variable""" + + begin_commands: List[CommandData] + """List of commands that begin the current state""" + + end_commands: List[CommandData] + """List of commands that end the current state""" + + check_commands: List[CommandData] + """List of commands that check the current state""" class AutomaticSourceOutputGenerator(OutputGenerator): @@ -111,216 +446,10 @@ class AutomaticSourceOutputGenerator(OutputGenerator): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - # ** Global types for automatic source generation ** - # Length Member data - self.LengthMember = namedtuple('LengthMember', - ['array_name', # The name of the array - 'length_name']) # The name of the length parameter - # Handle data - self.HandleData = namedtuple('HandleData', - [ # The name of the handle - 'name', - # The name of the handle's direct parent - 'parent', - # A list of all the handle's ancestors - 'ancestors', - # None or a comma-delimited list indicating #define values to use around this handle - 'protect_value', - # Empty string or string to use after #if to protect this handle - 'protect_string', - # Name of extension this handle is associated with (or None) - 'ext_name']) - # Flag data - self.FlagBits = namedtuple('FlagBits', - [ # The name of the flag - 'name', - # The base type of the flag (for example uint64_t) - 'type', - # The list of valid flag values - 'valid_flags', - # None or a comma-delimited list indicating #define values to use around this flag - 'protect_value', - # Empty string or string to use after #if to protect this flag - 'protect_string', - # Name of extension this command is associated with (or None) - 'ext_name']) - - # Individual Enum bit value - self.EnumBitValue = namedtuple('EnumBitValue', - [ # Name of an individual enum bit - 'name', - # None or a comma-delimited list indicating #define values to use around this value - 'protect_value', - # Empty string or string to use after #if to protect this value - 'protect_string', - # Name of extension this command is associated with (or None) - 'ext_name', - # None or the name of the type this is an alias for - 'alias']) - # Enum type data - self.EnumData = namedtuple('EnumData', - [ # The name of the enum - 'name', - # List of possible EnumBitValue for this enum. - 'values', - # None or a comma-delimited list indicating #define values to use around this enum - 'protect_value', - # Empty string or string to use after #if to protect this enum - 'protect_string', - # Name of extension this command is associated with (or None) - 'ext_name']) - # Struct/Union member or Command parameter data - self.MemberOrParam = namedtuple('MemberOrParam', - [ # The type of this parameter - 'type', - # Boolean indicating if this type is a handle - 'is_handle', - # Boolean indicating if this has a const identifier - 'is_const', - # Boolean indicating if this is a boolean type - 'is_bool', - # Boolean indicating if this is optional (pointers may be NULL, etc) - 'is_optional', - # Boolean indicating if this is an array - 'is_array', - # Number of dimensions for this array - 'array_dimen', - # Boolean indicating if this is a statically sized array - 'is_static_array', - # List of static array sizes for each dimension - 'static_array_sizes', - # Name of array count if this is a value, and not a number - 'array_count_var', - # Indicates the array parameter that this is a length for - 'array_length_for', - # Depth of pointers for this type (* = 1, ** == 2) - 'pointer_count', - # If this is a pointer, and an array, it's the max size of that array - 'pointer_count_var', - # Is this parameter null-terminated - 'is_null_terminated', - # Boolean indicating if this should not have any automatic validation performed - 'no_auto_validity', - # The parameter name - 'name', - # Name of valid extension structs for this param (usually for 'next') - 'valid_extension_structs', - # The complete C-declaration for this parameter. - 'cdecl', - # None or comma-separated list of valid values - 'values']) - # Command data - self.CommandData = namedtuple('CommandData', - [ # Name of command - 'name', - # Boolean indicating this is a create/connect command - 'is_create_connect', - # Boolean indicating this is a destroy/disconnect command - 'is_destroy_disconnect', - # Name of extension this command is associated with (or None) - 'ext_name', - # Type of extension (instance, device) - 'ext_type', - # Additional extensions required for this command to be valid - 'required_exts', - # Type of handle used as the primary type for this command - 'handle_type', - # Base handle for this command - 'handle', - # True if an instance is used somewhere in the command - 'has_instance', - # Type of return (or None) - 'return_type', - # Documented return values (core only) - 'return_values', - # List of MemberOrParam for each parameter in this command - 'params', - # None or a comma-delimited list indicating #define values to use around this command - 'protect_value', - # Empty string or string to use after #if to protect this command - 'protect_string', - # Boolean indicating this command begins some kind of state - 'begins_state', - # Boolean indicating this command ends some kind of state - 'ends_state', - # Boolean indicating this command checks for some kind of state - 'checks_state', - # The complete C-declaration for this command - 'cdecl']) - # Information regarding a structure or union - self.StructUnionData = namedtuple('StructUnionData', - [ # Name of the structure or union - 'name', - # Name of extension this struct/union is associated with (or None) - 'ext_name', - # Additional extensions required for this struct/union to be valid - 'required_exts', - # Boolean indicating that this struct/union is only for returning information - 'returned_only', - # List of MemberOrParam for each member in this struct/union - 'members', - # None or a comma-delimited list indicating #define values to use around this structure/union - 'protect_value', - # Empty string or string to use after #if to protect this structure/union - 'protect_string']) - # Information on a given extension - self.ExtensionData = namedtuple('ExtensionData', - [ # Name of this extension (ex. XR_EXT_foo) - 'name', - # Vendor tag associated with this extension - 'vendor_tag', - # Type of extension (instance, device, ...) - 'type', - # Define containing a string version of the extension name - 'define', - # Number of commands in the extension - 'num_commands', - # List of required extensions for using this extension's functionality - 'required_exts', - # None or a comma-delimited list indicating #define values to use around this extension - 'protect_value', - # Empty string or string to use after #if to protect this extension - 'protect_string']) - # Base type listing (converts from a type into a name which is used as a type somewhere else). - self.BaseTypeData = namedtuple('BaseTypeData', - [ # The base type - 'type', - # The name of the derived type - 'name']) - # Type listing - self.TypeData = namedtuple('TypeData', - [ # The name of the type - 'name', - # None or a comma-delimited list indicating #define values to use around this type - 'protect_value', - # Empty string or string to use after #if to protect this type - 'protect_string', - # None or the name of the type this is an alias for - 'alias']) - # Structure relation group data - self.StructRelationGroup = namedtuple('StructRelationGroup', - [ # The name of the generic structure defining the common elements - 'generic_struct_name', - # Children of the base structure - 'child_struct_names']) - # API state listing - self.ApiState = namedtuple('ApiState', - [ # The name of the state - 'state', - # The type that is associated with the state (handle/struct/...) - 'type', - # State variable - 'variable', - # List of commands that begin the current state - 'begin_commands', - # List of commands that end the current state - 'end_commands', - # List of commands that check the current state - 'check_commands']) # Did we encounter an error self.encountered_error = False # List of strings containing all vendor tags - self.vendor_tags = [] + self.vendor_tags: List[str] = [] # Current vendor tag that should be used by this extension self.current_vendor_tag = '' # A define used to set the current API version in a component (in the loader, layers, etc). @@ -328,25 +457,25 @@ def __init__(self, *args, **kwargs): # A defined used to grab the current API Header's version self.header_version = '' # A list of all the API's core commands (CommandData). - self.core_commands = [] + self.core_commands: List[CommandData] = [] # A list of all the API's extension commands (CommandData). - self.ext_commands = [] + self.ext_commands: List[CommandData] = [] # A list of all extensions (ExtensionData) for this API - self.extensions = [] + self.extensions: List[ExtensionData] = [] # A list of all base data types (BaseTypeData) for this API - self.api_base_types = [] + self.api_base_types: List[BaseTypeData] = [] # A list of all handles (HandleData) for this API - self.api_handles = [] + self.api_handles: List[HandleData] = [] # A list of all structures (StructUnionData) for this API - self.api_structures = [] + self.api_structures: List[StructUnionData] = [] # A list of all unions (StructUnionData) for this API - self.api_unions = [] + self.api_unions: List[StructUnionData] = [] # A list of all enumeration (EnumData) for this API - self.api_enums = [] + self.api_enums: List[EnumData] = [] # A list of all flags (FlagBits) for this API - self.api_flags = [] + self.api_flags: List[FlagBits] = [] # A list of all bitmasks (EnumData) for this API - self.api_bitmasks = [] + self.api_bitmasks: List[EnumData] = [] # A list of all object types self.api_object_types = [] # A list of all result types @@ -572,7 +701,7 @@ def endFeature(self): if self.type == 'instance' or self.type == 'system': # Add the completed extension to the list of extensions self.extensions.append( - self.ExtensionData( + ExtensionData( name=self.currentExtension, vendor_tag=self.current_vendor_tag, type=self.type, @@ -636,7 +765,7 @@ def genGroup(self, group_info, name, alias): extension_to_check = elem.get('extname', self.currentExtension) alias = elem.get('alias') values.append( - self.EnumBitValue( + EnumBitValue( name=elem_name, protect_value=enum_protect_value, protect_string=enum_protect_string, @@ -648,7 +777,7 @@ def genGroup(self, group_info, name, alias): ' with the expected vendor tag \"%s\"' % ( name, self.currentExtension, self.current_vendor_tag)) self.api_enums.append( - self.EnumData( + EnumData( name=name, values=values, protect_value=top_protect_value, @@ -660,7 +789,7 @@ def genGroup(self, group_info, name, alias): ' end with the expected vendor tag \"%s\"' % ( name, self.currentExtension, self.current_vendor_tag)) self.api_bitmasks.append( - self.EnumData( + EnumData( name=name, values=values, protect_value=top_protect_value, @@ -684,7 +813,7 @@ def genGroup(self, group_info, name, alias): item_name, len(item_name), self.max_result_length)) alias = elem.get('alias') self.api_result_types.append( - self.TypeData( + TypeData( name=item_name, protect_value=protect_value, protect_string=protect_string, @@ -703,7 +832,7 @@ def genGroup(self, group_info, name, alias): ' not end with the expected vendor tag \"%s\"' % ( item_name, self.currentExtension, self.current_vendor_tag)) self.api_object_types.append( - self.TypeData( + TypeData( name=item_name, protect_value=protect_value, protect_string=protect_string, @@ -730,7 +859,7 @@ def genGroup(self, group_info, name, alias): if alias: self.aliases[item_name] = alias self.api_structure_types.append( - self.TypeData( + TypeData( name=item_name, protect_value=protect_value, protect_string=protect_string, @@ -799,7 +928,7 @@ def genType(self, type_info, type_name, alias): # - We need to know when it's created and destroyed, # - We need to setup unordered_maps and mutexes to track dispatch tables for each handle self.api_handles.append( - self.HandleData( + HandleData( name=type_name, parent=self.getHandleParent(type_name), ancestors=self.getHandleAncestors(type_name), @@ -813,7 +942,7 @@ def genType(self, type_info, type_name, alias): base_type = basetype_info[0] base_name = basetype_info[1] self.api_base_types.append( - self.BaseTypeData( + BaseTypeData( type=base_type, name=base_name)) elif type_category == 'define': @@ -831,7 +960,7 @@ def genType(self, type_info, type_name, alias): bitvalues = type_elem.get('bitvalues') # Record a bitmask and all it's valid flag bit values self.api_flags.append( - self.FlagBits( + FlagBits( name=mask_name, type=mask_type, valid_flags=bitvalues, @@ -927,6 +1056,16 @@ def genStructUnion(self, type_info, type_category, type_name, alias): required_exts.extend(ext_names.split(',')) returned_only = (type_info.elem.get('returnedonly') == "true") + # Check if this is a base header. + if type_name.endswith("BaseHeader{}".format(self.current_vendor_tag)): + # Check if the relation group already existed + existing_relation_group = self.getRelationGroupForBaseStruct(type_name) + if existing_relation_group is None: + # Create with an empty child list + relation_group = StructRelationGroup(generic_struct_name=type_name, + child_struct_names=[]) + self._struct_relation_groups[type_name] = relation_group + # Search through the members to determine all the array lengths arraylengths = dict() for member in members: @@ -942,10 +1081,10 @@ def genStructUnion(self, type_info, type_category, type_name, alias): static_array_sizes = [] no_auto_validity = True if member.get( 'noautovalidity') else False - is_optional = (self.paramIsOptional(member) or (member_name == 'next')) + is_optional = (member_name == 'next') or (has_any_optional_in_param(member)) is_handle = self.isHandle(member_type) - is_static_array = self.paramIsStaticArray(member) - is_array = is_static_array + static_array_dim = self.paramIsStaticArray(member) + is_array = static_array_dim > 0 array_count_var = '' # Determine if this is an array length member array_name_for_length = arraylengths.get(member_name, '') @@ -961,7 +1100,7 @@ def genStructUnion(self, type_info, type_category, type_name, alias): cdecl, member_type, member_name) # If this is a static array, grab the sizes - if is_static_array: + if static_array_dim: static_array_sizes = self.paramStaticArraySizes(member) # If the enum field is there, then this is an array with an enum @@ -989,26 +1128,27 @@ def genStructUnion(self, type_info, type_category, type_name, alias): # Append this member to the list of current members members_info.append( - self.MemberOrParam(type=member_type, - name=member_name, - is_const=is_const, - is_handle=is_handle, - is_bool=True if 'XrBool' in member_type else False, - is_optional=is_optional, - no_auto_validity=no_auto_validity, - valid_extension_structs=self.registry.validextensionstructs[ - type_name] if member_name == 'next' else None, - is_array=is_array, - is_static_array=is_static_array, - static_array_sizes=static_array_sizes, - array_dimen=array_dimen, - array_count_var=array_count_var, - array_length_for=array_name_for_length, - pointer_count=pointer_count, - pointer_count_var=pointer_count_var, - is_null_terminated=is_null_terminated, - cdecl=cdecl, - values=member_values)) + MemberOrParam(type=member_type, + name=member_name, + is_const=is_const, + is_handle=is_handle, + is_bool=True if 'XrBool' in member_type else False, + is_optional=is_optional, + no_auto_validity=no_auto_validity, + valid_extension_structs=self.registry.validextensionstructs[ + type_name] if member_name == 'next' else None, + is_array=is_array, + is_static_array=(static_array_dim > 0), + static_array_sizes=static_array_sizes, + array_dimen=array_dimen, + array_count_var=array_count_var, + array_length_for=array_name_for_length, + pointer_count=pointer_count, + pointer_count_var=pointer_count_var, + is_null_terminated=is_null_terminated, + cdecl=cdecl, + values=member_values)) + # If this structure/union expands a generic one, save the information and validate that # it contains at least the same elements as the generic one. if type_info.elem.get('parentstruct'): @@ -1021,8 +1161,8 @@ def genStructUnion(self, type_info, type_category, type_name, alias): else: # Create with an empty child list for now child_list = [] - relation_group = self.StructRelationGroup(generic_struct_name=generic_struct_name, - child_struct_names=child_list) + relation_group = StructRelationGroup(generic_struct_name=generic_struct_name, + child_struct_names=child_list) self._struct_relation_groups[generic_struct_name] = relation_group # Get the structure information for the group's generic structure @@ -1053,22 +1193,22 @@ def genStructUnion(self, type_info, type_category, type_name, alias): type_name, generic_struct_name)) if is_union: self.api_unions.append( - self.StructUnionData(name=type_name, - ext_name=self.currentExtension, - required_exts=required_exts, - protect_value=protect_value, - protect_string=protect_string, - returned_only=returned_only, - members=members_info)) + StructUnionData(name=type_name, + ext_name=self.currentExtension, + required_exts=required_exts, + protect_value=protect_value, + protect_string=protect_string, + returned_only=returned_only, + members=members_info)) else: self.api_structures.append( - self.StructUnionData(name=type_name, - ext_name=self.currentExtension, - required_exts=required_exts, - protect_value=protect_value, - protect_string=protect_string, - returned_only=returned_only, - members=members_info)) + StructUnionData(name=type_name, + ext_name=self.currentExtension, + required_exts=required_exts, + protect_value=protect_value, + protect_string=protect_string, + returned_only=returned_only, + members=members_info)) # Add a command to the appropriate list of commands (core or extension) # self the AutomaticSourceOutputGenerator object @@ -1077,6 +1217,8 @@ def genStructUnion(self, type_info, type_category, type_name, alias): # name the name of the command # cmd_info the XML information for this command def addCommandToDispatchList(self, ext_name, ext_type, name, cmd_info): + if self.registry is None: + raise MissingRegistryError() cmd_params = [] required_exts = [] is_core = True if self.isCoreExtensionName(ext_name) else False @@ -1138,7 +1280,7 @@ def addCommandToDispatchList(self, ext_name, ext_type, name, cmd_info): # Generate a list of commands for param in params: - is_array = self.paramIsStaticArray(param) + is_array = self.paramIsStaticArray(param) > 0 param_cdecl = self.makeCParamDecl(param, 0) array_count_var = '' pointer_count_var = '' @@ -1183,16 +1325,16 @@ def addCommandToDispatchList(self, ext_name, ext_type, name, cmd_info): # Add the command parameter to the list cmd_params.append( - self.MemberOrParam( + MemberOrParam( type=param_type, name=param_name, is_const=('const' in param_cdecl.strip().lower()), is_handle=self.isHandle(param_type), is_bool=('XrBool' in paramInfo[0]), - is_optional=self.paramIsOptional(param), + is_optional=has_any_optional_in_param(param), no_auto_validity=(param.get('noautovalidity') is not None), is_array=is_array, - is_static_array=self.paramIsStaticArray(param), + is_static_array=self.paramIsStaticArray(param) > 0, static_array_sizes=self.paramStaticArraySizes( param) if self.paramIsStaticArray(param) else None, array_dimen=array_dimen, @@ -1220,44 +1362,44 @@ def addCommandToDispatchList(self, ext_name, ext_type, name, cmd_info): if handle is not None and handle_type != 'XrInstance': core_command_type = 'device' self.core_commands.append( - self.CommandData(name=name, - is_create_connect=is_create_connect, - is_destroy_disconnect=is_destroy_disconnect, - ext_name=ext_name, - ext_type=core_command_type, - required_exts=required_exts, - protect_value=protect_value, - protect_string=protect_string, - return_type=return_type, - return_values=return_values, - handle=handle, - handle_type=handle_type, - has_instance=cmd_has_instance, - params=cmd_params, - begins_state=begins_state, - ends_state=ends_state, - checks_state=checks_state, - cdecl=self.makeCDecls(cmd_info.elem)[0])) + CommandData(name=name, + is_create_connect=is_create_connect, + is_destroy_disconnect=is_destroy_disconnect, + ext_name=ext_name, + ext_type=core_command_type, + required_exts=required_exts, + protect_value=protect_value, + protect_string=protect_string, + return_type=return_type, + return_values=return_values, + handle=handle, + handle_type=handle_type, + has_instance=cmd_has_instance, + params=cmd_params, + begins_state=begins_state, + ends_state=ends_state, + checks_state=checks_state, + cdecl=self.makeCDecls(cmd_info.elem)[0])) else: self.ext_commands.append( - self.CommandData(name=name, - is_create_connect=is_create_connect, - is_destroy_disconnect=is_destroy_disconnect, - ext_name=ext_name, - ext_type=ext_type, - required_exts=required_exts, - protect_value=protect_value, - protect_string=protect_string, - return_type=return_type, - return_values=return_values, - handle=handle, - handle_type=handle_type, - has_instance=cmd_has_instance, - params=cmd_params, - begins_state=begins_state, - ends_state=ends_state, - checks_state=checks_state, - cdecl=self.makeCDecls(cmd_info.elem)[0])) + CommandData(name=name, + is_create_connect=is_create_connect, + is_destroy_disconnect=is_destroy_disconnect, + ext_name=ext_name, + ext_type=ext_type, + required_exts=required_exts, + protect_value=protect_value, + protect_string=protect_string, + return_type=return_type, + return_values=return_values, + handle=handle, + handle_type=handle_type, + has_instance=cmd_has_instance, + params=cmd_params, + begins_state=begins_state, + ends_state=ends_state, + checks_state=checks_state, + cdecl=self.makeCDecls(cmd_info.elem)[0])) def findState(self, state): for api_state in self.api_states: @@ -1291,12 +1433,12 @@ def addCommandToBeginStates(self, comma_list_states, command): begin_list.append(command) # Create and append the new state self.api_states.append( - self.ApiState(state=cur_state, - type=state_type, - variable=state_variable, - begin_commands=begin_list, - end_commands=end_list, - check_commands=check_list)) + ApiState(state=cur_state, + type=state_type, + variable=state_variable, + begin_commands=begin_list, + end_commands=end_list, + check_commands=check_list)) else: # Found, so just add a new begin command found_state.begin_commands.append(command) @@ -1327,12 +1469,12 @@ def addCommandToEndStates(self, comma_list_states, command): end_list.append(command) # Create and append the new state self.api_states.append( - self.ApiState(state=cur_state, - type=state_type, - variable=state_variable, - begin_commands=begin_list, - end_commands=end_list, - check_commands=check_list)) + ApiState(state=cur_state, + type=state_type, + variable=state_variable, + begin_commands=begin_list, + end_commands=end_list, + check_commands=check_list)) else: # Found, so just add a new end command found_state.end_commands.append(command) @@ -1363,12 +1505,12 @@ def addCommandToCheckStates(self, comma_list_states, command): check_list.append(command) # Create and append the new state self.api_states.append( - self.ApiState(state=cur_state, - type=state_type, - variable=state_variable, - begin_commands=begin_list, - end_commands=end_list, - check_commands=check_list)) + ApiState(state=cur_state, + type=state_type, + variable=state_variable, + begin_commands=begin_list, + end_commands=end_list, + check_commands=check_list)) else: # Found, so just add a new check command found_state.check_commands.append(command) @@ -1376,7 +1518,7 @@ def addCommandToCheckStates(self, comma_list_states, command): # Check if the parameter passed in is a static array # self the AutomaticSourceOutputGenerator object # param the XML information for the param - def paramIsStaticArray(self, param): + def paramIsStaticArray(self, param) -> int: is_static_array = 0 param_name = param.find('name') if param_name.tail and ('[' in param_name.tail): diff --git a/src/scripts/generate_api_layer_manifest.py b/src/scripts/generate_api_layer_manifest.py index fc843f3cf..570e9ffa6 100755 --- a/src/scripts/generate_api_layer_manifest.py +++ b/src/scripts/generate_api_layer_manifest.py @@ -26,6 +26,8 @@ # file itself as a starting point. # json_file the JSON file we're creating # library_file the library (so/dll) file we're referencing in the JSON file + + def getRelativePath(json_file, library_file): directory_slash = '/' relative_path = '' @@ -76,6 +78,7 @@ def getRelativePath(json_file, library_file): print(relative_path) return relative_path + def main(argv): output_file = '' layer_name = '' @@ -85,7 +88,7 @@ def main(argv): description = '' generate_badjson_jsons = False - usage = '\ngenerate_api_layer_manifest.py \n' + usage = '\ngenerate_api_layer_manifest.py \n' usage += ' -f/--file \n' usage += ' -n/--name \n' usage += ' -l/--lib \n' @@ -95,7 +98,7 @@ def main(argv): usage += ' -b/--bad\n' try: - opts, _ = getopt.getopt(argv,"hbf:n:l:a:v:d:",["bad","file=","name=","lib=","api=","ver=","desc="]) + opts, _ = getopt.getopt(argv, "hbf:n:l:a:v:d:", ["bad", "file=", "name=", "lib=", "api=", "ver=", "desc="]) except getopt.GetoptError: print(usage) sys.exit(2) @@ -118,7 +121,7 @@ def main(argv): elif opt in ("-b", "--bad"): generate_badjson_jsons = True - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "%s",\n' % cur_layer_json_version file_text += ' "api_layer": {\n' file_text += ' "name": "XR_APILAYER_%s",\n' % layer_name @@ -153,7 +156,7 @@ def main(argv): # Missing bad_name = '_badjson_file_ver_missing' - file_text = '{\n' + file_text = '{\n' file_text += ' "api_layer": {\n' file_text += ' "name": "XR_APILAYER_LUNARG_%s%s",\n' % (layer_name, bad_name) file_text += ' "library_path": "%s",\n' % library_location @@ -170,7 +173,7 @@ def main(argv): # Use int bad_name = '_badjson_file_ver_int' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": 1,\n' file_text += ' "api_layer": {\n' file_text += ' "name": "XR_APILAYER_LUNARG_%s%s",\n' % (layer_name, bad_name) @@ -188,7 +191,7 @@ def main(argv): # Use invalid string bad_name = '_badjson_file_ver_string' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "invalid string",\n' file_text += ' "api_layer": {\n' file_text += ' "name": "XR_APILAYER_LUNARG_%s%s",\n' % (layer_name, bad_name) @@ -206,7 +209,7 @@ def main(argv): # Too low of a version bad_name = '_badjson_file_ver_all_low' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "0.0.0",\n' file_text += ' "api_layer": {\n' file_text += ' "name": "XR_APILAYER_LUNARG_%s%s",\n' % (layer_name, bad_name) @@ -224,7 +227,7 @@ def main(argv): # Too high of a major version bad_name = '_badjson_file_ver_major_high' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "15.0.0",\n' file_text += ' "api_layer": {\n' file_text += ' "name": "XR_APILAYER_LUNARG_%s%s",\n' % (layer_name, bad_name) @@ -242,7 +245,7 @@ def main(argv): # Too high of a minor version bad_name = '_badjson_file_ver_minor_high' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "1.15.0",\n' file_text += ' "api_layer": {\n' file_text += ' "name": "XR_APILAYER_LUNARG_%s%s",\n' % (layer_name, bad_name) @@ -263,7 +266,7 @@ def main(argv): # Completely Missing bad_name = '_badjson_layer_missing' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "%s",\n' % cur_layer_json_version file_text += ' "name": "XR_APILAYER_LUNARG_%s%s",\n' % (layer_name, bad_name) file_text += ' "library_path": "%s",\n' % library_location @@ -279,7 +282,7 @@ def main(argv): # Empty bad_name = '_badjson_layer_empty' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "%s",\n' % cur_layer_json_version file_text += ' "api_layer": {\n' file_text += ' },\n' @@ -300,7 +303,7 @@ def main(argv): # Use int bad_name = '_badjson_name_int' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "%s",\n' % cur_layer_json_version file_text += ' "api_layer": {\n' file_text += ' "name": 1,\n' @@ -318,7 +321,7 @@ def main(argv): # Missing bad_name = '_badjson_name_missing' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "%s",\n' % cur_layer_json_version file_text += ' "api_layer": {\n' file_text += ' "library_path": "%s",\n' % library_location @@ -338,7 +341,7 @@ def main(argv): # Missing bad_name = '_badjson_path_missing' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "%s",\n' % cur_layer_json_version file_text += ' "api_layer": {\n' file_text += ' "name": "XR_APILAYER_LUNARG_%s%s",\n' % (layer_name, bad_name) @@ -355,7 +358,7 @@ def main(argv): # Use int bad_name = '_badjson_path_int' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "%s",\n' % cur_layer_json_version file_text += ' "api_layer": {\n' file_text += ' "name": "XR_APILAYER_LUNARG_%s%s",\n' % (layer_name, bad_name) @@ -373,11 +376,11 @@ def main(argv): # Replace valid path with invalid one bad_name = '_badjson_path_no_file' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "%s",\n' % cur_layer_json_version file_text += ' "api_layer": {\n' file_text += ' "name": "XR_APILAYER_LUNARG_%s%s",\n' % (layer_name, bad_name) - file_text += ' "library_path": "%s",\n' % library_location.replace("test_layers","not_real") + file_text += ' "library_path": "%s",\n' % library_location.replace("test_layers", "not_real") file_text += ' "api_version": "%s",\n' % api_version file_text += ' "implementation_version": "%s",\n' % implementation_version file_text += ' "description": "%s"\n' % description @@ -394,7 +397,7 @@ def main(argv): # Missing bad_name = '_badjson_api_int' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "%s",\n' % cur_layer_json_version file_text += ' "api_layer": {\n' file_text += ' "name": "XR_APILAYER_LUNARG_%s%s",\n' % (layer_name, bad_name) @@ -411,7 +414,7 @@ def main(argv): # Use int bad_name = '_badjson_api_int' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "%s",\n' % cur_layer_json_version file_text += ' "api_layer": {\n' file_text += ' "name": "XR_APILAYER_LUNARG_%s%s",\n' % (layer_name, bad_name) @@ -429,7 +432,7 @@ def main(argv): # Use float bad_name = '_badjson_api_float' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "%s",\n' % cur_layer_json_version file_text += ' "api_layer": {\n' file_text += ' "name": "XR_APILAYER_LUNARG_%s%s",\n' % (layer_name, bad_name) @@ -447,7 +450,7 @@ def main(argv): # Bad string bad_name = '_badjson_api_string' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "%s",\n' % cur_layer_json_version file_text += ' "api_layer": {\n' file_text += ' "name": "XR_APILAYER_LUNARG_%s%s",\n' % (layer_name, bad_name) @@ -465,7 +468,7 @@ def main(argv): # Too high of a major API version bad_name = '_badjson_api_major_high' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "%s",\n' % cur_layer_json_version file_text += ' "api_layer": {\n' file_text += ' "name": "XR_APILAYER_LUNARG_%s%s",\n' % (layer_name, bad_name) @@ -486,7 +489,7 @@ def main(argv): # Always fail negotiate bad_name = '_badnegotiate_always' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "%s",\n' % cur_layer_json_version file_text += ' "api_layer": {\n' file_text += ' "name": "XR_APILAYER_LUNARG_%s%s",\n' % (layer_name, bad_name) @@ -508,7 +511,7 @@ def main(argv): # Pass negotiate, but return null GIPA bad_name = '_badnegotiate_invalid_gipa' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "%s",\n' % cur_layer_json_version file_text += ' "api_layer": {\n' file_text += ' "name": "XR_APILAYER_LUNARG_%s%s",\n' % (layer_name, bad_name) @@ -530,7 +533,7 @@ def main(argv): # Pass negotiate, but return invalid interface version bad_name = '_badnegotiate_invalid_interface' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "%s",\n' % cur_layer_json_version file_text += ' "api_layer": {\n' file_text += ' "name": "XR_APILAYER_LUNARG_%s%s",\n' % (layer_name, bad_name) @@ -552,7 +555,7 @@ def main(argv): # Pass negotiate, but return invalid api version bad_name = '_badnegotiate_invalid_api' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "%s",\n' % cur_layer_json_version file_text += ' "api_layer": {\n' file_text += ' "name": "XR_APILAYER_LUNARG_%s%s",\n' % (layer_name, bad_name) @@ -578,7 +581,7 @@ def main(argv): # Provide a good relative path layer_suffix_name = '_good_relative_path' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "%s",\n' % cur_layer_json_version file_text += ' "api_layer": {\n' file_text += ' "name": "XR_APILAYER_LUNARG_%s%s",\n' % (layer_name, layer_suffix_name) @@ -596,11 +599,11 @@ def main(argv): # Provide a bad relative path layer_suffix_name = '_badjson_relative_path' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "%s",\n' % cur_layer_json_version file_text += ' "api_layer": {\n' file_text += ' "name": "XR_APILAYER_LUNARG_%s%s",\n' % (layer_name, layer_suffix_name) - file_text += ' "library_path": "%s",\n' % relative_lib.replace("test_layers","not_real") + file_text += ' "library_path": "%s",\n' % relative_lib.replace("test_layers", "not_real") file_text += ' "api_version": "%s",\n' % api_version file_text += ' "implementation_version": "%s",\n' % implementation_version file_text += ' "description": "%s"\n' % description @@ -612,5 +615,6 @@ def main(argv): f.write(file_text) f.close() + if __name__ == "__main__": main(sys.argv[1:]) diff --git a/src/scripts/generate_runtime_manifest.py b/src/scripts/generate_runtime_manifest.py index 8de78dacc..985108fb5 100755 --- a/src/scripts/generate_runtime_manifest.py +++ b/src/scripts/generate_runtime_manifest.py @@ -21,18 +21,19 @@ cur_runtime_json_version = '1.0.0' + def main(argv): output_file = '' library_location = '' generate_badjson_jsons = False - usage = '\ngenerate_runtime_manifest.py \n' + usage = '\ngenerate_runtime_manifest.py \n' usage += ' -f/--file \n' usage += ' -l/--lib \n' usage += ' -b/--bad\n' try: - opts, args = getopt.getopt(argv,"hbf:l:",["bad","file=","lib="]) + opts, args = getopt.getopt(argv, "hbf:l:", ["bad", "file=", "lib="]) except getopt.GetoptError: print(usage) sys.exit(2) @@ -47,7 +48,7 @@ def main(argv): elif opt in ("-b", "--bad"): generate_badjson_jsons = True - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "%s",\n' % cur_runtime_json_version file_text += ' "runtime": {\n' file_text += ' "library_path": "%s",\n' % library_location @@ -66,7 +67,7 @@ def main(argv): # Missing bad_name = '_badjson_file_ver_missing.json' - file_text = '{\n' + file_text = '{\n' file_text += ' "runtime": {\n' file_text += ' "library_path": "%s",\n' % library_location file_text += ' }\n' @@ -78,7 +79,7 @@ def main(argv): # Use int bad_name = '_badjson_file_ver_int.json' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": 1,\n' file_text += ' "runtime": {\n' file_text += ' "library_path": "%s",\n' % library_location @@ -91,7 +92,7 @@ def main(argv): # Use invalid string bad_name = '_badjson_file_ver_string.json' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "invalid string",\n' file_text += ' "runtime": {\n' file_text += ' "library_path": "%s",\n' % library_location @@ -104,7 +105,7 @@ def main(argv): # Too low of a version bad_name = '_badjson_file_ver_all_low.json' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "0.0.0",\n' file_text += ' "runtime": {\n' file_text += ' "library_path": "%s",\n' % library_location @@ -117,7 +118,7 @@ def main(argv): # Too high of a major version bad_name = '_badjson_file_ver_major_high.json' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "15.0.0",\n' file_text += ' "runtime": {\n' file_text += ' "library_path": "%s",\n' % library_location @@ -130,7 +131,7 @@ def main(argv): # Too high of a minor version bad_name = '_badjson_file_ver_minor_high.json' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "1.15.0",\n' file_text += ' "runtime": {\n' file_text += ' "library_path": "%s",\n' % library_location @@ -146,7 +147,7 @@ def main(argv): # Completely Missing bad_name = '_badjson_runtime_missing.json' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "%s",\n' % cur_runtime_json_version file_text += ' "library_path": "%s",\n' % library_location file_text += '}\n' @@ -157,7 +158,7 @@ def main(argv): # Empty bad_name = '_badjson_runtime_empty.json' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "%s",\n' % cur_runtime_json_version file_text += ' "runtime": {\n' file_text += ' },\n' @@ -173,7 +174,7 @@ def main(argv): # Missing bad_name = '_badjson_path_missing.json' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "%s",\n' % cur_runtime_json_version file_text += ' "runtime": {\n' file_text += ' }\n' @@ -185,7 +186,7 @@ def main(argv): # Use int bad_name = '_badjson_path_int.json' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "%s",\n' % cur_runtime_json_version file_text += ' "runtime": {\n' file_text += ' "library_path": 1,\n' @@ -198,10 +199,10 @@ def main(argv): # Replace valid path with invalid one bad_name = '_badjson_path_no_file.json' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "%s",\n' % cur_runtime_json_version file_text += ' "runtime": {\n' - file_text += ' "library_path": "%s",\n' % library_location.replace("test_runtimes","not_real") + file_text += ' "library_path": "%s",\n' % library_location.replace("test_runtimes", "not_real") file_text += ' }\n' file_text += '}\n' bad_file = output_file.replace(".json", bad_name) @@ -214,7 +215,7 @@ def main(argv): # Always fail negotiate bad_name = '_badnegotiate_always.json' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "%s",\n' % cur_runtime_json_version file_text += ' "runtime": {\n' file_text += ' "library_path": "%s",\n' % library_location @@ -231,7 +232,7 @@ def main(argv): # Pass negotiate, but return null GIPA bad_name = '_badnegotiate_invalid_gipa.json' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "%s",\n' % cur_runtime_json_version file_text += ' "runtime": {\n' file_text += ' "library_path": "%s",\n' % library_location @@ -248,7 +249,7 @@ def main(argv): # Pass negotiate, but return invalid interface version bad_name = '_badnegotiate_invalid_interface.json' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "%s",\n' % cur_runtime_json_version file_text += ' "runtime": {\n' file_text += ' "library_path": "%s",\n' % library_location @@ -265,7 +266,7 @@ def main(argv): # Pass negotiate, but return invalid api version bad_name = '_badnegotiate_invalid_api.json' - file_text = '{\n' + file_text = '{\n' file_text += ' "file_format_version": "%s",\n' % cur_runtime_json_version file_text += ' "runtime": {\n' file_text += ' "library_path": "%s",\n' % library_location @@ -280,5 +281,6 @@ def main(argv): f.write(file_text) f.close() + if __name__ == "__main__": main(sys.argv[1:]) diff --git a/src/scripts/loader_source_generator.py b/src/scripts/loader_source_generator.py index 0134c813b..83f26e73a 100755 --- a/src/scripts/loader_source_generator.py +++ b/src/scripts/loader_source_generator.py @@ -16,6 +16,8 @@ # automatic_source_generator.py class to produce the # generated source code for the loader. +import dataclasses + from automatic_source_generator import (AutomaticSourceOutputGenerator, undecorate) from generator import write @@ -236,31 +238,20 @@ def outputLoaderGeneratedFuncs(self): # These should be mutually exclusive - verify it. assert ((not cur_cmd.is_destroy_disconnect) or - (pointer_count == 0)) + (pointer_count == 0)) else: tramp_variable_defines += self.printCodeGenErrorMessage( 'Command %s does not have an OpenXR Object handle as the first parameter.' % cur_cmd.name) tramp_param_replace.append( - self.MemberOrParam(type=param.type, + dataclasses.replace(param, name=cmd_tramp_param_name, is_const=is_const, is_handle=cmd_tramp_is_handle, - is_bool=param.is_bool, - is_optional=param.is_optional, - no_auto_validity=param.no_auto_validity, - is_array=param.is_array, - is_static_array=param.is_static_array, static_array_sizes=static_array_sizes, array_dimen=array_dimen, - array_count_var=param.array_count_var, - array_length_for=param.array_length_for, pointer_count=pointer_count, - pointer_count_var=param.pointer_count_var, - is_null_terminated=param.is_null_terminated, - valid_extension_structs=None, - cdecl=param.cdecl, - values=param.values)) + valid_extension_structs=None)) count = count + 1 if cur_cmd.protect_value: diff --git a/src/scripts/src_genxr.py b/src/scripts/src_genxr.py index 922e9d90c..b90248f9c 100755 --- a/src/scripts/src_genxr.py +++ b/src/scripts/src_genxr.py @@ -93,8 +93,8 @@ def makeGenOpts(args): allFeatures = allExtensions = r'.*' # Turn lists of names/patterns into matching regular expressions - emitExtensionsPat = makeREstring(emitExtensions, allExtensions) - featuresPat = makeREstring(features, allFeatures) + emitExtensionsPat = makeREstring(emitExtensions, allExtensions) + featuresPat = makeREstring(features, allFeatures) # REUSE-IgnoreStart # Copyright text prefixing all headers (list of strings). @@ -134,64 +134,64 @@ def makeGenOpts(args): genOpts['function_info.cpp'] = [ ConformanceGenerator, AutomaticSourceGeneratorOptions( - conventions = conventions, - filename = 'function_info.cpp', - directory = directory, - apiname = 'openxr', - profile = None, - versions = featuresPat, - emitversions = featuresPat, - defaultExtensions = 'openxr', - addExtensions = None, - removeExtensions = None, - emitExtensions = emitExtensionsPat, - prefixText = prefixStrings + xrPrefixStrings, - protectFeature = False, - protectProto = '#ifndef', - protectProtoStr = 'XR_NO_PROTOTYPES', - apicall = 'XRAPI_ATTR ', - apientry = 'XRAPI_CALL ', - apientryp = 'XRAPI_PTR *', - alignFuncParam = 48) - ] + conventions=conventions, + filename='function_info.cpp', + directory=directory, + apiname='openxr', + profile=None, + versions=featuresPat, + emitversions=featuresPat, + defaultExtensions='openxr', + addExtensions=None, + removeExtensions=None, + emitExtensions=emitExtensionsPat, + prefixText=prefixStrings + xrPrefixStrings, + protectFeature=False, + protectProto='#ifndef', + protectProtoStr='XR_NO_PROTOTYPES', + apicall='XRAPI_ATTR ', + apientry='XRAPI_CALL ', + apientryp='XRAPI_PTR *', + alignFuncParam=48) + ] genOpts['gen_dispatch.cpp'] = [ ConformanceLayerGenerator, AutomaticSourceGeneratorOptions( - conventions = conventions, - filename = 'gen_dispatch.cpp', - directory = directory, - apiname = 'openxr', - profile = None, - versions = featuresPat, - emitversions = featuresPat, - defaultExtensions = 'openxr', - addExtensions = None, - removeExtensions = None, - emitExtensions = emitExtensionsPat, - apicall = 'XRAPI_ATTR ', - apientry = 'XRAPI_CALL ', - apientryp = 'XRAPI_PTR *',) - ] + conventions=conventions, + filename='gen_dispatch.cpp', + directory=directory, + apiname='openxr', + profile=None, + versions=featuresPat, + emitversions=featuresPat, + defaultExtensions='openxr', + addExtensions=None, + removeExtensions=None, + emitExtensions=emitExtensionsPat, + apicall='XRAPI_ATTR ', + apientry='XRAPI_CALL ', + apientryp='XRAPI_PTR *',) + ] genOpts['gen_dispatch.h'] = [ ConformanceLayerGenerator, AutomaticSourceGeneratorOptions( - conventions = conventions, - filename = 'gen_dispatch.h', - directory = directory, - apiname = 'openxr', - profile = None, - versions = featuresPat, - emitversions = featuresPat, - defaultExtensions = 'openxr', - addExtensions = None, - removeExtensions = None, - emitExtensions = emitExtensionsPat, - apicall = 'XRAPI_ATTR ', - apientry = 'XRAPI_CALL ', - apientryp = 'XRAPI_PTR *',) - ] + conventions=conventions, + filename='gen_dispatch.h', + directory=directory, + apiname='openxr', + profile=None, + versions=featuresPat, + emitversions=featuresPat, + defaultExtensions='openxr', + addExtensions=None, + removeExtensions=None, + emitExtensions=emitExtensionsPat, + apicall='XRAPI_ATTR ', + apientry='XRAPI_CALL ', + apientryp='XRAPI_PTR *',) + ] DISPATCH_TABLE_FILES = [ 'xr_generated_dispatch_table.h', @@ -202,146 +202,147 @@ def makeGenOpts(args): for filename in DISPATCH_TABLE_FILES: genOpts[filename] = [ - UtilitySourceOutputGenerator, - AutomaticSourceGeneratorOptions( - conventions = conventions, - filename = filename, - directory = directory, - apiname = 'openxr', - profile = None, - versions = featuresPat, - emitversions = featuresPat, - defaultExtensions = 'openxr', - addExtensions = None, - removeExtensions = None, - emitExtensions = emitExtensionsPat) - ] + UtilitySourceOutputGenerator, + AutomaticSourceGeneratorOptions( + conventions=conventions, + filename=filename, + directory=directory, + apiname='openxr', + profile=None, + versions=featuresPat, + emitversions=featuresPat, + defaultExtensions='openxr', + addExtensions=None, + removeExtensions=None, + emitExtensions=emitExtensionsPat) + ] genOpts['xr_generated_loader.hpp'] = [ - LoaderSourceOutputGenerator, - AutomaticSourceGeneratorOptions( - conventions = conventions, - filename = 'xr_generated_loader.hpp', - directory = directory, - apiname = 'openxr', - profile = None, - versions = featuresPat, - emitversions = featuresPat, - defaultExtensions = 'openxr', - addExtensions = None, - removeExtensions = None, - emitExtensions = emitExtensionsPat, - prefixText = prefixStrings + xrPrefixStrings, - protectFeature = False, - protectProto = '#ifndef', - protectProtoStr = 'XR_NO_PROTOTYPES', - apicall = 'XRAPI_ATTR ', - apientry = 'XRAPI_CALL ', - apientryp = 'XRAPI_PTR *', - alignFuncParam = 48) - ] + LoaderSourceOutputGenerator, + AutomaticSourceGeneratorOptions( + conventions=conventions, + filename='xr_generated_loader.hpp', + directory=directory, + apiname='openxr', + profile=None, + versions=featuresPat, + emitversions=featuresPat, + defaultExtensions='openxr', + addExtensions=None, + removeExtensions=None, + emitExtensions=emitExtensionsPat, + prefixText=prefixStrings + xrPrefixStrings, + protectFeature=False, + protectProto='#ifndef', + protectProtoStr='XR_NO_PROTOTYPES', + apicall='XRAPI_ATTR ', + apientry='XRAPI_CALL ', + apientryp='XRAPI_PTR *', + alignFuncParam=48) + ] genOpts['xr_generated_loader.cpp'] = [ - LoaderSourceOutputGenerator, - AutomaticSourceGeneratorOptions( - conventions = conventions, - filename = 'xr_generated_loader.cpp', - directory = directory, - apiname = 'openxr', - profile = None, - versions = featuresPat, - emitversions = featuresPat, - defaultExtensions = 'openxr', - addExtensions = None, - removeExtensions = None, - emitExtensions = emitExtensionsPat, - prefixText = prefixStrings + xrPrefixStrings, - protectFeature = False, - protectProto = '#ifndef', - protectProtoStr = 'XR_NO_PROTOTYPES', - apicall = 'XRAPI_ATTR ', - apientry = 'XRAPI_CALL ', - apientryp = 'XRAPI_PTR *', - alignFuncParam = 48) - ] + LoaderSourceOutputGenerator, + AutomaticSourceGeneratorOptions( + conventions=conventions, + filename='xr_generated_loader.cpp', + directory=directory, + apiname='openxr', + profile=None, + versions=featuresPat, + emitversions=featuresPat, + defaultExtensions='openxr', + addExtensions=None, + removeExtensions=None, + emitExtensions=emitExtensionsPat, + prefixText=prefixStrings + xrPrefixStrings, + protectFeature=False, + protectProto='#ifndef', + protectProtoStr='XR_NO_PROTOTYPES', + apicall='XRAPI_ATTR ', + apientry='XRAPI_CALL ', + apientryp='XRAPI_PTR *', + alignFuncParam=48) + ] # Source files generated for the api_dump layer genOpts['xr_generated_api_dump.cpp'] = [ - ApiDumpOutputGenerator, - AutomaticSourceGeneratorOptions( - conventions = conventions, - filename = 'xr_generated_api_dump.cpp', - directory = directory, - apiname = 'openxr', - profile = None, - versions = featuresPat, - emitversions = featuresPat, - defaultExtensions = 'openxr', - addExtensions = None, - removeExtensions = None, - emitExtensions = emitExtensionsPat, - apicall = 'XRAPI_ATTR ', - apientry = 'XRAPI_CALL ', - apientryp = 'XRAPI_PTR *') - ] + ApiDumpOutputGenerator, + AutomaticSourceGeneratorOptions( + conventions=conventions, + filename='xr_generated_api_dump.cpp', + directory=directory, + apiname='openxr', + profile=None, + versions=featuresPat, + emitversions=featuresPat, + defaultExtensions='openxr', + addExtensions=None, + removeExtensions=None, + emitExtensions=emitExtensionsPat, + apicall='XRAPI_ATTR ', + apientry='XRAPI_CALL ', + apientryp='XRAPI_PTR *') + ] genOpts['xr_generated_api_dump.hpp'] = [ - ApiDumpOutputGenerator, - AutomaticSourceGeneratorOptions( - conventions = conventions, - filename = 'xr_generated_api_dump.hpp', - directory = directory, - apiname = 'openxr', - profile = None, - versions = featuresPat, - emitversions = featuresPat, - defaultExtensions = 'openxr', - addExtensions = None, - removeExtensions = None, - emitExtensions = emitExtensionsPat, - apicall = 'XRAPI_ATTR ', - apientry = 'XRAPI_CALL ', - apientryp = 'XRAPI_PTR *') - ] + ApiDumpOutputGenerator, + AutomaticSourceGeneratorOptions( + conventions=conventions, + filename='xr_generated_api_dump.hpp', + directory=directory, + apiname='openxr', + profile=None, + versions=featuresPat, + emitversions=featuresPat, + defaultExtensions='openxr', + addExtensions=None, + removeExtensions=None, + emitExtensions=emitExtensionsPat, + apicall='XRAPI_ATTR ', + apientry='XRAPI_CALL ', + apientryp='XRAPI_PTR *') + ] # Source files generated for the core validation layer genOpts['xr_generated_core_validation.hpp'] = [ - ValidationSourceOutputGenerator, - AutomaticSourceGeneratorOptions( - conventions = conventions, - filename = 'xr_generated_core_validation.hpp', - directory = directory, - apiname = 'openxr', - profile = None, - versions = featuresPat, - emitversions = featuresPat, - defaultExtensions = 'openxr', - addExtensions = None, - removeExtensions = None, - emitExtensions = emitExtensionsPat, - apicall = 'XRAPI_ATTR ', - apientry = 'XRAPI_CALL ', - apientryp = 'XRAPI_PTR *') - ] + ValidationSourceOutputGenerator, + AutomaticSourceGeneratorOptions( + conventions=conventions, + filename='xr_generated_core_validation.hpp', + directory=directory, + apiname='openxr', + profile=None, + versions=featuresPat, + emitversions=featuresPat, + defaultExtensions='openxr', + addExtensions=None, + removeExtensions=None, + emitExtensions=emitExtensionsPat, + apicall='XRAPI_ATTR ', + apientry='XRAPI_CALL ', + apientryp='XRAPI_PTR *') + ] genOpts['xr_generated_core_validation.cpp'] = [ - ValidationSourceOutputGenerator, - AutomaticSourceGeneratorOptions( - conventions = conventions, - filename = 'xr_generated_core_validation.cpp', - directory = directory, - apiname = 'openxr', - profile = None, - versions = featuresPat, - emitversions = featuresPat, - defaultExtensions = 'openxr', - addExtensions = None, - removeExtensions = None, - emitExtensions = emitExtensionsPat, - apicall = 'XRAPI_ATTR ', - apientry = 'XRAPI_CALL ', - apientryp = 'XRAPI_PTR *') - ] + ValidationSourceOutputGenerator, + AutomaticSourceGeneratorOptions( + conventions=conventions, + filename='xr_generated_core_validation.cpp', + directory=directory, + apiname='openxr', + profile=None, + versions=featuresPat, + emitversions=featuresPat, + defaultExtensions='openxr', + addExtensions=None, + removeExtensions=None, + emitExtensions=emitExtensionsPat, + apicall='XRAPI_ATTR ', + apientry='XRAPI_CALL ', + apientryp='XRAPI_PTR *') + ] + def genTarget(args): """Create an API generator and corresponding generator options based on @@ -383,6 +384,7 @@ def genTarget(args): args.target, file=sys.stderr) sys.exit(1) + # -feature name # -extension name # For both, "name" may be a single name, or a space-separated list @@ -453,7 +455,7 @@ def genTarget(args): if args.time: # Log diagnostics and warnings - setLogFile(setDiag = True, setWarn = True, filename = '-') + setLogFile(setDiag=True, setWarn=True, filename='-') # Create the API generator & generator options (gen, options) = genTarget(args) diff --git a/src/scripts/validation_layer_generator.py b/src/scripts/validation_layer_generator.py index 5c295c82a..8f683241d 100644 --- a/src/scripts/validation_layer_generator.py +++ b/src/scripts/validation_layer_generator.py @@ -24,7 +24,7 @@ import re from automatic_source_generator import (AutomaticSourceOutputGenerator, - undecorate) + undecorate, MemberOrParam) from generator import write # The following commands have a manually defined component to them. @@ -1387,7 +1387,7 @@ def writeValidateInlineHandleValidation(self, cmd_name, vuid_name, member_param, inline_validate_handle += '}\n' return inline_validate_handle - def outputParamMemberContents(self, is_command, struct_command_name, param_member, param_member_prefix, instance_info_variable, + def outputParamMemberContents(self, is_command, struct_command_name, param_member: MemberOrParam, param_member_prefix, instance_info_variable, command_name_variable, is_first_param, primary_handle, primary_handle_desc_name, primary_handle_tuple, wrote_handle_proto, indent): param_member_contents = '' diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 9fb27a5f8..b910ffc61 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2017 The Khronos Group Inc. +# Copyright (c) 2017-2023, The Khronos Group Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -13,9 +13,6 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -# -# Author: -# add_subdirectory(c_compile_test) add_subdirectory(hello_xr) diff --git a/src/tests/c_compile_test/CMakeLists.txt b/src/tests/c_compile_test/CMakeLists.txt index b8e2ecac2..e4d4da776 100644 --- a/src/tests/c_compile_test/CMakeLists.txt +++ b/src/tests/c_compile_test/CMakeLists.txt @@ -16,38 +16,42 @@ # if(ANDROID) - add_library(openxr_c_compile_test MODULE - main.c - $ + add_library( + openxr_c_compile_test MODULE main.c + $ ) - target_link_libraries(openxr_c_compile_test ${ANDROID_LIBRARY} ${ANDROID_LOG_LIBRARY}) - target_include_directories(openxr_c_compile_test PRIVATE ${ANDROID_NATIVE_APP_GLUE}) -else() - add_executable(openxr_c_compile_test - main.c + target_link_libraries( + openxr_c_compile_test ${ANDROID_LIBRARY} ${ANDROID_LOG_LIBRARY} + ) + target_include_directories( + openxr_c_compile_test PRIVATE ${ANDROID_NATIVE_APP_GLUE} ) +else() + add_executable(openxr_c_compile_test main.c) endif() set_target_properties(openxr_c_compile_test PROPERTIES FOLDER ${TESTS_FOLDER}) -add_dependencies(openxr_c_compile_test - generate_openxr_header +target_include_directories( + openxr_c_compile_test + PRIVATE "${PROJECT_SOURCE_DIR}/src" "${PROJECT_SOURCE_DIR}/src/common" + "${PROJECT_SOURCE_DIR}/external/include" ) -target_include_directories(openxr_c_compile_test - PRIVATE ${PROJECT_SOURCE_DIR}/src - PRIVATE ${PROJECT_SOURCE_DIR}/src/common - PRIVATE ${PROJECT_BINARY_DIR}/include - PRIVATE ${PROJECT_SOURCE_DIR}/external/include -) -if(Vulkan_FOUND) - target_include_directories(openxr_c_compile_test - PRIVATE ${Vulkan_INCLUDE_DIRS} +if(XR_USE_GRAPHICS_API_VULKAN) + target_include_directories( + openxr_c_compile_test PRIVATE ${Vulkan_INCLUDE_DIRS} ) endif() target_link_libraries(openxr_c_compile_test OpenXR::openxr_loader) if(MSVC) - target_compile_options(openxr_c_compile_test PRIVATE /Zc:wchar_t /Zc:forScope /W4) - if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + target_compile_options( + openxr_c_compile_test PRIVATE /Zc:wchar_t /Zc:forScope /W4 + ) + if(NOT + CMAKE_CXX_COMPILER_ID + STREQUAL + "Clang" + ) # If actually msvc and not clang-cl target_compile_options(openxr_c_compile_test PRIVATE /WX) endif() diff --git a/src/tests/hello_xr/CMakeLists.txt b/src/tests/hello_xr/CMakeLists.txt index d4cf369c6..cd5abc909 100644 --- a/src/tests/hello_xr/CMakeLists.txt +++ b/src/tests/hello_xr/CMakeLists.txt @@ -15,104 +15,153 @@ # limitations under the License. # -file(GLOB LOCAL_HEADERS "*.h") -file(GLOB LOCAL_SOURCE "*.cpp") -file(GLOB VULKAN_SHADERS "vulkan_shaders/*.glsl") - -# For including compiled shaders -include_directories(${CMAKE_CURRENT_BINARY_DIR}) +set(LOCAL_HEADERS + check.h + common.h + d3d_common.h + geometry.h + graphicsapi.h + graphicsplugin.h + logger.h + openxr_program.h + options.h + pch.h + platformdata.h + platformplugin.h +) +set(LOCAL_SOURCE + d3d_common.cpp + graphicsplugin_d3d11.cpp + graphicsplugin_d3d12.cpp + graphicsplugin_factory.cpp + graphicsplugin_opengl.cpp + graphicsplugin_opengles.cpp + graphicsplugin_vulkan.cpp + logger.cpp + main.cpp + openxr_program.cpp + pch.cpp + platformplugin_android.cpp + platformplugin_factory.cpp + platformplugin_posix.cpp + platformplugin_win32.cpp +) +set(VULKAN_SHADERS vulkan_shaders/frag.glsl vulkan_shaders/vert.glsl) if(ANDROID) - add_library(hello_xr MODULE + add_library( + hello_xr MODULE ${LOCAL_SOURCE} ${LOCAL_HEADERS} ${VULKAN_SHADERS} - $) - target_link_libraries(hello_xr ${ANDROID_LIBRARY} ${ANDROID_LOG_LIBRARY}) + $ + ) + target_link_libraries( + hello_xr PRIVATE ${ANDROID_LIBRARY} ${ANDROID_LOG_LIBRARY} + ) # Only for Android because it lacks a command line - set(HELLOXR_DEFAULT_GRAPHICS_PLUGIN "OpenGLES" CACHE STRING "Which graphics plugin should be used by default for Hello XR artifacts?") + set(HELLOXR_DEFAULT_GRAPHICS_PLUGIN + "OpenGLES" + CACHE + STRING + "Which graphics plugin should be used by default for Hello XR artifacts?" + ) # These are the recognized options: provide them as a helper in the CMake GUI - set_property(CACHE HELLOXR_DEFAULT_GRAPHICS_PLUGIN PROPERTY STRINGS "OpenGLES" "Vulkan") + set_property( + CACHE HELLOXR_DEFAULT_GRAPHICS_PLUGIN PROPERTY STRINGS "OpenGLES" + "Vulkan" + ) # Now handle the value, normally provided by Gradle if(HELLOXR_DEFAULT_GRAPHICS_PLUGIN STREQUAL "OpenGLES") message(STATUS "hello_xr will default to OpenGL ES graphics plugin") - target_compile_definitions(hello_xr PRIVATE DEFAULT_GRAPHICS_PLUGIN_OPENGLES) + target_compile_definitions( + hello_xr PRIVATE DEFAULT_GRAPHICS_PLUGIN_OPENGLES + ) elseif(HELLOXR_DEFAULT_GRAPHICS_PLUGIN STREQUAL "Vulkan") message(STATUS "hello_xr will default to Vulkan graphics plugin") - target_compile_definitions(hello_xr PRIVATE DEFAULT_GRAPHICS_PLUGIN_VULKAN) + target_compile_definitions( + hello_xr PRIVATE DEFAULT_GRAPHICS_PLUGIN_VULKAN + ) endif() else() - add_executable(hello_xr - ${LOCAL_SOURCE} - ${LOCAL_HEADERS} - ${VULKAN_SHADERS}) + add_executable(hello_xr ${LOCAL_SOURCE} ${LOCAL_HEADERS} ${VULKAN_SHADERS}) endif() -set_target_properties(hello_xr PROPERTIES FOLDER ${SAMPLES_FOLDER}) +set_target_properties(hello_xr PROPERTIES FOLDER ${SAMPLES_FOLDER}) source_group("Headers" FILES ${LOCAL_HEADERS}) source_group("Shaders" FILES ${VULKAN_SHADERS}) +target_link_libraries(hello_xr PRIVATE OpenXR::openxr_loader) + compile_glsl(run_hello_xr_glsl_compiles ${VULKAN_SHADERS}) -add_dependencies(hello_xr - generate_openxr_header - run_hello_xr_glsl_compiles -) +add_dependencies(hello_xr run_hello_xr_glsl_compiles) -target_include_directories(hello_xr +target_include_directories( + hello_xr PRIVATE - ${PROJECT_SOURCE_DIR}/src - ${PROJECT_SOURCE_DIR}/src/common - ${PROJECT_SOURCE_DIR}/src/tests/hello_xr/vulkan_shaders - - # for helper headers - ${PROJECT_SOURCE_DIR}/external/include + "${PROJECT_SOURCE_DIR}/src" + "${PROJECT_SOURCE_DIR}/src/common" + "${PROJECT_SOURCE_DIR}/src/tests/hello_xr/vulkan_shaders" + # for helper headers + "${PROJECT_SOURCE_DIR}/external/include" + # For including compiled shaders + "${CMAKE_CURRENT_BINARY_DIR}" ) -if(GLSLANG_VALIDATOR AND NOT GLSL_COMPILER) +target_link_libraries(hello_xr PRIVATE OpenXR::openxr_loader) + +if(GLSLANG_VALIDATOR AND NOT GLSLC_COMMAND) target_compile_definitions(hello_xr PRIVATE USE_GLSLANGVALIDATOR) endif() -if(Vulkan_FOUND) - target_include_directories(hello_xr - PRIVATE - ${Vulkan_INCLUDE_DIRS} - ) +if(XR_USE_GRAPHICS_API_VULKAN) + target_include_directories(hello_xr PRIVATE ${Vulkan_INCLUDE_DIRS}) + target_link_libraries(hello_xr PRIVATE ${Vulkan_LIBRARY}) endif() -target_link_libraries(hello_xr OpenXR::openxr_loader) if(TARGET openxr-gfxwrapper) - target_link_libraries(hello_xr openxr-gfxwrapper) + target_link_libraries(hello_xr PRIVATE openxr-gfxwrapper) endif() if(WIN32) + target_link_libraries(hello_xr PRIVATE ole32) if(MSVC) target_compile_definitions(hello_xr PRIVATE _CRT_SECURE_NO_WARNINGS) target_compile_options(hello_xr PRIVATE /Zc:wchar_t /Zc:forScope /W4) - if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + if(NOT + CMAKE_CXX_COMPILER_ID + STREQUAL + "Clang" + ) # If actually msvc and not clang-cl target_compile_options(openxr_c_compile_test PRIVATE /WX) endif() - endif() - target_link_libraries(hello_xr ole32) - if(MSVC) - # Right now can't build this on MinGW because of directxcolors, directxmath, etc. - target_link_libraries(hello_xr d3d11 d3d12 d3dcompiler dxgi) - endif() -endif() -if(Vulkan_LIBRARY) - target_link_libraries(hello_xr ${Vulkan_LIBRARY}) + # Right now can't build d3d features on MinGW because of directxcolors, directxmath, etc. + target_link_libraries( + hello_xr + PRIVATE + d3d11 + d3d12 + d3dcompiler + dxgi + ) + endif() endif() if(NOT ANDROID) - install(TARGETS hello_xr - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - COMPONENT hello_xr) + install( + TARGETS hello_xr RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + COMPONENT hello_xr + ) if(NOT WIN32) - install(FILES hello_xr.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1/ COMPONENT ManPages) + install( + FILES hello_xr.1 + DESTINATION ${CMAKE_INSTALL_MANDIR}/man1/ + COMPONENT ManPages + ) endif() endif() - diff --git a/src/tests/list/CMakeLists.txt b/src/tests/list/CMakeLists.txt index b8eea1a92..16fa50758 100644 --- a/src/tests/list/CMakeLists.txt +++ b/src/tests/list/CMakeLists.txt @@ -15,28 +15,28 @@ # limitations under the License. # -add_executable(openxr_runtime_list - list.cpp +add_executable(openxr_runtime_list list.cpp) +target_include_directories( + openxr_runtime_list + PRIVATE "${PROJECT_SOURCE_DIR}/src" "${PROJECT_SOURCE_DIR}/src/common" + "${PROJECT_SOURCE_DIR}/external/include" ) -add_dependencies(openxr_runtime_list - generate_openxr_header -) -target_include_directories(openxr_runtime_list - PRIVATE ${PROJECT_SOURCE_DIR}/src - PRIVATE ${PROJECT_SOURCE_DIR}/src/common - PRIVATE ${PROJECT_BINARY_DIR}/include - PRIVATE ${PROJECT_SOURCE_DIR}/external/include -) -if(Vulkan_FOUND) - target_include_directories(openxr_runtime_list - PRIVATE ${Vulkan_INCLUDE_DIRS} +if(XR_USE_GRAPHICS_API_VULKAN) + target_include_directories( + openxr_runtime_list PRIVATE ${Vulkan_INCLUDE_DIRS} ) endif() target_link_libraries(openxr_runtime_list OpenXR::openxr_loader) if(MSVC) - target_compile_options(openxr_runtime_list PRIVATE /Zc:wchar_t /Zc:forScope /W4) - if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + target_compile_options( + openxr_runtime_list PRIVATE /Zc:wchar_t /Zc:forScope /W4 + ) + if(NOT + CMAKE_CXX_COMPILER_ID + STREQUAL + "Clang" + ) # If actually msvc and not clang-cl target_compile_options(openxr_runtime_list PRIVATE /WX) endif() @@ -44,9 +44,14 @@ endif() set_target_properties(openxr_runtime_list PROPERTIES FOLDER ${TESTS_FOLDER}) -install(TARGETS openxr_runtime_list - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - COMPONENT openxr_runtime_list) +install( + TARGETS openxr_runtime_list RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + COMPONENT openxr_runtime_list +) if(NOT WIN32) - install(FILES openxr_runtime_list.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1/ COMPONENT ManPages) + install( + FILES openxr_runtime_list.1 + DESTINATION ${CMAKE_INSTALL_MANDIR}/man1/ + COMPONENT ManPages + ) endif() diff --git a/src/tests/list_json/CMakeLists.txt b/src/tests/list_json/CMakeLists.txt index f5c736f81..1f7f5c057 100644 --- a/src/tests/list_json/CMakeLists.txt +++ b/src/tests/list_json/CMakeLists.txt @@ -15,67 +15,69 @@ # limitations under the License. # -file(GLOB LOCAL_HEADERS "*.h") -file(GLOB LOCAL_SOURCE "*.cpp") - if(ANDROID) - add_library(openxr_runtime_list_json MODULE - ${LOCAL_SOURCE} - ${LOCAL_HEADERS} - $) - target_link_libraries(openxr_runtime_list_json ${ANDROID_LIBRARY} ${ANDROID_LOG_LIBRARY}) - target_include_directories(openxr_runtime_list_json PRIVATE ${ANDROID_NATIVE_APP_GLUE}) + add_library( + openxr_runtime_list_json MODULE + list_json.cpp $ + ) + target_link_libraries( + openxr_runtime_list_json PRIVATE ${ANDROID_LIBRARY} + ${ANDROID_LOG_LIBRARY} + ) + target_include_directories( + openxr_runtime_list_json PRIVATE ${ANDROID_NATIVE_APP_GLUE} + ) else() - add_executable(openxr_runtime_list_json - ${LOCAL_SOURCE} - ${LOCAL_HEADERS}) + add_executable(openxr_runtime_list_json list_json.cpp) endif() -set_target_properties(openxr_runtime_list_json PROPERTIES FOLDER ${TESTS_FOLDER}) -source_group("Headers" FILES ${LOCAL_HEADERS}) -source_group("Shaders" FILES ${VULKAN_SHADERS}) - -target_include_directories(openxr_runtime_list_json - PRIVATE - ${PROJECT_SOURCE_DIR}/src - ${PROJECT_SOURCE_DIR}/src/common +set_target_properties( + openxr_runtime_list_json PROPERTIES FOLDER ${TESTS_FOLDER} +) +target_link_libraries(openxr_runtime_list_json PRIVATE OpenXR::openxr_loader) +target_include_directories( + openxr_runtime_list_json PRIVATE "${PROJECT_SOURCE_DIR}/src" + "${PROJECT_SOURCE_DIR}/src/common" ) +target_link_libraries(openxr_runtime_list_json PRIVATE OpenXR::openxr_loader) -if(Vulkan_FOUND) - target_include_directories(openxr_runtime_list_json - PRIVATE - ${Vulkan_INCLUDE_DIRS} +if(XR_USE_GRAPHICS_API_VULKAN) + target_include_directories( + openxr_runtime_list_json PRIVATE ${Vulkan_INCLUDE_DIRS} ) + target_link_libraries(openxr_runtime_list_json PRIVATE ${Vulkan_LIBRARY}) endif() -target_link_libraries(openxr_runtime_list_json OpenXR::openxr_loader) if(WIN32) if(MSVC) - target_compile_definitions(openxr_runtime_list_json PRIVATE _CRT_SECURE_NO_WARNINGS) - target_compile_options(openxr_runtime_list_json PRIVATE /Zc:wchar_t /Zc:forScope /W4) - if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + target_compile_definitions( + openxr_runtime_list_json PRIVATE _CRT_SECURE_NO_WARNINGS + ) + target_compile_options( + openxr_runtime_list_json PRIVATE /Zc:wchar_t /Zc:forScope /W4 + ) + if(NOT + CMAKE_CXX_COMPILER_ID + STREQUAL + "Clang" + ) # If actually msvc and not clang-cl target_compile_options(openxr_runtime_list_json PRIVATE /WX) endif() endif() - - target_link_libraries(openxr_runtime_list_json ole32) - if(MSVC) - # Right now can't build this on MinGW because of directxcolors, directxmath, etc. - target_link_libraries(openxr_runtime_list_json d3d11 d3d12 d3dcompiler dxgi) - endif() -endif() - -if(Vulkan_LIBRARY) - target_link_libraries(openxr_runtime_list_json ${Vulkan_LIBRARY}) endif() if(NOT ANDROID) - install(TARGETS openxr_runtime_list_json + install( + TARGETS openxr_runtime_list_json RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - COMPONENT openxr_runtime_list_json) + COMPONENT openxr_runtime_list_json + ) endif() if(NOT WIN32) - install(FILES openxr_runtime_list_json.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1/ COMPONENT ManPages) + install( + FILES openxr_runtime_list_json.1 + DESTINATION ${CMAKE_INSTALL_MANDIR}/man1/ + COMPONENT ManPages + ) endif() - diff --git a/src/tests/loader_test/CMakeLists.txt b/src/tests/loader_test/CMakeLists.txt index 67295a7d0..6daf1f584 100644 --- a/src/tests/loader_test/CMakeLists.txt +++ b/src/tests/loader_test/CMakeLists.txt @@ -15,16 +15,13 @@ # limitations under the License. # -add_executable(loader_test - loader_test_utils.cpp - loader_test.cpp -) +add_executable(loader_test loader_test_utils.cpp loader_test.cpp) openxr_add_filesystem_utils(loader_test) set_target_properties(loader_test PROPERTIES FOLDER ${LOADER_TESTS_FOLDER}) target_link_libraries(loader_test PRIVATE OpenXR::openxr_loader) -add_dependencies(loader_test - generate_openxr_header +add_dependencies( + loader_test XrApiLayer_test XrApiLayer_api_dump test_runtime @@ -34,37 +31,42 @@ if(TARGET openxr-gfxwrapper) endif() target_include_directories( loader_test - PRIVATE ${CMAKE_CURRENT_BINARY_DIR} - PRIVATE ${PROJECT_BINARY_DIR}/src - PRIVATE ${PROJECT_BINARY_DIR}/include - PRIVATE ${PROJECT_SOURCE_DIR}/src/common - PRIVATE ${PROJECT_SOURCE_DIR}/external/include + PRIVATE + "${CMAKE_CURRENT_BINARY_DIR}" + "${PROJECT_BINARY_DIR}/src" + "${PROJECT_SOURCE_DIR}/src/common" + "${PROJECT_SOURCE_DIR}/external/include" ) -if(Vulkan_FOUND) - target_include_directories(loader_test - PRIVATE ${Vulkan_INCLUDE_DIRS} - ) +if(XR_USE_GRAPHICS_API_VULKAN) + target_include_directories(loader_test PRIVATE ${Vulkan_INCLUDE_DIRS}) endif() if(WIN32) if(MSVC) target_compile_definitions(loader_test PRIVATE _CRT_SECURE_NO_WARNINGS) target_compile_options(loader_test PRIVATE /Zc:wchar_t /Zc:forScope /W4) - if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + if(NOT + CMAKE_CXX_COMPILER_ID + STREQUAL + "Clang" + ) # If actually msvc and not clang-cl target_compile_options(loader_test PRIVATE /WX) endif() + target_link_libraries(loader_test PRIVATE d3d11) endif() - target_link_libraries(loader_test PRIVATE d3d11) endif() -add_test(NAME loader_test +add_test( + NAME loader_test COMMAND loader_test - WORKING_DIRECTORY "$") + WORKING_DIRECTORY "$" +) -file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/resources) -file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/resources/layers) -file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/resources/runtimes) +file( + MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/resources/layers" + "${CMAKE_CURRENT_BINARY_DIR}/resources/runtimes" +) add_subdirectory(test_layers) add_subdirectory(test_runtimes) diff --git a/src/tests/loader_test/test_layers/CMakeLists.txt b/src/tests/loader_test/test_layers/CMakeLists.txt index d19ee3ada..136b47536 100644 --- a/src/tests/loader_test/test_layers/CMakeLists.txt +++ b/src/tests/loader_test/test_layers/CMakeLists.txt @@ -21,51 +21,65 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES}) string(TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG) - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_CURRENT_BINARY_DIR}) - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_CURRENT_BINARY_DIR}) - set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_CURRENT_BINARY_DIR}) -endforeach(OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} + ${CMAKE_CURRENT_BINARY_DIR} + ) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} + ${CMAKE_CURRENT_BINARY_DIR} + ) + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} + ${CMAKE_CURRENT_BINARY_DIR} + ) +endforeach() -add_library(XrApiLayer_test SHARED - layer_test.cpp - XrApiLayer_test.def -) +add_library(XrApiLayer_test MODULE layer_test.cpp XrApiLayer_test.def) set_target_properties(XrApiLayer_test PROPERTIES FOLDER ${LOADER_TESTS_FOLDER}) -add_dependencies(XrApiLayer_test - xr_global_generated_files - generate_openxr_header -) -target_include_directories(XrApiLayer_test - PRIVATE ${PROJECT_SOURCE_DIR}/src - PRIVATE ${PROJECT_SOURCE_DIR}/src/common - PRIVATE ${PROJECT_BINARY_DIR}/include +target_link_libraries(XrApiLayer_test PRIVATE OpenXR::headers) +add_dependencies(XrApiLayer_test xr_global_generated_files) +target_include_directories( + XrApiLayer_test PRIVATE "${PROJECT_SOURCE_DIR}/src" + "${PROJECT_SOURCE_DIR}/src/common" ) -if(Vulkan_FOUND) - target_include_directories(XrApiLayer_test - PRIVATE ${Vulkan_INCLUDE_DIRS} - ) +if(XR_USE_GRAPHICS_API_VULKAN) + target_include_directories(XrApiLayer_test PRIVATE ${Vulkan_INCLUDE_DIRS}) endif() if(CMAKE_SYSTEM_NAME STREQUAL "Windows") target_compile_definitions(XrApiLayer_test PRIVATE _CRT_SECURE_NO_WARNINGS) # Turn off transitional "changed behavior" warning message for Visual Studio versions prior to 2015. # The changed behavior is that constructor initializers are now fixed to clear the struct members. - target_compile_options(XrApiLayer_test PRIVATE "$<$,$,19>>:/wd4351>") + target_compile_options( + XrApiLayer_test + PRIVATE + "$<$,$,19>>:/wd4351>" + ) elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") - set_target_properties(XrApiLayer_test PROPERTIES LINK_FLAGS "-Wl,-Bsymbolic,--exclude-libs,ALL") + set_target_properties( + XrApiLayer_test PROPERTIES LINK_FLAGS + "-Wl,-Bsymbolic,--exclude-libs,ALL" + ) elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") - set_target_properties(XrApiLayer_test PROPERTIES LINK_FLAGS "-Wl,-exported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/XrApiLayer_test.expsym") + set_target_properties( + XrApiLayer_test + PROPERTIES + LINK_FLAGS + "-Wl,-exported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/XrApiLayer_test.expsym" + ) endif() gen_xr_layer_json( - ${PROJECT_BINARY_DIR}/src/tests/loader_test/resources/layers/XrApiLayer_test.json + "${PROJECT_BINARY_DIR}/src/tests/loader_test/resources/layers/XrApiLayer_test.json" test - ${CMAKE_CURRENT_BINARY_DIR}/$ + "${CMAKE_CURRENT_BINARY_DIR}/$" 1 Test_description -b ) # Add generated file to our sources so we depend on it, and thus trigger generation. -target_sources(XrApiLayer_test PRIVATE ${PROJECT_BINARY_DIR}/src/tests/loader_test/resources/layers/XrApiLayer_test.json) +target_sources( + XrApiLayer_test + PRIVATE + "${PROJECT_BINARY_DIR}/src/tests/loader_test/resources/layers/XrApiLayer_test.json" +) diff --git a/src/tests/loader_test/test_runtimes/CMakeLists.txt b/src/tests/loader_test/test_runtimes/CMakeLists.txt index 06bed7339..fe3fb1d51 100644 --- a/src/tests/loader_test/test_runtimes/CMakeLists.txt +++ b/src/tests/loader_test/test_runtimes/CMakeLists.txt @@ -21,41 +21,40 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES}) string(TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG) - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_CURRENT_BINARY_DIR}) - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_CURRENT_BINARY_DIR}) - set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_CURRENT_BINARY_DIR}) -endforeach(OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} + ${CMAKE_CURRENT_BINARY_DIR} + ) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} + ${CMAKE_CURRENT_BINARY_DIR} + ) + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} + ${CMAKE_CURRENT_BINARY_DIR} + ) +endforeach() -add_library(test_runtime SHARED - runtime_test.cpp - test_runtime.def -) +add_library(test_runtime MODULE runtime_test.cpp test_runtime.def) set_target_properties(test_runtime PROPERTIES FOLDER ${LOADER_TESTS_FOLDER}) +target_link_libraries(test_runtime PRIVATE OpenXR::headers) -add_dependencies(test_runtime - xr_global_generated_files - generate_openxr_header -) -target_include_directories(test_runtime - PRIVATE ${PROJECT_SOURCE_DIR}/src - PRIVATE ${PROJECT_SOURCE_DIR}/src/common - PRIVATE ${PROJECT_BINARY_DIR}/include +add_dependencies(test_runtime xr_global_generated_files) +target_include_directories( + test_runtime PRIVATE ${PROJECT_SOURCE_DIR}/src + ${PROJECT_SOURCE_DIR}/src/common ) -if(Vulkan_FOUND) - target_include_directories(test_runtime - PRIVATE ${Vulkan_INCLUDE_DIRS} - ) +if(XR_USE_GRAPHICS_API_VULKAN) + target_include_directories(test_runtime PRIVATE ${Vulkan_INCLUDE_DIRS}) endif() macro(gen_xr_runtime_json filename libfile) - add_custom_command(OUTPUT ${filename} + add_custom_command( + OUTPUT ${filename} COMMAND - ${CMAKE_COMMAND} -E env - ${PYTHON_EXECUTABLE} - ${PROJECT_SOURCE_DIR}/src/scripts/generate_runtime_manifest.py -f ${filename} -l ${libfile} ${ARGN} - DEPENDS - ${PROJECT_SOURCE_DIR}/src/scripts/generate_runtime_manifest.py - COMMENT "Generating Runtime JSON ${filename} using -f ${filename} -l ${libfile} ${ARGN}" + "${PYTHON_EXECUTABLE}" + "${PROJECT_SOURCE_DIR}/src/scripts/generate_runtime_manifest.py" -f + ${filename} -l ${libfile} ${ARGN} + DEPENDS "${PROJECT_SOURCE_DIR}/src/scripts/generate_runtime_manifest.py" + COMMENT + "Generating Runtime JSON ${filename} using -f ${filename} -l ${libfile} ${ARGN}" ) endmacro() @@ -63,18 +62,33 @@ if(WIN32) target_compile_definitions(test_runtime PRIVATE _CRT_SECURE_NO_WARNINGS) # Turn off transitional "changed behavior" warning message for Visual Studio versions prior to 2015. # The changed behavior is that constructor initializers are now fixed to clear the struct members. - target_compile_options(test_runtime PRIVATE "$<$,$,19>>:/wd4351>") + target_compile_options( + test_runtime + PRIVATE + "$<$,$,19>>:/wd4351>" + ) elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") - set_target_properties(test_runtime PROPERTIES LINK_FLAGS "-Wl,-Bsymbolic,--exclude-libs,ALL") + set_target_properties( + test_runtime PROPERTIES LINK_FLAGS "-Wl,-Bsymbolic,--exclude-libs,ALL" + ) elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") - set_target_properties(test_runtime PROPERTIES LINK_FLAGS "-Wl,-exported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/test_runtime.expsym") + set_target_properties( + test_runtime + PROPERTIES + LINK_FLAGS + "-Wl,-exported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/test_runtime.expsym" + ) endif() gen_xr_runtime_json( - ${PROJECT_BINARY_DIR}/src/tests/loader_test/resources/runtimes/test_runtime.json - ${CMAKE_CURRENT_BINARY_DIR}/$ + "${PROJECT_BINARY_DIR}/src/tests/loader_test/resources/runtimes/test_runtime.json" + "${CMAKE_CURRENT_BINARY_DIR}/$" -b ) # Add generated file to our sources so we depend on it, and thus trigger generation. -target_sources(test_runtime PRIVATE ${PROJECT_BINARY_DIR}/src/tests/loader_test/resources/runtimes/test_runtime.json) +target_sources( + test_runtime + PRIVATE + "${PROJECT_BINARY_DIR}/src/tests/loader_test/resources/runtimes/test_runtime.json" +) diff --git a/src/version.cmake b/src/version.cmake index 5e64c70d2..3a6e0398a 100644 --- a/src/version.cmake +++ b/src/version.cmake @@ -21,28 +21,76 @@ set(PATCH "0") set(OPENXR_SDK_HOTFIX_VERSION) if(EXISTS "${PROJECT_SOURCE_DIR}/specification/registry/xr.xml") - file(STRINGS ${PROJECT_SOURCE_DIR}/specification/registry/xr.xml lines REGEX "#define XR_CURRENT_API_VERSION") + file( + STRINGS ${PROJECT_SOURCE_DIR}/specification/registry/xr.xml lines + REGEX "#define XR_CURRENT_API_VERSION" + ) else() - file(STRINGS ${PROJECT_SOURCE_DIR}/include/openxr/openxr.h lines REGEX "#define XR_CURRENT_API_VERSION") + file( + STRINGS ${PROJECT_SOURCE_DIR}/include/openxr/openxr.h lines + REGEX "#define XR_CURRENT_API_VERSION" + ) endif() list(LENGTH lines len) if(${len} EQUAL 1) - list(GET lines 0 cur_line) + list( + GET + lines + 0 + cur_line + ) # Grab just the stuff in the parentheses of XR_MAKE_VERSION( ), # by replacing the whole line with the stuff in the parentheses - string(REGEX REPLACE "^.+\\(([^\)]+)\\).+$" "\\1" VERSION_WITH_WHITESPACE ${cur_line}) + string( + REGEX + REPLACE + "^.+\\(([^\)]+)\\).+$" + "\\1" + VERSION_WITH_WHITESPACE + ${cur_line} + ) # Remove whitespace - string(REPLACE " " "" VERSION_NO_WHITESPACE ${VERSION_WITH_WHITESPACE}) + string( + REPLACE + " " + "" + VERSION_NO_WHITESPACE + ${VERSION_WITH_WHITESPACE} + ) # Grab components - string(REGEX REPLACE "^([0-9]+)\\,[0-9]+\\,[0-9]+" "\\1" MAJOR "${VERSION_NO_WHITESPACE}") - string(REGEX REPLACE "^[0-9]+\\,([0-9]+)\\,[0-9]+" "\\1" MINOR "${VERSION_NO_WHITESPACE}") - string(REGEX REPLACE "^[0-9]+\\,[0-9]+\\,([0-9]+)" "\\1" PATCH "${VERSION_NO_WHITESPACE}") + string( + REGEX + REPLACE + "^([0-9]+)\\,[0-9]+\\,[0-9]+" + "\\1" + MAJOR + "${VERSION_NO_WHITESPACE}" + ) + string( + REGEX + REPLACE + "^[0-9]+\\,([0-9]+)\\,[0-9]+" + "\\1" + MINOR + "${VERSION_NO_WHITESPACE}" + ) + string( + REGEX + REPLACE + "^[0-9]+\\,[0-9]+\\,([0-9]+)" + "\\1" + PATCH + "${VERSION_NO_WHITESPACE}" + ) else() - message(FATAL_ERROR "Unable to fetch major/minor/patch version from registry or header") + message( + FATAL_ERROR + "Unable to fetch major/minor/patch version from registry or header" + ) endif() # Check for an SDK hotfix version indicator file.