Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 74 additions & 73 deletions .github/workflows/c-cpp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,121 +3,122 @@ name: Build and test OpenVR driver
on: [ push, pull_request, workflow_dispatch ]

jobs:
setup-matrix:
name: Setup build matrix
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.setup-matrix.outputs.matrix }}
steps:
- id: setup-matrix
shell: bash
run: |
cat <<EOF | jq -c > matrix.json
{
"include": [
{"os": "windows-2025", "name": "win64"},
{"os": "ubuntu-latest", "name": "x64-linux"},
{"os": "ubuntu-24.04-arm", "name": "aarch64-linux"}
]
}
EOF
echo "matrix=$(cat matrix.json)" >> $GITHUB_OUTPUT

build:
name: Build (${{ matrix.os }})
needs: [setup-matrix]
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [windows-latest, ubuntu-latest, ubuntu-24.04-arm]
include:
- os: windows-latest
triplet: x64-windows-static-md
name: win64
target: ALL_BUILD
release_dir: Release # dir of driver binaries within env.CMAKE_BUILD_DIR, VS multi-config uses <CONFIG>/ subfolder
- os: ubuntu-latest
triplet: x64-linux
name: x64-linux
target: all
release_dir: "" # makefile single config won't have subfolder
- os: ubuntu-24.04-arm
triplet: arm64-linux
name: aarch64-linux
target: all
release_dir: "" # makefile single config won't have subfolder
matrix: ${{ fromJson(needs.setup-matrix.outputs.matrix) }}
env:
# Indicates the CMake build directory where project files and binaries are being produced.
CMAKE_BUILD_DIR: ${{ github.workspace }}/build
# Indicates the location of the vcpkg as a Git submodule of the project repository.
VCPKG_ROOT: ${{ github.workspace }}/vcpkg

steps:
- uses: actions/checkout@v6
with:
submodules: true

- uses: lukka/get-cmake@latest

- name: Get submodule commit hashes
id: submodule_hashes
run: git submodule foreach --recursive git rev-parse HEAD > submodule_hashes.txt

- name: Restore vcpkg and its artifacts
id: get-submodule-commit-hashes
run: git submodule foreach --recursive git rev-parse HEAD > submodule-hashes.txt

- name: Generate cache key
id: gen-cache-key
shell: bash
run: |
echo "cache-key=${{ matrix.os }}-${{ hashFiles('submodule-hashes.txt') }}-${{ hashFiles('CMakeLists.txt') }}" >> $GITHUB_OUTPUT

- name: Set up CPM cache
id: setup-cpm-cache
uses: actions/cache@v5
with:
# The first path is where vcpkg generates artifacts while consuming the vcpkg.json manifest file.
# The second path is the location of vcpkg (it contains the vcpkg executable and data files).
# The other paths starting with "!" are exclusions: they contain termporary files generated during the build of the installed packages.
path: |
${{ env.CMAKE_BUILD_DIR }}/vcpkg_installed/
${{ env.VCPKG_ROOT }}
!${{ env.VCPKG_ROOT }}/buildtrees
!${{ env.VCPKG_ROOT }}/packages
!${{ env.VCPKG_ROOT }}/downloads
# The key is composed in a way that it gets properly invalidated: this must happen whenever vcpkg/submodule Git commit id changes, or the list of packages changes. In this case a cache miss must happen and a new entry with a new key with be pushed to GitHub the cache service.
# The key includes: hash of the vcpkg.json file, the hash of the vcpkg Git commit id, and the used vcpkg's triplet. The vcpkg's commit id would suffice, but computing an hash out it does not harm.
# Note: given a key, the cache content is immutable. If a cache entry has been created improperly, in order the recreate the right content the key must be changed as well, and it must be brand new (i.e. not existing already).
key: ${{ matrix.triplet }}-${{ hashFiles( '**/vcpkg.json', '**/CMakeLists.txt' ) }}-${{ hashFiles( 'submodule_hashes.txt' )}}
path: ~/cpm-cache
key: cpm-${{ steps.gen-cache-key.outputs.cache-key }}
restore-keys: |
cpm-${{ matrix.os }}-

- if: matrix.os == 'windows-latest'
name: Set up vcpkg for Windows
run: ${{ env.VCPKG_ROOT }}/bootstrap-vcpkg.bat

