Update for latest design consideratiosn

This commit is contained in:
Xaymar
2026-02-01 16:37:58 +01:00
parent e1fbf5303c
commit a47c660f06
32 changed files with 20 additions and 2080 deletions
-11
View File
@@ -10,14 +10,3 @@ Redistribution and use in source and binary forms, with or without modification,
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
## Third Party Projects & Licenses
| Project | Copyright (c) | License |
|---|---|---|
| boost::asio (WebSocket++) | | Boost Software License - Version 1.0 |
| libpqxx | 2000-2026 Jeroen T. Vermeulen | [3-Clause BSD License](https://github.com/jtv/libpqxx/blob/master/COPYING) |
| nlohmann::json | 2013-2026 Niels Lohmann | [MIT License](https://github.com/nlohmann/json/blob/develop/LICENSE.MIT) |
| WebSocket++ | 2014 Peter Thorson | [Modified 3-Clause BSD License](https://github.com/zaphoyd/websocketpp/blob/master/COPYING) |
### Notes
- We've applied the ASIO compatibility patches to WebSocket++ in order to use the newest versions.
+20 -16
View File
@@ -1,22 +1,26 @@
# Archipelago Room Server # Peninsula
A room server implementation for the multiworld randomizer Archipelago. Peninsula is an alternative server implementation for the popular Multi World Randomizer Archipelago. It's aim is to be performant, scalable, and easily distributable so it can behind load balancers. All in the name of reducing the hosting cost of large async or sync rooms.
Licensed under 3-Clause BSD License. For more information see COPYING.md ## Design Considerations
- Store everything in databases or files accessible from all servers hosting peninsula.
- Require no interconnectivity beyond the database (or a cache like Redis) between servers.
- PHP based which is available on a wide range of web hosting offers.
## Design ### Pros
Some brainstorming about what needs to be done. - Significantly bigger lobbies (sync and async) through distributed processing.
- Much cheaper to host as we can take advantage of web hosting deals.
### Basics ### Cons
In the ideal case there is one room server per machine that handles all rooms and users that connect to that machine. It'd also be nice if it could be controlled via WebSocket as well either locally or remotely. - All realtime information (notifications, chat, deathlink, ...) will require a polling client, causing delays.
- WebSocket clients require a bridge to convert between the two protocols.
- Higher traffic due to repeated information being required.
## Frequently Asked Questions (FAQ) ## Sub-projects
*All the questions that were asked or would be asked frequently.* This project is split into three projects:
### Why rewrite the room server in a different programming language? - The backend, which is PHP based and handles all interaction with the database.
While Python is quite nice when it comes to ease of use and how quickly you can get something off the ground it suffers from significant performance issues. Some of them can be reduced with CPython or similar but you can never fully get rid of them entirely. This is the case for most if not all higher level languages that either need an intermediate representation or are compiled at runtime (JIT). - The frontend, which is JavaScript based and handles user-facing information.
- The bridge, which converts WebSocket clients to the Peninsula protocol.
Lower level languages tend to avoid this by shifting the heavy lifting to a compile and link step resulting in much faster execution. However they're harder to work with and any issues that occur during runtime tend to be unrecoverable. Technically Rust is "safer" to write this in but I have a personal hatred for Rust's awful inconsistent syntax and rules.
### Isn't uWebSockets faster than WebSocket++?
Maybe? There aren't any proper benchmarks out there for this kind of stuff. Most of the benchmarks tend to be tied to databases which will be end up being the bottleneck. I just picked what integrates with C++ more.
## License
Licensed under 3-Clause BSD License. For more information see [COPYING.md](https://github.com/Xaymar/peninsula/blob/root/README.md).
-117
View File
@@ -1,117 +0,0 @@
# AUTOGENERATED COPYRIGHT HEADER START
# Copyright (C) 2018-2023 Michael Fabian 'Xaymar' Dirks <info@xaymar.com>
# AUTOGENERATED COPYRIGHT HEADER END
# Basic Formatting
TabWidth: 4
UseTab: ForContinuationAndIndentation
ColumnLimit: 0
#- 0 does not respect the original line breaks!
# Language
Language: Cpp
Standard: c++17
# Indentation
AccessModifierOffset: 0
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
IndentCaseLabels: false
#IndentPPDirectives: true
IndentWidth: 4
IndentWrappedFunctionNames: true
NamespaceIndentation: All
# Includes
#IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^"warning-disable.hpp"$'
Priority: 50
- Regex: '^(<|")(config.hpp|common.hpp|ui-common.hpp|strings.hpp|version.hpp|obs.h)("|>)'
Priority: 100
- Regex: '^<obs-'
Priority: 150
- Regex: '^<'
Priority: 200
- Regex: '^<Q'
Priority: 250
- Regex: '^"'
Priority: 300
- Regex: '.moc"$'
Priority: 300
- Regex: '^"warning-enable.hpp"$'
Priority: 500
SortIncludes: true
# Alignment
AlignAfterOpenBracket: true
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: true
AlignEscapedNewlines: Left
AlignOperands: true
AlignTrailingComments: false
AlignArrayOfStructures: Right
DerivePointerAlignment: false
PointerAlignment: Left
# Wrapping and Breaking
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
# AfterExternBlock: false
AfterFunction: true
AfterNamespace: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: false
BinPackArguments: true
BinPackParameters: true
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeBraces: Custom
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
#BreakInheritanceList: BeforeColon
BreakStringLiterals: true
ConstructorInitializerAllOnOneLineOrOnePerLine: false
Cpp11BracedListStyle: true
# Spaces
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
#SpaceBeforeCpp11BracedList: false
#SpaceBeforeCtorInitializerColon: true
#SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
#SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
# Other
CommentPragmas: '^(!FIXME!|!TODO!|ToDo:)'
CompactNamespaces: false
DisableFormat: false
FixNamespaceComments: true
#ForEachMacros: ''
KeepEmptyLinesAtTheStartOfBlocks: false
ReflowComments: false
SortUsingDeclarations: true
-3
View File
@@ -1,3 +0,0 @@
[submodule "cmake/externalcontent"]
path = cmake/externalcontent
url = https://github.com/Xaymar/cmake-externalcontent.git
-38
View File
@@ -1,38 +0,0 @@
{
"version": 6,
"cmakeMinimumRequired": {
"major": 4,
"minor": 2,
"patch": 1
},
"configurePresets": [
{
"name": "default",
"displayName": "Default",
"description": "Default",
"binaryDir": "${sourceDir}/build/",
"installDir": "${sourceDir}/distrib/",
"cacheVariables": {
"CMAKE_VERBOSE_MAKEFILE": "ON",
"CMAKE_INTERPROCEDURAL_OPTIMIZATION": "ON"
},
"hidden": false
}
],
"buildPresets": [
{
"configurePreset": "default",
"name": "default-debug",
"description": "",
"displayName": "Debug",
"configuration": "Debug"
},
{
"configurePreset": "default",
"name": "default-release",
"description": "",
"displayName": "Release",
"configuration": "Release"
}
]
}
@@ -1,21 +0,0 @@
# AUTOGENERATED COPYRIGHT HEADER START
# Copyright (C) 2017-2024 Michael Fabian 'Xaymar' Dirks <info@xaymar.com>
# AUTOGENERATED COPYRIGHT HEADER END
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file.
[*]
insert_final_newline = true
trim_trailing_whitespace = true
charset = utf-8
indent_style = tab
indent_size = 4
[*.yml]
indent_style = space
indent_size = 2
[*.md]
trim_trailing_whitespace = false
@@ -1,2 +0,0 @@
blank_issues_enabled: false
contact_links:
@@ -1,21 +0,0 @@
---
name: "Suggest an Enhancment to a Feature or a new Feature"
title: "Replace Me Or Have Your Request Closed"
description: "Is there something lacking that you would like to have supported?"
labels: ["enhancement", "help wanted"]
body:
- type: textarea
attributes:
label: "Explain the Feature/Enhancement"
description: "Describe the feature or enhancement in as much detail as possible, leave nothing out. If you think images or example videos help describe the Feature/Enhancement, include them."
validations:
required: true
- type: textarea
attributes:
label: "Examples"
description: "Provide some examples of how this feature would/should be used."
validations:
required: true
- type: textarea
attributes:
label: "Any additional information we need to know?"
@@ -1,137 +0,0 @@
name: "Report a Bug/Crash/Freeze"
title: "Replace Me Or Have Your Report Closed"
description: "Encountered a problem, a bug or a crash?"
labels: ["bug", "help wanted"]
body:
- type: dropdown
attributes:
label: "Operating System"
description: "What Operating System do you use for OBS Studio and StreamFX? Select 'Other' if your Operating System is not listed"
options:
- "Windows 10 1903 and higher"
- "MacOS 10.15 and higher"
- "Linux (like Debian/Ubuntu)"
- "Linux (like Arch Linux)"
- "Linux (like FreeBSD)"
- "(Other)"
validations:
required: true
- type: dropdown
attributes:
label: "OBS Studio Version?"
description: "Which OBS Studio version are you using to run StreamFX? Versions include all patches (the third element in 'A.B.C'), and release candidates for that version. Select 'Other' if you are using a custom build."
options:
- "27.1"
- "27.0"
- "26.1"
- "26.0"
- "25.0"
- "(Other)"
validations:
required: true
- type: dropdown
attributes:
label: "StreamFX Version"
description: "On which StreamFX version did you first encounter this issue?"
options:
- "0.12.0a1"
- "0.11.1"
- "0.11.1b1"
- "0.11.1a1"
- "0.11.0"
- "0.11.0c1"
- "0.11.0b3"
- "0.11.0b2"
- "0.11.0b1"
- "0.11.0a8"
- "0.11.0a7"
- "0.11.0a6"
- "0.11.0a5"
- "0.11.0a4"
- "0.11.0a3"
- "0.11.0a2"
- "0.11.0a1"
- "0.10.1"
- "0.10.0"
- "0.10.0b3"
- "0.10.0b2"
- "0.10.0b1"
- "0.10.0a2"
- "0.10.0a1"
- "0.10.0a0"
- "0.9.3"
- "0.9.2"
- "0.9.1"
- "0.9.0"
- "0.9.0a3"
- "0.9.0a2"
- "0.9.0a1"
- "0.8.3"
- "0.8.2"
- "0.8.1"
- "0.8.0"
- "0.8.0b3"
- "0.8.0b2"
- "0.8.0b2hf2"
- "0.8.0b2hf1"
- "0.8.0b1"
- "0.8.0a4"
- "0.8.0a3"
- "0.8.0a2"
- "0.8.0a1"
- "0.7.2"
- "0.7.1"
- "0.7.0"
- "0.6.3"
- "0.6.2"
- "0.6.1"
- "0.6.0"
- "0.5.2"
- "0.5.1"
- "0.5.0"
- "0.5.0preview3"
- "0.5.0preview2"
- "0.5.0preview1"
- "0.4.3"
- "0.4.3preview1"
- "0.4.2"
- "0.4.1"
- "0.4.0"
- "0.3.0"
- "0.2.0"
- "0.1.1"
- "0.1.0"
validations:
required: true
- type: input
attributes:
label: "OBS Studio Log"
description: "Upload a normal log file that showcases the issue happening. If you encountered a crash, also fill out the next field."
validations:
required: true
- type: textarea
attributes:
label: "OBS Studio Crash Log"
description: "If OBS Studio crashed (not froze) paste the crash log here, or upload it somewhere and paste the link here."
- type: textarea
attributes:
label: "Current Behavior"
description: "What actually happened when you used StreamFX?"
validations:
required: true
- type: textarea
attributes:
label: "Expected Behavior"
description: "What did you expect to happen when using StreamFX?"
validations:
required: true
- type: textarea
attributes:
label: "Steps to Reproduce the Bug"
description: "What steps are required to consistently reproduce the bug/crash/freeze?"
validations:
required: true
- type: textarea
attributes:
label: "Any additional Information we need to know?"
description: "If you answered '(Other)' to any system relevant information, explain what you mean by that here."
@@ -1,8 +0,0 @@
### Explain the Pull Request
<!-- Describe the PR in as much detail as possible, leave nothing out. -->
<!-- If you think images or example videos help describe the PR, include them. -->
<!-- Additionally, link any PRs, Issues, etc. that may be relevant. -->
### Checklist
- [ ] I will become the maintainer for this part of code.
- [ ] I have tested this code. <!-- If you lie here, it will show in the CI builds. -->
@@ -1,88 +0,0 @@
name: Generate Documentation
on:
push:
branches:
- '*'
- '!documentation'
paths:
- '.github/workflows/documentation.yml'
- 'docs/**'
- 'tools/**'
- 'LICENSE'
jobs:
docs:
name: "Generate Documentation"
runs-on: ubuntu-latest
steps:
- name: "Set up Git"
shell: bash
run: |
git config --global user.name 'GitHub Actions'
git config --global user.email 'xaymar@users.noreply.github.com'
git config --global pull.ff only
git config --global pull.rebase true
- name: "Clone"
uses: actions/checkout@v3
with:
submodules: 'recursive'
fetch-depth: 0
- name: "Clone Documentation"
uses: actions/checkout@v3
with:
ref: 'documentation'
path: 'build/docs/html'
submodules: 'recursive'
fetch-depth: 0
# git clone --progress --recursive -b documentation --single-branch https://x-access-token:${{ github.token }}@github.com/${{ github.repository }} "${{ github.workspace }}/build/docs/html"
- name: "Install Prerequisites"
shell: bash
run: |
sudo apt-get install make python3 python3-pip python3-virtualenv
- name: "Install Sphinx and Themes into a VirtualEnv"
shell: bash
run: |
source ~/.profile
virtualenv build/venv
source build/venv/bin/activate
pip install sphinx
pip install sphinx-rtd-theme
- name: "Generate Documentation"
shell: bash
run: |
source ~/.profile
source build/venv/bin/activate
pushd tools
make html
ls -lha
popd
ls -lha
- name: "Update Documentation"
shell: bash
run: |
pushd build/docs/html
git add .
git --no-pager diff --patch --minimal HEAD --
git update-index --refresh
if ! git diff-index --quiet HEAD --; then
git commit -a -m "${{ github.sha }}"
# Only push from master branch.
if [[ "${{ github.ref }}" == "refs/heads/master" ]]; then
git push
echo "Documentation has been updated!"
else
git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
fi
else
echo "Documentation is still up to date."
fi
popd
-38
View File
@@ -1,38 +0,0 @@
name: Automated Testing
on:
push:
branches:
- '*'
- '!documentation'
paths:
- '.github/workflows/test.yml'
- 'tests/**'
- 'version.cmake'
pull_request:
paths:
- '.github/workflows/test.yml'
- 'tests/**'
- 'version.cmake'
jobs:
test:
name: "Run Tests"
runs-on: ubuntu-latest
steps:
- name: "Clone"
uses: actions/checkout@v3
with:
submodules: recursive
fetch-depth: 0
- name: "Install Prerequisites"
shell: bash
run: |
sudo apt-get install build-essential cmake
- name: "Run Tests"
shell: bash
run: |
cmake -Htests -Bbuild/tests
-2
View File
@@ -1,2 +0,0 @@
build
.venv
@@ -1,706 +0,0 @@
# Copyright 2026 Narta Xaymar Dirks <info@xaymar.com>
#
# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# ExternalContent is an attempt at solving the issues I have with FetchContent and ExternalProject:
# - Both pollute the parent cache with variables and aren't fully separated.
# - Both are considerably slower.
# - Anything that uses them ends up with poor performance too.
# Goals:
# - Never pollute the parent cache unless absolutely needed.
#!TODO: Add support for older CMake versions.
cmake_minimum_required(VERSION 4.2.0)
function(InitializeExternalContent)
endfunction()
macro(ExternalContent_ParseURL OUTPUT_VAR URL)
# Parse the given url.
string(REGEX
MATCH "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?"
URL_MATCH
"${URL}"
)
if(NOT "${URL}" STREQUAL "${URL_MATCH}")
message(FATAL_ERROR "ExternalContent: Failed to parse URL '${URL}' completely. Only managed to parse '${URL_MATCH}'.")
endif()
set(${OUTPUT_VAR}_PROTOCOL_FULL ${CMAKE_MATCH_1})
set(${OUTPUT_VAR}_PROTOCOL ${CMAKE_MATCH_2})
set(${OUTPUT_VAR}_HOST_FULL ${CMAKE_MATCH_3})
set(${OUTPUT_VAR}_HOST ${CMAKE_MATCH_4})
set(${OUTPUT_VAR}_PATH ${CMAKE_MATCH_5})
set(${OUTPUT_VAR}_QUERY_FULL ${CMAKE_MATCH_6})
set(${OUTPUT_VAR}_QUERY ${CMAKE_MATCH_7})
set(${OUTPUT_VAR}_FRAGMENT_FULL ${CMAKE_MATCH_8})
set(${OUTPUT_VAR}_FRAGMENT ${CMAKE_MATCH_9})
endmacro()
macro(ExternalContent_ParsePath OUTPUT_VAR INPUT_VAR)
cmake_path(GET "${INPUT_VAR}" FILENAME "${OUTPUT_VAR}_FILENAME")
cmake_path(GET "${INPUT_VAR}" EXTENSION "${OUTPUT_VAR}_EXTENSION")
endmacro()
function(ExternalContent)
set(EXTERNALCONTENT_PREFIX "${CMAKE_BINARY_DIR}/ExternalContentFiles/")
if(TRUE) # Resolve dependencies
# Dependency: Git
find_package(Git QUIET)
endif()
if(TRUE) # Parse and validate the arguments
# Ensure any missing value is at it's default value
set(EXTERNALCONTENT_NAME "")
set(EXTERNALCONTENT_TEMP_PATH "")
set(EXTERNALCONTENT_SOURCE_PATH "")
set(EXTERNALCONTENT_BINARY_PATH "")
set(EXTERNALCONTENT_INSTALL_PATH "")
set(EXTERNALCONTENT_BUILDSYSTEM_SUFFIX "")
set(EXTERNALCONTENT_SKIP_DOWNLOAD OFF)
set(EXTERNALCONTENT_DIRTY OFF)
set(EXTERNALCONTENT_DOWNLOAD_URL "")
set(EXTERNALCONTENT_DOWNLOAD_FILE "")
set(EXTERNALCONTENT_DOWNLOAD_HASH "")
set(EXTERNALCONTENT_GIT_URL OFF)
set(EXTERNALCONTENT_GIT_REF OFF)
set(EXTERNALCONTENT_GIT_CLONE_ARGS "")
set(EXTERNALCONTENT_GIT_CHECKOUT_ARGS "")
set(EXTERNALCONTENT_SKIP_PATCH OFF)
set(EXTERNALCONTENT_PATCH_FUNCTION OFF)
set(EXTERNALCONTENT_DIRTY OFF)
set(EXTERNALCONTENT_SKIP_CONFIGURE OFF)
set(EXTERNALCONTENT_CONFIGURE_FUNCTION OFF)
set(EXTERNALCONTENT_CONFIGURE_ARGS "")
set(EXTERNALCONTENT_DIRTY OFF)
set(EXTERNALCONTENT_SKIP_BUILD OFF)
set(EXTERNALCONTENT_BUILD_FUNCTION OFF)
set(EXTERNALCONTENT_BUILD_ARGS "")
set(EXTERNALCONTENT_DIRTY OFF)
set(EXTERNALCONTENT_SKIP_INSTALL OFF)
set(EXTERNALCONTENT_INSTALL_FUNCTION OFF)
set(EXTERNALCONTENT_INSTALL_ARGS "")
set(EXTERNALCONTENT_DIRTY OFF)
set(_EXTERNALCONTENT_FLAGS
## Skip the download step entirely.
"SKIP_DOWNLOAD"
## Skip the configure step entirely.
"SKIP_CONFIGURE"
## Skip the patch step entirely.
"SKIP_PATCH"
## Skip the build step entirely.
"SKIP_BUILD"
## Skip the install step entirely.
"SKIP_INSTALL"
)
set(_EXTERNALCONTENT_PARAMS_SINGLE
## What is this external content called?
# Should be a unique name that also is a valid filesystem directory name.
"NAME"
## Where should we place the temporary files?
#
# Optional.
"TEMP_PATH"
## Where should we place the source files?
# You can also specify this in combination with SKIP_DOWNLOAD to use existing files.
#
# Optional.
"SOURCE_PATH"
## Where should we place the binary files (if any)?
#
# Optional. Ignored if SKIP_BUILD is set.
"BINARY_PATH"
## Where should we place the installable files (if any)?
#
# Optional. Ignored if SKIP_INSTALL is set.
"INSTALL_PATH"
## (download) From which url should this be downloaded?
# Required if no other method is provided.
"DOWNLOAD_URL"
## (download) What is the file called?
# Optional, but required if the URL does not contain a file name.
"DOWNLOAD_FILE"
## (download) What is the expected hash of the download?
# Should be in the format: (type);(hash)
# See [https://cmake.org/cmake/help/latest/command/string.html#hash] for a list of valid hash types.
#
# Optional, but recommended.
"DOWNLOAD_HASH"
## (git) Git repository to clone.
# Required if no other method is provided.
"GIT_URL"
## (git) Git reference to clone/checkout.
# Required.
"GIT_REF"
## Where in the downloaded directory is the actual content located?
# Some projects store their key configuration files outside of the parent tree.
#
# Optional.
"BUILDSYSTEM_SUFFIX"
## Provide a custom function for the configure step.
# This function is expected to message(FATAL_ERROR) if an error occurs.
#
# Function Signature:
# function(my_custom_configure NAME SOURCE_PATH BINARY_PATH INSTALL_PATH)
# # ...
# endfunction()
#
# Optional.
"CONFIGURE_FUNCTION"
## Provide a custom function for the patch step.
# This function is expected to message(FATAL_ERROR) if an error occurs.
#
# Function Signature:
# function(my_custom_patch NAME SOURCE_PATH BINARY_PATH INSTALL_PATH)
# # ...
# endfunction()
#
# Optional.
"PATCH_FUNCTION"
## Provide a custom function for the build step.
# This function is expected to message(FATAL_ERROR) if an error occurs.
#
# Function Signature:
# function(my_custom_build NAME SOURCE_PATH BINARY_PATH INSTALL_PATH)
# # ...
# endfunction()
#
# Optional.
"BUILD_FUNCTION"
## Provide a custom function for the install step.
# This function is expected to message(FATAL_ERROR) if an error occurs.
#
# Function Signature:
# function(my_custom_install NAME SOURCE_PATH BINARY_PATH INSTALL_PATH)
# # ...
# endfunction()
#
# Optional.
"INSTALL_FUNCTION"
)
set(_EXTERNALCONTENT_PARAMS_MULTI
## (git) Additional options provided to the clone command line.
# Optional. :)
"GIT_CLONE_OPTIONS"
## (git) Additional options provided to the checkout command line.
# Optional. :)
"GIT_CHECKOUT_OPTIONS"
## Provide additional arguments for the configure step.
# Only used by some build systems.
#
# Optional. Ignored if CONFIGURE_FUNCTION is set.
"CONFIGURE_ARGS"
## Provide additional arguments for the build step.
# Only used by some build systems.
#
# Optional. Ignored if BUILD_FUNCTION is set.
"BUILD_ARGS"
## Provide additional arguments for the install step.
# Only used by some build systems.
#
# Optional. Ignored if INSTALL_FUNCTION is set.
"INSTALL_ARGS"
)
cmake_parse_arguments(PARSE_ARGV 0
"EXTERNALCONTENT"
"${_EXTERNALCONTENT_FLAGS}"
"${_EXTERNALCONTENT_PARAMS_SINGLE}"
"${_EXTERNALCONTENT_PARAMS_MULTI}"
)
# Validate the NAME parameter
string(LENGTH "${EXTERNALCONTENT_NAME}" EXTERNALCONTENT_NAME_LENGTH)
if((NOT EXTERNALCONTENT_NAME) OR (EXTERNALCONTENT_NAME_LENGTH EQUAL 0))
message(STATUS "${EXTERNALCONTENT_NAME} ${EXTERNALCONTENT_NAME_LENGTH}")
message(FATAL_ERROR "[EC: ${EXTERNALCONTENT_NAME}] You must provide a NAME for the external content.")
endif()
# Ensure that we have some kind of source for the content.
string(LENGTH EXTERNALCONTENT_SOURCE_PATH EXTERNALCONTENT_SOURCE_PATH_LENGTH)
string(LENGTH EXTERNALCONTENT_DOWNLOAD_URL EXTERNALCONTENT_DOWNLOAD_URL_LENGTH)
string(LENGTH EXTERNALCONTENT_GIT_URL EXTERNALCONTENT_GIT_URL_LENGTH)
if(
(
SKIP_DOWNLOAD AND (
(NOT EXTERNALCONTENT_SOURCE_PATH)
OR (EXTERNALCONTENT_SOURCE_PATH_LENGTH EQUAL 0)
)
) OR (
(
(NOT EXTERNALCONTENT_DOWNLOAD_URL)
OR (EXTERNALCONTENT_DOWNLOAD_URL_LENGTH EQUAL 0)
) AND (
(NOT EXTERNALCONTENT_GIT_URL)
OR (EXTERNALCONTENT_GIT_URL_LENGTH EQUAL 0)
)
)
)
message(FATAL_ERROR "[EC: ${EXTERNALCONTENT_NAME}] You must provide a source for the external content.")
endif()
# Ensure that there's always a path for things.
string(LENGTH "${EXTERNALCONTENT_TEMP_PATH}" EXTERNALCONTENT_TEMP_PATH_LENGTH)
if((NOT EXTERNALCONTENT_TEMP_PATH) OR (EXTERNALCONTENT_TEMP_PATH_LENGTH EQUAL 0))
set(EXTERNALCONTENT_TEMP_PATH "${EXTERNALCONTENT_PREFIX}/${EXTERNALCONTENT_NAME}.tmp")
endif()
string(LENGTH "${EXTERNALCONTENT_SOURCE_PATH}" EXTERNALCONTENT_SOURCE_PATH_LENGTH)
if((NOT EXTERNALCONTENT_SOURCE_PATH) OR (EXTERNALCONTENT_SOURCE_PATH_LENGTH EQUAL 0))
set(EXTERNALCONTENT_SOURCE_PATH "${EXTERNALCONTENT_PREFIX}/${EXTERNALCONTENT_NAME}.src")
endif()
string(LENGTH "${EXTERNALCONTENT_BINARY_PATH}" EXTERNALCONTENT_BINARY_PATH_LENGTH)
if((NOT EXTERNALCONTENT_BINARY_PATH) OR (EXTERNALCONTENT_BINARY_PATH_LENGTH EQUAL 0))
set(EXTERNALCONTENT_BINARY_PATH "${EXTERNALCONTENT_PREFIX}/${EXTERNALCONTENT_NAME}.bin")
endif()
string(LENGTH "${EXTERNALCONTENT_INSTALL_PATH}" EXTERNALCONTENT_INSTALL_PATH_LENGTH)
if((NOT EXTERNALCONTENT_INSTALL_PATH) OR (EXTERNALCONTENT_INSTALL_PATH_LENGTH EQUAL 0))
set(EXTERNALCONTENT_INSTALL_PATH "${EXTERNALCONTENT_PREFIX}/${EXTERNALCONTENT_NAME}.dst")
endif()
# Validate the download URL
if(EXTERNALCONTENT_DOWNLOAD_URL)
ExternalContent_ParseURL(EXTERNALCONTENT_DOWNLOAD_URL "${EXTERNALCONTENT_DOWNLOAD_URL}")
ExternalContent_ParsePath(EXTERNALCONTENT_DOWNLOAD "EXTERNALCONTENT_DOWNLOAD_URL_PATH")
if(EXTERNALCONTENT_DOWNLOAD_FILE)
ExternalContent_ParsePath(EXTERNALCONTENT_DOWNLOAD "EXTERNALCONTENT_DOWNLOAD_FILE")
else()
ExternalContent_ParsePath(EXTERNALCONTENT_DOWNLOAD "EXTERNALCONTENT_DOWNLOAD_URL_PATH")
endif()
# Set the object that is being used.
set(EXTERNALCONTENT_DOWNLOAD_OBJECT "${EXTERNALCONTENT_TEMP_PATH}/${EXTERNALCONTENT_DOWNLOAD_FILENAME}")
endif()
# Validate the download hash.
list(LENGTH EXTERNALCONTENT_DOWNLOAD_HASH EXTERNALCONTENT_DOWNLOAD_HASH_LENGTH)
if(EXTERNALCONTENT_DOWNLOAD_HASH AND (EXTERNALCONTENT_DOWNLOAD_HASH_LENGTH GREATER 0))
list(GET EXTERNALCONTENT_DOWNLOAD_HASH 0 EXTERNALCONTENT_DOWNLOAD_HASH_TYPE)
list(GET EXTERNALCONTENT_DOWNLOAD_HASH 1 EXTERNALCONTENT_DOWNLOAD_HASH_HASH)
string(TOLOWER "${EXTERNALCONTENT_DOWNLOAD_HASH_HASH}" EXTERNALCONTENT_DOWNLOAD_HASH_HASH)
elseif(EXTERNALCONTENT_DOWNLOAD_HASH)
message(WARNING "[EC: ${EXTERNALCONTENT_NAME}] DOWNLOAD_HASH set to invalid value '${EXTERNALCONTENT_DOWNLOAD_HASH}', ignoring.")
unset(EXTERNALCONTENT_DOWNLOAD_HASH)
endif()
# Validate the git URL
if(EXTERNALCONTENT_GIT_URL)
ExternalContent_ParseURL(EXTERNALCONTENT_GIT_URL "${EXTERNALCONTENT_GIT_URL}")
string(LENGTH EXTERNALCONTENT_GIT_REF EXTERNALCONTENT_GIT_REF_LENGTH)
if(((NOT EXTERNALCONTENT_GIT_REF) OR (EXTERNALCONTENT_GIT_REF_LENGTH EQUAL 0)))
message(FATAL_ERROR "[EC: ${EXTERNALCONTENT_NAME}] GIT_REF must be set when using git for sanity reasons.")
endif()
endif()
endif()
set(${EXTERNALCONTENT_NAME}_TEMP_PATH "${EXTERNALCONTENT_TEMP_PATH}" PARENT_SCOPE)
set(${EXTERNALCONTENT_NAME}_SOURCE_PATH "${EXTERNALCONTENT_SOURCE_PATH}" PARENT_SCOPE)
set(${EXTERNALCONTENT_NAME}_BINARY_PATH "${EXTERNALCONTENT_BINARY_PATH}" PARENT_SCOPE)
set(${EXTERNALCONTENT_NAME}_INSTALL_PATH "${EXTERNALCONTENT_INSTALL_PATH}" PARENT_SCOPE)
# Download and extract the content.
set(EXTERNALCONTENT_DIRTY OFF)
if(NOT EXTERNALCONTENT_SKIP_DOWNLOAD)
if(EXTERNALCONTENT_DOWNLOAD_URL) # download: Download the file and optionally verify the hash.
set(EXTERNALCONTENT_FORCE_DOWNLOAD OFF)
# Check if the file actually differs (or is missing)
if(EXISTS "${EXTERNALCONTENT_DOWNLOAD_OBJECT}")
if(EXTERNALCONTENT_DOWNLOAD_HASH)
file(${EXTERNALCONTENT_DOWNLOAD_HASH_TYPE} ${EXTERNALCONTENT_DOWNLOAD_OBJECT} EXTERNALCONTENT_DOWNLOAD_OBJECT_HASH)
if(NOT (EXTERNALCONTENT_DOWNLOAD_OBJECT_HASH STREQUAL EXTERNALCONTENT_DOWNLOAD_HASH_HASH)) # File hash differs.
set(EXTERNALCONTENT_FORCE_DOWNLOAD ON)
set(EXTERNALCONTENT_DIRTY ON)
endif()
endif()
else() # File is missing entirely.
set(EXTERNALCONTENT_DIRTY ON)
endif()
# Also consider things dirty if the source directory is missing.
if(NOT EXISTS ${EXTERNALCONTENT_SOURCE_PATH})
set(EXTERNALCONTENT_DIRTY ON)
endif()
if(EXTERNALCONTENT_DIRTY)
message(STATUS "[EC: ${EXTERNALCONTENT_NAME}] Downloading '${EXTERNALCONTENT_DOWNLOAD_FILE}' from '${EXTERNALCONTENT_DOWNLOAD_URL}'...")
if((NOT EXISTS "${EXTERNALCONTENT_DOWNLOAD_OBJECT}") OR EXTERNALCONTENT_FORCE_DOWNLOAD)
# Download the new file.
file(DOWNLOAD "${EXTERNALCONTENT_DOWNLOAD_URL}" "${EXTERNALCONTENT_DOWNLOAD_OBJECT}" SHOW_PROGRESS)
# Verify the hash matches.
if(EXTERNALCONTENT_DOWNLOAD_HASH)
file(${EXTERNALCONTENT_DOWNLOAD_HASH_TYPE} ${EXTERNALCONTENT_DOWNLOAD_OBJECT} EXTERNALCONTENT_DOWNLOAD_OBJECT_HASH)
if(NOT (EXTERNALCONTENT_DOWNLOAD_OBJECT_HASH STREQUAL EXTERNALCONTENT_DOWNLOAD_HASH_HASH)) # File hash differs.
file(REMOVE "${EXTERNALCONTENT_DOWNLOAD_OBJECT}")
message(FATAL_ERROR "[EC: ${EXTERNALCONTENT_NAME}] Downloaded file has hash '${EXTERNALCONTENT_DOWNLOAD_OBJECT_HASH}' but expected hash '${EXTERNALCONTENT_DOWNLOAD_HASH_HASH}'. Aborting.")
endif()
endif()
endif()
# Remove the previously extracted content.
if(EXISTS ${EXTERNALCONTENT_SOURCE_PATH})
file(REMOVE_RECURSE "${EXTERNALCONTENT_SOURCE_PATH}")
endif()
# Extract the whole thing.
file(ARCHIVE_EXTRACT
INPUT "${EXTERNALCONTENT_DOWNLOAD_OBJECT}"
DESTINATION "${EXTERNALCONTENT_SOURCE_PATH}"
VERBOSE
)
else()
message(STATUS "[EC: ${EXTERNALCONTENT_NAME}] Skipping download as nothing has changed.")
endif()
elseif(EXTERNALCONTENT_GIT_URL) # git: Clone or Checkout to the specific repository.
set(EXTERNALCONTENT_GIT_CLONE_ARGS
clone
${EXTERNALCONTENT_GIT_CLONE_OPTIONS}
-v
-b ${EXTERNALCONTENT_GIT_REF}
"${EXTERNALCONTENT_GIT_URL}"
"${EXTERNALCONTENT_SOURCE_PATH}"
)
set(EXTERNALCONTENT_GIT_CHECKOUT_ARGS
checkout
${EXTERNALCONTENT_GIT_CHECKOUT_OPTIONS}
-f
${EXTERNALCONTENT_GIT_REF}
)
# Hash the given options.
string(SHA3_512 EXTERNALCONTENT_GIT_CLONE_ARGS_HASH "${EXTERNALCONTENT_SOURCE_PATH} ${EXTERNALCONTENT_GIT_CLONE_ARGS}")
string(SHA3_512 EXTERNALCONTENT_GIT_CHECKOUT_ARGS_HASH "${EXTERNALCONTENT_SOURCE_PATH} ${EXTERNALCONTENT_GIT_CHECKOUT_ARGS}")
# Ensure that the commands still match up.
if(EXISTS "${EXTERNALCONTENT_TEMP_PATH}/git-clone.sha3")
file(READ "${EXTERNALCONTENT_TEMP_PATH}/git-clone.sha3" EXTERNALCONTENT_HASH_CMP)
if(NOT (EXTERNALCONTENT_HASH_CMP STREQUAL EXTERNALCONTENT_GIT_CLONE_ARGS_HASH))
message(STATUS "[EC: ${EXTERNALCONTENT_NAME}] Clone command changed, cloning again...")
set(EXTERNALCONTENT_FORCE_CLONE ON)
set(EXTERNALCONTENT_DIRTY ON)
endif()
else()
set(EXTERNALCONTENT_FORCE_CLONE ON)
set(EXTERNALCONTENT_DIRTY ON)
endif()
if(EXISTS "${EXTERNALCONTENT_TEMP_PATH}/git-checkout.sha3")
file(READ "${EXTERNALCONTENT_TEMP_PATH}/git-checkout.sha3" EXTERNALCONTENT_HASH_CMP)
if(NOT (EXTERNALCONTENT_HASH_CMP STREQUAL EXTERNALCONTENT_GIT_CHECKOUT_ARGS_HASH))
set(EXTERNALCONTENT_DIRTY ON)
endif()
else()
set(EXTERNALCONTENT_DIRTY ON)
endif()
# Delete the directory if the clone args are dirty or if the directory isn't a git repository
if((EXISTS "${EXTERNALCONTENT_SOURCE_PATH}") AND (EXTERNALCONTENT_FORCE_CLONE OR (NOT EXISTS "${EXTERNALCONTENT_SOURCE_PATH}/.git")))
file(REMOVE_RECURSE "${EXTERNALCONTENT_SOURCE_PATH}")
set(EXTERNALCONTENT_DIRTY ON)
endif()
if(NOT EXISTS "${EXTERNALCONTENT_SOURCE_PATH}")
# If the directory doesn't exist, we'll treat it as dirty and create it.
set(EXTERNALCONTENT_DIRTY ON)
file(MAKE_DIRECTORY "${EXTERNALCONTENT_SOURCE_PATH}")
endif()
#!TODO: Reduce complex git commands?
if(EXTERNALCONTENT_DIRTY)
# Do we need to clone or checkout?
if(NOT EXISTS "${EXTERNALCONTENT_SOURCE_PATH}/.git")
message(STATUS "[EC: ${EXTERNALCONTENT_NAME}] Cloning via git...")
execute_process(
COMMAND "${GIT_EXECUTABLE}" ${EXTERNALCONTENT_GIT_CLONE_ARGS}
WORKING_DIRECTORY "${EXTERNALCONTENT_SOURCE_PATH}"
COMMAND_ECHO STDOUT
)
else()
message(STATUS "[EC: ${EXTERNALCONTENT_NAME}] Checking out via git...")
execute_process(
COMMAND "${GIT_EXECUTABLE}" ${EXTERNALCONTENT_GIT_CHECKOUT_ARGS}
WORKING_DIRECTORY "${EXTERNALCONTENT_SOURCE_PATH}"
COMMAND_ECHO STDOUT
)
endif()
# Write the hash to the cache file.
file(WRITE "${EXTERNALCONTENT_TEMP_PATH}/git-clone.sha3" "${EXTERNALCONTENT_GIT_CLONE_ARGS_HASH}")
file(WRITE "${EXTERNALCONTENT_TEMP_PATH}/git-checkout.sha3" "${EXTERNALCONTENT_GIT_CHECKOUT_ARGS_HASH}")
else()
message(STATUS "[EC: ${EXTERNALCONTENT_NAME}] Skipping download as nothing has changed.")
endif()
else()
message(FATAL_ERROR "[EC: ${EXTERNALCONTENT_NAME}] Unknown download type but SKIP_DOWNLOAD is not set.")
endif()
endif()
# Patch
if(NOT EXTERNALCONTENT_SKIP_PATCH)
if(EXTERNALCONTENT_PATCH_FUNCTION)
cmake_language(EVAL CODE "${EXTERNALCONTENT_PATCH_FUNCTION}(\"${EC_TEMP_PATH}\" \"${EXTERNALCONTENT_SOURCE_PATH}\" \"${EXTERNALCONTENT_BINARY_PATH}\" \"${EXTERNALCONTENT_INSTALL_PATH}\")")
endif()
endif()
# Configure
if(NOT EXTERNALCONTENT_SKIP_CONFIGURE)
if(EXTERNALCONTENT_CONFIGURE_FUNCTION)
cmake_language(EVAL CODE "${EXTERNALCONTENT_CONFIGURE_FUNCTION}(\"${EC_TEMP_PATH}\" \"${EXTERNALCONTENT_SOURCE_PATH}\" \"${EXTERNALCONTENT_BINARY_PATH}\" \"${EXTERNALCONTENT_INSTALL_PATH}\")")
elseif(EXISTS "${EXTERNALCONTENT_SOURCE_PATH}/${EXTERNALCONTENT_BUILDSYSTEM_SUFFIX}CMakeLists.txt")
# This is a CMake project.
set(EXTERNALCONTENT_CONFIGURE_ARGS
-S "${EXTERNALCONTENT_SOURCE_PATH}/${EXTERNALCONTENT_BUILDSYSTEM_SUFFIX}"
-B "${EXTERNALCONTENT_BINARY_PATH}"
-Wno-dev
--no-warn-unused-cli
--install-prefix "${EXTERNALCONTENT_INSTALL_PATH}"
${EXTERNALCONTENT_CONFIGURE_ARGS}
)
# Hash the given options.
string(SHA3_512 EXTERNALCONTENT_CONFIGURE_ARGS_HASH "${EC_TEMP_PATH} ${EXTERNALCONTENT_CONFIGURE_ARGS}")
# Ensure we don't spawn useless sub-processes all the time.
if(EXISTS "${EXTERNALCONTENT_BINARY_PATH}/CMakeCache.txt")
if(EXISTS "${EXTERNALCONTENT_TEMP_PATH}/configure.sha3")
file(READ "${EXTERNALCONTENT_TEMP_PATH}/configure.sha3" EXTERNALCONTENT_HASH_CMP)
if(NOT (EXTERNALCONTENT_HASH_CMP STREQUAL EXTERNALCONTENT_CONFIGURE_ARGS_HASH))
set(EXTERNALCONTENT_DIRTY ON)
endif()
else()
set(EXTERNALCONTENT_DIRTY ON)
endif()
else()
set(EXTERNALCONTENT_DIRTY ON)
endif()
# Configure & Generate
if(EXTERNALCONTENT_DIRTY)
execute_process(
COMMAND "cmake" ${EXTERNALCONTENT_CONFIGURE_ARGS}
WORKING_DIRECTORY "${EXTERNALCONTENT_SOURCE_PATH}/${EXTERNALCONTENT_BUILDSYSTEM_SUFFIX}"
COMMAND_ECHO STDOUT
)
# Write the hash to the cache file.
file(WRITE "${EXTERNALCONTENT_TEMP_PATH}/configure.sha3" "${EXTERNALCONTENT_CONFIGURE_ARGS_HASH}")
else()
message(STATUS "[EC: ${EXTERNALCONTENT_NAME}] Skipping configure as nothing has changed.")
endif()
elseif(EXISTS "${EXTERNALCONTENT_SOURCE_PATH}/${EXTERNALCONTENT_BUILDSYSTEM_SUFFIX}meson.build")
# This is a meson project.
set(EXTERNALCONTENT_CONFIGURE_ARGS
setup build
--prefix "${EXTERNALCONTENT_INSTALL_PATH}"
${EXTERNALCONTENT_CONFIGURE_ARGS}
)
# Hash the given options.
string(SHA3_512 EXTERNALCONTENT_CONFIGURE_ARGS_HASH "${EC_TEMP_PATH} ${EXTERNALCONTENT_CONFIGURE_ARGS}")
# Test if there were any changes only if we're not already in a dirty state.
if(NOT EXTERNALCONTENT_DIRTY)
# Ensure we don't spawn useless sub-processes all the time.
if(EXISTS "${EXTERNALCONTENT_BINARY_PATH}/CMakeCache.txt")
if(EXISTS "${EXTERNALCONTENT_TEMP_PATH}/configure.sha3")
file(READ "${EXTERNALCONTENT_TEMP_PATH}/configure.sha3" EXTERNALCONTENT_HASH_CMP)
if(NOT (EXTERNALCONTENT_HASH_CMP STREQUAL EXTERNALCONTENT_CONFIGURE_ARGS_HASH))
set(EXTERNALCONTENT_DIRTY ON)
endif()
else()
set(EXTERNALCONTENT_DIRTY ON)
endif()
else()
set(EXTERNALCONTENT_DIRTY ON)
endif()
endif()
# Configure & Generate
if(EXTERNALCONTENT_DIRTY)
execute_process(
COMMAND "meson" ${EXTERNALCONTENT_CONFIGURE_ARGS}
WORKING_DIRECTORY "${EXTERNALCONTENT_SOURCE_PATH}/${EXTERNALCONTENT_BUILDSYSTEM_SUFFIX}"
COMMAND_ECHO STDOUT
)
# Write the hash to the cache file.
file(WRITE "${EXTERNALCONTENT_TEMP_PATH}/configure.sha3" "${EXTERNALCONTENT_CONFIGURE_ARGS_HASH}")
else()
message(STATUS "[EC: ${EXTERNALCONTENT_NAME}] Skipping configure as nothing has changed.")
endif()
else()
message(FATAL_ERROR "[EC: ${EXTERNALCONTENT_NAME}] We don't know how to handle this build system yet. Consider using CONFIGURE_FUNCTION or SKIP_CONFIGURE.")
endif()
endif()
# Build
if(NOT EXTERNALCONTENT_SKIP_BUILD)
if(EXTERNALCONTENT_BUILD_FUNCTION)
cmake_language(EVAL CODE "${EXTERNALCONTENT_BUILD_FUNCTION}(\"${EC_TEMP_PATH}\" \"${EXTERNALCONTENT_SOURCE_PATH}\" \"${EXTERNALCONTENT_BINARY_PATH}\" \"${EXTERNALCONTENT_INSTALL_PATH}\")")
elseif(EXISTS "${EXTERNALCONTENT_SOURCE_PATH}/CMakeLists.txt")
# This is a CMake project.
set(EXTERNALCONTENT_BUILD_ARGS
"--build" "${EXTERNALCONTENT_BINARY_PATH}"
${EXTERNALCONTENT_BUILD_ARGS}
)
# Hash the given options.
string(SHA3_512 EXTERNALCONTENT_BUILD_ARGS_HASH "${EC_TEMP_PATH} ${EXTERNALCONTENT_SOURCE_PATH} ${EXTERNALCONTENT_BINARY_PATH} ${EXTERNALCONTENT_INSTALL_PATH} ${EXTERNALCONTENT_BUILD_ARGS}")
# Test if there were any changes only if we're not already in a dirty state.
if(NOT EXTERNALCONTENT_DIRTY)
# Ensure we don't spawn useless sub-processes all the time.
if(EXISTS "${EXTERNALCONTENT_TEMP_PATH}/build.sha3")
file(READ "${EXTERNALCONTENT_TEMP_PATH}/build.sha3" EXTERNALCONTENT_HASH_CMP)
if(NOT (EXTERNALCONTENT_HASH_CMP STREQUAL EXTERNALCONTENT_BUILD_ARGS_HASH))
set(EXTERNALCONTENT_DIRTY ON)
endif()
else()
set(EXTERNALCONTENT_DIRTY ON)
endif()
endif()
# Build
if(EXTERNALCONTENT_DIRTY)
execute_process(
COMMAND "cmake" ${EXTERNALCONTENT_BUILD_ARGS}
WORKING_DIRECTORY "${EXTERNALCONTENT_BINARY_PATH}"
COMMAND_ECHO STDOUT
)
# Write the hash to the cache file.
file(WRITE "${EXTERNALCONTENT_TEMP_PATH}/build.sha3" "${EXTERNALCONTENT_BUILD_ARGS_HASH}")
else()
message(STATUS "[EC: ${EXTERNALCONTENT_NAME}] Skipping build as nothing has changed.")
endif()
elseif(EXISTS "${EXTERNALCONTENT_SOURCE_PATH}/${EXTERNALCONTENT_BUILDSYSTEM_SUFFIX}meson.build")
# This is a meson project.
set(EXTERNALCONTENT_BUILD_ARGS
"--build" "${EXTERNALCONTENT_BINARY_PATH}"
${EXTERNALCONTENT_BUILD_ARGS}
)
# Hash the given options.
string(SHA3_512 EXTERNALCONTENT_BUILD_ARGS_HASH "${EC_TEMP_PATH} ${EXTERNALCONTENT_SOURCE_PATH} ${EXTERNALCONTENT_BINARY_PATH} ${EXTERNALCONTENT_INSTALL_PATH} ${EXTERNALCONTENT_BUILD_ARGS}")
# Test if there were any changes only if we're not already in a dirty state.
if(NOT EXTERNALCONTENT_DIRTY)
# Ensure we don't spawn useless sub-processes all the time.
if(EXISTS "${EXTERNALCONTENT_TEMP_PATH}/build.sha3")
file(READ "${EXTERNALCONTENT_TEMP_PATH}/build.sha3" EXTERNALCONTENT_HASH_CMP)
if(NOT (EXTERNALCONTENT_HASH_CMP STREQUAL EXTERNALCONTENT_BUILD_ARGS_HASH))
set(EXTERNALCONTENT_DIRTY ON)
endif()
else()
set(EXTERNALCONTENT_DIRTY ON)
endif()
endif()
# Build
if(EXTERNALCONTENT_DIRTY)
execute_process(
COMMAND "meson" ${EXTERNALCONTENT_BUILD_ARGS}
WORKING_DIRECTORY "${EXTERNALCONTENT_BINARY_PATH}"
COMMAND_ECHO STDOUT
)
# Write the hash to the cache file.
file(WRITE "${EXTERNALCONTENT_TEMP_PATH}/build.sha3" "${EXTERNALCONTENT_BUILD_ARGS_HASH}")
else()
message(STATUS "[EC: ${EXTERNALCONTENT_NAME}] Skipping build as nothing has changed.")
endif()
else()
message(FATAL_ERROR "[EC: ${EXTERNALCONTENT_NAME}] We don't know how to handle this build system yet. Consider using BUILD_FUNCTION or SKIP_BUILD.")
endif()
endif()
# Install
if(NOT EXTERNALCONTENT_SKIP_INSTALL)
if(EXTERNALCONTENT_INSTALL_FUNCTION)
cmake_language(EVAL CODE "${EXTERNALCONTENT_INSTALL_FUNCTION}(\"${EC_TEMP_PATH}\" \"${EXTERNALCONTENT_SOURCE_PATH}\" \"${EXTERNALCONTENT_BINARY_PATH}\" \"${EXTERNALCONTENT_INSTALL_PATH}\")")
elseif(EXISTS "${EXTERNALCONTENT_SOURCE_PATH}/CMakeLists.txt")
# This is a CMake project.
set(EXTERNALCONTENT_CMAKE_ARGS
--install "${EXTERNALCONTENT_BINARY_PATH}"
--prefix "${EXTERNALCONTENT_INSTALL_PATH}"
${EXTERNALCONTENT_INSTALL_ARGS}
)
# Hash the given options.
string(SHA3_512 EXTERNALCONTENT_INSTALL_ARGS_HASH "${EC_TEMP_PATH} ${EXTERNALCONTENT_SOURCE_PATH} ${EXTERNALCONTENT_BINARY_PATH} ${EXTERNALCONTENT_INSTALL_PATH} ${EXTERNALCONTENT_CMAKE_ARGS}")
# Test if there were any changes only if we're not already in a dirty state.
if(NOT EXTERNALCONTENT_DIRTY)
# Ensure we don't spawn useless sub-processes all the time.
if(EXISTS "${EXTERNALCONTENT_TEMP_PATH}/install.sha3")
file(READ "${EXTERNALCONTENT_TEMP_PATH}/install.sha3" EXTERNALCONTENT_HASH_CMP)
if(NOT (EXTERNALCONTENT_HASH_CMP STREQUAL EXTERNALCONTENT_INSTALL_ARGS_HASH))
set(EXTERNALCONTENT_DIRTY ON)
endif()
else()
set(EXTERNALCONTENT_DIRTY ON)
endif()
# Ensure that we actually have the files installed too.
if(NOT EXISTS "${EXTERNALCONTENT_INSTALL_PATH}")
set(EXTERNALCONTENT_DIRTY ON)
endif()
endif()
# Install
if(EXTERNALCONTENT_DIRTY)
execute_process(
COMMAND "cmake" ${EXTERNALCONTENT_CMAKE_ARGS}
WORKING_DIRECTORY "${EXTERNALCONTENT_BINARY_PATH}"
COMMAND_ECHO STDOUT
)
# Write the hash to the cache file.
file(WRITE "${EXTERNALCONTENT_TEMP_PATH}/install.sha3" "${EXTERNALCONTENT_INSTALL_ARGS_HASH}")
else()
message(STATUS "[EC: ${EXTERNALCONTENT_NAME}] Skipping install as nothing has changed.")
endif()
else()
message(FATAL_ERROR "[EC: ${EXTERNALCONTENT_NAME}] We don't know how to handle this install system yet. Consider using INSTALL_FUNCTION or SKIP_INSTALL.")
endif()
endif()
endfunction()
-11
View File
@@ -1,11 +0,0 @@
Copyright 2026 Narta Xaymar Dirks <info@xaymar.com>
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-18
View File
@@ -1,18 +0,0 @@
# ExternalContent (for CMake)
Download, Configure, Build and Install external content all without polluting the global cache! ExternalContent tries to ensure full separation of the build environments unlike FetchContent and ExternalProject. You won't ever have to worry about a subproject not being made to CMakes wishful specification - which aren't even well defined anyway.
## [Documentation](https://xaymar.github.io/cmake-externalproject/)
The documentation is generated by Sphinx with the `Read the Docs` theme and is available at [xaymar.github.io/cmake-externalproject/](https://xaymar.github.io/cmake-externalproject/).
## License
> Copyright 2026 Narta Xaymar Dirks <info@xaymar.com>
>
> Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
>
> 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
>
> 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
>
> 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
>
> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-56
View File
@@ -1,56 +0,0 @@
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
# -- Project information -----------------------------------------------------
project = 'version'
copyright = "2026, Narta Xaymar Dirks"
author = "Narta Xaymar Dirks"
version = "1.0.0"
release = "1.0.0"
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = [
"Thumbs.db"
".DS_Store"
]
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = []
-344
View File
@@ -1,344 +0,0 @@
===============
ExternalContent
===============
Download, Configure, Build and Install external content all without polluting the global cache! ExternalContent tries to ensure full separation of the build environments unlike FetchContent and ExternalProject. You won't ever have to worry about a subproject not being made to CMakes wishful specification - which aren't even well defined anyway.
--------
Synopsis
--------
.. parsed-literal::
ExternalContent(
`NAME`_ <name>
[`TEMP_PATH`_ <path>]
[`SOURCE_PATH`_ <path>]
[`BINARY_PATH`_ <path>]
[`INSTALL_PATH`_ <path>]
[`SKIP_DOWNLOAD`_
|
[`DOWNLOAD_URL`_ <url>
[`DOWNLOAD_FILE`_ <filename.extension>]
[`DOWNLOAD_HASH`_ <type>:<hash>]
]
|
[ `GIT_URL` <url>
[`GIT_REF` <ref>]
[`GIT_CLONE_OPTIONS`_ <option> [<option> [...]]]
[`GIT_CHECKOUT_OPTIONS`_ <option> [<option> [...]]]
]
]
[`SKIP_CONFIGURE`_ |
[ `CONFIGURE_FUNCTION`_ <function-name>] |
[ `CONFIGURE_ARGS`_ <option> [<option> [...]]]
]
[`SKIP_BUILD`_ |
[ `BUILD_FUNCTION`_ <function-name>] |
[ `BUILD_ARGS`_ <option> [<option> [...]]]
]
[`SKIP_INSTALL`_ |
[ `INSTALL_FUNCTION`_ <function-name>] |
[ `INSTALL_ARGS`_ <option> [<option> [...]]]
]
)
-----
Usage
-----
General Options
===============
.. _NAME:
NAME
-----------
.. code-block:: cmake
ExternalContent(... NAME "<name>" ...)
The unique identifier for this external content which must be a valid directory name and also a valid target name. Will also be used to store some output variables.
Paths
=====
.. _TEMP_PATH:
TEMP_PATH
---------
.. code-block:: cmake
ExternalContent(... TEMP_PATH "<path>" ...)
Optional. Specifies where we should store any temporary files for this external content. It's recommended to leave this be.
.. _SOURCE_PATH:
SOURCE_PATH:
------------
.. code-block:: cmake
ExternalContent(... SOURCE_PATH "<path>" ...)
Optional. Specifies where the source should be extracted to. Can be used with `SKIP_DOWNLOAD`_ to specify existing code as external content.
.. _BINARY_PATH:
BINARY_PATH:
------------
.. code-block:: cmake
ExternalContent(... BINARY_PATH "<path>" ...)
Optional. Specifies where the build files should be located.
.. _INSTALL_PATH:
INSTALL_PATH:
-------------
.. code-block:: cmake
ExternalContent(... INSTALL_PATH "<path>" ...)
Optional. Specifies where the external content should be installed to.
Downloads
=========
.. _SKIP_DOWNLOAD:
SKIP_DOWNLOAD
#############
.. code-block:: cmake
ExternalContent(... SKIP_DOWNLOAD ...)
Optional. When set skips downloading entirely. Allows using existing code as external content if used with `SOURCE_PATH`_.
From File
---------
.. _DOWNLOAD_URL:
DOWNLOAD_URL
############
.. code-block:: cmake
ExternalContent(... DOWNLOAD_URL <url> ...)
Optional.
.. _DOWNLOAD_FILE:
DOWNLOAD_FILE
#############
.. code-block:: cmake
ExternalContent(... DOWNLOAD_FILE <filename.extension> ...)
Required if `DOWNLOAD_URL`_ does not contain a proper filename with a recognizable extension.
.. _DOWNLOAD_HASH:
DOWNLOAD_HASH
#############
.. code-block:: cmake
ExternalContent(... DOWNLOAD_HASH <type>;<hash> ...)
Optional. Verifies the downloaded file against the given hash after downloading to ensure that nothing has gone wrong. The type can be any of the ones supported by `file(HASH ...) <https://cmake.org/cmake/help/latest/command/file.html#hash>`__
From Git Repository
-------------------
.. _GIT_URL:
GIT_URL
#######
.. code-block:: cmake
ExternalContent(... GIT_URL <url> ...)
Optional. Downloads the source code from a given git repository url.
.. _GIT_REF:
GIT_REF
#######
.. code-block:: cmake
ExternalContent(... GIT_REF <ref> ...)
Required if `GIT_URL`_ is provided. Must be either a branch, tag, or commit hash.
.. _GIT_CLONE_OPTIONS:
GIT_CLONE_OPTIONS
#################
.. code-block:: cmake
ExternalContent(... GIT_CLONE_OPTIONS <option> [<option> [...]] ...)
Optional. One or more options that are passed through to git-clone.
.. _GIT_CHECKOUT_OPTIONS:
GIT_CHECKOUT_OPTIONS
####################
.. code-block:: cmake
ExternalContent(... GIT_CHECKOUT_OPTIONS <option> [<option> [...]] ...)
Optional. One or more options that are passed through to git-checkout.
Configuring
===========
.. _SKIP_CONFIGURE:
SKIP_CONFIGURE:
---------------
.. code-block:: cmake
ExternalContent(... SKIP_CONFIGURE ...)
Optional. Skips the entire configure section.
.. _CONFIGURE_FUNCTION:
CONFIGURE_FUNCTION:
-------------------
.. code-block:: cmake
ExternalContent(... CONFIGURE_FUNCTION <function-name> ...)
Optional. Specify a custom function to be used to configure this external content instead of the default handler. The function is expected to have the following signature:
.. code-block:: cmake
function(my_custom_configure_function TEMP_PATH SOURCE_PATH BINARY_PATH INSTALL_PATH)
# Remember to FATAL_ERROR on all errors.
endfunction()
.. _CONFIGURE_ARGS:
CONFIGURE_ARGS:
---------------
.. code-block:: cmake
ExternalContent(... CONFIGURE_ARGS <option> [<option> [...]] ...)
Optional. Arguments to pass to the default configure handler. Can be specified multiple times or have several options chained after another.
Building
========
.. _SKIP_BUILD:
SKIP_BUILD:
-----------
.. code-block:: cmake
ExternalContent(... SKIP_BUILD ...)
Optional. Skips the entire build section.
.. _BUILD_FUNCTION:
BUILD_FUNCTION:
---------------
.. code-block:: cmake
ExternalContent(... BUILD_FUNCTION <function-name> ...)
Optional. Specify a custom function to be used to build this external content instead of the default handler. The function is expected to have the following signature:
.. code-block:: cmake
function(my_custom_build_function TEMP_PATH SOURCE_PATH BINARY_PATH INSTALL_PATH)
# Remember to FATAL_ERROR on all errors.
endfunction()
.. _BUILD_ARGS:
BUILD_ARGS:
-----------
.. code-block:: cmake
ExternalContent(... BUILD_ARGS <option> [<option> [...]] ...)
Optional. Arguments to pass to the default build handler. Can be specified multiple times or have several options chained after another.
Installing
==========
.. _SKIP_INSTALL:
SKIP_INSTALL:
-------------
.. code-block:: cmake
ExternalContent(... SKIP_INSTALL ...)
Optional. Skips the entire install section.
.. _INSTALL_FUNCTION:
INSTALL_FUNCTION:
-----------------
.. code-block:: cmake
ExternalContent(... INSTALL_FUNCTION <function-name> ...)
Optional. Specify a custom function to be used to install this external content instead of the default handler. The function is expected to have the following signature:
.. code-block:: cmake
function(my_custom_install_function TEMP_PATH SOURCE_PATH BINARY_PATH INSTALL_PATH)
# Remember to FATAL_ERROR on all errors.
endfunction()
.. _INSTALL_ARGS:
INSTALL_ARGS:
-------------
.. code-block:: cmake
ExternalContent(... INSTALL_ARGS <option> [<option> [...]] ...)
Optional. Arguments to pass to the default install handler. Can be specified multiple times or have several options chained after another.
-------
Exports
-------
<name>_SOURCE_PATH
<name>_BINARY_PATH
<name>_INSTALL_PATH
@@ -1,20 +0,0 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = ../docs
BUILDDIR = ../build/docs
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
@@ -1,35 +0,0 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=../docs
set BUILDDIR=../build/docs
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.https://www.sphinx-doc.org/
exit /b 1
)
if "%1" == "" goto help
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd
@@ -1,10 +0,0 @@
{
"folders": [
{
"path": "."
}
],
"settings": {
"editor.tabSize": 4
}
}
@@ -1,27 +0,0 @@
From 344c9b970ecf8e66c3e89f5c4a4d2b9106b5486e Mon Sep 17 00:00:00 2001
From: Xaymar <info@xaymar.com>
Date: Sun, 18 Jan 2026 03:53:06 +0100
Subject: [PATCH] Use actual nlohmann/json.hpp include
---
include/json.hpp | 24765 ----------------------------------------
include/jsonrpcpp.hpp | 2 +-
1 files changed, 1 insertion(+), 1 deletions(-)
delete mode 100644 include/json.hpp
diff --git a/include/jsonrpcpp.hpp b/include/jsonrpcpp.hpp
index 1cea0ac..236850c 100644
--- a/include/jsonrpcpp.hpp
+++ b/include/jsonrpcpp.hpp
@@ -23,7 +23,7 @@
#define JSON_RPC_HPP
// nlohmann-json
-#include <json.hpp>
+#include <nlohmann/json.hpp>
// standard headers
#include <cstring>
--
2.48.1.windows.1
-100
View File
@@ -1,100 +0,0 @@
# Copyright 2025-2026 Narta Xaymar Dirks <info@xaymar.com>
#
# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# Require the latest CMake version.
cmake_minimum_required(VERSION 4.2.1)
project("room")
#--------------------------------------------------------------------------------#
# Project
#--------------------------------------------------------------------------------#
file(GLOB_RECURSE _INCLUDE FOLLOW_SYMLINKS CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/pub/*")
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}/pub" PREFIX "Public" FILES ${_INCLUDE})
file(GLOB_RECURSE _SOURCE FOLLOW_SYMLINKS CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/priv/*")
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}/priv" PREFIX "Private" FILES ${_SOURCE})
add_executable(${PROJECT_NAME} MACOSX_BUNDLE)
set_target_properties(${PROJECT_NAME} PROPERTIES
# Always generate position independent code.
POSITION_INDEPENDENT_CODE ON
# Set C++ Standard and Extensions
C_STANDARD 17
C_STANDARD_REQUIRED ON
CXX_STANDARD 20
CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS OFF
# Remove prefix from generated files.
PREFIX ""
IMPORT_PREFIX ""
# Never treat warnings as errors.
COMPILE_WARNING_AS_ERROR OFF
)
target_sources(${PROJECT_NAME}
PRIVATE
${_SOURCE}
PUBLIC
${_INCLUDE}
)
target_include_directories(${PROJECT_NAME}
PRIVATE "priv"
PUBLIC "pub"
# Very dumb fix to get wolfSSL to play nice. Why is it extracting the openssl stuff into a subdirectory?
PRIVATE $<TARGET_PROPERTY:wolfssl::wolfssl,INTERFACE_INCLUDE_DIRECTORIES>/wolfssl
PRIVATE $<TARGET_PROPERTY:wolfssl::wolfssl,INTERFACE_INCLUDE_DIRECTORIES>
)
target_link_libraries(${PROJECT_NAME}
PRIVATE wolfssl::wolfssl
PRIVATE asio::asio
PRIVATE websocketpp::websocketpp
PRIVATE zlib-ng::zlib
PRIVATE nlohmann_json::nlohmann_json
PRIVATE badaix::jsonrpcpp
)
target_compile_definitions(${PROJECT_NAME}
PRIVATE _WEBSOCKETPP_CPP11_STL_
)
if(ENABLE_SSL AND wolfssl_FOUND)
target_compile_definitions(${PROJECT_NAME}
PRIVATE ARCHIPELAGO_ENABLE_SSL
)
endif()
if(ENABLE_COMPRESSION AND zlib-ng_FOUND)
target_compile_definitions(${PROJECT_NAME}
PRIVATE ARCHIPELAGO_ENABLE_COMPRESSION
)
endif()
if(WIN32)
# Disable/Enable a ton of things.
target_compile_definitions(${PROJECT_NAME} PRIVATE
# Microsoft Visual C++:
#- No secure CRT warnings.
PRIVATE _CRT_SECURE_NO_WARNINGS
#- Properly align objects when std::align is used.
PRIVATE _ENABLE_EXTENDED_ALIGNED_STORAGE
# Target Windows 10 (adjust later?).
PRIVATE _WIN32_WINNT=0x0A00
)
endif()
-35
View File
@@ -1,35 +0,0 @@
# Archipelago - Room Server
The room server is meant to handle the direct user workload from Archipelago clients for each room.
## Design
There are some things we need to keep in mind for the server design:
### Performance
The only limiting factor for hosting should be the servers hardware and not our programming or chosen language. Try to minimize overhead as much as possible for every component.
### Scalability
Only run the rooms themselves instead of the whole website, api, management, etc all in one service. This allows using less expensive hardware for the room servers such as virtual servers and similar.
## Protocols
The room server implements the client protocol for the management server and the server protocol for the room server(s).
### Management (Client)
See the `Archipelago - Manager Server` project for the protocol information.
### Room (Server)
At the current time the following protocols are to be supported:
#### Official Protocol
The server currently implements the official protocol ([documented here on the official repository](https://github.com/ArchipelagoMW/Archipelago/blob/main/docs/network%20protocol.md)). This can be implemented in one of two ways:
##### 1. Individual Room Servers
This is the way the official server currently does it: Each room gets its own WebSocket server and the associated overhead. This has some drawbacks:
- The number of rooms is hard limited to 65535 per IPv4 and IPv6 address assigned to the machine.
- Opening many has some not insignificant user-space and kernel-space overhead attached to it.
- Port scanning allows people to see which rooms are running, if any.
For obvious reasons, we do not want to implement this.
##### 2. Single Overall Room Server
We can use the password field to uniquely identify which room a user actually wants to work with. This allows us to remove all the drawbacks in exchange for additional workload required to ensure that we don't stall all rooms.
-27
View File
@@ -1,27 +0,0 @@
/** Copyright 2025-2026 Narta Xaymar Dirks <info@xaymar.com>
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**/
#include <filesystem>
#include <string>
#include "manager.hpp"
#include <windows.h>
int main(int _argc, char** _argv)
{
// Launch the manager part of the app.
apsr::manager manager{};
return manager.run(_argc, _argv);
}
-46
View File
@@ -1,46 +0,0 @@
/** Copyright 2025-2026 Narta Xaymar Dirks <info@xaymar.com>
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**/
#include "manager.hpp"
#include <iostream>
const std::string_view default_config =
R"({
"client-options": {
/** What should we identify as?
*
* Available variables (via ${}):
* - version: Current version of the server.
*/
"user-agent": "Archipelago Room Server v${version}"
}
})";
apsr::manager::~manager()
{
}
apsr::manager::manager()
{
_client.set_user_agent("Archipelago Room Server");
}
int32_t apsr::manager::run(int argc, char** argv)
{
// Spawn threads to handle all ASIO workload.
//!TODO: Make this a command line or environment option.
std::cout << "Hello World!" << std::endl;
return 0;
}
-39
View File
@@ -1,39 +0,0 @@
/** Copyright 2025-2026 Narta Xaymar Dirks <info@xaymar.com>
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**/
#include <cinttypes>
#include <list>
#include <thread>
// JSON and JSON-RPC 2.0
#include <nlohmann/json.hpp>
#include <jsonrpcpp.hpp>
// WebSocket Client
#include <websocketpp/config/asio_no_tls_client.hpp>
#include <websocketpp/client.hpp>
namespace apsr {
class manager {
std::string _host_url;
websocketpp::client<websocketpp::config::asio_client> _client;
public:
~manager();
manager();
public:
int32_t run(int argc, char** argv);
};
} // namespace apsr
-13
View File
@@ -1,13 +0,0 @@
/** Copyright 2025-2026 Narta Xaymar Dirks <info@xaymar.com>
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**/
m
-14
View File
@@ -1,14 +0,0 @@
/** Copyright 2025-2026 Narta Xaymar Dirks <info@xaymar.com>
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**/
#include "room.hpp"
-20
View File
@@ -1,20 +0,0 @@
/** Copyright 2025-2026 Narta Xaymar Dirks <info@xaymar.com>
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**/
namespace archipelago {
/** Room Information
*/
class room {
};
}
-14
View File
@@ -1,14 +0,0 @@
/** Copyright 2025-2026 Narta Xaymar Dirks <info@xaymar.com>
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**/
#include "server.hpp"
-43
View File
@@ -1,43 +0,0 @@
/** Copyright 2025-2026 Narta Xaymar Dirks <info@xaymar.com>
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**/
// SSL
#ifdef ARCHIPELAGO_ENABLE_SSL
#include <websocketpp/config/asio.hpp>
#else
#include <websocketpp/config/asio_no_tls.hpp>
#endif
// WebSocket
#include <websocketpp/server.hpp>
// JSON and JSON-RPC 2.0
#include <nlohmann/json.hpp>
#include <jsonrpcpp.hpp>
namespace archipelago {
class server {
#ifdef ARCHIPELAGO_ENABLE_SSL
websocketpp::server<websocketpp::config::asio_tls> _ws_server;
#else
websocketpp::server<websocketpp::config::asio> _ws_server;
#endif
public:
~server();
server();
};
} // namespace archipelago