Just move some things for now
This commit is contained in:
@@ -5,6 +5,7 @@ Peninsula is an alternative server implementation for the popular Multi World Ra
|
|||||||
- Store everything in databases or files accessible from all servers hosting peninsula.
|
- 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.
|
- 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.
|
- PHP based which is available on a wide range of web hosting offers.
|
||||||
|
- Provide a passive Poll-style API which requires clients to regularly request information.
|
||||||
|
|
||||||
### Pros
|
### Pros
|
||||||
- Significantly bigger lobbies (sync and async) through distributed processing.
|
- Significantly bigger lobbies (sync and async) through distributed processing.
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
# Peninsula - Backend
|
||||||
|
The backend provides all necessary API endpoints to guarantee that the frontend does not require any server-side dynamic content generation. This should ensure that hosting the frontend is much cheaper than hosting the backend, likely requiring far less servers to handle. This backend is based on the lightweight CodeIgniter framework to simplify how much work is required for the implementation.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
We require some PHP modules for proper operation:
|
||||||
|
|
||||||
|
- json (enabled by default - don't turn it off)
|
||||||
|
- [intl](http://www.php.net/manual/en/intl.requirements.php)
|
||||||
|
- [mbstring](http://www.php.net/manual/en/mbstring.installation.php)
|
||||||
|
|
||||||
|
And depending on your Database of choice, one of:
|
||||||
|
|
||||||
|
- [mysqlnd](http://www.php.net/manual/en/mysqlnd.install.php) (MySQL, MariaDB)
|
||||||
|
- [pgsql](https://www.php.net/manual/en/pgsql.installation.php) (PostgreSQL)
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
### Released Build
|
||||||
|
1. Download the backend package from [the provided release packages](https://github.com/xaymar/peninsula/releases/).
|
||||||
|
2. Extract it on your server.
|
||||||
|
3. Perform the [Configuration](#Configuration) step.
|
||||||
|
4. Set the web root to be the `public/` directory.
|
||||||
|
5. Set up rewrites or try_files to rewrite any non-existing request to `/index.php`.
|
||||||
|
6. Enjoy.
|
||||||
|
|
||||||
|
### Local Build
|
||||||
|
1. Make a fresh clone of this repository, or run `git clean -fqX`.
|
||||||
|
2. Run `composer install --no-dev`.
|
||||||
|
3. Copy the contents of this directory to the machine that is supposed to host the backend.
|
||||||
|
4. Set up your webserver to have a virtual host with a root directory pointing at `public/`.
|
||||||
|
5. Ensure that all requests that don't match an exact file are forwarded to `index.php`.
|
||||||
|
6. Enjoy.
|
||||||
|
|
||||||
|
### Example Server Configurations
|
||||||
|
These examples are provided without warranty or guarantee of functionality. They're references to look at and configure your own server with.
|
||||||
|
|
||||||
|
#### nginx
|
||||||
|
```
|
||||||
|
server {
|
||||||
|
# The hostname under which we can find this server.
|
||||||
|
server_name "backend.peninsula.example.com";
|
||||||
|
|
||||||
|
# Listen for both HTTP and HTTPS.
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
listen 443 ssl;
|
||||||
|
listen [::]:443 ssl;
|
||||||
|
|
||||||
|
# Enable HTTP2 and QUIC (HTTP3).
|
||||||
|
http2 on;
|
||||||
|
quic_gso on;
|
||||||
|
|
||||||
|
# Set up the necessary SSL certificates for HTTPS.
|
||||||
|
ssl_certificate "/etc/certs/snakeoil.pub";
|
||||||
|
ssl_certificate "/etc/certs/snakeoil.priv";
|
||||||
|
|
||||||
|
# Set the root to the proper directory.
|
||||||
|
root "/var/www/peninsula/backend/public/";
|
||||||
|
|
||||||
|
# Try a few paths before handing it off to the framework.
|
||||||
|
try_files $uri $uri/ /index.php?$request_uri;
|
||||||
|
|
||||||
|
# Disallow access to all files starting with a '.', except for localhost.
|
||||||
|
location ~ /\. {
|
||||||
|
allow 127.0.0.1;
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Turn off logging for common files.
|
||||||
|
location = /favicon.ico {
|
||||||
|
access_log off;
|
||||||
|
log_not_found off;
|
||||||
|
error_log off;
|
||||||
|
}
|
||||||
|
location = /robots.txt {
|
||||||
|
access_log off;
|
||||||
|
log_not_found off;
|
||||||
|
error_log off;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Handle PHP Files
|
||||||
|
location ~* [^/]\.php(|/.*)(|\?.*)$ {
|
||||||
|
include "fastcgi.conf";
|
||||||
|
fastcgi_index index.php;
|
||||||
|
fastcgi_split_path_info ^(.+\.php)(|/.*)$;
|
||||||
|
fastcgi_param PATH_INFO $fastcgi_path_info;
|
||||||
|
|
||||||
|
# Always try the PHP files
|
||||||
|
try_files $fastcgi_script_name?$request_uri $fastcgi_script_name =404;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
# 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
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "cmake/externalcontent"]
|
||||||
|
path = cmake/externalcontent
|
||||||
|
url = https://github.com/Xaymar/cmake-externalcontent.git
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
# 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
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
blank_issues_enabled: false
|
||||||
|
contact_links:
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
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?"
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
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."
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
### 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. -->
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
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
|
||||||
|
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
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
|
||||||
|
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
build
|
||||||
|
.venv
|
||||||
@@ -0,0 +1,706 @@
|
|||||||
|
# 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()
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
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.
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# 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.
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
# 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 = []
|
||||||
@@ -0,0 +1,344 @@
|
|||||||
|
===============
|
||||||
|
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
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
# 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)
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
@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
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"folders": [
|
||||||
|
{
|
||||||
|
"path": "."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"editor.tabSize": 4
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
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
|
||||||
|
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
# 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()
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
# 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.
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
/** 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);
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/** 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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/** 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
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
/** 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
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
/** 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"
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
/** 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 {
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
/** 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"
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
/** 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
|
||||||
+108
@@ -0,0 +1,108 @@
|
|||||||
|
# Peninsula API Documentation (v1.0)
|
||||||
|
This document aims to instruct developers on how to implement the Peninsula style Archipelago API. The Peninsula style API is a passive poll based API architecture enabling distributed processing of all requests.
|
||||||
|
|
||||||
|
## API Endpoints
|
||||||
|
These endpoints are all available under the path `/api/1.0/` for compatibility and future proofing.
|
||||||
|
|
||||||
|
### /api/1.0/accounts/
|
||||||
|
Provides endpoints related to client authentication, linking, management and similar.
|
||||||
|
|
||||||
|
#### `GET /api/1.0/accounts/`
|
||||||
|
List all currently registered accounts.
|
||||||
|
|
||||||
|
#### `POST /api/1.0/accounts/register/`
|
||||||
|
Register a new client with the system. This is an [Illegal Request](#Illegal-Request) if the client is already logged in.
|
||||||
|
|
||||||
|
##### Parameters
|
||||||
|
|
||||||
|
|
||||||
|
#### `POST /api/1.0/accounts/login/`
|
||||||
|
Log in as an existing client. This is an [Illegal Request](#Illegal-Request) if the client is already logged in.
|
||||||
|
|
||||||
|
#### `POST /api/1.0/accounts/logout/`
|
||||||
|
Perform the necessary steps to log out. This is an [Unauthorized Request](#Unauthorized-Request) if not already logged in.
|
||||||
|
|
||||||
|
#### `POST /api/1.0/accounts/delete/`
|
||||||
|
Mark one or more accounts for deletion.
|
||||||
|
|
||||||
|
##### Parameters
|
||||||
|
| Type | Name | Description |
|
||||||
|
|---|---|---|
|
||||||
|
| POST Data | accounts[string] | A zero-indexed array of client UUIDs to delete. Optional. |
|
||||||
|
|
||||||
|
##### Behavior
|
||||||
|
- If the client is not logged in this request should be considered an [Unauthorized Request](#Unauthorized-Request).
|
||||||
|
- If the client is logged in and no `accounts` parameter was provided, the accounts account should be marked for deletion.
|
||||||
|
- If the client is logged in and `accounts` parameter was provided, and the client is authorized to perform this, the accounts listed should be marked for deletion.
|
||||||
|
- In all other cases, this should be considered an [Illegal Request](Illegal-Request).
|
||||||
|
|
||||||
|
##### Replies
|
||||||
|
###### Mark own Account for Deletion
|
||||||
|
```http
|
||||||
|
{
|
||||||
|
"accounts": {
|
||||||
|
"<uuid>": {
|
||||||
|
"delete-at": "<unix-timestamp>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
###### Mark other Accounts for Deletion
|
||||||
|
```http
|
||||||
|
{
|
||||||
|
"accounts": {
|
||||||
|
"<uuid>": {
|
||||||
|
"delete-at": "<unix-timestamp>"
|
||||||
|
},
|
||||||
|
"<uuid>": {
|
||||||
|
"delete-at": "<unix-timestamp>"
|
||||||
|
},
|
||||||
|
"<uuid>": {
|
||||||
|
"delete-at": "<unix-timestamp>"
|
||||||
|
},
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `POST /api/1.0/accounts/restore/`
|
||||||
|
Unmark an account for deletion. Can only be performed by the account itself.
|
||||||
|
|
||||||
|
##### Parameters
|
||||||
|
No Parameters.
|
||||||
|
|
||||||
|
##### Behavior
|
||||||
|
- If the client is not logged in this request should be considered an [Unauthorized Request](#Unauthorized-Request).
|
||||||
|
- If the client is logged in and the account exists, the account should be unmarked for deletion.
|
||||||
|
- In all other cases, this should be considered an [Illegal Request](Illegal-Request).
|
||||||
|
|
||||||
|
##### Replies
|
||||||
|
```http
|
||||||
|
Clear-Cookie: session
|
||||||
|
|
||||||
|
{
|
||||||
|
"session": null
|
||||||
|
"accounts": {
|
||||||
|
"<uuid>": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `POST /api/1.0/accounts/expunge/`
|
||||||
|
Forcefully delete an account
|
||||||
|
|
||||||
|
### Rooms
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Terminology
|
||||||
|
|
||||||
|
###### Unauthorized Request
|
||||||
|
An unauthorized request is a request for which the client did not provide the necessary authentification to perform the request. The expected response to these is a `401 Unauthorized` status.
|
||||||
|
|
||||||
|
###### Forbidden Request
|
||||||
|
A forbidden request is a request for which authorization was provided, but it does not provide the necessary rights to perform the action. The expected response to these is a `403 Forbidden` state.
|
||||||
|
|
||||||
|
###### Illegal Request
|
||||||
|
An illegal request is a request which is not valid in the current context. The expected response to these is a `400 Bad Request` status.
|
||||||
Reference in New Issue
Block a user