- if: matrix.os != 'windows-latest'
name: Set up vcpkg for Unix
run: ${{ env.VCPKG_ROOT }}/bootstrap-vcpkg.sh

- name: Configure CMake
run: cmake -S "${{github.workspace}}" -B "${{env.CMAKE_BUILD_DIR}}" -DVCPKG_TARGET_TRIPLET=${{matrix.triplet}} -DCMAKE_BUILD_TYPE=Release

- name: Build
run: cmake --build "${{env.CMAKE_BUILD_DIR}}" --config Release --target "${{ matrix.target }}" -j 6 --
- uses: hendrikmuhs/ccache-action@v1.2
id: setup-ccache
with:
key: ccache-${{ steps.gen-cache-key.outputs.cache-key }}
restore-keys: |
ccache-${{ matrix.os }}-

- if: matrix.os == 'windows-2025'
name: Configure and build on Windows
shell: cmd
run: |
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
cmake -S "${{ github.workspace }}" -B "${{ env.CMAKE_BUILD_DIR }}" -G Ninja ^
-DCPM_SOURCE_CACHE=%USERPROFILE%\cpm-cache ^
-DCMAKE_C_COMPILER_LAUNCHER=ccache ^
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache ^
-DSLIMEVR_BUILD_TESTS=ON ^
-DCMAKE_BUILD_TYPE=Release
cmake --build "${{ env.CMAKE_BUILD_DIR }}" --config Release -j6

- if: matrix.os != 'windows-2025'
name: Configure and build on Unix
run: |
cmake -S "${{ github.workspace }}" -B "${{ env.CMAKE_BUILD_DIR }}" -G Ninja \
-DCPM_SOURCE_CACHE=~/cpm-cache \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DSLIMEVR_BUILD_TESTS=ON \
-DCMAKE_BUILD_TYPE=Release
cmake --build "${{ env.CMAKE_BUILD_DIR }}" --config Release -j6

- name: Upload driver
uses: actions/upload-artifact@v7
with:
name: slimevr-openvr-driver-${{ matrix.name }}
path: ${{ env.CMAKE_BUILD_DIR }}/${{ matrix.release_dir }}/driver
path: ${{ env.CMAKE_BUILD_DIR }}/driver

- name: Upload tests
uses: actions/upload-artifact@v7
with:
name: tests-${{ matrix.name }}
path: ${{ env.CMAKE_BUILD_DIR }}/${{ matrix.release_dir }}/tests*
path: ${{ env.CMAKE_BUILD_DIR }}/tests*

test:
name: Run tests (${{ matrix.os }})
needs: build
runs-on: ${{ matrix.os }}
needs: [setup-matrix, build]
strategy:
fail-fast: false
matrix:
os: [windows-latest, ubuntu-latest, ubuntu-24.04-arm]
include:
- os: windows-latest
triplet: x64-windows-static-md
name: win64
target: ALL_BUILD
- os: ubuntu-latest
triplet: x64-linux
name: x64-linux
target: all
- os: ubuntu-24.04-arm
triplet: arm64-linux
name: aarch64-linux
target: all
matrix: ${{ fromJson(needs.setup-matrix.outputs.matrix) }}
runs-on: ${{ matrix.os }}
steps:
- name: Download build artifact
uses: actions/download-artifact@v8
with:
name: tests-${{ matrix.name }}
path: ${{ github.workspace }}
- if: matrix.os == 'windows-latest'
- if: matrix.os == 'windows-2025'
name: Run tests on Windows
working-directory: ${{ github.workspace }}/
run: .\tests.exe
- if: matrix.os != 'windows-latest'
- if: matrix.os != 'windows-2025'
name: Run tests on Unix
working-directory: ${{ github.workspace }}/
run: chmod +x ./tests && ./tests
Expand Down
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,3 @@
[submodule "libraries/linalg"]
path = libraries/linalg
url = https://github.com/sgorsten/linalg.git
[submodule "vcpkg"]
path = vcpkg
url = https://github.com/Microsoft/vcpkg.git
101 changes: 45 additions & 56 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,42 +1,23 @@
cmake_minimum_required(VERSION 3.8.0)
cmake_minimum_required(VERSION 3.19)

#if (NOT DEFINED VCPKG_TARGET_TRIPLET)
if(WIN32)
set(VCPKG_TARGET_TRIPLET "x64-windows-static-md")
endif()
#endif()

set (CMAKE_CXX_STANDARD 20)
# PIE is required
include(CheckPIESupported)
check_pie_supported()

# If the toolchain is already defined, do not attempt to find it
if(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
# If the VCPKG_ROOT environment variable is not defined, try to automatically define it from AppData/home
if(NOT DEFINED ENV{VCPKG_ROOT})
if(WIN32)
file(READ "$ENV{LOCALAPPDATA}/vcpkg/vcpkg.path.txt" VCPKG_ROOT)
elseif(UNIX)
file(READ "$ENV{HOME}/.vcpkg/vcpkg.path.txt" VCPKG_ROOT)
endif()

set(VCPKG_PATH "${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake")
else()
set(VCPKG_PATH "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake")
endif()

if(EXISTS "${VCPKG_PATH}")
message("vcpkg CMake toolchain was found at \"${VCPKG_PATH}\"")
set(CMAKE_TOOLCHAIN_FILE "${VCPKG_PATH}")
else()
message(FATAL_ERROR "vcpkg could not be found")
endif()
endif()
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

project(SlimeVR-OpenVR-Driver VERSION 0.2.0)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set(DRIVER_NAME "slimevr")

include(CTest)
enable_testing()
option(SLIMEVR_BUILD_TESTS "Build tests" OFF)

if (SLIMEVR_BUILD_TESTS)
include(CTest)
enable_testing()
endif()

# OpenVR
set(OPENVR_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libraries/openvr/headers")
Expand All @@ -62,22 +43,24 @@ elseif(APPLE)
set(PLATFORM_NAME "osx")
endif()

# Protobuf
# Installation:
# Please refer to this readme to install protobuf in your system: https://github.com/protocolbuffers/protobuf/blob/master/src/README.md
# WARNING: CLang has an arror building protobuf messages, use MSVC 2019
set(protobuf_MODULE_COMPATIBLE ON CACHE BOOL "")
find_package(Protobuf CONFIG REQUIRED)
protobuf_generate_cpp(PROTO_SRC PROTO_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/src/bridge/ProtobufMessages.proto")
SET_SOURCE_FILES_PROPERTIES(${PROTO_SRC} ${PROTO_INCL} PROPERTIES GENERATED TRUE)
include(cmake/CPM.cmake)

find_package(simdjson CONFIG REQUIRED)

# libuv
find_package(uvw CONFIG REQUIRED)
CPMAddPackage(URI "gh:protocolbuffers/protobuf@31.1"
OPTIONS "protobuf_BUILD_TESTS OFF" "protobuf_MSVC_STATIC_RUNTIME OFF")
CPMAddPackage(URI "gh:simdjson/simdjson@4.6.4")
CPMAddPackage(URI "gh:libuv/libuv@1.52.1")
CPMAddPackage(URI "gh:skypjack/uvw#bf9c298ea6598e78913c6cd186211412ddac04d6")
if (SLIMEVR_BUILD_TESTS)
CPMAddPackage(URI "gh:catchorg/Catch2@3.15.0")
endif()

# Catch2
find_package(Catch2 3 REQUIRED)
include("${protobuf_SOURCE_DIR}/cmake/protobuf-generate.cmake")
protobuf_generate(
LANGUAGE cpp
PROTOS "${CMAKE_CURRENT_SOURCE_DIR}/src/bridge/ProtobufMessages.proto"
IMPORT_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/src/bridge"
OUT_VAR PROTO_GENERATED_FILES
)

# Project
set(DEPS_INCLUDES
Expand All @@ -90,38 +73,44 @@ set(DEPS_LIBS
protobuf::libprotobuf
protobuf::libprotobuf-lite
simdjson::simdjson
libuv::libuv
uvw::uvw
)

# compile into a static lib
file(GLOB_RECURSE SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")
file(GLOB_RECURSE HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.hpp")
add_library("${PROJECT_NAME}_static" STATIC ${SOURCES} ${PROTO_HEADER} ${PROTO_SRC})
add_library("${PROJECT_NAME}_static" STATIC ${SOURCES} ${PROTO_GENERATED_FILES})
target_link_libraries("${PROJECT_NAME}_static" PUBLIC ${DEPS_LIBS})
set_property(TARGET "${PROJECT_NAME}_static" PROPERTY CXX_STANDARD 20)
include_directories("${PROJECT_NAME}_static" PUBLIC ${DEPS_INCLUDES} ${Protobuf_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR})
set_target_properties("${PROJECT_NAME}_static" PROPERTIES CXX_STANDARD 20)
target_include_directories("${PROJECT_NAME}_static" PUBLIC ${DEPS_INCLUDES} ${Protobuf_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR})
if(UNIX)
target_compile_options("${PROJECT_NAME}_static" PRIVATE "-fPIC")
target_link_libraries("${PROJECT_NAME}_static" PUBLIC atomic)
endif()

# compile driver
file(GLOB_RECURSE DRIVER_MAIN "${CMAKE_CURRENT_SOURCE_DIR}/src/DriverFactory.cpp")
add_library("${PROJECT_NAME}" SHARED ${DRIVER_MAIN} ${HEADERS} ${PROTO_HEADER})
add_library("${PROJECT_NAME}" SHARED ${DRIVER_MAIN} ${HEADERS})
target_include_directories("${PROJECT_NAME}" PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries("${PROJECT_NAME}" PUBLIC "${PROJECT_NAME}_static")
set_property(TARGET "${PROJECT_NAME}" PROPERTY CXX_STANDARD 20)
set_target_properties("${PROJECT_NAME}" PROPERTIES CXX_STANDARD 20)

# compile tests
function(build_tests target_name test_dir)
function(build_tests target_name test_dir executable_name)
file(GLOB TESTS "${CMAKE_CURRENT_SOURCE_DIR}/${test_dir}/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/${test_dir}/*.hpp")
file(GLOB TESTS_COMMON "${CMAKE_CURRENT_SOURCE_DIR}/test/common/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/test/common/*.hpp")
add_executable(${target_name} ${TESTS} ${TESTS_COMMON} ${HEADERS} ${PROTO_HEADER})
target_link_libraries(${target_name} PUBLIC "${PROJECT_NAME}_static" Catch2::Catch2WithMain)
set_property(TARGET ${target_name} PROPERTY CXX_STANDARD 20)
set_target_properties(${target_name} PROPERTIES CXX_STANDARD 20 OUTPUT_NAME "${executable_name}")
endfunction()
build_tests(tests "test")
build_tests(tests_integration "test/integration")
add_test(NAME tests COMMAND "tests")

if (SLIMEVR_BUILD_TESTS)
build_tests("${PROJECT_NAME}-Tests" "test" "tests")
build_tests("${PROJECT_NAME}-Tests-Integration" "test/integration" "tests_integration")
add_test(NAME "Driver tests" COMMAND "${PROJECT_NAME}-Tests")
add_test(NAME "Driver tests (with real server)" COMMAND "${PROJECT_NAME}-Tests-Integration")
endif()

# IDE Config
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}/src" PREFIX "Header Files" FILES ${HEADERS})
Expand Down
24 changes: 24 additions & 0 deletions cmake/CPM.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# SPDX-License-Identifier: MIT
#
# SPDX-FileCopyrightText: Copyright (c) 2019-2023 Lars Melchior and contributors

set(CPM_DOWNLOAD_VERSION 0.42.3)
set(CPM_HASH_SUM "a609e875fd532b067174250f6abbc3dac22fe2d64869783fb1e80bda1625c844")

if(CPM_SOURCE_CACHE)
set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
elseif(DEFINED ENV{CPM_SOURCE_CACHE})
set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
else()
set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
endif()

# Expand relative path. This is important if the provided path contains a tilde (~)
get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE)

file(DOWNLOAD
https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake
${CPM_DOWNLOAD_LOCATION} EXPECTED_HASH SHA256=${CPM_HASH_SUM}
)

include(${CPM_DOWNLOAD_LOCATION})
1 change: 0 additions & 1 deletion vcpkg
Submodule vcpkg deleted from 2fa711
11 changes: 0 additions & 11 deletions vcpkg.json

This file was deleted.

Loading