mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-07 22:56:30 -10:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e1cee23b82 |
No files matched your search
@@ -1,182 +0,0 @@
|
||||
version: 2
|
||||
|
||||
references:
|
||||
container_config: &container_config
|
||||
docker:
|
||||
- image: "debian:stretch"
|
||||
working_directory: /root/build
|
||||
|
||||
restore_repo: &restore_repo
|
||||
restore_cache:
|
||||
keys:
|
||||
- source-repo-{{ .Branch }}-{{ .Revision }}
|
||||
- source-repo-{{ .Branch }}
|
||||
- source-repo
|
||||
|
||||
cmake_configure: &cmake_configure
|
||||
run:
|
||||
name: Creating Build Files
|
||||
command: |
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
CXXFLAGS="-m64 -mtune=generic -mfpmath=sse -msse -msse2 -pipe -Wno-unknown-pragmas"
|
||||
CFLAGS="-m64 -mtune=generic -mfpmath=sse -msse -msse2 -pipe -Wno-unknown-pragmas"
|
||||
|
||||
if [[ "$CC" =~ ^clang.*$ ]]; then
|
||||
CXXFLAGS="$CXXFLAGS -stdlib=libc++"
|
||||
fi
|
||||
|
||||
eval $CC --version
|
||||
|
||||
export CXXFLAGS
|
||||
export CFLAGS
|
||||
CMAKE="cmake -G Ninja -DFSO_FATAL_WARNINGS=ON $CMAKE_OPTIONS"
|
||||
eval $CMAKE -DCMAKE_BUILD_TYPE=$CONFIGURATION -DFSO_BUILD_TESTS=ON -DFSO_BUILD_INCLUDED_LIBS=ON ..
|
||||
|
||||
compile: &compile
|
||||
run:
|
||||
name: Compiling Source code
|
||||
command: |
|
||||
cd build
|
||||
ninja -k 20 all
|
||||
|
||||
run_tests: &run_tests
|
||||
run:
|
||||
name: Run unit tests
|
||||
command: |
|
||||
./build/bin/unittests --gtest_shuffle
|
||||
|
||||
compile_steps: &compile_steps
|
||||
steps:
|
||||
- *restore_repo
|
||||
- *cmake_configure
|
||||
- *compile
|
||||
- *run_tests
|
||||
jobs:
|
||||
checkout_code:
|
||||
<<: *container_config
|
||||
steps:
|
||||
- run:
|
||||
name: Installing Git
|
||||
command: 'apt-get update && apt-get -yq install git'
|
||||
- *restore_repo
|
||||
- checkout
|
||||
- run:
|
||||
name: Updating submodules
|
||||
command: 'git submodule update --init --recursive'
|
||||
- save_cache:
|
||||
key: source-repo-{{ .Branch }}-{{ .Revision }}
|
||||
paths:
|
||||
- .
|
||||
|
||||
build_gcc_lowest_debug:
|
||||
docker:
|
||||
- image: asarium/fso_compile:gcc-lowest
|
||||
working_directory: /root/build
|
||||
environment:
|
||||
CC: gcc
|
||||
CXX: g++
|
||||
CONFIGURATION: Debug
|
||||
<<: *compile_steps
|
||||
|
||||
build_gcc_lowest_release:
|
||||
docker:
|
||||
- image: asarium/fso_compile:gcc-lowest
|
||||
working_directory: /root/build
|
||||
environment:
|
||||
CC: gcc
|
||||
CXX: g++
|
||||
CONFIGURATION: Release
|
||||
<<: *compile_steps
|
||||
|
||||
build_gcc_latest_debug:
|
||||
docker:
|
||||
- image: asarium/fso_compile:gcc-latest
|
||||
working_directory: /root/build
|
||||
environment:
|
||||
CC: gcc
|
||||
CXX: g++
|
||||
CONFIGURATION: Debug
|
||||
<<: *compile_steps
|
||||
|
||||
build_gcc_latest_release:
|
||||
docker:
|
||||
- image: asarium/fso_compile:gcc-latest
|
||||
working_directory: /root/build
|
||||
environment:
|
||||
CC: gcc
|
||||
CXX: g++
|
||||
CONFIGURATION: Release
|
||||
<<: *compile_steps
|
||||
|
||||
build_clang_latest_debug:
|
||||
docker:
|
||||
- image: asarium/fso_compile:clang-latest
|
||||
working_directory: /root/build
|
||||
environment:
|
||||
CC: clang-8
|
||||
CXX: clang++-8
|
||||
CONFIGURATION: Debug
|
||||
<<: *compile_steps
|
||||
|
||||
build_clang_latest_release:
|
||||
docker:
|
||||
- image: asarium/fso_compile:clang-latest
|
||||
working_directory: /root/build
|
||||
environment:
|
||||
CC: clang-8
|
||||
CXX: clang++-8
|
||||
CONFIGURATION: Release
|
||||
<<: *compile_steps
|
||||
|
||||
build_clang_lowest_debug:
|
||||
docker:
|
||||
- image: asarium/fso_compile:clang-lowest
|
||||
working_directory: /root/build
|
||||
environment:
|
||||
CC: clang
|
||||
CXX: clang++
|
||||
CONFIGURATION: Debug
|
||||
<<: *compile_steps
|
||||
|
||||
build_clang_lowest_release:
|
||||
docker:
|
||||
- image: asarium/fso_compile:clang-lowest
|
||||
working_directory: /root/build
|
||||
environment:
|
||||
CC: clang
|
||||
CXX: clang++
|
||||
CONFIGURATION: Release
|
||||
<<: *compile_steps
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
|
||||
build_test:
|
||||
jobs:
|
||||
- checkout_code
|
||||
- build_gcc_lowest_debug:
|
||||
requires:
|
||||
- checkout_code
|
||||
- build_gcc_lowest_release:
|
||||
requires:
|
||||
- checkout_code
|
||||
- build_gcc_latest_debug:
|
||||
requires:
|
||||
- checkout_code
|
||||
- build_gcc_latest_release:
|
||||
requires:
|
||||
- checkout_code
|
||||
- build_clang_latest_debug:
|
||||
requires:
|
||||
- checkout_code
|
||||
- build_clang_latest_release:
|
||||
requires:
|
||||
- checkout_code
|
||||
- build_clang_lowest_debug:
|
||||
requires:
|
||||
- checkout_code
|
||||
- build_clang_lowest_release:
|
||||
requires:
|
||||
- checkout_code
|
||||
-104
@@ -1,104 +0,0 @@
|
||||
---
|
||||
Language: Cpp
|
||||
Standard: Cpp11
|
||||
# BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -2
|
||||
AlignAfterOpenBracket: DontAlign
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlines: Left
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowAllArgumentsOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortEnumsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
BraceWrapping:
|
||||
AfterClass: false
|
||||
AfterControlStatement: false
|
||||
AfterEnum: false
|
||||
AfterFunction: true
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
IndentBraces: false
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Custom
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 120
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
||||
IncludeBlocks: Regroup
|
||||
IncludeCategories:
|
||||
- Regex: '^(<.*\.(h|hh|hpp)>)$' # Includes of external libraries
|
||||
Priority: 5
|
||||
- Regex: '^(<.*>)$' # standard library includes (won't match deprecated C headers)
|
||||
Priority: 6
|
||||
- Regex: '^"globalincs\/.*\.h"$' # globalincs always come first
|
||||
Priority: 1
|
||||
- Regex: '^"[^/]*\.(h)"$' # Local includes
|
||||
Priority: 2
|
||||
- Regex: '^".*\.(h)"$' # standard engine includes
|
||||
Priority: 3
|
||||
- Regex: '.*' # Catch all in case something is unhandled above
|
||||
Priority: 4
|
||||
IncludeIsMainRegex: '$'
|
||||
IndentCaseLabels: false
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PointerAlignment: Left
|
||||
ReflowComments: true
|
||||
SortIncludes: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
TabWidth: 4
|
||||
UseTab: ForContinuationAndIndentation
|
||||
...
|
||||
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
---
|
||||
Checks: "-*,\
|
||||
modernize-*,\
|
||||
-modernize-avoid-c-arrays,\
|
||||
-modernize-make-unique,\
|
||||
-modernize-raw-string-literal,\
|
||||
-modernize-use-trailing-return-type,\
|
||||
-modernize-use-using,\
|
||||
performance-*,\
|
||||
-performance-type-promotion-in-math-fn,\
|
||||
misc-*,\
|
||||
-misc-macro-parentheses,\
|
||||
-misc-misplaced-widening-cast,\
|
||||
-misc-non-private-member-variables-in-classes,\
|
||||
-misc-static-assert,\
|
||||
-misc-unused-parameters,\
|
||||
readability-*,\
|
||||
-readability-avoid-const-params-in-decls,\
|
||||
-readability-else-after-return,\
|
||||
-readability-function-size,\
|
||||
-readability-identifier-naming,\
|
||||
-readability-implicit-bool-conversion,\
|
||||
-readability-inconsistent-declaration-parameter-name,\
|
||||
-readability-isolate-declaration,\
|
||||
-readability-magic-numbers,\
|
||||
-readability-named-parameter,\
|
||||
-readability-qualified-auto,\
|
||||
-readability-uppercase-literal-suffix,\
|
||||
"
|
||||
WarningsAsErrors: ''
|
||||
HeaderFilterRegex: 'code/.*$|freespace2/.*$|qtfred/.*$|test/src/.*$|build/.*$'
|
||||
AnalyzeTemporaryDtors: false
|
||||
CheckOptions:
|
||||
- key: 'misc-assert-side-effect.AssertMacros'
|
||||
value: 'assert,Assert,Assertion'
|
||||
- key: 'modernize-use-emplace.ContainersWithPushBack'
|
||||
value: 'std::vector;std::deque;std::list;SCP_vector;SCP_deque;SCP_list'
|
||||
- key: 'readability-braces-around-statements.ShortStatementLines'
|
||||
value: '4' # Avoid flagging simple if (...) return false; statements
|
||||
...
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
/build
|
||||
/.git
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
|
||||
build:
|
||||
image: teaci/msys$$arch
|
||||
pull: true
|
||||
shell: mingw$$arch
|
||||
commands:
|
||||
- git submodule update --init --recursive
|
||||
- if [ $$arch = 32 ]; then target=i686; fi
|
||||
- if [ $$arch = 64 ]; then target=x86_64; fi
|
||||
- pacman -S --needed --noconfirm --noprogressbar mingw-w64-${target}-pkg-config mingw-w64-${target}-cmake
|
||||
- mkdir build && cd build
|
||||
- cmake -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=$$CONFIGURATION -DFSO_USE_SPEECH=OFF -DFSO_USE_VOICEREC=OFF -DFSO_FATAL_WARNINGS=ON -DFSO_BUILD_FRED2=OFF ..
|
||||
- make -j$(nproc) all
|
||||
|
||||
matrix:
|
||||
arch:
|
||||
- 64
|
||||
- 32
|
||||
CONFIGURATION:
|
||||
- Debug
|
||||
- Release
|
||||
@@ -5,11 +5,3 @@ indent_style = tab
|
||||
|
||||
[*.sdr]
|
||||
indent_style = tab
|
||||
|
||||
[*.{yml,yaml}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.sh]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
@@ -1,7 +0,0 @@
|
||||
# Default for everything
|
||||
# * text=auto
|
||||
|
||||
# For the test data and built-in files to make them consistent on all platforms
|
||||
*.tbl text eol=lf
|
||||
*.tbm text eol=lf
|
||||
*.sdr text eol=lf
|
||||
@@ -1,14 +0,0 @@
|
||||
|
||||
cmake/ @asarium
|
||||
|
||||
ci/ @asarium @z64555
|
||||
|
||||
code/executor/ @asarium
|
||||
|
||||
code/scpui/ @asarium
|
||||
|
||||
code/scripting/ @asarium
|
||||
|
||||
code/controlconfig/ @z64555
|
||||
|
||||
code/model/modelanimation*.* @bmagnu
|
||||
@@ -1,305 +0,0 @@
|
||||
name: Build Nightly package
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'nightly_*'
|
||||
|
||||
env:
|
||||
QT_VERSION: 5.12.9
|
||||
|
||||
jobs:
|
||||
build_linux:
|
||||
strategy:
|
||||
matrix:
|
||||
configuration: [FastDebug, Release]
|
||||
name: Linux
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/scp-fs2open/linux_build:sha-8a6bbbe
|
||||
steps:
|
||||
- name: Cache Qt
|
||||
id: cache-qt-lin
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ github.workspace }}/../Qt
|
||||
key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v2
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
cached: ${{ steps.cache-qt-lin.outputs.cache-hit }}
|
||||
setup-python: 'false'
|
||||
aqtversion: ==1.1.3
|
||||
|
||||
- uses: actions/checkout@v1
|
||||
name: Checkout
|
||||
with:
|
||||
submodules: true
|
||||
- name: Configure CMake
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
COMPILER: gcc-5
|
||||
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
|
||||
- name: Compile
|
||||
working-directory: ./build
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
run: |
|
||||
LD_LIBRARY_PATH=$Qt5_DIR/lib:$LD_LIBRARY_PATH ninja -k 20 all
|
||||
- name: Run Tests
|
||||
working-directory: ./build
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
XDG_RUNTIME_DIR: /root
|
||||
run: $GITHUB_WORKSPACE/ci/linux/run_tests.sh
|
||||
- name: Generate AppImage
|
||||
working-directory: ./build
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
run: $GITHUB_WORKSPACE/ci/linux/generate_appimage.sh $GITHUB_WORKSPACE/build/install
|
||||
- name: Upload build result
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: linux-${{ matrix.configuration }}
|
||||
path: ${{ github.workspace }}/build/install/*.AppImage
|
||||
linux_zip:
|
||||
name: Build Linux distribution zip
|
||||
needs: build_linux
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/scp-fs2open/sftp_upload:sha-748b19d
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
name: Checkout
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: '0'
|
||||
- name: Download Release builds
|
||||
uses: actions/download-artifact@v1
|
||||
with:
|
||||
name: linux-Release
|
||||
path: builds
|
||||
- name: Download FastDebug builds
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: linux-FastDebug
|
||||
path: builds
|
||||
- name: Create Distribution package
|
||||
working-directory: ./builds
|
||||
run: $GITHUB_WORKSPACE/ci/linux/create_dist_pack.sh Linux
|
||||
- name: Upload result package
|
||||
working-directory: ./builds
|
||||
env:
|
||||
INDIEGAMES_USER: ${{ secrets.INDIEGAMES_USER }}
|
||||
INDIEGAMES_SSHPASS: ${{ secrets.INDIEGAMES_PASSWORD }}
|
||||
DATACORDER_USER: ${{ secrets.DATACORDER_USER }}
|
||||
DATACORDER_SSHPASS: ${{ secrets.DATACORDER_PASSWORD }}
|
||||
run: $GITHUB_WORKSPACE/ci/linux/upload_dist_package.sh nightly
|
||||
|
||||
build_windows:
|
||||
strategy:
|
||||
matrix:
|
||||
configuration: [FastDebug, Release]
|
||||
arch: [Win32, x64]
|
||||
simd: [SSE2]
|
||||
name: Windows
|
||||
runs-on: windows-2019
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
name: Checkout
|
||||
with:
|
||||
submodules: true
|
||||
- name: Cache Qt
|
||||
id: cache-qt-win
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ github.workspace }}/../Qt
|
||||
key: ${{ runner.os }}-${{ matrix.arch }}-QtCache-${{ env.QT_VERSION }}
|
||||
- name: Install Qt (32 bit)
|
||||
uses: jurplel/install-qt-action@v2
|
||||
if: ${{ matrix.arch == 'Win32' }}
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
arch: win32_msvc2017
|
||||
cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
|
||||
aqtversion: ==0.8
|
||||
- name: Install Qt (64 bit)
|
||||
uses: jurplel/install-qt-action@v2
|
||||
if: ${{ matrix.arch == 'x64' }}
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
arch: win64_msvc2017_64
|
||||
cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
|
||||
aqtversion: ==0.8
|
||||
|
||||
- name: Configure CMake
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
ARCHITECTURE: ${{ matrix.arch }}
|
||||
SIMD: ${{ matrix.simd }}
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DFSO_USE_SPEECH="ON" \
|
||||
-DFSO_USE_VOICEREC="ON" -DMSVC_SIMD_INSTRUCTIONS="$SIMD" \
|
||||
-DFSO_BUILD_QTFRED=ON -DFSO_BUILD_TESTS=ON \
|
||||
-DFSO_INSTALL_DEBUG_FILES="ON" -A "$ARCHITECTURE" \
|
||||
-G "Visual Studio 16 2019" -T "v142" ..
|
||||
- name: Compile
|
||||
working-directory: ./build
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
COMPILER: ${{ matrix.compiler }}
|
||||
shell: bash
|
||||
run: |
|
||||
cmake --build . --config "$CONFIGURATION" --target INSTALL -- /verbosity:minimal
|
||||
ls -alR "$(pwd)/install"
|
||||
- name: Run Tests
|
||||
working-directory: ./build
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
shell: bash
|
||||
run: ./bin/$CONFIGURATION/unittests --gtest_shuffle
|
||||
- name: Upload build result
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: windows-${{ matrix.configuration }}-${{ matrix.arch }}-${{ matrix.simd }}
|
||||
path: ${{ github.workspace }}/build/install/*
|
||||
windows_zip:
|
||||
name: Build Windows distribution zip
|
||||
needs: build_windows
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/scp-fs2open/sftp_upload:sha-748b19d
|
||||
strategy:
|
||||
matrix:
|
||||
arch: [Win32, x64]
|
||||
simd: [SSE2]
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
name: Checkout
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: '0'
|
||||
- name: Download Release builds
|
||||
uses: actions/download-artifact@v1
|
||||
with:
|
||||
name: windows-Release-${{ matrix.arch }}-${{ matrix.simd }}
|
||||
path: builds
|
||||
- name: Download FastDebug builds
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: windows-FastDebug-${{ matrix.arch }}-${{ matrix.simd }}
|
||||
path: builds
|
||||
- name: Create Distribution package
|
||||
working-directory: ./builds
|
||||
shell: bash
|
||||
env:
|
||||
ARCH: ${{ matrix.arch }}
|
||||
SIMD: ${{ matrix.simd }}
|
||||
run: $GITHUB_WORKSPACE/ci/linux/create_dist_pack.sh Windows
|
||||
- name: Upload result package
|
||||
working-directory: ./builds
|
||||
shell: bash
|
||||
env:
|
||||
INDIEGAMES_USER: ${{ secrets.INDIEGAMES_USER }}
|
||||
INDIEGAMES_SSHPASS: ${{ secrets.INDIEGAMES_PASSWORD }}
|
||||
DATACORDER_USER: ${{ secrets.DATACORDER_USER }}
|
||||
DATACORDER_SSHPASS: ${{ secrets.DATACORDER_PASSWORD }}
|
||||
run: $GITHUB_WORKSPACE/ci/linux/upload_dist_package.sh nightly
|
||||
|
||||
build_mac:
|
||||
strategy:
|
||||
matrix:
|
||||
configuration: [FastDebug, Release]
|
||||
compiler: [clang]
|
||||
arch: [x86_64]
|
||||
name: Mac
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- name: Cache Qt
|
||||
id: cache-qt-mac
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ github.workspace }}/../Qt
|
||||
key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v2
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
cached: ${{ steps.cache-qt-mac.outputs.cache-hit }}
|
||||
setup-python: 'false'
|
||||
aqtversion: ==1.1.3
|
||||
|
||||
- uses: actions/checkout@v1
|
||||
name: Checkout
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: 0
|
||||
- name: Set up test version
|
||||
shell: bash
|
||||
run: |
|
||||
[[ "${{ github.ref }}" =~ ^refs\/heads\/test\/(.*)$ ]]
|
||||
# Override the revision string so that the builds are named correctly
|
||||
echo "set(FSO_VERSION_REVISION_STR ${BASH_REMATCH[1]})" > "version_override.cmake"]
|
||||
- name: Configure CMake
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
COMPILER: ${{ matrix.compiler }}
|
||||
ARCHITECTURE: ${{ matrix.arch }}
|
||||
JOB_CMAKE_OPTIONS: ${{ matrix.cmake_options }}
|
||||
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
|
||||
- name: Compile
|
||||
working-directory: ./build
|
||||
run: LD_LIBRARY_PATH=$Qt5_DIR/lib:$LD_LIBRARY_PATH ninja all
|
||||
- name: Run Tests
|
||||
working-directory: ./build
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
XDG_RUNTIME_DIR: /root
|
||||
run: $GITHUB_WORKSPACE/ci/linux/run_tests.sh
|
||||
- name: Package build result
|
||||
working-directory: ./build
|
||||
run: cd bin && tar -cvzf macos-build.tar *.app
|
||||
- name: Upload build result
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: mac-${{ matrix.configuration }}
|
||||
path: ${{ github.workspace }}/build/bin/macos-build.tar
|
||||
mac_zip:
|
||||
name: Build Mac distribution zip
|
||||
needs: build_mac
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/scp-fs2open/sftp_upload:sha-748b19d
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
name: Checkout
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: '0'
|
||||
ref: '${{ github.ref }}'
|
||||
- name: Download Release builds
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: mac-Release
|
||||
path: builds
|
||||
- name: Download FastDebug builds
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: mac-FastDebug
|
||||
path: builds
|
||||
- name: Create Distribution package
|
||||
working-directory: ./builds
|
||||
run: $GITHUB_WORKSPACE/ci/linux/create_dist_pack.sh Mac
|
||||
- name: Upload result package
|
||||
working-directory: ./builds
|
||||
env:
|
||||
INDIEGAMES_USER: ${{ secrets.INDIEGAMES_USER }}
|
||||
INDIEGAMES_SSHPASS: ${{ secrets.INDIEGAMES_PASSWORD }}
|
||||
DATACORDER_USER: ${{ secrets.DATACORDER_USER }}
|
||||
DATACORDER_SSHPASS: ${{ secrets.DATACORDER_PASSWORD }}
|
||||
run: $GITHUB_WORKSPACE/ci/linux/upload_dist_package.sh nightly
|
||||
@@ -1,320 +0,0 @@
|
||||
name: Build Release package
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'release_*'
|
||||
|
||||
env:
|
||||
QT_VERSION: 5.12.9
|
||||
|
||||
jobs:
|
||||
create_release:
|
||||
name: Create GitHub release
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Create Release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
# Creates a release package page on github
|
||||
# create_release.inputs: (notable inputs)
|
||||
# allowUpdates=false if true, update an existing release if it exists
|
||||
# artifactErrorsFailBuild=false if true, fails the build should artifact read/write errors occur
|
||||
# artifacts optional set of paths to artifacts to upload to the release. comma delimited.
|
||||
# removeArtifacts=false if true, remove existing artifacts
|
||||
# replaceArtifacts=false if true, replace/overwrite existing artifacts
|
||||
# create_release.outputs:
|
||||
# id id of the created release
|
||||
# html_url HTML URL of the release
|
||||
# upload_url FTP URL of the release where assets are uploaded
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token
|
||||
with:
|
||||
tag_name: ${{ github.ref }}
|
||||
release_name: Release ${{ github.ref }}
|
||||
draft: false
|
||||
prerelease: false
|
||||
|
||||
build_linux:
|
||||
strategy:
|
||||
matrix:
|
||||
# Run this job for each configuration
|
||||
# The current config running is accesible with `matrix.configuration`
|
||||
configuration: [FastDebug, Release]
|
||||
name: Linux
|
||||
needs: create_release # Don't run this job until create_release is done and successful
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/scp-fs2open/linux_build:sha-8a6bbbe
|
||||
steps:
|
||||
- name: Cache Qt
|
||||
id: cache-qt-lin
|
||||
uses: actions/cache@v1
|
||||
# cache the Qt directory so we don't have to reinstall it every time
|
||||
# cache.inputs:
|
||||
# path - A list of files, directories, and wildcard patterns to cache and restore. See @actions/glob for supported patterns.
|
||||
# key - An explicit key for restoring and saving the cache
|
||||
# restore-keys - An ordered list of keys to use for restoring the cache if no cache hit occurred for key
|
||||
# cache.outputs:
|
||||
# cache-hit true when an exact match was found for the key, false otherwise.
|
||||
with:
|
||||
path: ${{ github.workspace }}/../Qt
|
||||
key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v2
|
||||
# installs Qt in the action workflow
|
||||
# install-qt-action.inputs:
|
||||
# version desired qt version to install
|
||||
# host Host platform of Qt, default to platform used by runs-on
|
||||
# target target platform of Qt, default to desktop
|
||||
# arch target architecture of Qt, only used for windows or android builds
|
||||
# dir root dir Qt will be installed to
|
||||
# install-deps if true, auto-install dependencies on linux. Default true
|
||||
# modules whitespace delimited list string of additional addon modules to install
|
||||
# archives whitespace delimited list string of Qt archives to install
|
||||
# cached if true, Don't download Qt but set ENVARs; use with cache.outputs.cache-hit
|
||||
# setup-python Set to false to skip using setup-python to find/download a valid python version
|
||||
# set-env if true, set ENVARs; default = false
|
||||
# aqtversion version of aqtinstall to use; default = 2.0.0
|
||||
# py7zrversion version of py7zr to use; default = 0.16.1
|
||||
# extra additional arguments to pass to aqinstall
|
||||
# ENVARS set:
|
||||
# Qt5_DIR / Qt6_DIR
|
||||
# Qt bin dir appended to PATH
|
||||
# QT_PLUGIN_PATH, QML2_IMPORT_PATH, PKG_CONFIG_PATH, LD_LIBRARY_PATH
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
cached: ${{ steps.cache-qt-lin.outputs.cache-hit }}
|
||||
setup-python: 'false'
|
||||
aqtversion: ==1.1.3
|
||||
|
||||
- uses: actions/checkout@v1
|
||||
# checks-out your repository under $GITHUB_WORKSPACE, so your workflow can access it.
|
||||
name: Checkout
|
||||
with:
|
||||
submodules: true # `true` to checkout submodules, `recursive` to recursively checkout submodules
|
||||
- name: Configure CMake
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
COMPILER: gcc-5
|
||||
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
|
||||
- name: Compile
|
||||
working-directory: ./build
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
run: |
|
||||
LD_LIBRARY_PATH=$Qt5_DIR/lib:$LD_LIBRARY_PATH ninja -k 20 all
|
||||
- name: Run Tests
|
||||
working-directory: ./build
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
XDG_RUNTIME_DIR: /root
|
||||
run: $GITHUB_WORKSPACE/ci/linux/run_tests.sh
|
||||
- name: Generate AppImage
|
||||
working-directory: ./build
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
run: $GITHUB_WORKSPACE/ci/linux/generate_appimage.sh $GITHUB_WORKSPACE/build/install
|
||||
- name: Upload build result
|
||||
uses: actions/upload-artifact@v2
|
||||
# Upload the url file for use with other runners
|
||||
# upload-artifact.inputs:
|
||||
# if-no-files-found=warn What to do if path fails to find any files.
|
||||
# warn Display a warning but do not fail the action
|
||||
# error Display an error and fail the action
|
||||
# ignore No display, No fail
|
||||
# retention-days=0 Days to keep the artifact.
|
||||
# 0 Use default retention policy of the repo
|
||||
# 1~90 Min 1, Max 90 days to keep the artifact unless changed by repo settings page
|
||||
with:
|
||||
name: linux-${{ matrix.configuration }}
|
||||
path: ${{ github.workspace }}/build/install/*.AppImage
|
||||
linux_zip:
|
||||
name: Build Linux distribution zip
|
||||
needs: build_linux
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/scp-fs2open/sftp_upload:sha-748b19d
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
name: Checkout
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: '0' # value 0 to fetch all history and tags for all branches
|
||||
- name: Download Release builds
|
||||
# Grab the release builds
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: linux-Release
|
||||
path: builds
|
||||
- name: Download FastDebug builds
|
||||
# Grab the debug builds
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: linux-FastDebug
|
||||
path: builds
|
||||
- name: Create Distribution package
|
||||
# Zip both builds together
|
||||
id: generate_package
|
||||
working-directory: ./builds
|
||||
run: $GITHUB_WORKSPACE/ci/linux/create_dist_pack.sh Linux
|
||||
- name: Upload result package
|
||||
# Stash the result to artifact filespace
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ steps.generate_package.outputs.package_name }}
|
||||
path: ${{ steps.generate_package.outputs.package_path }}
|
||||
- name: Publish result package
|
||||
# publish the zipped result
|
||||
uses: softprops/action-gh-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
files: ${{ steps.generate_package.outputs.package_path }}
|
||||
|
||||
build_windows:
|
||||
strategy:
|
||||
matrix:
|
||||
configuration: [FastDebug, Release]
|
||||
arch: [Win32, x64]
|
||||
simd: [SSE2, AVX]
|
||||
needs: create_release
|
||||
name: Windows
|
||||
runs-on: windows-2019
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
# Checkout repo
|
||||
name: Checkout
|
||||
with:
|
||||
submodules: true
|
||||
- name: Cache Qt
|
||||
# Cache Qt
|
||||
id: cache-qt-win
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ github.workspace }}/../Qt
|
||||
key: ${{ runner.os }}-${{ matrix.arch }}-QtCache-${{ env.QT_VERSION }}
|
||||
- name: Install Qt (32 bit)
|
||||
# Install Qt 32bit if matrix.arch == Win32
|
||||
uses: jurplel/install-qt-action@v2
|
||||
if: ${{ matrix.arch == 'Win32' }}
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
arch: win32_msvc2017
|
||||
cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
|
||||
aqtversion: ==0.8
|
||||
- name: Install Qt (64 bit)
|
||||
# Install Qt 64bit if matrix.arch == x64
|
||||
uses: jurplel/install-qt-action@v2
|
||||
if: ${{ matrix.arch == 'x64' }}
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
arch: win64_msvc2017_64
|
||||
cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
|
||||
aqtversion: ==0.8
|
||||
|
||||
- name: Configure CMake
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
ARCHITECTURE: ${{ matrix.arch }}
|
||||
SIMD: ${{ matrix.simd }}
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DFSO_USE_SPEECH="ON" \
|
||||
-DFSO_USE_VOICEREC="ON" -DMSVC_SIMD_INSTRUCTIONS="$SIMD" \
|
||||
-DFSO_BUILD_QTFRED=ON -DFSO_BUILD_TESTS=ON \
|
||||
-DFSO_INSTALL_DEBUG_FILES="ON" -A "$ARCHITECTURE" \
|
||||
-G "Visual Studio 16 2019" -T "v142" ..
|
||||
- name: Compile
|
||||
working-directory: ./build
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
COMPILER: ${{ matrix.compiler }}
|
||||
shell: bash
|
||||
run: |
|
||||
cmake --build . --config "$CONFIGURATION" --target INSTALL -- /verbosity:minimal
|
||||
ls -alR "$(pwd)/install"
|
||||
- name: Run Tests
|
||||
working-directory: ./build
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
shell: bash
|
||||
run: ./bin/$CONFIGURATION/unittests --gtest_shuffle
|
||||
- name: Upload build result
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: windows-${{ matrix.configuration }}-${{ matrix.arch }}-${{ matrix.simd }}
|
||||
path: ${{ github.workspace }}/build/install/*
|
||||
|
||||
windows_zip:
|
||||
name: Build Windows distribution zip
|
||||
needs: build_windows
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/scp-fs2open/sftp_upload:sha-748b19d
|
||||
strategy:
|
||||
fail-fast: false # Run the other jobs in the matrix instead of failing them
|
||||
matrix:
|
||||
arch: [Win32, x64]
|
||||
simd: [SSE2, AVX]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
name: Checkout
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: '0'
|
||||
|
||||
- name: Download Release builds
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: windows-Release-${{ matrix.arch }}-${{ matrix.simd }}
|
||||
path: builds
|
||||
|
||||
- name: Download FastDebug builds
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: windows-FastDebug-${{ matrix.arch }}-${{ matrix.simd }}
|
||||
path: builds
|
||||
|
||||
- name: Create Distribution package
|
||||
id: generate_package
|
||||
working-directory: ./builds
|
||||
shell: bash
|
||||
env:
|
||||
ARCH: ${{ matrix.arch }}
|
||||
SIMD: ${{ matrix.simd }}
|
||||
run: $GITHUB_WORKSPACE/ci/linux/create_dist_pack.sh Windows
|
||||
|
||||
- name: Upload result package
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ steps.generate_package.outputs.package_name }}
|
||||
path: ${{ steps.generate_package.outputs.package_path }}
|
||||
|
||||
- name: Upload debug package
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ steps.generate_package.outputs.debug_name }}
|
||||
path: ${{ steps.generate_package.outputs.debug_path }}
|
||||
|
||||
- name: Publish packages
|
||||
uses: softprops/action-gh-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
files: |
|
||||
${{ steps.generate_package.outputs.package_path }}
|
||||
${{ steps.generate_package.outputs.debug_path }}
|
||||
|
||||
post_build:
|
||||
name: Post builds to Nebula and Forum
|
||||
needs: [linux_zip, windows_zip]
|
||||
uses: ./.github/workflows/post-build-release.yaml
|
||||
with:
|
||||
linux_result: ${{ needs.build_linux.result }}
|
||||
windows_result: ${{ needs.build_windows.result }}
|
||||
releaseTag: ${{ github.ref_name }}
|
||||
@@ -1,53 +0,0 @@
|
||||
name: Publish Standalone docker image
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'nightly_*'
|
||||
- 'release_*'
|
||||
|
||||
jobs:
|
||||
build_images:
|
||||
if: github.repository == 'scp-fs2open/fs2open.github.com'
|
||||
strategy:
|
||||
matrix:
|
||||
configuration: [FastDebug, Release]
|
||||
include:
|
||||
- configuration: FastDebug
|
||||
tag_suffix: -debug
|
||||
- configuration: Release
|
||||
tag_suffix: ""
|
||||
fail-fast: false
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
name: Checkout
|
||||
with:
|
||||
submodules: true
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: Docker meta
|
||||
id: docker_meta
|
||||
uses: crazy-max/ghaction-docker-meta@v1
|
||||
with:
|
||||
images: ghcr.io/scp-fs2open/standalone_server
|
||||
tag-latest: false
|
||||
|
||||
- name: Login to GitHub Docker Registry
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.CR_PAT }}
|
||||
- name: Build and push
|
||||
id: docker_build
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
file: ./docker/standalone/Dockerfile
|
||||
push: true
|
||||
tags: ${{ steps.docker_meta.outputs.tags }}${{ matrix.tag_suffix }}
|
||||
labels: ${{ steps.docker_meta.outputs.labels }}
|
||||
build-args: |
|
||||
build_type=${{ matrix.configuration }}
|
||||
@@ -1,318 +0,0 @@
|
||||
name: Build Test package
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'test/*'
|
||||
|
||||
env:
|
||||
QT_VERSION: 5.12.9
|
||||
|
||||
jobs:
|
||||
build_linux:
|
||||
strategy:
|
||||
matrix:
|
||||
configuration: [FastDebug, Release]
|
||||
name: Linux
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/scp-fs2open/linux_build:sha-8a6bbbe
|
||||
steps:
|
||||
- name: Cache Qt
|
||||
id: cache-qt-lin
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ github.workspace }}/../Qt
|
||||
key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v2
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
cached: ${{ steps.cache-qt-lin.outputs.cache-hit }}
|
||||
setup-python: 'false'
|
||||
aqtversion: ==1.1.3
|
||||
|
||||
- uses: actions/checkout@v1
|
||||
name: Checkout
|
||||
with:
|
||||
submodules: true
|
||||
- name: Set up test version
|
||||
shell: bash
|
||||
run: |
|
||||
[[ "${{ github.ref }}" =~ ^refs\/heads\/test\/(.*)$ ]]
|
||||
# Override the revision string so that the builds are named correctly
|
||||
echo "set(FSO_VERSION_REVISION_STR ${BASH_REMATCH[1]})" > "version_override.cmake"
|
||||
- name: Configure CMake
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
COMPILER: gcc-5
|
||||
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
|
||||
- name: Compile
|
||||
working-directory: ./build
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
run: |
|
||||
LD_LIBRARY_PATH=$Qt5_DIR/lib:$LD_LIBRARY_PATH ninja -k 20 all
|
||||
- name: Run Tests
|
||||
working-directory: ./build
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
XDG_RUNTIME_DIR: /root
|
||||
run: $GITHUB_WORKSPACE/ci/linux/run_tests.sh
|
||||
- name: Generate AppImage
|
||||
working-directory: ./build
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
run: $GITHUB_WORKSPACE/ci/linux/generate_appimage.sh $GITHUB_WORKSPACE/build/install
|
||||
- name: Upload build result
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: linux-${{ matrix.configuration }}
|
||||
path: ${{ github.workspace }}/build/install/*.AppImage
|
||||
linux_zip:
|
||||
name: Build Linux distribution zip
|
||||
needs: build_linux
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/scp-fs2open/sftp_upload:sha-748b19d
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
name: Checkout
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: '0'
|
||||
ref: '${{ github.ref }}'
|
||||
- name: Download Release builds
|
||||
uses: actions/download-artifact@v1
|
||||
with:
|
||||
name: linux-Release
|
||||
path: builds
|
||||
- name: Download FastDebug builds
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: linux-FastDebug
|
||||
path: builds
|
||||
- name: Create Distribution package
|
||||
working-directory: ./builds
|
||||
run: $GITHUB_WORKSPACE/ci/linux/create_dist_pack.sh Linux
|
||||
- name: Upload result package
|
||||
working-directory: ./builds
|
||||
env:
|
||||
INDIEGAMES_USER: ${{ secrets.INDIEGAMES_USER }}
|
||||
INDIEGAMES_SSHPASS: ${{ secrets.INDIEGAMES_PASSWORD }}
|
||||
DATACORDER_USER: ${{ secrets.DATACORDER_USER }}
|
||||
DATACORDER_SSHPASS: ${{ secrets.DATACORDER_PASSWORD }}
|
||||
run: $GITHUB_WORKSPACE/ci/linux/upload_dist_package.sh test
|
||||
|
||||
build_windows:
|
||||
strategy:
|
||||
matrix:
|
||||
configuration: [FastDebug, Release]
|
||||
arch: [Win32, x64]
|
||||
simd: [SSE2]
|
||||
name: Windows
|
||||
runs-on: windows-2019
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
name: Checkout
|
||||
with:
|
||||
submodules: true
|
||||
- name: Set up test version
|
||||
shell: bash
|
||||
run: |
|
||||
[[ "${{ github.ref }}" =~ ^refs\/heads\/test\/(.*)$ ]]
|
||||
# Override the revision string so that the builds are named correctly
|
||||
echo "set(FSO_VERSION_REVISION_STR ${BASH_REMATCH[1]})" > "version_override.cmake"
|
||||
- name: Cache Qt
|
||||
id: cache-qt-win
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ github.workspace }}/../Qt
|
||||
key: ${{ runner.os }}-${{ matrix.arch }}-QtCache-${{ env.QT_VERSION }}
|
||||
- name: Install Qt (32 bit)
|
||||
uses: jurplel/install-qt-action@v2
|
||||
if: ${{ matrix.arch == 'Win32' }}
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
arch: win32_msvc2017
|
||||
cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
|
||||
aqtversion: ==0.8
|
||||
- name: Install Qt (64 bit)
|
||||
uses: jurplel/install-qt-action@v2
|
||||
if: ${{ matrix.arch == 'x64' }}
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
arch: win64_msvc2017_64
|
||||
cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
|
||||
aqtversion: ==0.8
|
||||
|
||||
- name: Configure CMake
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
ARCHITECTURE: ${{ matrix.arch }}
|
||||
SIMD: ${{ matrix.simd }}
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DFSO_USE_SPEECH="ON" \
|
||||
-DFSO_USE_VOICEREC="ON" -DMSVC_SIMD_INSTRUCTIONS="$SIMD" \
|
||||
-DFSO_BUILD_QTFRED=ON -DFSO_BUILD_TESTS=ON \
|
||||
-DFSO_INSTALL_DEBUG_FILES="ON" -A "$ARCHITECTURE" \
|
||||
-G "Visual Studio 16 2019" -T "v142" ..
|
||||
- name: Compile
|
||||
working-directory: ./build
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
COMPILER: ${{ matrix.compiler }}
|
||||
shell: bash
|
||||
run: |
|
||||
cmake --build . --config "$CONFIGURATION" --target INSTALL -- /verbosity:minimal
|
||||
ls -alR "$(pwd)/install"
|
||||
- name: Run Tests
|
||||
working-directory: ./build
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
shell: bash
|
||||
run: ./bin/$CONFIGURATION/unittests --gtest_shuffle
|
||||
- name: Upload build result
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: windows-${{ matrix.configuration }}-${{ matrix.arch }}-${{ matrix.simd }}
|
||||
path: ${{ github.workspace }}/build/install/*
|
||||
windows_zip:
|
||||
name: Build Windows distribution zip
|
||||
needs: build_windows
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/scp-fs2open/sftp_upload:sha-748b19d
|
||||
strategy:
|
||||
matrix:
|
||||
arch: [Win32, x64]
|
||||
simd: [SSE2]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
name: Checkout
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: '0'
|
||||
ref: '${{ github.ref }}'
|
||||
- name: Download Release builds
|
||||
uses: actions/download-artifact@v1
|
||||
with:
|
||||
name: windows-Release-${{ matrix.arch }}-${{ matrix.simd }}
|
||||
path: builds
|
||||
- name: Download FastDebug builds
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: windows-FastDebug-${{ matrix.arch }}-${{ matrix.simd }}
|
||||
path: builds
|
||||
- name: Create Distribution package
|
||||
working-directory: ./builds
|
||||
shell: bash
|
||||
env:
|
||||
ARCH: ${{ matrix.arch }}
|
||||
SIMD: ${{ matrix.simd }}
|
||||
run: $GITHUB_WORKSPACE/ci/linux/create_dist_pack.sh Windows
|
||||
- name: Upload result package
|
||||
working-directory: ./builds
|
||||
shell: bash
|
||||
env:
|
||||
INDIEGAMES_USER: ${{ secrets.INDIEGAMES_USER }}
|
||||
INDIEGAMES_SSHPASS: ${{ secrets.INDIEGAMES_PASSWORD }}
|
||||
DATACORDER_USER: ${{ secrets.DATACORDER_USER }}
|
||||
DATACORDER_SSHPASS: ${{ secrets.DATACORDER_PASSWORD }}
|
||||
run: $GITHUB_WORKSPACE/ci/linux/upload_dist_package.sh test
|
||||
|
||||
build_mac:
|
||||
strategy:
|
||||
matrix:
|
||||
configuration: [FastDebug, Release]
|
||||
compiler: [clang]
|
||||
arch: [x86_64]
|
||||
name: Mac
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- name: Cache Qt
|
||||
id: cache-qt-mac
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ github.workspace }}/../Qt
|
||||
key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v2
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
cached: ${{ steps.cache-qt-mac.outputs.cache-hit }}
|
||||
setup-python: 'false'
|
||||
aqtversion: ==1.1.3
|
||||
|
||||
- uses: actions/checkout@v1
|
||||
name: Checkout
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: 0
|
||||
- name: Set up test version
|
||||
shell: bash
|
||||
run: |
|
||||
[[ "${{ github.ref }}" =~ ^refs\/heads\/test\/(.*)$ ]]
|
||||
# Override the revision string so that the builds are named correctly
|
||||
echo "set(FSO_VERSION_REVISION_STR ${BASH_REMATCH[1]})" > "version_override.cmake"
|
||||
- name: Configure CMake
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
COMPILER: ${{ matrix.compiler }}
|
||||
ARCHITECTURE: ${{ matrix.arch }}
|
||||
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
|
||||
- name: Compile
|
||||
working-directory: ./build
|
||||
run: LD_LIBRARY_PATH=$Qt5_DIR/lib:$LD_LIBRARY_PATH ninja all
|
||||
- name: Run Tests
|
||||
working-directory: ./build
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
XDG_RUNTIME_DIR: /root
|
||||
run: $GITHUB_WORKSPACE/ci/linux/run_tests.sh
|
||||
- name: Package build result
|
||||
working-directory: ./build
|
||||
run: cd bin && tar -cvzf macos-build.tar *.app
|
||||
- name: Upload build result
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: mac-${{ matrix.configuration }}
|
||||
path: ${{ github.workspace }}/build/bin/macos-build.tar
|
||||
mac_zip:
|
||||
name: Build Mac distribution zip
|
||||
needs: build_mac
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/scp-fs2open/sftp_upload:sha-748b19d
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
name: Checkout
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: '0'
|
||||
ref: '${{ github.ref }}'
|
||||
- name: Download Release builds
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: mac-Release
|
||||
path: builds
|
||||
- name: Download FastDebug builds
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: mac-FastDebug
|
||||
path: builds
|
||||
- name: Create Distribution package
|
||||
working-directory: ./builds
|
||||
run: $GITHUB_WORKSPACE/ci/linux/create_dist_pack.sh Mac
|
||||
- name: Upload result package
|
||||
working-directory: ./builds
|
||||
env:
|
||||
INDIEGAMES_USER: ${{ secrets.INDIEGAMES_USER }}
|
||||
INDIEGAMES_SSHPASS: ${{ secrets.INDIEGAMES_PASSWORD }}
|
||||
DATACORDER_USER: ${{ secrets.DATACORDER_USER }}
|
||||
DATACORDER_SSHPASS: ${{ secrets.DATACORDER_PASSWORD }}
|
||||
run: $GITHUB_WORKSPACE/ci/linux/upload_dist_package.sh test
|
||||
@@ -1,62 +0,0 @@
|
||||
name: Build caches for master
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
env:
|
||||
QT_VERSION: 5.12.9
|
||||
|
||||
jobs:
|
||||
build_linux:
|
||||
strategy:
|
||||
matrix:
|
||||
configuration: [Debug, Release]
|
||||
compiler: [gcc-5, gcc-10]
|
||||
cmake_options: [""]
|
||||
include:
|
||||
# Also include configurations that check if the code compiles without the graphics backends
|
||||
- configuration: Debug
|
||||
compiler: gcc-10
|
||||
cmake_options: -DFSO_BUILD_WITH_OPENGL=OFF -DFSO_BUILD_WITH_VULKAN=OFF
|
||||
- configuration: Release
|
||||
compiler: gcc-10
|
||||
cmake_options: -DFSO_BUILD_WITH_OPENGL=OFF -DFSO_BUILD_WITH_VULKAN=OFF
|
||||
name: Linux
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/scp-fs2open/linux_build:sha-8a6bbbe
|
||||
steps:
|
||||
- name: Cache Qt
|
||||
id: cache-qt-lin
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ github.workspace }}/../Qt
|
||||
key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v2
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
cached: ${{ steps.cache-qt-lin.outputs.cache-hit }}
|
||||
setup-python: 'false'
|
||||
aqtversion: ==1.1.3
|
||||
|
||||
- uses: actions/checkout@v1
|
||||
name: Checkout
|
||||
with:
|
||||
submodules: true
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1
|
||||
with:
|
||||
key: ${{ runner.os }}-${{ matrix.configuration }}-${{ matrix.compiler }}
|
||||
|
||||
- name: Configure CMake
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
COMPILER: ${{ matrix.compiler }}
|
||||
JOB_CMAKE_OPTIONS: ${{ matrix.cmake_options }}
|
||||
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
|
||||
- name: Compile
|
||||
working-directory: ./build
|
||||
run: LD_LIBRARY_PATH=$Qt5_DIR/lib:$LD_LIBRARY_PATH ninja -k 20 all
|
||||
@@ -1,65 +0,0 @@
|
||||
name: Post Release builds
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
# Trigger when called by other workflows
|
||||
inputs:
|
||||
linux_result: # job.result; either success, failure, canceled or skipped
|
||||
required: true
|
||||
type: string
|
||||
windows_result: # job.result
|
||||
required: true
|
||||
type: string
|
||||
releaseTag:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
workflow_dispatch:
|
||||
# Trigger manually from Github
|
||||
inputs:
|
||||
releaseTag:
|
||||
description: Release Tag
|
||||
required: true
|
||||
type: string
|
||||
|
||||
env:
|
||||
GITHUB_REPO: ${{ github.repository }} # repo this workflow was called from
|
||||
INDIEGAMES_USER: ${{ secrets.INDIEGAMES_USER }}
|
||||
INDIEGAMES_SSHPASS: ${{ secrets.INDIEGAMES_PASSWORD }}
|
||||
NEBULA_USER: ${{ secrets.NEBULA_USER }}
|
||||
NEBULA_PASSWORD: ${{ secrets.NEBULA_PASSWORD }}
|
||||
HLP_API: ${{ secrets.HLP_API }}
|
||||
HLP_KEY: ${{ secrets.HLP_KEY }}
|
||||
RELEASE_TAG: ${{ github.event.inputs.releaseTag }}
|
||||
|
||||
jobs:
|
||||
post_builds:
|
||||
name: Post builds on Nebula and the forums
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: '0'
|
||||
ref: ${{ env.RELEASE_TAG }}
|
||||
|
||||
- name: Install Python dependencies
|
||||
run: pip install -r ci/post/requirements.txt
|
||||
|
||||
- name: Post Builds (Auto trigger)
|
||||
if: ${{ github.event_name == 'workflow_call' }}
|
||||
env:
|
||||
LINUX_RESULT: ${{ github.event.inputs.linux_result }}
|
||||
WINDOWS_RESULT: ${{ github.event.inputs.windows_result }}
|
||||
run: python ci/post/main.py release
|
||||
|
||||
- name: Post Builds (Manual trigger)
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
# assume user knows what they're doing...
|
||||
env:
|
||||
LINUX_RESULT: success
|
||||
WINDOWS_RESULT: success
|
||||
run: |
|
||||
echo "releaseTag= ${{ env.RELEASE_TAG }}"
|
||||
echo "repository= ${{ github.repository }}"
|
||||
python ci/post/main.py release
|
||||
@@ -1,219 +0,0 @@
|
||||
name: Check a pull request
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
env:
|
||||
QT_VERSION: 5.12.9
|
||||
|
||||
jobs:
|
||||
build_linux:
|
||||
strategy:
|
||||
matrix:
|
||||
configuration: [Debug, Release]
|
||||
compiler: [gcc-5, gcc-10, clang-9]
|
||||
cmake_options: [""]
|
||||
include:
|
||||
# Also include configurations that check if the code compiles without the graphics backends
|
||||
- configuration: Debug
|
||||
compiler: gcc-10
|
||||
cmake_options: -DFSO_BUILD_WITH_OPENGL=OFF -DFSO_BUILD_WITH_VULKAN=OFF
|
||||
- configuration: Release
|
||||
compiler: gcc-10
|
||||
cmake_options: -DFSO_BUILD_WITH_OPENGL=OFF -DFSO_BUILD_WITH_VULKAN=OFF
|
||||
name: Linux
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/scp-fs2open/linux_build:sha-8a6bbbe
|
||||
steps:
|
||||
- name: Cache Qt
|
||||
id: cache-qt-lin
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ github.workspace }}/../Qt
|
||||
key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v2
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
cached: ${{ steps.cache-qt-lin.outputs.cache-hit }}
|
||||
setup-python: 'false'
|
||||
aqtversion: ==1.1.3
|
||||
|
||||
- uses: actions/checkout@v1
|
||||
name: Checkout
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: 0
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1
|
||||
with:
|
||||
key: ${{ runner.os }}-${{ matrix.configuration }}-${{ matrix.compiler }}
|
||||
|
||||
- name: Configure CMake
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
COMPILER: ${{ matrix.compiler }}
|
||||
JOB_CMAKE_OPTIONS: ${{ matrix.cmake_options }}
|
||||
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
|
||||
- name: Compile
|
||||
working-directory: ./build
|
||||
run: LD_LIBRARY_PATH=$Qt5_DIR/lib:$LD_LIBRARY_PATH ninja -k 20 all
|
||||
- name: Run Tests
|
||||
working-directory: ./build
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
XDG_RUNTIME_DIR: /root
|
||||
run: $GITHUB_WORKSPACE/ci/linux/run_tests.sh
|
||||
- name: Run Clang Tidy
|
||||
# Clang-tidy reuses the precompiled headers so this only makes sense for the clang compilers
|
||||
if: startsWith(matrix.compiler, 'clang-')
|
||||
run: $GITHUB_WORKSPACE/ci/linux/clang_tidy.sh ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }}
|
||||
- name: Process clang-tidy warnings
|
||||
if: startsWith(matrix.compiler, 'clang-')
|
||||
uses: asarium/clang-tidy-action@v1
|
||||
with:
|
||||
fixesFile: clang-fixes.yaml
|
||||
|
||||
build_windows:
|
||||
strategy:
|
||||
matrix:
|
||||
configuration: [Debug, Release]
|
||||
compiler: [MSVC]
|
||||
arch: [Win32, x64]
|
||||
name: Windows
|
||||
runs-on: windows-2019
|
||||
steps:
|
||||
- name: Prepare Environment
|
||||
run: choco install ninja
|
||||
- uses: actions/checkout@v1
|
||||
name: Checkout
|
||||
with:
|
||||
submodules: true
|
||||
- name: Cache Qt
|
||||
id: cache-qt-win
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ github.workspace }}/../Qt
|
||||
key: ${{ runner.os }}-${{ matrix.arch }}-QtCache-${{ env.QT_VERSION }}
|
||||
- name: Install Qt (32 bit)
|
||||
uses: jurplel/install-qt-action@v2
|
||||
if: ${{ matrix.compiler == 'MSVC' && matrix.arch == 'Win32' }}
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
arch: win32_msvc2017
|
||||
cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
|
||||
aqtversion: ==0.8
|
||||
- name: Install Qt (64 bit)
|
||||
uses: jurplel/install-qt-action@v2
|
||||
if: ${{ matrix.compiler == 'MSVC' && matrix.arch == 'x64' }}
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
arch: win64_msvc2017_64
|
||||
cached: ${{ steps.cache-qt-win.outputs.cache-hit }}
|
||||
aqtversion: ==0.8
|
||||
|
||||
- name: Configure CMake
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
COMPILER: ${{ matrix.compiler }}
|
||||
ARCHITECTURE: ${{ matrix.arch }}
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
if [ "$COMPILER" = "MinGW" ]; then
|
||||
cmake -DFSO_USE_SPEECH="OFF" -DFSO_FATAL_WARNINGS="ON" -DFSO_USE_VOICEREC="OFF" -DFSO_BUILD_TESTS="ON" \
|
||||
-DFSO_BUILD_FRED2="OFF" -DCMAKE_BUILD_TYPE=$CONFIGURATION -G "Ninja" ..
|
||||
else
|
||||
cmake -DFSO_USE_SPEECH="ON" -DFSO_FATAL_WARNINGS="ON" -DFSO_USE_VOICEREC="OFF" -DFSO_BUILD_TESTS="ON" \
|
||||
-DMSVC_SIMD_INSTRUCTIONS=SSE2 -DFSO_BUILD_FRED2="ON" -G "Visual Studio 16 2019" \
|
||||
-DFSO_BUILD_QTFRED=ON -T "v142" -A "$ARCHITECTURE" ..
|
||||
fi
|
||||
- name: Compile
|
||||
working-directory: ./build
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
COMPILER: ${{ matrix.compiler }}
|
||||
shell: bash
|
||||
run: |
|
||||
if [ "$COMPILER" = "MinGW" ]; then
|
||||
cmake --build . --config "$CONFIGURATION"
|
||||
else
|
||||
cmake --build . --config "$CONFIGURATION" -- /verbosity:minimal
|
||||
fi
|
||||
- name: Run Tests
|
||||
working-directory: ./build
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
COMPILER: ${{ matrix.compiler }}
|
||||
shell: bash
|
||||
run: |
|
||||
if [ "$COMPILER" = "MinGW" ]; then
|
||||
./bin/unittests --gtest_shuffle
|
||||
else
|
||||
"./bin/$CONFIGURATION/unittests" --gtest_shuffle
|
||||
fi
|
||||
|
||||
build_mac:
|
||||
strategy:
|
||||
matrix:
|
||||
configuration: [Debug, Release]
|
||||
compiler: [clang]
|
||||
arch: [x86_64]
|
||||
cmake_options: [""]
|
||||
name: Mac
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- name: Cache Qt
|
||||
id: cache-qt-mac
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ github.workspace }}/../Qt
|
||||
key: ${{ runner.os }}-QtCache-${{ env.QT_VERSION }}
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v2
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
dir: ${{ github.workspace }}/..
|
||||
cached: ${{ steps.cache-qt-mac.outputs.cache-hit }}
|
||||
setup-python: 'false'
|
||||
aqtversion: ==1.1.3
|
||||
|
||||
- uses: actions/checkout@v1
|
||||
name: Checkout
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: 0
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1
|
||||
with:
|
||||
key: ${{ runner.os }}-${{ matrix.configuration }}-${{ matrix.compiler }}
|
||||
|
||||
- name: Configure CMake
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
COMPILER: ${{ matrix.compiler }}
|
||||
ARCHITECTURE: ${{ matrix.arch }}
|
||||
JOB_CMAKE_OPTIONS: ${{ matrix.cmake_options }}
|
||||
run: $GITHUB_WORKSPACE/ci/linux/configure_cmake.sh
|
||||
- name: Compile
|
||||
working-directory: ./build
|
||||
run: LD_LIBRARY_PATH=$Qt5_DIR/lib:$LD_LIBRARY_PATH ninja all
|
||||
- name: Run Tests
|
||||
working-directory: ./build
|
||||
env:
|
||||
CONFIGURATION: ${{ matrix.configuration }}
|
||||
XDG_RUNTIME_DIR: /root
|
||||
run: $GITHUB_WORKSPACE/ci/linux/run_tests.sh
|
||||
- name: Run Clang Tidy
|
||||
# Clang-tidy reuses the precompiled headers so this only makes sense for the clang compilers
|
||||
if: startsWith(matrix.compiler, 'clang-')
|
||||
run: $GITHUB_WORKSPACE/ci/linux/clang_tidy.sh ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }}
|
||||
- name: Process clang-tidy warnings
|
||||
if: startsWith(matrix.compiler, 'clang-')
|
||||
uses: asarium/clang-tidy-action@v1
|
||||
with:
|
||||
fixesFile: clang-fixes.yaml
|
||||
+3
-1
@@ -26,6 +26,9 @@
|
||||
*.unsuccessfulbuild
|
||||
ipch/
|
||||
[Oo]bj/
|
||||
[Bb]in
|
||||
[Dd]ebug*/
|
||||
[Rr]elease*/
|
||||
Ankh.NoLoad
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
@@ -257,4 +260,3 @@ CMakeSettings.json
|
||||
# This gets ignored by one of the rules above for some reason...
|
||||
!/code/scripting/lua/LuaConvert.h
|
||||
!/code/debugconsole/
|
||||
!/docker/build
|
||||
@@ -1,6 +1,3 @@
|
||||
[submodule "cmake/external/rpavlik-cmake-modules"]
|
||||
path = cmake/external/rpavlik-cmake-modules
|
||||
url = https://github.com/asarium/cmake-modules.git
|
||||
[submodule "lib/libRocket"]
|
||||
path = lib/libRocket
|
||||
url = https://github.com/asarium/libRocket.git
|
||||
+136
-160
@@ -1,175 +1,151 @@
|
||||
language: bash
|
||||
language: generic
|
||||
sudo: required
|
||||
dist: xenial
|
||||
dist: trusty
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/cmake-3.8
|
||||
directories:
|
||||
- $HOME/cmake
|
||||
- $HOME/.ccache
|
||||
- $HOME/curl_cache
|
||||
addons:
|
||||
apt:
|
||||
packages: &global_deps
|
||||
- ninja-build
|
||||
- libopenal-dev
|
||||
- libreadline6-dev
|
||||
- libpng12-dev
|
||||
- libjpeg62-dev
|
||||
- liblua5.1-0-dev
|
||||
- libjansson-dev
|
||||
- libsdl2-dev
|
||||
- libfreetype6-dev
|
||||
- qt57base
|
||||
coverity_scan:
|
||||
project:
|
||||
name: "scp-fs2open/fs2open.github.com"
|
||||
notification_email: [email protected]
|
||||
build_command: "ci/travis/script.sh"
|
||||
# must match TRAVIS_BRANCH check below
|
||||
branch_pattern: coverity_scan
|
||||
apt:
|
||||
packages: &global_deps
|
||||
- ninja-build
|
||||
- libopenal-dev
|
||||
- libreadline6-dev
|
||||
- libpng12-dev
|
||||
- libjpeg62-dev
|
||||
- liblua5.1-0-dev
|
||||
- libjansson-dev
|
||||
- libsdl2-dev
|
||||
- valgrind
|
||||
- qt57base
|
||||
coverity_scan:
|
||||
project:
|
||||
name: "scp-fs2open/fs2open.github.com"
|
||||
notification_email: [email protected]
|
||||
build_command: "ci/travis/script.sh"
|
||||
# must match TRAVIS_BRANCH check below
|
||||
branch_pattern: coverity_scan
|
||||
env:
|
||||
global:
|
||||
# The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
|
||||
# via the "travis encrypt" command using the project repo's public key
|
||||
# also note that fork's don't get access to secure keys
|
||||
# you have to test using a branch in the main repo
|
||||
- secure: "C3wF967ZeliwwP1vC12EMIBOaC568n26Z/cPnwzn317ve59DWH3YSfPZVgvt08GzmaXITGGsJvPB+qxfGoKvQzYE4O1B73q81RpUe5pB3IhF+ThQ91VfQZIRJR5xEGJaLINUlHTTZGX5jxlkVO9wAcauVj/s3b8sQ3dvUZauPvk="
|
||||
# These declarations set INDIEGAMES_USER and INDIEGAMES_PASSWORD for uploading nightly builds to the indiegames server
|
||||
- secure: "lUuRu8XIi8MKNf1ebOfyC4iVEpPyASojJIDWXRo2bNqEF4ILAljXdkVeXeN6H5yKCHD52cxCNTtyePIG/o3p3QEuGSVud9bDS3D7LaQicLETGGrsw3l07U49gF2OKHXGopg0MzBbZUU9QmhoFTAe8t6PV9NDuEayYCheqvTqjZg="
|
||||
- secure: "E/DHLYcPK/hBUqxBYYlUqp5sjgvIqY5A0qRHyQ4bmjsB+WB/Xx71bGCSiF7hk6lTxar1ZI1i5RAXXh9AIvNVaYAIdEOlCP+q3gvwCYuc5naZEKmkxlUCf0oEL4O9Fye93A/3VkFHuBdC1TGPYYf69m4W5r4367wWO9dPRIdWpJA="
|
||||
# These declarations set DATACORDER_USER and DATACORDER_PASSWORD
|
||||
- secure: "dpBH/dDN3bmU/NFlh+2v9isNx9wX0ocoRy+W+kBXRH32sosUGp26REhMqgVRpBNP5oxPBU8ic5bEogxAYWCB+0xUygBbkxAwyMPgoA34s0OXdTCY/ofw14ni8qqV2Ffy7fQJbP/jkMURyiMHx3kBTxNv3YjxKJqLnOuOMlQLpT8="
|
||||
- secure: "tLMRBD1Ufp5iKNwlqPDVbbuczgusaXNoBJyAnPATpJq2YwlkW4j3PqP9rW5vd85+52xam2EOP20w9PoBR5J6FLdiXRu4Lf7yCEhSHFAgowVqQj8QcJpPlyXr90bM4emFGrGqpdxVwxyQ5AFhKwLuEZKsI14GYLN+UMEwpNCMing="
|
||||
global:
|
||||
# The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
|
||||
# via the "travis encrypt" command using the project repo's public key
|
||||
# also note that fork's don't get access to secure keys
|
||||
# you have to test using a branch in the main repo
|
||||
- secure: "C3wF967ZeliwwP1vC12EMIBOaC568n26Z/cPnwzn317ve59DWH3YSfPZVgvt08GzmaXITGGsJvPB+qxfGoKvQzYE4O1B73q81RpUe5pB3IhF+ThQ91VfQZIRJR5xEGJaLINUlHTTZGX5jxlkVO9wAcauVj/s3b8sQ3dvUZauPvk="
|
||||
# These declarations set INDIEGAMES_USER and INDIEGAMES_PASSWORD for uploading nightly builds to the indiegames server
|
||||
- secure: "lUuRu8XIi8MKNf1ebOfyC4iVEpPyASojJIDWXRo2bNqEF4ILAljXdkVeXeN6H5yKCHD52cxCNTtyePIG/o3p3QEuGSVud9bDS3D7LaQicLETGGrsw3l07U49gF2OKHXGopg0MzBbZUU9QmhoFTAe8t6PV9NDuEayYCheqvTqjZg="
|
||||
- secure: "E/DHLYcPK/hBUqxBYYlUqp5sjgvIqY5A0qRHyQ4bmjsB+WB/Xx71bGCSiF7hk6lTxar1ZI1i5RAXXh9AIvNVaYAIdEOlCP+q3gvwCYuc5naZEKmkxlUCf0oEL4O9Fye93A/3VkFHuBdC1TGPYYf69m4W5r4367wWO9dPRIdWpJA="
|
||||
# These declarations set FS2DOWNLOADS_USER and FS2DOWNLOADS_PASSWORD
|
||||
- secure: "h6GbMX2jLsW1bS9fCM9fthOSJ1nfQQIRWi6EUH2p8u4NFLD5Bfi/C8JhQPKHUzyo3wvKkSHl+PsW7bgr1oXLusRwAur/dtv2N3imqvtbfIz305b00hZlsvbcYmQmUzQFSAdOGShK57JJ5aKQKccaUBP25KqB7Q+JaqBRdaMBS54="
|
||||
- secure: "fUDAPAUUaaYZy8I4zU3SJ0JcK7aw4eb6eTdaEr7LyNyTMSfPgwY6P1MrbSQC0lJNQIUQ5ffjdxE5g7D7OYpoJF9L14ni4UY8t2QASt7kmpgcYihmjeuYy8FQXgmFG8CTxiWBPKTybZJ7voQcvIvRaNG7b2wM9PMfc5lRIondB6c="
|
||||
deploy:
|
||||
- provider: releases
|
||||
api_key:
|
||||
secure: "q619+eQTe7lv8UVphK4OIzU8Jw84KBbVkuprN2sWIubRcV3IbZr2+WahJoUMt+nyhiy3YjDYtstO2ZgkxupwnZgwGUBVIiD1c4SPuyy+HTjNMOtiVsEUHT2hf+xPAemWpTlK5HcwhMmHAOh6rt6dEj57QOg0gcmGiwD/tCbEriA="
|
||||
skip_cleanup: true
|
||||
file_glob: true
|
||||
file: "/tmp/builds/*"
|
||||
on:
|
||||
condition: '"$RELEASE_BUILD" == true'
|
||||
tags: true
|
||||
- provider: releases
|
||||
api_key:
|
||||
secure: "Wdt4Ccefo7a0ZDjEJQJgpghh7n72FtNJuKSAPUvoz4gtEX6Ct9J8yJI1t9V3jE3CTbbLJ21/Q6eZRDfT7UfNJe5DdepoJsP9DeFhKMWqQCq+AChqQWlm0KeZAffJoJreL8vXYhnRYcLT9ceZHEH6AqwN9TPV+xJziGPISAkYNZ8="
|
||||
skip_cleanup: true
|
||||
file_glob: true
|
||||
file: "/tmp/builds/*"
|
||||
on:
|
||||
condition: '"$RELEASE_BUILD" == true'
|
||||
tags: true
|
||||
|
||||
- provider: script
|
||||
script: bash ci/travis/ftp_deploy.sh
|
||||
on:
|
||||
condition: '"$NIGHTLY_BUILD" == true'
|
||||
tags: true
|
||||
- provider: script
|
||||
script: bash ci/travis/ftp_deploy.sh
|
||||
on:
|
||||
condition: '"$NIGHTLY_BUILD" == true'
|
||||
tags: true
|
||||
|
||||
- provider: script
|
||||
skip_cleanup: true
|
||||
script: bash ci/travis/ftp_deploy.sh
|
||||
on:
|
||||
condition: $TEST_BUILD = true
|
||||
all_branches: true
|
||||
- provider: script
|
||||
skip_cleanup: true
|
||||
script: bash ci/travis/ftp_deploy.sh
|
||||
on:
|
||||
condition: $TEST_BUILD = true
|
||||
all_branches: true
|
||||
|
||||
matrix:
|
||||
include:
|
||||
# note that gcc Debug MUST be 1st for Coverity
|
||||
- os: linux
|
||||
env: CONFIGURATION="Debug" CC=gcc-5 CXX=g++-5
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'ppa:beineri/opt-qt571-xenial'
|
||||
packages:
|
||||
- *global_deps
|
||||
- g++-5
|
||||
- os: linux
|
||||
env: CONFIGURATION="Debug" CC=gcc-9 CXX=g++-9
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'ppa:beineri/opt-qt571-xenial'
|
||||
packages:
|
||||
- g++-9
|
||||
- *global_deps
|
||||
- os: linux
|
||||
env: CONFIGURATION="Debug" CC=clang-9 CXX=clang++-9 CMAKE_OPTIONS="-DCMAKE_EXPORT_COMPILE_COMMANDS=ON"
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'ppa:beineri/opt-qt571-xenial'
|
||||
packages:
|
||||
- *global_deps
|
||||
- g++-9
|
||||
script:
|
||||
- ./ci/travis/script.sh
|
||||
- ./ci/travis/clang_tidy.sh
|
||||
- os: osx
|
||||
env: CONFIGURATION="Debug"
|
||||
|
||||
- os: windows
|
||||
env: CONFIGURATION="Debug" CMAKE_TOOLSET=v141 CMAKE_GENERATOR="Visual Studio 15 2017"
|
||||
- os: windows
|
||||
env: CONFIGURATION="Debug" CMAKE_TOOLSET="" CMAKE_GENERATOR="Ninja"
|
||||
|
||||
- os: linux
|
||||
env: CONFIGURATION="Release" CC=gcc-5 CXX=g++-5
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'ppa:beineri/opt-qt571-xenial'
|
||||
packages:
|
||||
- *global_deps
|
||||
- g++-5
|
||||
- os: linux
|
||||
env: CONFIGURATION="Release" CC=gcc-9 CXX=g++-9
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'ppa:beineri/opt-qt571-xenial'
|
||||
packages:
|
||||
- g++-9
|
||||
- *global_deps
|
||||
- os: linux
|
||||
env: CONFIGURATION="Release" CC=clang-9 CXX=clang++-9 CMAKE_OPTIONS="-DCMAKE_EXPORT_COMPILE_COMMANDS=ON"
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'ppa:beineri/opt-qt571-xenial'
|
||||
packages:
|
||||
- *global_deps
|
||||
- g++-9
|
||||
script:
|
||||
- ./ci/travis/script.sh
|
||||
- ./ci/travis/clang_tidy.sh
|
||||
- os: osx
|
||||
env: CONFIGURATION="Release"
|
||||
|
||||
- os: windows
|
||||
env: CONFIGURATION="Release" CMAKE_TOOLSET=v141 CMAKE_GENERATOR="Visual Studio 15 2017"
|
||||
- os: windows
|
||||
env: CONFIGURATION="Release" CMAKE_TOOLSET="" CMAKE_GENERATOR="Ninja"
|
||||
# There is a GCC compiler bug with MinGW that causes compilation failures on Windows at the moment
|
||||
allow_failures:
|
||||
- os: windows
|
||||
env: CONFIGURATION="Debug" CMAKE_TOOLSET="" CMAKE_GENERATOR="Ninja"
|
||||
- os: windows
|
||||
env: CONFIGURATION="Release" CMAKE_TOOLSET="" CMAKE_GENERATOR="Ninja"
|
||||
fast_finish: true
|
||||
include:
|
||||
# note that gcc Debug MUST be 1st for Coverity
|
||||
- os: linux
|
||||
env: CONFIGURATION="Debug" CC=gcc-5 CXX=g++-5
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'ppa:beineri/opt-qt571-trusty'
|
||||
packages:
|
||||
- *global_deps
|
||||
- g++-5
|
||||
- os: linux
|
||||
env: CONFIGURATION="Debug" CC=gcc-7 CXX=g++-7
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'ppa:beineri/opt-qt571-trusty'
|
||||
packages:
|
||||
- g++-7
|
||||
- *global_deps
|
||||
- os: linux
|
||||
env: CONFIGURATION="Debug" CC=clang-3.6 CXX=clang++-3.6
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- llvm-toolchain-precise
|
||||
- sourceline: 'ppa:beineri/opt-qt571-trusty'
|
||||
packages:
|
||||
- *global_deps
|
||||
- clang-3.6
|
||||
- libc++-dev
|
||||
- os: osx
|
||||
env: CONFIGURATION="Debug"
|
||||
|
||||
- os: linux
|
||||
env: CONFIGURATION="Release" CC=gcc-5 CXX=g++-5
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'ppa:beineri/opt-qt571-trusty'
|
||||
packages:
|
||||
- *global_deps
|
||||
- g++-5
|
||||
- os: linux
|
||||
env: CONFIGURATION="Release" CC=gcc-7 CXX=g++-7
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- sourceline: 'ppa:beineri/opt-qt571-trusty'
|
||||
packages:
|
||||
- g++-7
|
||||
- *global_deps
|
||||
- os: linux
|
||||
env: CONFIGURATION="Release" CC=clang-3.6 CXX=clang++-3.6
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- llvm-toolchain-precise
|
||||
- sourceline: 'ppa:beineri/opt-qt571-trusty'
|
||||
packages:
|
||||
- *global_deps
|
||||
- clang-3.6
|
||||
- libc++-dev
|
||||
- os: osx
|
||||
env: CONFIGURATION="Release"
|
||||
before_install:
|
||||
# ugly hack; if running a coverity scan abort all except the 1st build
|
||||
# see note re gcc compiler above needing to be 1st
|
||||
# also note that branch_pattern & the TRAVIS_BRANCH check must match
|
||||
# unfortunately COVERITY_SCAN_BRANCH isn't defined until later in the
|
||||
# build process
|
||||
- if ([[ "${TRAVIS_JOB_NUMBER##*.}" != "1" ]] && [[ "${TRAVIS_BRANCH}" == "coverity_scan" ]]); then false ; fi
|
||||
- source "./ci/travis/check_release.sh"
|
||||
- "./ci/travis/before_install.sh"
|
||||
# ugly hack; if running a coverity scan abort all except the 1st build
|
||||
# see note re gcc compiler above needing to be 1st
|
||||
# also note that branch_pattern & the TRAVIS_BRANCH check must match
|
||||
# unfortunately COVERITY_SCAN_BRANCH isn't defined until later in the
|
||||
# build process
|
||||
- if ([[ "${TRAVIS_JOB_NUMBER##*.}" != "1" ]] && [[ "${TRAVIS_BRANCH}" == "coverity_scan" ]]); then false ; fi
|
||||
- source "./ci/travis/check_release.sh"
|
||||
- "./ci/travis/before_install.sh"
|
||||
install:
|
||||
- if [ "$TRAVIS_OS_NAME" = "windows" ]; then export PATH="/c/Program Files/CMake/bin":$PATH; fi
|
||||
- "./ci/travis/install.sh"
|
||||
- export PATH=$HOME/cmake-3.6/bin:$PATH
|
||||
- "./ci/travis/install.sh"
|
||||
- export PATH=$HOME/cmake/bin:$PATH
|
||||
before_script:
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then QT_ENV_SCRIPT=$(find /opt -name 'qt*-env.sh'); source $QT_ENV_SCRIPT; fi
|
||||
- "./ci/travis/before_script.sh"
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then QT_ENV_SCRIPT=$(find /opt -name 'qt*-env.sh'); source $QT_ENV_SCRIPT; fi
|
||||
- "./ci/travis/before_script.sh"
|
||||
script:
|
||||
- if [ "$BUILD_DEPLOYMENT" = true ] ; then ./ci/travis/release.sh ; else ./ci/travis/script.sh ; fi
|
||||
- if [ "$BUILD_DEPLOYMENT" = true ] ; then ./ci/travis/release.sh ; else ./ci/travis/script.sh ; fi
|
||||
@@ -0,0 +1,29 @@
|
||||
Original source (Freespace 2) by Volition, Inc.; see "credits.tbl"
|
||||
|
||||
Modifications by the FreeSpace Source Code Project (FSSCP)
|
||||
http://fs2source.warpcore.org
|
||||
|
||||
FS2_OPEN STAFF:
|
||||
|
||||
Project leader:
|
||||
Edward "Inquisitor" Gardner
|
||||
|
||||
Programmers:
|
||||
"Bobboau"
|
||||
Dennis "DTP" Pedersen
|
||||
Ian "Goober5000" Warfield
|
||||
Joe "Righteous1" Dowd
|
||||
Mike "penguin" Harris
|
||||
"Mysterial"
|
||||
"PhReAk"
|
||||
Thomas "Random Tiger" Whittaker
|
||||
Will "Unknown PLayer" Rousnel
|
||||
"WMCoolmon"
|
||||
|
||||
Web support:
|
||||
Icefire and the staff at Volitionwatch.com
|
||||
Alex "Thunder" Avery and the staff at Hard Light Productions
|
||||
|
||||
Special thanks to:
|
||||
Volition for making FS2 such a great game
|
||||
Dave Baranec for giving us the code and keeping us sanity checked
|
||||
@@ -1,41 +0,0 @@
|
||||
## FreeSpace
|
||||
FreeSpace: The Great War (Released 1998) and FreeSpace 2 (1999) are mission-based space combat simulators, like X-Wing/TIE Fighter and Wing Commander. Among the greatest games of the genre, they were also effectively the last.
|
||||
|
||||
The FreeSpace series follows humanity and their Vasudan allies as they fight to withstand the xenocidal, enigmatic Shivans, a species of unknown origin, vast technological capability, and seemingly limitless malice.
|
||||
|
||||
## FreeSpace Open
|
||||
Thanks to Volition's generosity, we've continued development of FreeSpace 2 as FreeSpace Open, building graphical enhancements to bring the original games up to modern standards, telling new stories set in the FreeSpace universe and original worlds, and creating spectacular total conversions that let players fly in the beloved universes of Babylon 5, Battlestar Galactica, Wing Commander, and Star Wars.
|
||||
|
||||
## Hard-Light Productions
|
||||
HLP is a fan community built on love and open-source code. We're dedicated to bringing modders together and giving them a place to share their own hard work and draw inspiration from the work of others. Thanks to Volition's generosity, we've continued development of FreeSpace 2 as FreeSpace Open, building graphical enhancements to bring the original games up to modern standards, telling new stories set in the FreeSpace universe and original worlds, and creating spectacular total conversions that let players fly in the beloved universes of Babylon 5, Battlestar Galactica, Wing Commander, and Star Wars.
|
||||
Find us at:
|
||||
- Our [website](http://www.hard-light.net/) and [forums](http://www.hard-light.net/forums/)
|
||||
- [Discord](https://discord.gg/YNVP3WR)
|
||||
- [Facebook](https://www.facebook.com/groups/Hardlightproductions/)
|
||||
- [Youtube](https://www.youtube.com/channel/UCxKkd609hDtY6yNetR1iT4w)
|
||||
- [Reddit](https://www.reddit.com/r/freespace/)
|
||||
- [Twitter](https://twitter.com/hardlightpro)
|
||||
- [IRC](irc://irc.esper.net/hard-light)
|
||||
|
||||
|
||||
## How to get the game
|
||||
FreeSpace Open requires a retail installation of FreeSpace 2, which is available at the following stores:
|
||||
- [GOG.com](https://www.gog.com/game/freespace_2)
|
||||
- [Steam](https://store.steampowered.com/app/273620/Freespace_2/)
|
||||
After installing retail FS2, use [Knossos](https://fsnebula.org/knossos/) to upgrade to the most recent release of FSO. Knossos is an advanced mod manager and launcher for FSO.
|
||||
|
||||
## Improvements
|
||||
The new open source game engine has several distingushing features including:
|
||||
- Linux and Mac OS X support
|
||||
- OpenGL support
|
||||
- OpenAL audio support
|
||||
- Easy mod installation
|
||||
- OGG support
|
||||
- Hardware transform, clipping, and lighting
|
||||
|
||||
## The FreeSpace Upgrade Project
|
||||
While the SCP improves the code of the game engine to enable new and exciting features, the FreeSpace Upgrade Project (FSU) creates material that takes advantage of the improved game engine.
|
||||
The FSU improves the ships, effects, and background elements of FreeSpace 2. Every now and then these improvements are released as a pack called MediaVPs. These assorted improvements enhance the graphics of the game.
|
||||
While the best way to experience the FSU is by playing the game with it, you can watch this [comparison video](https://www.youtube.com/watch?v=RM1YC_gK-qo) between 1999 and 2019 to have an idea of how much more beautiful FSU makes the game.
|
||||
|
||||
^(Much of this content was pulled from existing sources, such as InsaneBaron's "What Is Hard Light Productions" [thread](https://www.hard-light.net/forums/index.php?topic=86650.0), the Wiki's [Getting Started article](https://wiki.hard-light.net/index.php/Getting_started) and more.)
|
||||
@@ -1,8 +0,0 @@
|
||||
Original source (Freespace 2) by Volition, Inc.; see "`credits.tbl`"
|
||||
|
||||
Modifications by the FreeSpace 2 Source Code Project [(FSO SCP)](https://www.hard-light.net/forums/index.php?board=50.0)
|
||||
[Project Contributors](https://github.com/scp-fs2open/fs2open.github.com/graphs/contributors)
|
||||
|
||||
Special thanks to:
|
||||
Volition for making FS2 such a great game
|
||||
Dave Baranec for giving us the code and keeping us sanity checked
|
||||
+6
-36
@@ -8,10 +8,9 @@ if ("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
endif()
|
||||
|
||||
include(cmake/util.cmake)
|
||||
include(cmake/embed_file.cmake)
|
||||
|
||||
# Set a few policies
|
||||
set_policy(CMP0051 NEW)
|
||||
set_policy(CMP0051 OLD)
|
||||
set_policy(CMP0053 NEW)
|
||||
set_policy(CMP0054 NEW)
|
||||
|
||||
@@ -43,16 +42,10 @@ PROJECT(FS2_Open)
|
||||
|
||||
find_program(CCACHE_PROGRAM ccache)
|
||||
# Currently only GCC support ccache properly without generating additional warnings
|
||||
# Enable ccache on Mac even for clang
|
||||
if(CCACHE_PROGRAM AND ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR APPLE))
|
||||
if(NOT CMAKE_C_COMPILER_LAUNCHER)
|
||||
message(STATUS "Using ccache for C compilation: ${CCACHE_PROGRAM}")
|
||||
SET(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_PROGRAM})
|
||||
endif()
|
||||
if(NOT CMAKE_CXX_COMPILER_LAUNCHER)
|
||||
message(STATUS "Using ccache for C++ compilation: ${CCACHE_PROGRAM}")
|
||||
SET(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_PROGRAM})
|
||||
endif()
|
||||
if(CCACHE_PROGRAM AND "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
message(STATUS "Using ccache for compilation: ${CCACHE_PROGRAM}")
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK "${CCACHE_PROGRAM}")
|
||||
endif()
|
||||
|
||||
IF(CMAKE_CROSSCOMPILING)
|
||||
@@ -91,6 +84,7 @@ IF (WIN32)
|
||||
OPTION(FSO_BUILD_FRED2 "Build FRED2 binary" ON)
|
||||
elseif(UNIX)
|
||||
option(FSO_BUILD_APPIMAGE "Build an AppImage package" OFF)
|
||||
set(APPIMAGE_ASSISTANT "" CACHE STRING "The root directory of an AppImage clone.")
|
||||
ENDIF(WIN32)
|
||||
|
||||
OPTION(FSO_BUILD_TOOLS "Build tools related to FSO" OFF)
|
||||
@@ -122,16 +116,6 @@ SET(FSO_RUN_ARGUMENTS "" CACHE STRING "Additional arguments passed to a generate
|
||||
|
||||
option(FSO_INSTALL_DEBUG_FILES "Install some debug files (currently only PDB files on windows)" OFF)
|
||||
|
||||
option(ENABLE_COTIRE "Enable cotire for faster compilation. Enabled by default." ON)
|
||||
|
||||
option(FSO_RELEASE_LOGGING "Enable logging output for release builds" OFF)
|
||||
|
||||
OPTION(FSO_BUILD_WITH_FFMPEG "Enable the usage of FFmpeg for sound and custscenes" ON)
|
||||
|
||||
OPTION(FSO_BUILD_WITH_OPENGL "Enable compilation of the OpenGL renderer" ON)
|
||||
|
||||
OPTION(FSO_BUILD_WITH_VULKAN "Enable compilation of the Vulkan renderer" ON)
|
||||
|
||||
MARK_AS_ADVANCED(FORCE FSO_CMAKE_DEBUG)
|
||||
MARK_AS_ADVANCED(FORCE FSO_BUILD_INCLUDED_LIBS)
|
||||
MARK_AS_ADVANCED(FORCE FSO_USE_OPENALSOFT)
|
||||
@@ -139,11 +123,6 @@ MARK_AS_ADVANCED(FORCE FSO_USE_LUAJIT)
|
||||
MARK_AS_ADVANCED(FORCE FSO_DEVELOPMENT_MODE)
|
||||
MARK_AS_ADVANCED(FORCE FSO_FATAL_WARNINGS)
|
||||
mark_as_advanced(FORCE FSO_INSTALL_DEBUG_FILES)
|
||||
mark_as_advanced(FORCE ENABLE_COTIRE)
|
||||
mark_as_advanced(FORCE FSO_RELEASE_LOGGING)
|
||||
mark_as_advanced(FORCE FSO_BUILD_WITH_FFMPEG)
|
||||
mark_as_advanced(FORCE FSO_BUILD_WITH_OPENGL)
|
||||
mark_as_advanced(FORCE FSO_BUILD_WITH_VULKAN)
|
||||
|
||||
# Include cotire file from https://github.com/sakra/cotire/
|
||||
include(cotire)
|
||||
@@ -163,15 +142,11 @@ if(FSO_BUILD_APPIMAGE)
|
||||
include(appimage)
|
||||
endif()
|
||||
|
||||
include(clang-tidy)
|
||||
|
||||
# This includes source code for some tools, either used in the build or also for something else
|
||||
ADD_SUBDIRECTORY(tools)
|
||||
|
||||
ADD_SUBDIRECTORY(lib)
|
||||
|
||||
ADD_SUBDIRECTORY(parsers)
|
||||
|
||||
ADD_SUBDIRECTORY(code)
|
||||
|
||||
ADD_SUBDIRECTORY(freespace2)
|
||||
@@ -211,14 +186,9 @@ include(doxygen)
|
||||
IF (WIN32)
|
||||
message(STATUS "Using text to speech: ${FSO_USE_SPEECH}")
|
||||
message(STATUS "Using voice recogition: ${FSO_USE_VOICEREC}")
|
||||
message(STATUS "Building FRED2: ${FSO_BUILD_FRED2}")
|
||||
elseif(UNIX)
|
||||
message(STATUS "Building AppImage: ${FSO_BUILD_APPIMAGE}")
|
||||
ENDIF()
|
||||
message(STATUS "Building FSO tools: ${FSO_BUILD_TOOLS}")
|
||||
message(STATUS "Building qtFRED: ${FSO_BUILD_QTFRED}")
|
||||
message(STATUS "Fatal warnings: ${FSO_FATAL_WARNINGS}")
|
||||
message(STATUS "Release logging: ${FSO_RELEASE_LOGGING}")
|
||||
message(STATUS "With FFmpeg: ${FSO_BUILD_WITH_FFMPEG}")
|
||||
message(STATUS "With OpenGL: ${FSO_BUILD_WITH_OPENGL}")
|
||||
message(STATUS "With Vulkan: ${FSO_BUILD_WITH_VULKAN}")
|
||||
@@ -0,0 +1,14 @@
|
||||
Volition Copyright (applies to original FreeSpace2 source code
|
||||
developed and released by Volition):
|
||||
|
||||
"Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
|
||||
All source code herein is the property of Volition, Inc. You may not
|
||||
sell or otherwise commercially exploit the source or things you
|
||||
created based on the source."
|
||||
|
||||
|
||||
Modifications by members of the FreeSpace Source Code Project are
|
||||
released under whatever terms the individual authors choose, but the
|
||||
above notice continues to apply to all fs2_open code.
|
||||
|
||||
+19
-179
@@ -1,182 +1,23 @@
|
||||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
|
||||
|
||||
## [22.0.0] - 2022-04-01 ([Thread](https://www.hard-light.net/forums/index.php?topic=98125.0))
|
||||
### Changed
|
||||
- Controls5 PR (aka multi-joy)
|
||||
- Timing system upgrade
|
||||
- Model animation code upgrades
|
||||
|
||||
|
||||
## [21.4.0] - 2021-09-27 ([Thread](https://www.hard-light.net/forums/index.php?topic=97802.0))
|
||||
### Changed
|
||||
- Multiple features; see thread
|
||||
- Multiple bugfixes; see thread
|
||||
### Deprecations
|
||||
- `script-eval` has been deprecated in favor of `script-eval-block`
|
||||
- renamed `hud-set-retail-gauge-active` to `hud-set-builtin-gauge-active`
|
||||
|
||||
|
||||
## [21.2.0] - 2021-05-02 ([Thread](https://www.hard-light.net/forums/index.php?topic=97561.0))
|
||||
### Changed
|
||||
- Added a dynamic action system for more modder control of effects
|
||||
- Removed fireball limit
|
||||
- Fixed bomb intercept in multiplayer
|
||||
- Changed nebula fog distance from a linear to exponential model
|
||||
- Turrets on moving subobjects enabled
|
||||
- LZ4 Compression added for game files
|
||||
|
||||
|
||||
## [21.0.0] - 2021-01-27 ([Thread](https://www.hard-light.net/forums/index.php?topic=97293.0))
|
||||
### Changed
|
||||
- More OpenGL optimizations
|
||||
- Full type information output for Lua documentation. Very useful for writing Lua scripts.
|
||||
- A new -weaponspew command-line option for printing MediaVP-style statistics, plus a weapon comparison spreadsheet, to the debug log.
|
||||
- Improved ship lookup behavior in SEXPs for improved performance.
|
||||
- BPTC/BC7 texture compression support
|
||||
- Refactoring and new features for the ship lab.
|
||||
- Missile multi-lock. It's finally in an official build!
|
||||
- Enhancements to the model code in preparation for cool features in 21.2.
|
||||
- IPv6 support for multiplayer
|
||||
- A lot of general fixes for multiplayer.
|
||||
### Deprecated
|
||||
- Dropped support for Windows XP
|
||||
- Scripting:
|
||||
- `ba.getFrametime()`: The parameter value was used incorrectly inside the implementation. To avoid breaking existing scripts and to improve readability this has been split into `ba.getMissionFrametime()` and `ba.getRealFrametime()`.
|
||||
- `gr.drawMonochromeImage()`: `gr.drawImage()` got a new parameter for drawing monochrome images and is more flexible in general so the monochrome variant is no longer needed.
|
||||
|
||||
|
||||
## [19.0.0] - 2020-01-25 ([Thread](https://www.hard-light.net/forums/index.php?topic=96226.0))
|
||||
### Meta
|
||||
- With this release we decided to drop the "`3.Major_revision.Minor_revision`" versioning scheme in favor of a year based scheme since the Major and Minor versions did not have much meaning anymore. Instead the scheme will now be "`<year>.<number that is incremented every release>.0`". The last 0 is still there because some of our systems expect that. It will be gone at some point.
|
||||
### Added
|
||||
- Full Unicode text support: You can now use non-ASCII characters without having to worry about special fonts and special characters. This is an opt-in mod flag.
|
||||
- Translation features for making it easier to only distribute one version of a mod which includes all languages.
|
||||
- OpenAL Soft is included by default in binary distributions of FSO now.
|
||||
- System for dynamically adding new SEXPs. With this a Lua script can expose functionality to the mission which can be used exactly the same as a standard SEXP with all the usual editing features in FRED.
|
||||
- Support for displaying decals on the surface of an object.
|
||||
- Integrated support for the [Discord Rich Presence API](https://discordapp.com/rich-presence).
|
||||
- New markup based user interface system using [libRocket](https://github.com/libRocket/libRocket).
|
||||
### Changed
|
||||
- Exposed the movie player to the scripting API for advanced display features
|
||||
- Various OpenGL optimizations for better graphics performance:
|
||||
- Animations now use texture arrays
|
||||
- Model uniforms get sent to the GPU using uniform buffers for less overhead
|
||||
- Various other minor changes
|
||||
- Converted pilot files from custom binary format to JSON
|
||||
- Replaced Blinn-Phong BRDF with GGX BRDF
|
||||
### Fixed
|
||||
- Refactored bitmap slot handling and removed the fixed upper limit on the number of bitmaps. No more bmpman corruption!
|
||||
|
||||
|
||||
## [3.8.0] - 2017-08-22 ([Release Thread](https://www.hard-light.net/forums/index.php?topic=93812.0))
|
||||
### Added
|
||||
- Support for APNG animations: [APNG](https://en.wikipedia.org/wiki/APNG) is a variant of the established PNG format which allows to store animations instead of single frames in a PNG file. This change allows to use these animation files in FSO which significantly improves usability for modders since they no longer have to store all individual frames as separate images.
|
||||
- Physically-Based Rendering (PBR): This upgrade of our rendering engine allows to use [PBR](https://en.wikipedia.org/wiki/Physically_based_rendering) assets to make models look more realistic and allow more artistic freedom for modders since they have more control over how a model looks. This also added support for HDR lighting which should improve the overall graphics experience.
|
||||
- Native particle systems: Particles have always been supported by FSO but the effects that could be created by them were very limited. There were some attempts to fix this by using Lua scripting for more advanced features but that suffered from performance issues. With these new particle systems that feature has been integrated directly into the engine which should improve performance and allow for better effects in the future.
|
||||
- TrueType Font support: [TrueType](https://en.wikipedia.org/wiki/TrueType) fonts improve the text rendering capabilities of FSO by allowing to use freely scaleable font faces instead of the previous bitmap fonts.
|
||||
### Changed
|
||||
- We now use SDL2 on all platforms: SDL is a library for abstracting away the differences between different platforms. We now use SDL2 for all platforms which reduces the amount of platform-specific code tremendously and should result in better usability on all platforms. This was a major change that has been in development for several years. Here are a few key features that were added:
|
||||
- Pilot and configuration data is now stored in the correct location across all platforms (this allows to run FSO on Windows from the Program Files directory without administrator rights)
|
||||
- All platforms now use the ini files for storing settings. This fixes a lot of issues with the registry on Windows.
|
||||
- Better support for input devices. Since SDL handles keyboard, mouse and joystick input we now have better support on newer OS versions. Note: This does not mean that we support multiple joysticks (yet). There is ongoing development effort to support this but this release does not have that yet.
|
||||
- CMake build system generation: This isn't relevant for players but we are now using [CMake](https://en.wikipedia.org/wiki/CMake) for handling compiling our builds. This improves cross-platform support and allows to implement advanced compilation features across multiple platforms. Modders will like the new "FastDebug" builds which are like the previous "Debug" builds but are compiled with all the optimizations of normal Release builds. That should make modding a lot easier since you can now debug your mod with almost the same performance as a Release build.
|
||||
- Improved shield effects: Rendering of the shields is now handled by special shaders which improves the overall quality of the effects and allows more freedom for future effects.
|
||||
- Use OpenGL Core Profile for rendering: This is another major graphical upgrade which adds support for the OpenGL Core profile across all platforms (this was also made possible by the SDL2 integration). This upgrade allows us to use more modern rendering techniques and is especially useful for our Linux users who use the open-source Mesa drivers since our shaders failed to compile with those drivers. Now everyone will be able to enjoy the new graphical features added in this and previous releases. This also made some internal changes to how we handle rendering which improves the usability of our rendering engine within our code.
|
||||
- Use FFmpeg for video & audio decoding: [FFmpeg](https://www.ffmpeg.org/) is a multi-media library which exposes functionality for decoding video and audio files to their raw form so that we can use that data. Thanks to this library we can now play 1080p cutscenes without any stuttering or frame-timing issues. It also allows to use more advanced audio and video codecs such as H.264 for video or Opus for audio.
|
||||
|
||||
|
||||
## [3.7.4] - 2016-07-04 ([Release thread](http://www.hard-light.net/forums/index.php?topic=92181.0))
|
||||
### Changed
|
||||
- Major graphics update including deferred lighting and shadows
|
||||
- Enhanced sound (up to 128 channels)
|
||||
### Fixed
|
||||
- "Tons" of bugfixes
|
||||
|
||||
|
||||
## [3.7.2] - 2015-04-23 ([Release thread](http://www.hard-light.net/forums/index.php?topic=89597.0))
|
||||
### Added
|
||||
- MediaVPS 2014 Support
|
||||
- Autospread on model point shields
|
||||
- WebUI based multiplayer standalone server (for non-Windows platforms)
|
||||
- Toggle subsytem scanning, scannable, cargo revealed, hidden from sensors, stealth and friendly stealth added to the `alter-ship-flag` SEXP
|
||||
- Support added to add more languages besides English, French, German and Polish, leading the way to better localization!
|
||||
- `player-is-cheating` SEXP
|
||||
- New ship flag to enable smarter AI use of afterburners. Now it can use them while flying waypoints or attacking capital ships (use the `free-afterburner-use` flag with `alter-ship-flag`)
|
||||
- Experimental configurations to make AVX builds (see [this post](http://www.hard-light.net/forums/index.php?topic=85566.0) for more explanations)
|
||||
- Frame profiling code, see what exactly is slowing down FreeSpace. (Mostly for devs or coders)
|
||||
### Changed
|
||||
- Unstretched interface screens
|
||||
- Automatically non stretched HUD gauges and simpler modder options for placing HUD gauges
|
||||
- `show-subtitle-text` can now display messages as well as raw text
|
||||
- Allow a user-specified number of credit images
|
||||
- event.log can now snapshot events checked in a frame and record the status of an event the previous time it was checked as well as the current state
|
||||
- Allow the specification of the positions of medals, callsigns and labels on the medal screen.
|
||||
- The number of medals is now dynamic!
|
||||
- `is-facing` now works for things that aren't ships (like waypoints!)
|
||||
- allowing `fade-in` and `fade-out` sexps to use any color, not just black, white and red.
|
||||
|
||||
|
||||
## [3.7.0] - 2013-08-31 ([Release thread](http://www.hard-light.net/forums/index.php?topic=85435.0))
|
||||
### Major Change
|
||||
- New Flexible Pilot Save File Code (combines single/multi pilots & allows safe switching between unfinished campaigns)
|
||||
### Changed
|
||||
- Raised the per-model debris limit to 48 (previously 32).
|
||||
- Increased the per-frame debris limit to 96 (previously 64)
|
||||
|
||||
|
||||
## [3.6.18] - 2013-03-01 ([Release thread](http://www.hard-light.net/forums/index.php?topic=83889.0))
|
||||
### Fixed
|
||||
- Critical damage bug which caused heavy balance issues in the game
|
||||
|
||||
|
||||
## [3.6.16] - 2013-01-31 ([Release thread](http://www.hard-light.net/forums/index.php?topic=83577.0))
|
||||
### Added
|
||||
- Diaspora TC support
|
||||
### Changed
|
||||
- Performance Improvements
|
||||
|
||||
|
||||
## [3.6.14] - 2012-10-23 - ([Release thread](https://www.hard-light.net/forums/index.php?topic=82648.0))
|
||||
### Added
|
||||
- Objecttype tables support for deciding how enemies respond to ship classes when disabled
|
||||
- Allow modders to set a [mood](http://www.hard-light.net/forums/index.php?topic=81991.msg1639770#msg1639770) for builtin messages and then switch the mood for the mission on the fly using a SEXP
|
||||
- Allow modders to set the chance of builtin messages being sent, how many will be sent per mission and how long is the delay between two messages
|
||||
- Allow campaigns to be hidden in the campaign and tech rooms ([Game settings.tbl](https://wiki.hard-light.net/index.php/Game_settings.tbl#.23Ignored_Campaign_File_Names))
|
||||
- Allow mods to set a default campaign ([Game settings.tbl](https://wiki.hard-light.net/index.php/Game_settings.tbl#.24Default_Campaign_File_Name:))
|
||||
- New SEXPs
|
||||
- `set-player-orders`
|
||||
- `is-event\goal-true\false-msecs-delay`
|
||||
- `get\set-num-countermeasures`
|
||||
- `directive-value`
|
||||
- `invalidate-all-arguments`
|
||||
- `validate-all-arguments`
|
||||
- `has-primary-weapon`
|
||||
- `has-secondary-weapon`
|
||||
- [`hud-display-gauge`](http://www.hard-light.net/forums/index.php?topic=68837.msg1361711#msg1361711)
|
||||
- `get-object-speed-x`
|
||||
- `get-object-speed-y`
|
||||
- `get-object-speed-z`
|
||||
### Changed
|
||||
- Major HUD gauges overhaul
|
||||
- Split the Locked flag so that you can lock Ships or Weapons on the game loadout screen independently
|
||||
- Mixed ammo for primary and secondary weapons - [`$Substitute`](http://www.hard-light.net/wiki/index.php/Weapons.tbl#.24Substitute:) - Allows you to have a weapon that fires other weapon ammo in a specific pattern (say a Gatling gun with tracers).
|
||||
- [`show-subtitle`](https://wiki.hard-light.net/index.php/SCP_SEXPs#show-subtitle) SEXP supports custom fonts
|
||||
- The active support ship limit per side is now dynamic. See [`set-support-ship`](https://wiki.hard-light.net/index.php/SCP_SEXPs#set-support-ship) for more info.
|
||||
### Fixed
|
||||
- Various multiplayer SEXP fixes
|
||||
- `rotating-subsys-set-time` now accelerates properly
|
||||
- [Fixed a whole heap of memory, logic and coding errors](http://www.hard-light.net/forums/index.php?topic=78044.0) -- using PVS-Studio: C/C++ source code analysis and checking tool
|
||||
|
||||
----
|
||||
|
||||
## [Older Changes] - Unformatted
|
||||
```
|
||||
ChangeLog for fs2_open. All times are UTC.
|
||||
|
||||
Features: September 2013
|
||||
http://www.hard-light.net/forums/index.php?topic=85700.0
|
||||
|
||||
- show-subtitle-text can now display messages as well as raw text - Goober5000
|
||||
- toggle subsytem scanning, scannable, cargo revealed, hidden from sensors, stealth and friendly stealth added to the alter-ship-flag sexp - karajorma
|
||||
- Support added to add more languages besides English, French, German and Polish, leading the way to better localization! - karajorma
|
||||
- event.log can now snapshot events checked in a frame and record the status of an event the previous time it was checked as well as the current state - karajorma
|
||||
- added a player-is-cheating sexp - The E
|
||||
- allow a user-specified number of credit images - Goober5000
|
||||
- allow the specification of the positions of medals, callsigns and labels on the medal screen. - Goober5000
|
||||
- lua function to check if a ship is warp capable, and access to a ship's auto-aim FOV - zookeeper
|
||||
- is-facing now works for things that aren't ships (like waypoints!) - zookeeper
|
||||
- experimental configurations to make AVX builds (see this post for more explainations) - The E
|
||||
- new ship flag to enable smarter AI use of afterburners. Now it can use them while flying waypoints or attacking capital ships (use the free-afterburner-use flag with alter-ship-flag) - Admiral MS
|
||||
- the number of medals is now dynamic! - Goober5000
|
||||
- frame profiling code, see what exactly is slowing down FreeSpace. (Mostly for devs or coders) - Swifty + The E
|
||||
- allowing fade-in and fade-out sexps to use any color, not just black, white and red. - Goober5000
|
||||
|
||||
==================================================================
|
||||
( massive gap in updates, maybe this will be filled in someday...)
|
||||
==================================================================
|
||||
@@ -510,7 +351,7 @@ ChangeLog for fs2_open. All times are UTC.
|
||||
(2.1.2.4), weapon/weapons.cpp (2.1.2.2):
|
||||
|
||||
Sorted out some bits and pieces. The background nebula blends now
|
||||
which is nice. – RT
|
||||
which is nice. – RT
|
||||
|
||||
2002-09-28 12:20 randomtiger
|
||||
|
||||
@@ -2045,4 +1886,3 @@ NOTE:
|
||||
|
||||
# generated by cvs2cl.pl
|
||||
# cvs2cl.pl -r -S --utc -f ChangeLog2
|
||||
```
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
Volition Copyright (applies to original FreeSpace2 source code
|
||||
developed and released by Volition):
|
||||
|
||||
>Copyright (C) Volition, Inc. 1999. All rights reserved.
|
||||
>
|
||||
>All source code herein is the property of Volition, Inc. You may not
|
||||
sell or otherwise commercially exploit the source or things you
|
||||
created based on the source.
|
||||
|
||||
|
||||
Modifications by members of the FreeSpace Source Code Project are
|
||||
released under whatever terms the individual authors choose, but the
|
||||
above notice continues to apply to all fs2_open code.
|
||||
|
||||
All modifications made on or after November 1, 2020, shall be released under
|
||||
the terms within [Unlicense](Unlicense.md). Modifications made before said date are released
|
||||
under the previous terms with the exception of modifications made by members
|
||||
of the FreeSpace Source Code Project that opt-in to the terms of Unlicense. Additionally,
|
||||
a list of contributors who have opted in to the Unlicense terms can be found
|
||||
in [**Licensing**](https://github.com/scp-fs2open/fs2open.github.com/wiki/Licensing).
|
||||
|
||||
See [**Licensing**](https://github.com/scp-fs2open/fs2open.github.com/wiki/Licensing) for more information.
|
||||
Binary file not shown.
@@ -0,0 +1,29 @@
|
||||
This is still in pretty rough form.
|
||||
|
||||
|
||||
=== for people building fs2_open:
|
||||
|
||||
Win32-MSVC:
|
||||
Use the Freespace2.dsw workspace and build within the IDE.
|
||||
|
||||
|
||||
Win32-MinGW:
|
||||
make
|
||||
|
||||
|
||||
Linux and other unix variants (NOT YET COMPLETE)
|
||||
./configure [options]
|
||||
make
|
||||
|
||||
|
||||
|
||||
=== for the project maintainers (people who need to
|
||||
=== keep the makefiles up to date) and those building
|
||||
=== from CVS:
|
||||
|
||||
./autogen.sh (should only has to be done once)
|
||||
./configure [options]
|
||||
make
|
||||
|
||||
automake v1.6.1+ and
|
||||
autoconf v2.54+ are required
|
||||
@@ -7,5 +7,36 @@ FreeSpace2 *S*ource *C*ode *P*roject
|
||||
Building
|
||||
--
|
||||
Before you do anything, make sure you have updated your git submodules, either by running `git submodule update --init --recursive` or by cloning the repository with the `--recursive` flag.<br/>
|
||||
<br/>
|
||||
For building you will need [CMake](http://www.cmake.org/cmake/resources/software.html). Version 3.4 is required. Once you have installed CMake you should create a build directory where the project/make files should be created, **do not create them inside the source tree!**<br>
|
||||
<br>
|
||||
On Windows you can use the `cmake-gui` executable to get a nice GUI, on Unix just use `cmake`. Use the newly created directory as build directory (change to this directory on Unix) and run cmake. On Windows this can be done by clicking the `Configure` button. Choose your compiler version and hit `Generate` when configuring is done. <br>
|
||||
Depending on the makefile generator used build the `all` or `ALL_BUILD` target to compile the project.<br>
|
||||
|
||||
The main instructions for building can be found at our github wiki, on the [Building](https://github.com/scp-fs2open/fs2open.github.com/wiki/Building) page.
|
||||
### Available variables to control the build
|
||||
* `FSO_BUILD_WXFRED2`: Build the wxfred2 project, requires wxWidgets
|
||||
* `FSO_FREESPACE_PATH`: Sets the path of your FreeSpace install, can be used to automatically run the generated executables with the correct working directory, this is an optional variable. By default this will use the value of the `FS2PATH` environment variable.
|
||||
* `FSO_BUILD_TOOLS`: Build some tools related to FSO
|
||||
* `CMAKE_BUILD_TYPE`: Sets the binary build type between `Debug` and `Release` (default)
|
||||
|
||||
#### Windows only variables
|
||||
* `FSO_BUILD_FRED2`: Build FRED2, requires a Visual Studio version that ships with MFC
|
||||
* `FSO_USE_SPEECH`: Build a binary with text-to-speech support
|
||||
* `FSO_USE_VOICEREC`: Build a binary with voice recognition support
|
||||
|
||||
#### Advanced variables
|
||||
You should only use these variables if you know what you're doing
|
||||
* `FSO_CMAKE_DEBUG`: Print CMake debugging informations
|
||||
* `FSO_BUILD_INCLUDED_LIBS`: Build libraries from the included source
|
||||
* `FSO_USE_OPENALSOFT`: Use [OpenALSoft](http://kcat.strangesoft.net/openal.html) for OpenAL support
|
||||
* `FSO_USE_LUAJIT`: Use [luajit](http://luajit.org/) as a replacement for lua
|
||||
* `FSO_DEVELOPMENT_MODE`: Toggles some development behavior, only use if you really need it.
|
||||
* `FSO_RUN_ARGUMENTS`: If you run an executable from within the project, these arguments will also be passed to the executable
|
||||
* `FSO_BUILD_POSTFIX`: Sets a postfix to be added to the executable name, may be useful for release candidates.
|
||||
|
||||
#### Visual Studio specific variables
|
||||
* `MSVC_USE_RUNTIME_DLL`: Use the DLL version of the runtime, experimental and not well tested.
|
||||
* `MSVC_SIMD_INSTRUCTIONS`: The instruction set the executables will be optimized for.
|
||||
|
||||
### Generating an installation package
|
||||
CMake can automatically generate installation packages of the project. To do this you will just need to run the `package` target of the build system and the package will be placed inside your build directory. On Windows you will have to install [NSIS](http://nsis.sourceforge.net/Main_Page) to use this.
|
||||
@@ -1,24 +0,0 @@
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to [**Unlicense**](https://unlicense.org).
|
||||
@@ -1,18 +0,0 @@
|
||||
#Updating Documentation
|
||||
####The goal of this file is simply to offer a comprehensive checklist of things we must check when updating the documentation.
|
||||
|
||||
1. Changelog:
|
||||
- Is [Changelog.md](https://github.com/scp-fs2open/fs2open.github.com/blob/master/Changelog.md) up-to-date with the latest release?
|
||||
- Is it in the proper [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) format?
|
||||
2. Build instructions:
|
||||
- If a programmer who never built FSO before read the build instruction at [Readme.md](https://github.com/scp-fs2open/fs2open.github.com/blob/master/Readme.md), would they manage to build FSO?
|
||||
- Is the information in the file up-to-date regarding other matters (such as versions of tools mentioned, links to other guides, etc.)?
|
||||
- Is the information in the [Building](https://github.com/scp-fs2open/fs2open.github.com/wiki/Building) article, and its sub-articles, still up-to-date?
|
||||
3. Forums:
|
||||
- Does the [Forum](https://www.hard-light.net/forums/index.php?board=50.0) contain enough clear information to help a new developer find their way into the up-to-date instructions?
|
||||
- Is there anything that might mislead a new developer to stumble onto old tools, dead links and/or old versions of the project?
|
||||
4. General documentation files:
|
||||
- Is the information in the following files up-to-date?
|
||||
- [About.md](https://github.com/scp-fs2open/fs2open.github.com/blob/master/About.md) (Should contain general information about FS, FS2, HLP, FSO and FSU)
|
||||
- [Authors.md](https://github.com/scp-fs2open/fs2open.github.com/blob/master/Authors.md) (Should contain information about the original developers, a way to see FSO's contributors, and special thanks to Volition and Dave Baranec)
|
||||
- [Copying.md](https://github.com/scp-fs2open/fs2open.github.com/blob/master/Copying.md) (Should contain Volition's Copyright terms and a way to check FSO's Licensing info)
|
||||
+20
-19
@@ -1,5 +1,4 @@
|
||||
version: 1.0.0.{build}
|
||||
image: Visual Studio 2015
|
||||
configuration:
|
||||
- Debug
|
||||
- Release
|
||||
@@ -7,13 +6,13 @@ clone_depth: 10
|
||||
environment:
|
||||
matrix:
|
||||
- BuildID: 0
|
||||
CMAKE_GENERATOR: Visual Studio 14 2015
|
||||
PlatformToolset: v140
|
||||
QT_DIR: C:\Qt\5.9\msvc2015
|
||||
CMAKE_GENERATOR: Visual Studio 12 2013
|
||||
PlatformToolset: v120_xp
|
||||
QT_DIR: C:\Qt\5.7\msvc2013
|
||||
- BuildID: 1
|
||||
CMAKE_GENERATOR: Visual Studio 14 2015 Win64
|
||||
PlatformToolset: v140
|
||||
QT_DIR: C:\Qt\5.9\msvc2015_64
|
||||
PlatformToolset: v140_xp
|
||||
QT_DIR: C:\Qt\5.7\msvc2015_64
|
||||
before_build:
|
||||
- git submodule update --init --recursive
|
||||
build_script:
|
||||
@@ -24,7 +23,7 @@ test_script:
|
||||
deploy:
|
||||
- provider: GitHub
|
||||
auth_token:
|
||||
secure: h55Scpy+3vmo1Yb7WlSIGA4d9DRnsbzUYc2LYsQdByQHZHbqrqjBpicH0D2FFLEO
|
||||
secure: 3kV4efHXwRnfXzmJPRAOs8D7+MhwXUXYeayI/P5y114L09kJa6b6L70beXdW7yYr
|
||||
on:
|
||||
ReleaseBuild: true # deploy on release push only
|
||||
|
||||
@@ -40,23 +39,25 @@ deploy:
|
||||
NightlyBuild: true # deploy on nightly push only
|
||||
|
||||
- provider: FTP
|
||||
protocol: sftp
|
||||
host: porphyrion.feralhosting.com
|
||||
username:
|
||||
secure: 36+bVD8eJgI0BVbi7TZ4zQ==
|
||||
protocol: ftp
|
||||
host: swc.fs2downloads.com
|
||||
username:
|
||||
secure: EXg2ADoKzMduZF90ip2Q0g==
|
||||
password:
|
||||
secure: CrzmDVca8AGG08iWPA1gOD4Ge06+wJ3rcBagBGclwYQ=
|
||||
folder: www/datacorder.porphyrion.feralhosting.com/public_html/builds/nightly/$(VersionName)
|
||||
secure: x0LL0uY9yBAQ7JTARhQ6AA==
|
||||
folder: swc.fs2downloads.com/builds/nightly/$(VersionName)
|
||||
beta: true
|
||||
on:
|
||||
NightlyBuild: true # deploy on nightly push only
|
||||
|
||||
- provider: FTP
|
||||
protocol: sftp
|
||||
host: porphyrion.feralhosting.com
|
||||
username:
|
||||
secure: 36+bVD8eJgI0BVbi7TZ4zQ==
|
||||
protocol: ftp
|
||||
host: swc.fs2downloads.com
|
||||
username:
|
||||
secure: EXg2ADoKzMduZF90ip2Q0g==
|
||||
password:
|
||||
secure: CrzmDVca8AGG08iWPA1gOD4Ge06+wJ3rcBagBGclwYQ=
|
||||
folder: www/datacorder.porphyrion.feralhosting.com/public_html/builds/test/$(VersionName)
|
||||
secure: x0LL0uY9yBAQ7JTARhQ6AA==
|
||||
folder: swc.fs2downloads.com/builds/test/$(VersionName)
|
||||
beta: true
|
||||
on:
|
||||
TestBuild: true # deploy on test build push only
|
||||
+50
-55
@@ -9,56 +9,56 @@ class BuildConfig {
|
||||
}
|
||||
|
||||
$NightlyConfigurations = @(
|
||||
# [BuildConfig]@{
|
||||
# Generator="Visual Studio 14 2015 Win64";
|
||||
# PackageType="Win64";
|
||||
# Toolset="v140";
|
||||
# SimdType="SSE2";
|
||||
# QtDir="C:\Qt\5.9\msvc2015_64";
|
||||
# SourcePackage=$false;
|
||||
# },
|
||||
# [BuildConfig]@{
|
||||
# Generator="Visual Studio 14 2015";
|
||||
# PackageType="Win32";
|
||||
# Toolset="v140";
|
||||
# SimdType="SSE2";
|
||||
# QtDir="C:\Qt\5.9\msvc2015";
|
||||
# SourcePackage=$false;
|
||||
# }
|
||||
[BuildConfig]@{
|
||||
Generator="Visual Studio 14 2015 Win64";
|
||||
PackageType="Win64";
|
||||
Toolset="v140_xp";
|
||||
SimdType="SSE2";
|
||||
QtDir="C:\Qt\5.7\msvc2015_64";
|
||||
SourcePackage=$false;
|
||||
},
|
||||
[BuildConfig]@{
|
||||
Generator="Visual Studio 14 2015";
|
||||
PackageType="Win32";
|
||||
Toolset="v140_xp";
|
||||
SimdType="SSE2";
|
||||
QtDir="C:\Qt\5.7\msvc2015";
|
||||
SourcePackage=$false;
|
||||
}
|
||||
)
|
||||
$ReleaseConfigurations = @(
|
||||
# [BuildConfig]@{
|
||||
# Generator="Visual Studio 14 2015";
|
||||
# PackageType="Win32";
|
||||
# Toolset="v140";
|
||||
# SimdType="SSE2";
|
||||
# QtDir="C:\Qt\5.9\msvc2015";
|
||||
# SourcePackage=$true;
|
||||
# }
|
||||
# [BuildConfig]@{
|
||||
# Generator="Visual Studio 14 2015";
|
||||
# PackageType="Win32-AVX";
|
||||
# Toolset="v140";
|
||||
# SimdType="AVX";
|
||||
# QtDir="C:\Qt\5.9\msvc2015";
|
||||
# SourcePackage=$false;
|
||||
# }
|
||||
# [BuildConfig]@{
|
||||
# Generator="Visual Studio 14 2015 Win64";
|
||||
# PackageType="Win64";
|
||||
# Toolset="v140";
|
||||
# SimdType="SSE2";
|
||||
# QtDir="C:\Qt\5.9\msvc2015_64";
|
||||
# SourcePackage=$false;
|
||||
# }
|
||||
# [BuildConfig]@{
|
||||
# Generator="Visual Studio 14 2015 Win64";
|
||||
# PackageType="Win64-AVX";
|
||||
# Toolset="v140";
|
||||
# SimdType="AVX";
|
||||
# QtDir="C:\Qt\5.9\msvc2015_64";
|
||||
# SourcePackage=$false;
|
||||
# }
|
||||
[BuildConfig]@{
|
||||
Generator="Visual Studio 14 2015";
|
||||
PackageType="Win32";
|
||||
Toolset="v140_xp";
|
||||
SimdType="SSE2";
|
||||
QtDir="C:\Qt\5.7\msvc2015";
|
||||
SourcePackage=$true;
|
||||
}
|
||||
[BuildConfig]@{
|
||||
Generator="Visual Studio 14 2015";
|
||||
PackageType="Win32-AVX";
|
||||
Toolset="v140_xp";
|
||||
SimdType="AVX";
|
||||
QtDir="C:\Qt\5.7\msvc2015";
|
||||
SourcePackage=$false;
|
||||
}
|
||||
[BuildConfig]@{
|
||||
Generator="Visual Studio 14 2015 Win64";
|
||||
PackageType="Win64";
|
||||
Toolset="v140_xp";
|
||||
SimdType="SSE2";
|
||||
QtDir="C:\Qt\5.7\msvc2015_64";
|
||||
SourcePackage=$false;
|
||||
}
|
||||
[BuildConfig]@{
|
||||
Generator="Visual Studio 14 2015 Win64";
|
||||
PackageType="Win64-AVX";
|
||||
Toolset="v140_xp";
|
||||
SimdType="AVX";
|
||||
QtDir="C:\Qt\5.7\msvc2015_64";
|
||||
SourcePackage=$false;
|
||||
}
|
||||
)
|
||||
|
||||
$BuildConfigurations = $null
|
||||
@@ -133,8 +133,6 @@ if ($DeployBuild) {
|
||||
|
||||
cmake -DCMAKE_INSTALL_PREFIX="$env:APPVEYOR_BUILD_FOLDER/../install" -DFSO_USE_SPEECH="ON" `
|
||||
-DFSO_USE_VOICEREC="ON" -DMSVC_SIMD_INSTRUCTIONS="$($buildConfig.SimdType)" `
|
||||
-DQT5_INSTALL_ROOT="$($buildConfig.QtDir)" -DFSO_BUILD_QTFRED=ON `
|
||||
-DFSO_INSTALL_DEBUG_FILES="ON" `
|
||||
-G "$($buildConfig.Generator)" -T "$($buildConfig.Toolset)" ..
|
||||
|
||||
$Configs = @("Release", "FastDebug")
|
||||
@@ -146,14 +144,11 @@ if ($DeployBuild) {
|
||||
}
|
||||
}
|
||||
|
||||
7z a -xr'!*.pdb' "$($PackageName)-builds-$($buildConfig.PackageType).zip" "$env:APPVEYOR_BUILD_FOLDER/../install/*"
|
||||
7z a "$($PackageName)-builds-$($buildConfig.PackageType).zip" "$env:APPVEYOR_BUILD_FOLDER/../install/*"
|
||||
Push-AppveyorArtifact "$($PackageName)-builds-$($buildConfig.PackageType).zip"
|
||||
|
||||
7z a "$($PackageName)-debug-$($buildConfig.PackageType).7z" "$env:APPVEYOR_BUILD_FOLDER/../install/*.pdb"
|
||||
Push-AppveyorArtifact "$($PackageName)-debug-$($buildConfig.PackageType).7z"
|
||||
} else {
|
||||
cmake -DFSO_USE_SPEECH="ON" -DFSO_FATAL_WARNINGS="ON" -DFSO_USE_VOICEREC="ON" -DFSO_BUILD_TESTS="ON" -DMSVC_SIMD_INSTRUCTIONS=SSE2 `
|
||||
-DFSO_BUILD_QTFRED=ON -DQT5_INSTALL_ROOT="$env:QT_DIR" -DFSO_BUILD_FRED2="ON" `
|
||||
-DFSO_BUILD_QTFRED=ON -DQT5_INSTALL_ROOT="$env:QT_DIR" -DFSO_BUILD_FRED2="OFF" `
|
||||
-G "$Env:CMAKE_GENERATOR" -T "$Env:PlatformToolset" ..
|
||||
|
||||
cmake --build . --config "$Env:CONFIGURATION" -- /verbosity:minimal
|
||||
|
||||
@@ -1,268 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
#===- clang-tidy-diff.py - ClangTidy Diff Checker ------------*- python -*--===#
|
||||
#
|
||||
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
# See https://llvm.org/LICENSE.txt for license information.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
#
|
||||
#===------------------------------------------------------------------------===#
|
||||
|
||||
r"""
|
||||
ClangTidy Diff Checker
|
||||
======================
|
||||
|
||||
This script reads input from a unified diff, runs clang-tidy on all changed
|
||||
files and outputs clang-tidy warnings in changed lines only. This is useful to
|
||||
detect clang-tidy regressions in the lines touched by a specific patch.
|
||||
Example usage for git/svn users:
|
||||
|
||||
git diff -U0 HEAD^ | clang-tidy-diff.py -p1
|
||||
svn diff --diff-cmd=diff -x-U0 | \
|
||||
clang-tidy-diff.py -fix -checks=-*,modernize-use-override
|
||||
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import glob
|
||||
import json
|
||||
import multiprocessing
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import threading
|
||||
import traceback
|
||||
|
||||
try:
|
||||
import yaml
|
||||
except ImportError:
|
||||
yaml = None
|
||||
|
||||
is_py2 = sys.version[0] == '2'
|
||||
|
||||
if is_py2:
|
||||
import Queue as queue
|
||||
else:
|
||||
import queue as queue
|
||||
|
||||
|
||||
def run_tidy(task_queue, lock, timeout):
|
||||
watchdog = None
|
||||
while True:
|
||||
command = task_queue.get()
|
||||
try:
|
||||
proc = subprocess.Popen(command,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
|
||||
if timeout is not None:
|
||||
watchdog = threading.Timer(timeout, proc.kill)
|
||||
watchdog.start()
|
||||
|
||||
stdout, stderr = proc.communicate()
|
||||
|
||||
with lock:
|
||||
sys.stdout.write(stdout.decode('utf-8'))
|
||||
sys.stdout.flush()
|
||||
if stderr:
|
||||
sys.stderr.write(stderr.decode('utf-8'))
|
||||
sys.stderr.flush()
|
||||
except Exception as e:
|
||||
with lock:
|
||||
sys.stderr.write('Failed: ' + str(e) + ': '.join(command) + '\n')
|
||||
finally:
|
||||
with lock:
|
||||
if (not timeout is None) and (not watchdog is None):
|
||||
if not watchdog.is_alive():
|
||||
sys.stderr.write('Terminated by timeout: ' +
|
||||
' '.join(command) + '\n')
|
||||
watchdog.cancel()
|
||||
task_queue.task_done()
|
||||
|
||||
|
||||
def start_workers(max_tasks, tidy_caller, task_queue, lock, timeout):
|
||||
for _ in range(max_tasks):
|
||||
t = threading.Thread(target=tidy_caller, args=(task_queue, lock, timeout))
|
||||
t.daemon = True
|
||||
t.start()
|
||||
|
||||
def merge_replacement_files(tmpdir, mergefile):
|
||||
"""Merge all replacement files in a directory into a single file"""
|
||||
# The fixes suggested by clang-tidy >= 4.0.0 are given under
|
||||
# the top level key 'Diagnostics' in the output yaml files
|
||||
mergekey = "Diagnostics"
|
||||
merged = []
|
||||
for replacefile in glob.iglob(os.path.join(tmpdir, '*.yaml')):
|
||||
content = yaml.safe_load(open(replacefile, 'r'))
|
||||
if not content:
|
||||
continue # Skip empty files.
|
||||
merged.extend(content.get(mergekey, []))
|
||||
|
||||
if merged:
|
||||
# MainSourceFile: The key is required by the definition inside
|
||||
# include/clang/Tooling/ReplacementsYaml.h, but the value
|
||||
# is actually never used inside clang-apply-replacements,
|
||||
# so we set it to '' here.
|
||||
output = { 'MainSourceFile': '', mergekey: merged }
|
||||
with open(mergefile, 'w') as out:
|
||||
yaml.safe_dump(output, out)
|
||||
else:
|
||||
# Empty the file:
|
||||
open(mergefile, 'w').close()
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=
|
||||
'Run clang-tidy against changed files, and '
|
||||
'output diagnostics only for modified '
|
||||
'lines.')
|
||||
parser.add_argument('-clang-tidy-binary', metavar='PATH',
|
||||
default='clang-tidy',
|
||||
help='path to clang-tidy binary')
|
||||
parser.add_argument('-p', metavar='NUM', default=0,
|
||||
help='strip the smallest prefix containing P slashes')
|
||||
parser.add_argument('-regex', metavar='PATTERN', default=None,
|
||||
help='custom pattern selecting file paths to check '
|
||||
'(case sensitive, overrides -iregex)')
|
||||
parser.add_argument('-iregex', metavar='PATTERN', default=
|
||||
r'.*\.(cpp|cc|c\+\+|cxx|c|cl|h|hpp|m|mm|inc)',
|
||||
help='custom pattern selecting file paths to check '
|
||||
'(case insensitive, overridden by -regex)')
|
||||
parser.add_argument('-j', type=int, default=1,
|
||||
help='number of tidy instances to be run in parallel.')
|
||||
parser.add_argument('-timeout', type=int, default=None,
|
||||
help='timeout per each file in seconds.')
|
||||
parser.add_argument('-fix', action='store_true', default=False,
|
||||
help='apply suggested fixes')
|
||||
parser.add_argument('-checks',
|
||||
help='checks filter, when not specified, use clang-tidy '
|
||||
'default',
|
||||
default='')
|
||||
parser.add_argument('-path', dest='build_path',
|
||||
help='Path used to read a compile command database.')
|
||||
if yaml:
|
||||
parser.add_argument('-export-fixes', metavar='FILE', dest='export_fixes',
|
||||
help='Create a yaml file to store suggested fixes in, '
|
||||
'which can be applied with clang-apply-replacements.')
|
||||
parser.add_argument('-extra-arg', dest='extra_arg',
|
||||
action='append', default=[],
|
||||
help='Additional argument to append to the compiler '
|
||||
'command line.')
|
||||
parser.add_argument('-extra-arg-before', dest='extra_arg_before',
|
||||
action='append', default=[],
|
||||
help='Additional argument to prepend to the compiler '
|
||||
'command line.')
|
||||
parser.add_argument('-quiet', action='store_true', default=False,
|
||||
help='Run clang-tidy in quiet mode')
|
||||
clang_tidy_args = []
|
||||
argv = sys.argv[1:]
|
||||
if '--' in argv:
|
||||
clang_tidy_args.extend(argv[argv.index('--'):])
|
||||
argv = argv[:argv.index('--')]
|
||||
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
# Extract changed lines for each file.
|
||||
filename = None
|
||||
lines_by_file = {}
|
||||
for line in sys.stdin:
|
||||
match = re.search('^\+\+\+\ \"?(.*?/){%s}([^ \t\n\"]*)' % args.p, line)
|
||||
if match:
|
||||
filename = match.group(2)
|
||||
if filename is None:
|
||||
continue
|
||||
|
||||
if args.regex is not None:
|
||||
if not re.match('^%s$' % args.regex, filename):
|
||||
continue
|
||||
else:
|
||||
if not re.match('^%s$' % args.iregex, filename, re.IGNORECASE):
|
||||
continue
|
||||
|
||||
match = re.search('^@@.*\+(\d+)(,(\d+))?', line)
|
||||
if match:
|
||||
start_line = int(match.group(1))
|
||||
line_count = 1
|
||||
if match.group(3):
|
||||
line_count = int(match.group(3))
|
||||
if line_count == 0:
|
||||
continue
|
||||
end_line = start_line + line_count - 1
|
||||
lines_by_file.setdefault(filename, []).append([start_line, end_line])
|
||||
|
||||
if not any(lines_by_file):
|
||||
print("No relevant changes found.")
|
||||
sys.exit(0)
|
||||
|
||||
max_task_count = args.j
|
||||
if max_task_count == 0:
|
||||
max_task_count = multiprocessing.cpu_count()
|
||||
max_task_count = min(len(lines_by_file), max_task_count)
|
||||
|
||||
tmpdir = None
|
||||
if yaml and args.export_fixes:
|
||||
tmpdir = tempfile.mkdtemp()
|
||||
|
||||
# Tasks for clang-tidy.
|
||||
task_queue = queue.Queue(max_task_count)
|
||||
# A lock for console output.
|
||||
lock = threading.Lock()
|
||||
|
||||
# Run a pool of clang-tidy workers.
|
||||
start_workers(max_task_count, run_tidy, task_queue, lock, args.timeout)
|
||||
|
||||
# Form the common args list.
|
||||
common_clang_tidy_args = []
|
||||
if args.fix:
|
||||
common_clang_tidy_args.append('-fix')
|
||||
if args.checks != '':
|
||||
common_clang_tidy_args.append('-checks=' + args.checks)
|
||||
if args.quiet:
|
||||
common_clang_tidy_args.append('-quiet')
|
||||
if args.build_path is not None:
|
||||
common_clang_tidy_args.append('-p=%s' % args.build_path)
|
||||
for arg in args.extra_arg:
|
||||
common_clang_tidy_args.append('-extra-arg=%s' % arg)
|
||||
for arg in args.extra_arg_before:
|
||||
common_clang_tidy_args.append('-extra-arg-before=%s' % arg)
|
||||
|
||||
for name in lines_by_file:
|
||||
line_filter_json = json.dumps(
|
||||
[{"name": name, "lines": lines_by_file[name]}],
|
||||
separators=(',', ':'))
|
||||
|
||||
# Run clang-tidy on files containing changes.
|
||||
command = [args.clang_tidy_binary]
|
||||
command.append('-line-filter=' + line_filter_json)
|
||||
if yaml and args.export_fixes:
|
||||
# Get a temporary file. We immediately close the handle so clang-tidy can
|
||||
# overwrite it.
|
||||
(handle, tmp_name) = tempfile.mkstemp(suffix='.yaml', dir=tmpdir)
|
||||
os.close(handle)
|
||||
command.append('-export-fixes=' + tmp_name)
|
||||
command.extend(common_clang_tidy_args)
|
||||
command.append(name)
|
||||
command.extend(clang_tidy_args)
|
||||
|
||||
task_queue.put(command)
|
||||
|
||||
# Wait for all threads to be done.
|
||||
task_queue.join()
|
||||
|
||||
if yaml and args.export_fixes:
|
||||
print('Writing fixes to ' + args.export_fixes + ' ...')
|
||||
try:
|
||||
merge_replacement_files(tmpdir, args.export_fixes)
|
||||
except:
|
||||
sys.stderr.write('Error exporting fixes.\n')
|
||||
traceback.print_exc()
|
||||
|
||||
if tmpdir:
|
||||
shutil.rmtree(tmpdir)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -1,23 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT=$(readlink -f "$0")
|
||||
HERE=$(dirname "$SCRIPT")
|
||||
|
||||
COMMIT_RANGE=$1..$2
|
||||
|
||||
if ! git rev-list $COMMIT_RANGE 2>&1 >/dev/null; then
|
||||
echo "\$COMMIT_RANGE ($COMMIT_RANGE) is not valid for this build (probably caused by a rebase)."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# In order to get a proper diff without irrelevant changes, we need to determine where we branched off from the base
|
||||
# branch
|
||||
BASE_COMMIT=$(git merge-base $1 $2)
|
||||
|
||||
echo "Running clang-tidy on changed files"
|
||||
git diff -U0 --no-color "$BASE_COMMIT..$2" | \
|
||||
$HERE/clang-tidy-diff.py -path "$(pwd)/build" -p1 \
|
||||
-regex '(code(?!((\/graphics\/shaders\/compiled)|(\/globalincs\/windebug)))|freespace2|qtfred|test|build|tools)\/.*\.(cpp|h)' \
|
||||
-clang-tidy-binary /usr/bin/clang-tidy-9 -j$(nproc) -export-fixes "$(pwd)/clang-fixes.yaml"
|
||||
@@ -1,47 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if [ "$COMPILER" = "gcc-5" ]; then
|
||||
export CC=gcc-5
|
||||
export CXX=g++-5
|
||||
fi
|
||||
if [ "$COMPILER" = "gcc-10" ]; then
|
||||
export CC=gcc-10
|
||||
export CXX=g++-10
|
||||
fi
|
||||
if [ "$COMPILER" = "clang-9" ]; then
|
||||
# Work around bug in clang that uses the wrong installation directory: https://bugs.llvm.org/show_bug.cgi?id=47460
|
||||
export CC=$(readlink -f $(which clang-9))
|
||||
export CXX=$(readlink -f $(which clang++-9))
|
||||
fi
|
||||
|
||||
LD_LIBRARY_PATH=$Qt5_DIR/lib:$LD_LIBRARY_PATH
|
||||
if [ "$RUNNER_OS" = "macOS" ]; then
|
||||
CXXFLAGS="-mtune=generic -pipe -Wno-unknown-pragmas"
|
||||
CFLAGS="-mtune=generic -pipe -Wno-unknown-pragmas"
|
||||
PLATFORM_CMAKE_OPTIONS=""
|
||||
export CMAKE_OSX_ARCHITECTURES="$ARCHITECTURE"
|
||||
else
|
||||
CXXFLAGS="-m64 -mtune=generic -mfpmath=sse -msse -msse2 -pipe -Wno-unknown-pragmas"
|
||||
CFLAGS="-m64 -mtune=generic -mfpmath=sse -msse -msse2 -pipe -Wno-unknown-pragmas"
|
||||
PLATFORM_CMAKE_OPTIONS="-DFSO_BUILD_APPIMAGE=ON"
|
||||
fi
|
||||
|
||||
CMAKE_OPTIONS="$JOB_CMAKE_OPTIONS"
|
||||
if [[ "$COMPILER" =~ ^clang.*$ ]]; then
|
||||
CMAKE_OPTIONS="$CMAKE_OPTIONS -DCLANG_USE_LIBCXX=ON"
|
||||
fi
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
export CXXFLAGS
|
||||
export CFLAGS
|
||||
export LD_LIBRARY_PATH
|
||||
|
||||
if [ "$RUNNER_OS" = "macOS" ]; then
|
||||
brew install ninja
|
||||
fi
|
||||
cmake -G Ninja -DFSO_FATAL_WARNINGS=ON -DCMAKE_EXPORT_COMPILE_COMMANDS=ON $CMAKE_OPTIONS $PLATFORM_CMAKE_OPTIONS \
|
||||
-DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DCMAKE_BUILD_TYPE=$CONFIGURATION \
|
||||
-DFFMPEG_USE_PRECOMPILED=ON -DFSO_BUILD_TESTS=ON -DFSO_BUILD_INCLUDED_LIBS=ON -DFSO_BUILD_QTFRED=ON \
|
||||
-DSHADERS_ENABLE_COMPILATION=ON ..
|
||||
@@ -1,36 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
SCRIPT=$(readlink -f "$0")
|
||||
HERE=$(dirname "$SCRIPT")
|
||||
|
||||
OS="$1"
|
||||
|
||||
source $HERE/dist_functions.sh
|
||||
|
||||
if [ "$OS" = "Linux" ]; then
|
||||
tar -cvzf "$(get_package_name)-builds-Linux.tar.gz" *
|
||||
|
||||
echo "::set-output name=package_path::$(pwd)/$(get_package_name)-builds-Linux.tar.gz"
|
||||
echo "::set-output name=package_name::$(get_package_name)-builds-Linux.tar.gz"
|
||||
echo "::set-output name=package_mime::$(file -b --mime-type "$(pwd)/$(get_package_name)-builds-Linux.tar.gz")"
|
||||
elif [ "$OS" = "Windows" ]; then
|
||||
7z a -xr'!*.pdb' "$(get_package_name)-builds-$ARCH-$SIMD.zip" "*"
|
||||
|
||||
echo "::set-output name=package_path::$(pwd)/$(get_package_name)-builds-$ARCH-$SIMD.zip"
|
||||
echo "::set-output name=package_name::$(get_package_name)-builds-$ARCH-$SIMD.zip"
|
||||
echo "::set-output name=package_mime::$(file -b --mime-type "$(pwd)/$(get_package_name)-builds-$ARCH-$SIMD.zip")"
|
||||
|
||||
7z a "$(get_package_name)-debug-$ARCH-$SIMD.7z" "*.pdb"
|
||||
|
||||
echo "::set-output name=debug_path::$(pwd)/$(get_package_name)-debug-$ARCH-$SIMD.7z"
|
||||
echo "::set-output name=debug_name::$(get_package_name)-debug-$ARCH-$SIMD.7z"
|
||||
echo "::set-output name=debug_mime::$(file -b --mime-type "$(pwd)/$(get_package_name)-debug-$ARCH-$SIMD.7z")"
|
||||
elif [ "$OS" = "Mac" ]; then
|
||||
tar -cvzf "$(get_package_name)-builds-Mac.tar.gz" *
|
||||
|
||||
echo "::set-output name=package_path::$(pwd)/$(get_package_name)-builds-Mac.tar.gz"
|
||||
echo "::set-output name=package_name::$(get_package_name)-builds-Mac.tar.gz"
|
||||
echo "::set-output name=package_mime::$(file -b --mime-type "$(pwd)/$(get_package_name)-builds-Mac.tar.gz")"
|
||||
else
|
||||
echo "Invalid OS: $OS"
|
||||
fi
|
||||
@@ -1,70 +0,0 @@
|
||||
function get_package_name() {
|
||||
if git describe --match 'nightly_*' --exact-match 2>/dev/null >/dev/null; then
|
||||
echo -n "$(git describe --match "nightly_*" --exact-match)"
|
||||
return
|
||||
fi
|
||||
|
||||
if git describe --match 'release_*' --exact-match 2>/dev/null >/dev/null; then
|
||||
echo -n "$(git describe --match "release_*" --exact-match | sed 's/release_/fs2_open_/i')"
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ "$(git branch --show-current)" =~ ^test\/(.*)$ ]]; then
|
||||
echo -n "test_${BASH_REMATCH[1]}"
|
||||
return
|
||||
fi
|
||||
|
||||
echo "unknown_config"
|
||||
}
|
||||
|
||||
function get_version_name() {
|
||||
if git describe --match 'nightly_*' --exact-match 2>/dev/null >/dev/null; then
|
||||
local tag_name=$(git describe --match "nightly_*" --exact-match)
|
||||
|
||||
# Use the bash regex matching for getting the relevant part of the tag name
|
||||
[[ $tag_name =~ ^nightly_(.*)$ ]]
|
||||
|
||||
echo -n "${BASH_REMATCH[1]}"
|
||||
return
|
||||
fi
|
||||
|
||||
if git describe --match 'release_*' --exact-match 2>/dev/null >/dev/null; then
|
||||
local tag_name=$(git describe --match "release_*" --exact-match)
|
||||
|
||||
# Use the bash regex matching for getting the relevant part of the tag name
|
||||
[[ $tag_name =~ ^release_(.*)$ ]]
|
||||
|
||||
echo -n "${BASH_REMATCH[1]}"
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ "$(git branch --show-current)" =~ ^test\/(.*)$ ]]; then
|
||||
echo -n "${BASH_REMATCH[1]}"
|
||||
return
|
||||
fi
|
||||
|
||||
echo "unknown_config"
|
||||
}
|
||||
|
||||
function upload_files_to_sftp() {
|
||||
# We need empty glob patterns to "disappear" in the for loop below since this will be run for different configurations
|
||||
# where it may be possible that some of the file patterns will not be present
|
||||
shopt -s nullglob
|
||||
|
||||
echo "cd $2/" > sftp_batch
|
||||
echo "mkdir $(get_version_name)" >> sftp_batch
|
||||
# Create directory but do not cause an error if it already exists
|
||||
sshpass -e sftp -oBatchMode=no -o "StrictHostKeyChecking no" -b sftp_batch $1 || true
|
||||
|
||||
echo "cd $2/$(get_version_name)/" > sftp_batch
|
||||
for file in *.tar.gz *.7z *.zip; do
|
||||
echo "put $file" >> sftp_batch
|
||||
done
|
||||
|
||||
echo "bye" >> sftp_batch
|
||||
|
||||
sshpass -e sftp -oBatchMode=no -o "StrictHostKeyChecking no" -b sftp_batch $1
|
||||
|
||||
rm sftp_batch
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
INSTALL_FOLDER=$1
|
||||
|
||||
# Install Freespace2 targets
|
||||
cmake -DCMAKE_INSTALL_PREFIX=$INSTALL_FOLDER -DCOMPONENT=Unspecified -P cmake_install.cmake
|
||||
cmake -DCMAKE_INSTALL_PREFIX=$INSTALL_FOLDER -DCOMPONENT=Freespace2 -P cmake_install.cmake
|
||||
|
||||
# We need to be a bit creative for determining the AppImage name since we don't want to hard-code the name
|
||||
FILENAME="$(find $INSTALL_FOLDER/bin -name 'fs2_open_*' -type f -printf "%f\n").AppImage"
|
||||
appimagetool -n $INSTALL_FOLDER "$INSTALL_FOLDER/$FILENAME"
|
||||
chmod +x "$INSTALL_FOLDER/$FILENAME"
|
||||
|
||||
ls -al $INSTALL_FOLDER
|
||||
@@ -1,13 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
SCRIPT=$(readlink -f "$0")
|
||||
HERE=$(dirname "$SCRIPT")
|
||||
|
||||
export LD_LIBRARY_PATH=$(pwd)/bin/lib:$LD_LIBRARY_PATH
|
||||
|
||||
if [ "$CONFIGURATION" = "Debug"] && [[ "$RUNNER_OS" != "macOS" ]] ; then
|
||||
valgrind --leak-check=full --error-exitcode=1 --gen-suppressions=all \
|
||||
--suppressions="$HERE/valgrind.supp" ./bin/unittests --gtest_shuffle
|
||||
else
|
||||
./bin/unittests --gtest_shuffle
|
||||
fi
|
||||
@@ -1,21 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
UPLOAD_TYPE=$1
|
||||
|
||||
SCRIPT=$(readlink -f "$0")
|
||||
HERE=$(dirname "$SCRIPT")
|
||||
|
||||
source $HERE/dist_functions.sh
|
||||
|
||||
if [ "$UPLOAD_TYPE" = "nightly" ]; then
|
||||
SSHPASS=$INDIEGAMES_SSHPASS upload_files_to_sftp "$INDIEGAMES_USER@scp.indiegames.us" "public_html/builds/nightly"
|
||||
|
||||
SSHPASS=$DATACORDER_SSHPASS upload_files_to_sftp "$DATACORDER_USER@porphyrion.feralhosting.com" "www/datacorder.porphyrion.feralhosting.com/public_html/builds/nightly"
|
||||
elif [ "$UPLOAD_TYPE" = "test" ]; then
|
||||
SSHPASS=$DATACORDER_SSHPASS upload_files_to_sftp "$DATACORDER_USER@porphyrion.feralhosting.com" "www/datacorder.porphyrion.feralhosting.com/public_html/builds/test"
|
||||
else
|
||||
echo "Unknown upload type $UPLOAD_TYPE"
|
||||
exit 1
|
||||
fi
|
||||
@@ -1,163 +0,0 @@
|
||||
{
|
||||
liblsan Invalid read
|
||||
Memcheck:Addr8
|
||||
obj:/usr/lib64/liblsan.so.0.0.0
|
||||
obj:/usr/lib64/liblsan.so.0.0.0
|
||||
obj:/usr/lib64/liblsan.so.0.0.0
|
||||
obj:*
|
||||
obj:*
|
||||
obj:*
|
||||
}
|
||||
{
|
||||
Travis memleak
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: definite
|
||||
fun:malloc
|
||||
fun:_dl_signal_error
|
||||
fun:_dl_open
|
||||
fun:dlopen_doit
|
||||
fun:_dl_catch_error
|
||||
fun:_dlerror_run
|
||||
fun:dlopen@@GLIBC_2.2.5
|
||||
obj:/usr/lib/x86_64-linux-gnu/libmirclient.so.7
|
||||
fun:call_init.part.0
|
||||
fun:call_init
|
||||
fun:_dl_init
|
||||
fun:dl_open_worker
|
||||
fun:_dl_catch_error
|
||||
}
|
||||
{
|
||||
CLang Lua unitialized value error
|
||||
Memcheck:Cond
|
||||
...
|
||||
fun:luaH_get
|
||||
fun:lua_rawget
|
||||
fun:_ZN12_GLOBAL__N_117ade_index_handlerEP9lua_State
|
||||
}
|
||||
{
|
||||
False-positive uninitialized variable warning
|
||||
Memcheck:Cond
|
||||
fun:_Z23cf_check_location_flagsjj
|
||||
fun:_Z29cf_create_default_path_stringPcjiPKcbj
|
||||
...
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: definite
|
||||
fun:_Znwm
|
||||
obj:*
|
||||
obj:*
|
||||
obj:*
|
||||
obj:/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.4.0
|
||||
obj:/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.4.0
|
||||
obj:/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.4.0
|
||||
fun:_Z7gr_initOSt10unique_ptrIN2os18GraphicsOperationsESt14default_deleteIS1_EEiiii
|
||||
fun:_ZN4test13FSTestFixture5SetUpEv
|
||||
fun:_ZN7testing8internal38HandleSehExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc
|
||||
fun:_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc
|
||||
fun:_ZN7testing4Test3RunEv
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: definite
|
||||
fun:_Znwm
|
||||
obj:*
|
||||
obj:*
|
||||
obj:*
|
||||
obj:/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.4.0
|
||||
obj:/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.4.0
|
||||
obj:/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.4.0
|
||||
fun:_Z7gr_initOSt10unique_ptrIN2os18GraphicsOperationsESt14default_deleteIS1_EEiiii
|
||||
fun:_ZN4test13FSTestFixture5SetUpEv
|
||||
fun:_ZN8FontTest5SetUpEv
|
||||
fun:_ZN7testing8internal38HandleSehExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc
|
||||
fun:_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: definite
|
||||
fun:malloc
|
||||
fun:_Znwm
|
||||
obj:*
|
||||
obj:*
|
||||
obj:*
|
||||
obj:/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.4.0
|
||||
obj:/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.4.0
|
||||
obj:/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.4.0
|
||||
fun:_Z7gr_initONSt3__110unique_ptrIN2os18GraphicsOperationsENS_14default_deleteIS2_EEEEiiii
|
||||
fun:_ZN4test13FSTestFixture5SetUpEv
|
||||
fun:_ZN8FontTest5SetUpEv
|
||||
fun:_ZN7testing8internal38HandleSehExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: definite
|
||||
fun:malloc
|
||||
fun:_Znwm
|
||||
obj:*
|
||||
obj:*
|
||||
obj:*
|
||||
obj:/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.4.0
|
||||
obj:/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.4.0
|
||||
obj:/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.4.0
|
||||
fun:_Z7gr_initONSt3__110unique_ptrIN2os18GraphicsOperationsENS_14default_deleteIS2_EEEEiiii
|
||||
fun:_ZN4test13FSTestFixture5SetUpEv
|
||||
fun:_ZN8FontTest5SetUpEv
|
||||
fun:_ZN7testing8internal38HandleSehExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: definite
|
||||
fun:malloc
|
||||
fun:_Znwm
|
||||
obj:*
|
||||
obj:*
|
||||
obj:*
|
||||
obj:/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.4.0
|
||||
obj:/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.4.0
|
||||
obj:/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.4.0
|
||||
fun:_Z7gr_initONSt3__110unique_ptrIN2os18GraphicsOperationsENS_14default_deleteIS2_EEEEiiii
|
||||
fun:_ZN4test13FSTestFixture5SetUpEv
|
||||
fun:_ZN7testing8internal38HandleSehExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc
|
||||
fun:_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc
|
||||
}
|
||||
{
|
||||
<insert_a_suppression_name_here>
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: definite
|
||||
fun:malloc
|
||||
fun:_dl_signal_error
|
||||
fun:_dl_open
|
||||
fun:dlopen_doit
|
||||
fun:_dl_catch_error
|
||||
fun:_dlerror_run
|
||||
fun:dlopen@@GLIBC_2.2.5
|
||||
obj:*
|
||||
obj:*
|
||||
fun:call_init.part.0
|
||||
fun:call_init
|
||||
fun:_dl_init
|
||||
fun:dl_open_worker
|
||||
}
|
||||
{
|
||||
dlopen leak
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: definite
|
||||
fun:malloc
|
||||
fun:_dl_exception_create
|
||||
fun:_dl_signal_error
|
||||
fun:_dl_map_object
|
||||
fun:dl_open_worker
|
||||
fun:_dl_catch_exception
|
||||
fun:_dl_open
|
||||
fun:dlopen_doit
|
||||
fun:_dl_catch_exception
|
||||
fun:_dl_catch_error
|
||||
fun:_dlerror_run
|
||||
fun:dlopen@@GLIBC_2.2.5
|
||||
}
|
||||
@@ -1,156 +0,0 @@
|
||||
# Retrives a log of commit messages and attempts to pretty them into a human-readbile format
|
||||
|
||||
import os
|
||||
import re
|
||||
import requests
|
||||
import sys
|
||||
|
||||
from datetime import datetime
|
||||
from subprocess import check_output
|
||||
|
||||
MAX_PAGES = 100 # maximum number of PR pages to go through
|
||||
warnings = 0
|
||||
|
||||
def get_last_page(response: requests.Response) -> int:
|
||||
"""
|
||||
@brief Extract the last page number from the response header
|
||||
|
||||
@param[in] response The response from a GET call
|
||||
|
||||
@returns The page number of the last page, or MAX_PAGES
|
||||
"""
|
||||
|
||||
# The link header is a dictionary in string form, and for that matter the
|
||||
# value is in front of the key. It is of the form '<<url1>>; rel=<key1>, <url2>, <key2>'
|
||||
link = response.headers['link']
|
||||
link = link.split(',')
|
||||
for x in link:
|
||||
y = x.split(';') # <url>; rel=<key>
|
||||
if "last" not in y[1]: # look for rel='last'
|
||||
continue
|
||||
# grab the page number from the URL
|
||||
# group(0) is `page=123`, group(1) is `123`
|
||||
last_page = int( re.search(r'page=(\d+)', y[0]).group(1) )
|
||||
if not last_page:
|
||||
print("Error: Could not find page number in url! URL: %s", y[0])
|
||||
sys.exit(1)
|
||||
|
||||
if last_page > MAX_PAGES:
|
||||
return MAX_PAGES
|
||||
else:
|
||||
return last_page
|
||||
|
||||
|
||||
def main():
|
||||
os.chdir(os.path.dirname(__file__)) # Change working directory to this file's directory
|
||||
|
||||
start_date = datetime.strptime(sys.argv[1], "%Y-%m-%d")
|
||||
|
||||
print("start_date: {}".format(start_date))
|
||||
|
||||
# Retrive the git log for master, since start date, order by date, in ascending order, use YYYY-MM-DD date format,
|
||||
# each line is of the form "<author short date> | <message>", only grab commits from master,
|
||||
# output to `fsofordigest.txt`,
|
||||
|
||||
# check_output(("git log master", "--after=2021-09-15", "--date-order", "--reverse", "--date=short",
|
||||
# "--pretty=\"%as | %s\"", "--first-parent",
|
||||
# "--output fsofordigest.txt"), text=True)
|
||||
|
||||
# The commit messages are either of the form "<body> (#<PR_number>)" or "Merge pull request #<PR_number> from <source_repo>"
|
||||
# For our purposes, we want them be all of the form "<body> (#<PR_number>)"
|
||||
# Typically, the second form does not have a usable body, so we'll have to pull the PR title from github
|
||||
|
||||
# Github's REST API allows us to retrieve PR's, but due to it being HTTP requests it has to page in the data.
|
||||
# We can loop over the GET request and check for a merge date.
|
||||
# The GET request doesn't have sorting by merge date, but does have sorting by the last time it was updated... which is usually
|
||||
# also the merge date but not always.
|
||||
|
||||
# Key attributes within the PR JSON objects:
|
||||
# "merged_at: <date>" # Date the PR was merged in
|
||||
# "merged: <bool>" # If the PR was merged yet
|
||||
# "html_url: <string>" # URL of the PR's HEAD commit, used by some clients to pull in the PR branch
|
||||
# "number: <int>" # The PR id number
|
||||
# "title: <string>" # Title of the PR
|
||||
# "body: <string>" # The body paragraph detailing the PR
|
||||
# "labels: [label_object]" # All labels attached to this PR
|
||||
|
||||
changelog = {}
|
||||
url = "https://api.github.com/repos/scp-fs2open/fs2open.github.com/pulls"
|
||||
last_page = MAX_PAGES
|
||||
for page in range(1, last_page + 1):
|
||||
# GET <url>?base=master&sort=updated&direction=desc&state=closed&page=1
|
||||
response = requests.get(url, params={
|
||||
"base": "master",
|
||||
"direction": "desc",
|
||||
"page": page,
|
||||
"state": "closed",
|
||||
"sort": "updated"
|
||||
})
|
||||
|
||||
# Check if good response
|
||||
if (response.status_code != 200) :
|
||||
print("Error: ", response.status_code)
|
||||
print(response.json()['message'])
|
||||
sys.exit(1)
|
||||
else:
|
||||
print("Request successful: 200")
|
||||
print("page={}".format(page))
|
||||
|
||||
# Update the last_page index at first iteration and possibly last iteration
|
||||
# This should cover the edge case of a new PR being added to the database before this script is finished
|
||||
if (page == 1) or (page == last_page):
|
||||
last_page = get_last_page(response)
|
||||
print("last_page={}".format(last_page))
|
||||
|
||||
# assume pulls are organized from newest to oldest
|
||||
for pull in response.json():
|
||||
if (pull['state'] != 'closed'):
|
||||
# This pull is not merged, so ignore
|
||||
print("Found irrelevant pull, skipping...")
|
||||
print("state: {}; number: {}".format(pull['state'], pull['number']))
|
||||
continue
|
||||
|
||||
if (pull['merged_at'] == None):
|
||||
# This pull wasn't merged, skip
|
||||
print("Found closed pull #{} ({}), skipping...".format(pull['number'], pull['closed_at']))
|
||||
continue
|
||||
|
||||
merge_date = datetime.strptime(pull['merged_at'], "%Y-%m-%dT%H:%M:%SZ")
|
||||
updated_date = datetime.strptime(pull['updated_at'], "%Y-%m-%dT%H:%M:%SZ")
|
||||
if (merge_date < start_date) and (updated_date >= start_date):
|
||||
# This pull is too old, but was updated within our timeframe. skip
|
||||
print("Found old pull #{} ({}), skipping...".format(pull['number'], pull['merged_at']))
|
||||
continue
|
||||
|
||||
if (updated_date < start_date):
|
||||
# This pull is too old
|
||||
print("Found old pull #{} ({}), stopping loop...".format(pull['number'], pull['updated_at']))
|
||||
page = last_page + 1
|
||||
break
|
||||
|
||||
# Add the pull to the changelog, indexed by its pull.number
|
||||
if pull['number'] not in changelog:
|
||||
# only add if the key isn't there already
|
||||
changelog[pull['number']] = {
|
||||
"date": merge_date,
|
||||
"title": pull['title'],
|
||||
"labels": pull['labels'],
|
||||
"url": pull['html_url']
|
||||
}
|
||||
print("Added pull #{} ({})".format(pull['number'], merge_date))
|
||||
# Else, silently ignore duplicate (for now...)
|
||||
|
||||
|
||||
# Write the changelog to file
|
||||
# 2021-09-28 | (#3661) Fix homing child weapons in niche circumstances
|
||||
print("Writing to change.log...")
|
||||
str = ''
|
||||
for key, value in changelog.items():
|
||||
str += "{} | (#{}) {} \n".format(value['date'].strftime("%Y-%m-%d"), key, value['title'])
|
||||
|
||||
with open("change.log", "w") as file:
|
||||
file.write(str)
|
||||
|
||||
print("Done!")
|
||||
|
||||
main()
|
||||
@@ -1,228 +0,0 @@
|
||||
import re # regex module
|
||||
from ftplib import FTP, error_perm
|
||||
from itertools import groupby
|
||||
from typing import List, Tuple, Dict
|
||||
|
||||
import requests # HTTP requests module
|
||||
|
||||
from util import retry_multi, GLOBAL_TIMEOUT # from util.py
|
||||
|
||||
|
||||
class ReleaseFile:
|
||||
"""! Class representing a Released file on Nebula
|
||||
|
||||
`name`: str
|
||||
Mod (or build) name,
|
||||
`url`: str
|
||||
Primary host URL,
|
||||
`group`: str
|
||||
Mod group string,
|
||||
`subgroup`: str
|
||||
Mod subgroup string,
|
||||
`mirrors`: List[str]
|
||||
List of URL's of FTP mirrors
|
||||
"""
|
||||
def __init__(self, name, url, group, subgroup=None, mirrors=None):
|
||||
if mirrors is None:
|
||||
mirrors = []
|
||||
self.mirrors = mirrors
|
||||
self.subgroup = subgroup
|
||||
self.group = group
|
||||
self.url = url
|
||||
self.name = name
|
||||
|
||||
self.base_url = "/".join(url.split('/')[0:-1]) + "/"
|
||||
self.filename = url.split('/')[-1]
|
||||
|
||||
# A list of tuples of (filename, hash)
|
||||
self.content_hashes = None
|
||||
|
||||
self.hash = None
|
||||
self.size = 0
|
||||
|
||||
def __repr__(self):
|
||||
return repr((self.name))
|
||||
|
||||
|
||||
class SourceFile:
|
||||
"""! Class represeting a source file
|
||||
|
||||
`name`: str
|
||||
File name,
|
||||
`url`: str
|
||||
FTP URL,
|
||||
`group`
|
||||
<unknown>
|
||||
|
||||
@details More details
|
||||
"""
|
||||
def __init__(self, name, url, group):
|
||||
self.group = group
|
||||
self.url = url
|
||||
self.name = name
|
||||
|
||||
|
||||
class FileGroup:
|
||||
"""! Represents a file group
|
||||
|
||||
`name`: str
|
||||
Name of this group
|
||||
`files`: List[ReleaseFile]
|
||||
List of files within this group
|
||||
`mainFile`: str
|
||||
If this FileGroup has a subgroup, `mainFile` is the head of that group
|
||||
`subFiles`: List[ReleaseFile]
|
||||
Files within a subgroup
|
||||
"""
|
||||
|
||||
def __init__(self, name, files: List[ReleaseFile]):
|
||||
self.files = files
|
||||
self.name = name
|
||||
|
||||
if len(files) == 1:
|
||||
self.mainFile = files[0]
|
||||
self.subFiles = {}
|
||||
else:
|
||||
self.mainFile = None
|
||||
subFiles = []
|
||||
for file in files:
|
||||
# We only have subcategories for Windows where SSE2 is the main group
|
||||
if file.subgroup == "SSE2":
|
||||
self.mainFile = file
|
||||
else:
|
||||
subFiles.append(file)
|
||||
|
||||
self.subFiles = dict(((x[0], next(x[1])) for x in groupby(subFiles, lambda f: f.subgroup)))
|
||||
|
||||
|
||||
def get_release_files(tag_name, config) -> Tuple[List[ReleaseFile], Dict[str, SourceFile]]:
|
||||
"""! Brief Gets the binary and source files from the Github Release server
|
||||
|
||||
@param[in] `tag_name` Git tag of the current release
|
||||
@param[in] `config` confi metadata set in main.py
|
||||
|
||||
@returns `List[ReleaseFile]` List of release files
|
||||
@returns `Dict[str, SourceFile]` Dictionary of source files
|
||||
|
||||
@details Sends an `HTTP GET` request to github using their REST API to retrieve metadata. The files are not
|
||||
actually downloaded here, just their metadata is gathered and organized in their respective container for later
|
||||
use.
|
||||
"""
|
||||
|
||||
@retry_multi(5) # retry at most 5 times
|
||||
def execute_request(path):
|
||||
"""!
|
||||
@brief Performs a GET request with the given path. To be used with Github's REST API.
|
||||
@returns If successful, returns a .JSON object
|
||||
"""
|
||||
headers = {
|
||||
"Accept": "application/vnd.github.v3+json"
|
||||
}
|
||||
url = "https://api.github.com" + path
|
||||
|
||||
# GET https://api.github.com/<path> Accept: "application/vnd.github.v3+json"
|
||||
|
||||
response = requests.get(url, headers=headers, timeout=GLOBAL_TIMEOUT)
|
||||
|
||||
response.raise_for_status() # Raise a RequestException if we failed, and trigger retry
|
||||
|
||||
return response.json()
|
||||
|
||||
build_group_regex = re.compile("fs2_open_.*-builds-([^.-]*)(-([^.]*))?.*") # regex for matching binary .zip's and .7z's
|
||||
source_file_regex = re.compile("fs2_open_.*-source-([^.]*)?.*") # regex for matching source .zip's and .7z's
|
||||
|
||||
# Get the github release metadata of the given tag name
|
||||
response = execute_request(
|
||||
"/repos/{}/releases/tags/{}".format(config["github"]["repo"], tag_name))
|
||||
|
||||
# Extract the binary and source files from the response["asset"] metadata
|
||||
binary_files = []
|
||||
source_files = {}
|
||||
for asset in response["assets"]:
|
||||
url = asset["browser_download_url"]
|
||||
name = asset["name"]
|
||||
|
||||
group_match = build_group_regex.match(name)
|
||||
|
||||
if group_match is not None:
|
||||
platform = group_match.group(1)
|
||||
# x64 is the Visual Studio name but for consistency we need Win64
|
||||
if platform == "x64":
|
||||
platform = "Win64"
|
||||
|
||||
binary_files.append(ReleaseFile(name, url, platform, group_match.group(3)))
|
||||
else:
|
||||
group_match = source_file_regex.match(name)
|
||||
|
||||
if group_match is None:
|
||||
continue
|
||||
|
||||
group = group_match.group(1)
|
||||
|
||||
source_files[group] = SourceFile(name, url, group)
|
||||
|
||||
binary_files.sort(key=lambda ReleaseFile: ReleaseFile.name)
|
||||
|
||||
return binary_files, source_files
|
||||
|
||||
|
||||
def get_ftp_files(build_type, tag_name, config) -> List[ReleaseFile] :
|
||||
"""!
|
||||
@brief Gets file metadata for nightlies hosted on FTP, as determined by config["ftp"] attributes
|
||||
|
||||
@param [in] `build_type` Unknown str
|
||||
@param [in] `tag_name` Github tag name of the release
|
||||
@param [in] `config` config metadata set in main.py
|
||||
"""
|
||||
|
||||
tag_regex = re.compile("nightly_(.*)")
|
||||
build_group_regex = re.compile("nightly_.*-builds-([^.]+).*")
|
||||
|
||||
files = []
|
||||
try:
|
||||
with FTP(config["ftp"]["host"], config["ftp"]["user"], config["ftp"]["pass"]) as ftp:
|
||||
# extract version
|
||||
version_str = tag_regex.match(tag_name).group(1)
|
||||
|
||||
# extract filepath w/ version
|
||||
# then list all ftp hits with that path
|
||||
path_template = config["ftp"]["path"]
|
||||
path = path_template.format(type=build_type, version=version_str)
|
||||
file_entries = list(ftp.mlsd(path, ["type"]))
|
||||
|
||||
# get all ftp hits of type file
|
||||
for entry in file_entries:
|
||||
if entry[1]["type"] == "file":
|
||||
files.append(entry[0])
|
||||
except error_perm:
|
||||
print("Received permanent FTP error!")
|
||||
return []
|
||||
|
||||
out_data = []
|
||||
for file in files:
|
||||
# from the file list, extract only nightly files
|
||||
file_match = build_group_regex.match(file)
|
||||
if file_match is None:
|
||||
print("Ignoring non nightly file '{}'".format(file))
|
||||
continue
|
||||
|
||||
group_match = file_match.group(1)
|
||||
primary_url = None
|
||||
mirrors = []
|
||||
|
||||
# x64 is the name Visual Studio uses but Win64 works better for us since that gets displayed in the nightly post
|
||||
if "x64" in group_match:
|
||||
group_match = group_match.replace("x64", "Win64")
|
||||
|
||||
# construct the download URL list for all mirrors. The first listed ftp location is taken as the Primary
|
||||
for mirror in config["ftp"]["mirrors"]:
|
||||
download_url = mirror.format(type=build_type, version=version_str, file=file)
|
||||
if primary_url is None:
|
||||
primary_url = download_url
|
||||
else:
|
||||
mirrors.append(download_url)
|
||||
|
||||
# Form the List[ReleaseFile] list with the download URL links
|
||||
out_data.append(ReleaseFile(file, primary_url, group_match, None, mirrors))
|
||||
|
||||
return out_data
|
||||
@@ -1,103 +0,0 @@
|
||||
from typing import List
|
||||
|
||||
import requests
|
||||
import semantic_version
|
||||
from mako.template import Template
|
||||
|
||||
from file_list import ReleaseFile
|
||||
|
||||
|
||||
class ForumAPI:
|
||||
POST_SIZE_MAX = 50000
|
||||
"""!
|
||||
Maximum number of characters allowed in a post, including BBCode (03/17/2022)
|
||||
|
||||
Check with HLP admins occasionally to verify this limit, they can set it in the forum's admin panel
|
||||
"""
|
||||
|
||||
def __init__(self, config):
|
||||
self.config = config
|
||||
|
||||
def create_post(self, title, content, board):
|
||||
"""!
|
||||
@brief Create a post on the forums
|
||||
|
||||
@param[in] title Title of the post
|
||||
@param[in] content Body of the post
|
||||
@param[in] board Which board/forum to post to
|
||||
|
||||
@returns { "thread_url": <url_of_created_thread> }
|
||||
"""
|
||||
|
||||
if (self.config["hlp"]["api"] == "") or (self.config["hlp"]["key"] == ""):
|
||||
print("Post failed! No API or API_KEY given!")
|
||||
return
|
||||
|
||||
resp = requests.post(self.config["hlp"]["api"], data={
|
||||
"api_key": self.config["hlp"]["key"],
|
||||
"board": str(board),
|
||||
"subject": title,
|
||||
"body": content
|
||||
})
|
||||
|
||||
if resp.text != "OK":
|
||||
print("Post failed! Response: %s" %resp.text)
|
||||
|
||||
return resp.json()
|
||||
|
||||
def post_nightly(self, date, revision, files, log, success):
|
||||
"""!
|
||||
@brief Post a new Nightly topic on the forums using nightly.mako
|
||||
|
||||
@param[in] date The date to use
|
||||
@param[in] version The build's version
|
||||
@param[in] groups dict[Any, file_list.FileGroup]; FileGroups of SSE2, AVX, etc.
|
||||
@param[in] sources URL's of builds on github or fs2net
|
||||
"""
|
||||
|
||||
print("Posting nightly thread...")
|
||||
|
||||
title = "Nightly: {} - Revision {}".format(date, revision)
|
||||
|
||||
template = Template(filename=self.config["templates"]["nightly"])
|
||||
rendered = template.render_unicode(**{
|
||||
"date": date,
|
||||
"revision": revision,
|
||||
"files": files,
|
||||
"log": log,
|
||||
"success": success
|
||||
})
|
||||
|
||||
print("Creating post...")
|
||||
self.create_post(title, rendered, self.config["nightly"]["hlp_board"])
|
||||
|
||||
def post_release(self, date, version: semantic_version.Version, groups, sources):
|
||||
"""!
|
||||
@brief Post a new Release topic on the forums using release.mako.
|
||||
|
||||
@param[in] date The date to use
|
||||
@param[in] version The build's version
|
||||
@param[in] groups dict[Any, file_list.FileGroup]; FileGroups of SSE2, AVX, etc.
|
||||
@param[in] sources URL's of builds on github or fs2net
|
||||
|
||||
@returns If Successful, the URL of the created post
|
||||
"""
|
||||
|
||||
print("Posting release thread...")
|
||||
|
||||
title = "Release: {}".format(version)
|
||||
|
||||
template = Template(
|
||||
filename=self.config["templates"]["release"].format(major=version.major, minor=version.minor),
|
||||
module_directory='/tmp/mako_modules')
|
||||
rendered = template.render_unicode(**{
|
||||
"date": date,
|
||||
"version": version,
|
||||
"groups": groups,
|
||||
"sources": sources
|
||||
}).strip("\n")
|
||||
|
||||
print("Creating post...")
|
||||
|
||||
json = self.create_post(title, rendered, self.config["release"]["hlp_board"])
|
||||
return json["thread_url"]
|
||||
@@ -1,85 +0,0 @@
|
||||
# Class for use with interfacing with github via HTTP requests
|
||||
|
||||
import requests
|
||||
|
||||
from util import retry_multi, GLOBAL_TIMEOUT
|
||||
|
||||
class GithubAPI:
|
||||
headers = {
|
||||
"Accept": "application/vnd.github.v3+json"
|
||||
}
|
||||
url_root = "https://api.github.com"
|
||||
|
||||
def __init__(self, config):
|
||||
self.config = config
|
||||
|
||||
@retry_multi(5)
|
||||
def get(self, path):
|
||||
"""!
|
||||
@brief Performs a GET request with the given path. To be used with Github's REST API.
|
||||
@returns If successful, returns a .JSON object
|
||||
"""
|
||||
url = self.url_root + path
|
||||
|
||||
# GET https://api.github.com/<path> Accept: "application/vnd.github.v3+json"
|
||||
|
||||
response = requests.get(url, headers=self.headers, timeout=GLOBAL_TIMEOUT)
|
||||
|
||||
response.raise_for_status() # Raise a RequestException if we failed, and trigger retry
|
||||
|
||||
return response.json()
|
||||
|
||||
def get_release(self, tag_name):
|
||||
"""!
|
||||
@brief Retrieves the Github Release metadata as a JSON object
|
||||
@see https://docs.github.com/en/rest/reference/releases#get-a-release-by-tag-name
|
||||
"""
|
||||
return self.get("/repos/{}/releases/tags/{}".format(self.config["github"]["repo"], tag_name))
|
||||
|
||||
|
||||
def patch(self, path, data):
|
||||
"""!
|
||||
@brief Performs a PATCH request with the given path and body data (as dictionary)
|
||||
@returns If successful, returns a .JSON object
|
||||
"""
|
||||
url = self.url_root + path
|
||||
|
||||
response = requests.patch(url, headers=self.headers, timeout=GLOBAL_TIMEOUT, data=data)
|
||||
|
||||
response.raise_for_status()
|
||||
|
||||
return response.json()
|
||||
|
||||
def update_release(self, release_id, tag_name="", name="", body="", draft=None, prerelease=None):
|
||||
"""!
|
||||
@brief Updates a Github Release
|
||||
@param[in] release_id The id of the release, as obtained by get_release()
|
||||
@param[in] tag_name (optional) The git tag this release is associated with
|
||||
@param[in] name (optional) The name of the release
|
||||
@param[in] body (optional) Body text describing the release
|
||||
@param[in] draft (optional) If true, the release is marked as a "draft"
|
||||
@param[in] prerelease (optional) If true, the release is marked as a "prerelease"
|
||||
|
||||
@note If an optional argument is not provided, then its associated data is not changed
|
||||
"""
|
||||
path = "/repos/{}/releases/{}".format(self.config["github"]["repo"], release_id)
|
||||
|
||||
# Add to the data JSON if options are specified
|
||||
data = {}
|
||||
if tag_name != "":
|
||||
data["tag_name"] = tag_name
|
||||
|
||||
if name != "":
|
||||
data["name"] = name
|
||||
|
||||
if body != "":
|
||||
data["body"] = body
|
||||
|
||||
if draft != None:
|
||||
data["draft"] = data
|
||||
|
||||
if prerelease != None:
|
||||
data["prerelease"] = prerelease
|
||||
|
||||
self.patch(path, data)
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
import os
|
||||
import hashlib
|
||||
import tarfile
|
||||
import traceback
|
||||
import zipfile
|
||||
from tempfile import NamedTemporaryFile
|
||||
from zipfile import ZipFile
|
||||
|
||||
import requests
|
||||
import sys
|
||||
from mako.template import Template
|
||||
|
||||
from file_list import ReleaseFile
|
||||
from util import GLOBAL_TIMEOUT
|
||||
|
||||
|
||||
def _download_file(url, dest_file, session):
|
||||
print("Downloading " + url)
|
||||
# NOTE the stream=True parameter
|
||||
r = session.get(url, stream=True, timeout=GLOBAL_TIMEOUT)
|
||||
for chunk in r.iter_content(chunk_size=1024):
|
||||
if chunk: # filter out keep-alive new chunks
|
||||
dest_file.write(chunk)
|
||||
dest_file.flush()
|
||||
|
||||
|
||||
def _gen_hash(fileobj, hash_alg):
|
||||
h = hashlib.new(hash_alg)
|
||||
while True:
|
||||
data = fileobj.read(4096)
|
||||
|
||||
if not data:
|
||||
break
|
||||
|
||||
h.update(data)
|
||||
|
||||
return h.hexdigest()
|
||||
|
||||
|
||||
def get_hashed_file_list(file: ReleaseFile, session: requests.Session = None, hash_alg: str = "sha256"):
|
||||
if session is None:
|
||||
session = requests.Session()
|
||||
|
||||
with NamedTemporaryFile('w+b', suffix=file.filename) as local_file:
|
||||
_download_file(file.url, local_file, session)
|
||||
|
||||
filename = local_file.name
|
||||
hash_list = []
|
||||
|
||||
local_file.seek(0)
|
||||
file.hash = _gen_hash(local_file, hash_alg)
|
||||
file.size = os.stat(filename).st_size
|
||||
|
||||
try:
|
||||
if tarfile.is_tarfile(filename):
|
||||
with tarfile.open(filename) as archive:
|
||||
for entry in archive:
|
||||
if not entry.isfile():
|
||||
continue
|
||||
|
||||
print("Computing hash for " + entry.name)
|
||||
fileobj = archive.extractfile(entry)
|
||||
hash_list.append((entry.path, _gen_hash(fileobj, hash_alg)))
|
||||
elif zipfile.is_zipfile(filename):
|
||||
with ZipFile(filename) as archive:
|
||||
for entry in archive.infolist():
|
||||
# Python 3.6 has is_dir but that version is relatively new so we'll use the "safe" version here
|
||||
if entry.filename.endswith('/'):
|
||||
continue
|
||||
|
||||
print("Computing hash for " + entry.filename)
|
||||
with archive.open(entry) as fileobj:
|
||||
hash_list.append((entry.filename, _gen_hash(fileobj, hash_alg)))
|
||||
else:
|
||||
raise NotImplementedError("Unsupported archive type!")
|
||||
except:
|
||||
traceback.print_exception(*sys.exc_info())
|
||||
return
|
||||
|
||||
file.content_hashes = hash_list
|
||||
|
||||
|
||||
def render_installer_config(version, groups, config):
|
||||
template = Template(filename=config["templates"]["installer"], module_directory='/tmp/mako_modules')
|
||||
return template.render(**{
|
||||
"version": version,
|
||||
"groups": groups,
|
||||
}).strip("\n")
|
||||
-305
@@ -1,305 +0,0 @@
|
||||
# Post-build python script
|
||||
# Uploads build packages to Nebula and creates a forum post on https://www.hard-light.net
|
||||
# Uses the following environment variables (Set by the github action workflow before execution)
|
||||
|
||||
# FSO versioning
|
||||
# FSO_VERSION_MAJOR
|
||||
# FSO_VERSION_MINOR
|
||||
# FSO_VERSION_BUILD
|
||||
|
||||
# Credentials into IndieGames file host
|
||||
# INDIEGAMES_USER:
|
||||
# INDIEGAMES_SSHPASS:
|
||||
|
||||
# Credentials into Nebula Mod Database
|
||||
# NEBULA_USER:
|
||||
# NEBULA_PASSWORD:
|
||||
|
||||
# Credentials into hard-light.net for forum post
|
||||
# HLP_API:
|
||||
# HLP_KEY:
|
||||
|
||||
# LINUX_RESULT: bool, if the linux builds were sucessfully uploaded
|
||||
# WINDOWS_RESULT: bool, if the windows builds were successfully uploaded
|
||||
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
from subprocess import check_output
|
||||
from datetime import datetime
|
||||
from itertools import groupby
|
||||
|
||||
import semantic_version
|
||||
|
||||
# local .py files
|
||||
import file_list
|
||||
import installer
|
||||
import nebula
|
||||
import forum
|
||||
|
||||
# Compile regexes for extracting version components
|
||||
MAJOR_VERSION_PATTERN = re.compile("(?:set_if_not_defined|set)\(FSO_VERSION_MAJOR (\d+)\)")
|
||||
MINOR_VERSION_PATTERN = re.compile("(?:set_if_not_defined|set)\(FSO_VERSION_MINOR (\d+)\)")
|
||||
BUILD_VERSION_PATTERN = re.compile("(?:set_if_not_defined|set)\(FSO_VERSION_BUILD (\d+)\)")
|
||||
REVISION_VERSION_PATTERN = re.compile("(?:set_if_not_defined|set)\(FSO_VERSION_REVISION (\d+)\)")
|
||||
REVISION_STR_VERSION_PATTERN = re.compile("(?:set_if_not_defined|set)\(FSO_VERSION_REVISION_STR (\w+)\)")
|
||||
|
||||
LOG_FORMAT = """
|
||||
------------------------------------------------------------------------%n
|
||||
commit %h%nAuthor: %an <%ad>%n
|
||||
Commit: %cn <%cd>%n%n %s
|
||||
"""
|
||||
DATEFORMAT_VERSION = "%Y%m%d"
|
||||
DATEFORMAT_FORUM = "%d %B %Y"
|
||||
|
||||
def _match_version_number(text, regex):
|
||||
"""! Extracts the version component represented by `regex` from `text`
|
||||
|
||||
@param [in] `text` Filename with version string 'MAJOR.MINOR.BUILD'
|
||||
@param [in] `regex` Regex pattern of component to look for
|
||||
|
||||
@return The version component as integer
|
||||
"""
|
||||
match = regex.search(text)
|
||||
return int(match.group(1))
|
||||
|
||||
def _match_version_str(text, regex):
|
||||
"""! Extracts the version component represented by `regex` from `text`
|
||||
|
||||
@param [in] `text` Filename with version string 'MAJOR.MINOR.BUILD'
|
||||
@param [in] `regex` Regex pattern of component to look for
|
||||
|
||||
@return The version component as integer
|
||||
"""
|
||||
match = regex.search(text)
|
||||
return match.group(1)
|
||||
|
||||
|
||||
def get_source_version(date_version: datetime, tag_name: str) -> semantic_version.Version:
|
||||
"""! Retrieves the version string from version_override.cmake (and version.cmake)
|
||||
|
||||
@param[in] `date_version` Date this build is published for release
|
||||
@param[in] `tag_name` Tag of this release, used to determine if release, rc, or nightly
|
||||
|
||||
@return If release: `FSO_VERSION_MAJOR.FSO_VERSION_MINOR.FSO_VERSION_BUILD`
|
||||
@return If rc: `FSO_VERSION_MAJOR.FSO_VERSION_MINOR.FSO_VERSION_BUILD-FSO_VERSION_REVISION_STR`
|
||||
@return If nightly: `FSO_VERSION_MAJOR.FSO_VERSION_MINOR.FSO_VERSION_BUILD-FSO_VERSION_REVISION_STR` (uses both version_override.cmake and version.cmake)
|
||||
|
||||
@note This is the version used to identify in Nebula and the forums. version_override.cmake is used for the builds
|
||||
made by CI tools and version.cmake is used for builds made by devs.
|
||||
"""
|
||||
|
||||
with open(os.path.join("..", "..", "version_override.cmake"), "r") as f:
|
||||
filetext = f.read()
|
||||
major = _match_version_number(filetext, MAJOR_VERSION_PATTERN)
|
||||
minor = _match_version_number(filetext, MINOR_VERSION_PATTERN)
|
||||
build = _match_version_number(filetext, BUILD_VERSION_PATTERN)
|
||||
# revision = _match_version_number(filetext, REVISION_VERSION_PATTERN)
|
||||
revision_str = _match_version_str(filetext, REVISION_STR_VERSION_PATTERN)
|
||||
|
||||
print("Parsing version_override.cmake...")
|
||||
if "rc" in tag_name.lower():
|
||||
version = semantic_version.Version("{}.{}.{}-{}".format(major, minor, build, revision_str))
|
||||
|
||||
elif "release" in tag_name.lower():
|
||||
version = semantic_version.Version("{}.{}.{}".format(major, minor, build))
|
||||
|
||||
elif "nightly" in tag_name.lower():
|
||||
# Nightly's version_override.cmake only has FSO_VERSION_REVISION and FSO_VERSION_REVISION_STR set
|
||||
# So, we have to pull the rest of the version string from version.cmake
|
||||
print("Parsing version.cmake...")
|
||||
with open(os.path.join("..", "..", "cmake", "version.cmake"), "r") as f:
|
||||
major = _match_version_number(filetext, MAJOR_VERSION_PATTERN)
|
||||
minor = _match_version_number(filetext, MINOR_VERSION_PATTERN)
|
||||
build = _match_version_number(filetext, BUILD_VERSION_PATTERN)
|
||||
version = semantic_version.Version("{}.{}.{}-{}".format(major, minor, build, revision_str))
|
||||
|
||||
else:
|
||||
print(" ERROR: malformed tag_name %s" % tag_name)
|
||||
sys.exit(1)
|
||||
|
||||
print(" version: {}".format(version))
|
||||
print(" version.prerelease: {}".format(version.prerelease))
|
||||
return version
|
||||
|
||||
|
||||
def main():
|
||||
os.chdir(os.path.dirname(__file__)) # Change working directory to this file's directory
|
||||
|
||||
# Aggregate configuration data in a dictionary
|
||||
config = {
|
||||
"github": {
|
||||
"repo": os.environ["GITHUB_REPO"],
|
||||
},
|
||||
"ftp": {
|
||||
"host": "scp.indiegames.us",
|
||||
"user": os.environ["INDIEGAMES_USER"],
|
||||
"pass": os.environ["INDIEGAMES_SSHPASS"],
|
||||
"path": "public_html/builds/{type}/{version}/",
|
||||
"mirrors": (
|
||||
"https://porphyrion.feralhosting.com/datacorder/builds/{type}/{version}/{file}",
|
||||
"http://scp.indiegames.us/builds/{type}/{version}/{file}",
|
||||
),
|
||||
},
|
||||
"nebula": {
|
||||
"user": os.environ["NEBULA_USER"],
|
||||
"password": os.environ["NEBULA_PASSWORD"],
|
||||
},
|
||||
"hlp": {
|
||||
"api": os.environ["HLP_API"],
|
||||
"key": os.environ["HLP_KEY"],
|
||||
},
|
||||
"templates": {
|
||||
"nightly": "nightly.mako",
|
||||
"release": "release.mako",
|
||||
},
|
||||
"nightly": {
|
||||
"hlp_board": 173,
|
||||
},
|
||||
"release": {
|
||||
"hlp_board": 50,
|
||||
},
|
||||
}
|
||||
|
||||
# bail if this script is run from a workflow that doesn't identify as a release or nightly
|
||||
if sys.argv[1] not in ("release", "nightly"):
|
||||
print("ERROR: Invalid release mode %s passed. Expected release or nightly!" % sys.argv[1])
|
||||
sys.exit(1)
|
||||
|
||||
linux_success = os.environ["LINUX_RESULT"] == "success"
|
||||
windows_success = os.environ["WINDOWS_RESULT"] == "success"
|
||||
if (sys.argv[1] == "release"):
|
||||
if not (linux_success and windows_success):
|
||||
# bail if this is a release and either build workflow failed
|
||||
print("ERROR: One or more builds failed to publish! Cannot post release.")
|
||||
sys.exit(1)
|
||||
else:
|
||||
if not (linux_success or windows_success):
|
||||
# bail if this is a nightly build and both build workflows failed
|
||||
print("ERROR: All builds failed to publish! Cannot post nightly.")
|
||||
sys.exit(1)
|
||||
|
||||
# bail if tag_name doesn't match with sys.argv[1]
|
||||
tag_name = os.environ["RELEASE_TAG"] ##!< commit tag string
|
||||
if (sys.argv[1] == "release") and (not tag_name.startswith("release_")):
|
||||
print("ERROR: Invalid tag name detected. Expected release_ prefix for release builds but found %s (full ref = %s)" % tag_name, os.environ["GITHUB_REF"])
|
||||
sys.exit(1)
|
||||
|
||||
if (sys.argv[1] == "nightly") and (not tag_name.startswith("nightly_")):
|
||||
print("ERROR: Invalid tag name detected. Expected nightly_ prefix for nightly builds but found %s (full ref = %s)" % tag_name, os.environ["GITHUB_REF"])
|
||||
sys.exit(1)
|
||||
|
||||
# bail if tag_name does not exist in the repo
|
||||
if not check_output(("git", "show-ref", "--tags", "refs/tags/%s" % tag_name), text=True):
|
||||
print("ERROR: Couldn't find tag %s in repo (git show-ref)!" % tag_name)
|
||||
sys.exit(1)
|
||||
|
||||
# Populate version and date
|
||||
date = datetime.now() ##!< current date
|
||||
version = get_source_version(date.strftime(DATEFORMAT_VERSION), tag_name) ##!< form full version string
|
||||
|
||||
# find the previous tag release (used by nightly)
|
||||
tags = check_output(("git", "for-each-ref", "--sort=-taggerdate", "--format='%(tag)'", "refs/tags"), text=True).splitlines() # retrieve all tags in the repo by using git on the shell
|
||||
# NOTE: check_output returns canonical string representation. use repr() on strings its being compared to
|
||||
previous_tag = None
|
||||
found = False
|
||||
for tag in tags:
|
||||
if found:
|
||||
# Look for the "previous" tag with the same configuration ('release_' or 'nightly_')
|
||||
# Assumes older tags have a higher index than newer
|
||||
if tag.startswith("\'" + sys.argv[1] + "_"):
|
||||
previous_tag = tag
|
||||
break
|
||||
elif tag == repr(tag_name):
|
||||
# Ok, found the tag
|
||||
found = True
|
||||
|
||||
if not found:
|
||||
# couldn't find tag, bail
|
||||
print("ERROR: Couldn't find tag %s in repo! (git for-each-ref)" % tag_name)
|
||||
sys.exit(1)
|
||||
|
||||
if (sys.argv[1] == "nightly") and (not previous_tag):
|
||||
# couldn't find previous tag, bail
|
||||
print("ERROR: Could not find a previous tag for %s!" % tag_name)
|
||||
sys.exit(1)
|
||||
|
||||
if sys.argv[1] == "release":
|
||||
# Release specific action
|
||||
print("Retrieving file list...")
|
||||
files, sources = file_list.get_release_files(tag_name, config)
|
||||
|
||||
print("Hashing files...")
|
||||
for file in files:
|
||||
installer.get_hashed_file_list(file)
|
||||
|
||||
# Construct the file groups
|
||||
# split the file list into a dictionary of {group: files} pairs using `groupby()`
|
||||
# Since `groupby()` returns a iterator reference to the original files list, we have to do a weird hand toss
|
||||
# to save it as a dictionary
|
||||
## NOTE z64: files need to be sorted or else key duplication will occur!
|
||||
groups = {key: file_list.FileGroup(key, list(group)) for key, group in groupby(files, lambda g: g.group)}
|
||||
|
||||
# Error check for all group keys and subkeys to be used in the mako. Do this here for better debugging QoL
|
||||
if "Win32" in groups.keys():
|
||||
if "AVX" not in groups["Win32"].subFiles.keys():
|
||||
print("ERROR: No Win32-AVX builds were detected!")
|
||||
sys.exit(1)
|
||||
else:
|
||||
print("ERROR: No Win32 builds were detected!")
|
||||
sys.exit(1)
|
||||
|
||||
if "Win64" in groups.keys():
|
||||
if "AVX" not in groups["Win64"].subFiles.keys():
|
||||
print("ERROR: No x64-AVX builds were detected!")
|
||||
sys.exit(1)
|
||||
else:
|
||||
print("ERROR: No x64 builds were detected!")
|
||||
sys.exit(1)
|
||||
|
||||
if "Linux" not in groups.keys():
|
||||
print("ERROR: No Linux builds were detected!")
|
||||
sys.exit(1)
|
||||
|
||||
# z64: What dose this do???
|
||||
# print(installer.render_installer_config(version, groups, config))
|
||||
|
||||
# Publish release builds to Nebula
|
||||
print("Publishing to Nebula...")
|
||||
nebula.submit_release(
|
||||
nebula.render_nebula_release(version, "rc" if version.prerelease else "stable", files, config),
|
||||
config)
|
||||
|
||||
# Publish forum post, using the release.mako template
|
||||
print("Publishing to Hard-light.net...")
|
||||
fapi = forum.ForumAPI(config)
|
||||
fapi.post_release(date.strftime(DATEFORMAT_FORUM), version, groups, sources)
|
||||
|
||||
else:
|
||||
# Dead for now, nightly publish is done elsewhere
|
||||
# Nightly specific action
|
||||
print("Retrieving file list...")
|
||||
files = file_list.get_ftp_files("nightly", tag_name, config)
|
||||
|
||||
print("Hashing files...")
|
||||
for file in files:
|
||||
installer.get_hashed_file_list(file)
|
||||
|
||||
print("Publishing to Nebula...")
|
||||
nebula.submit_release(
|
||||
nebula.render_nebula_release(version, "nightly", files, config),
|
||||
config)
|
||||
|
||||
# Compile commit messages into a log with all commits between this nightly and the previous nightly
|
||||
log = check_output(("git", "log", "%s^..%s^" % (previous_tag, tag_name), "--no-merges", "--stat", "--pretty=format:\"%s\"" % LOG_FORMAT.strip()))
|
||||
|
||||
# Publish forum post, using the nighty.mako template
|
||||
print("Publishing to Hard-light.net...")
|
||||
fapi = forum.ForumAPI(config)
|
||||
fapi.post_nightly(date.strftime(DATEFORMAT_FORUM), os.environ["GITHUB_SHA"], files, log, (linux_success and windows_success))
|
||||
|
||||
print("Done!")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,241 +0,0 @@
|
||||
import os.path
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
import requests
|
||||
|
||||
from file_list import ReleaseFile
|
||||
from util import retry_multi, GLOBAL_TIMEOUT
|
||||
|
||||
metadata = {
|
||||
'type': 'engine',
|
||||
'title': 'FSO',
|
||||
'notes': '',
|
||||
'banner': 'https://fsnebula.org/storage/0d/e7/bf64bcdea9a9c115969cfb784e1ca457d24a7c2da4fc6f213521c3bb6abb.png',
|
||||
'screenshots': [],
|
||||
'videos': [],
|
||||
'first_release': '2017-09-24',
|
||||
'cmdline': '',
|
||||
'mod_flag': ['FSO'],
|
||||
'tile': 'https://fsnebula.org/storage/ec/cc/0bf23e028c26d5175ff52d003bff85b0a17b0ddfc1130d65bdf6d36f6324.png',
|
||||
'logo': None,
|
||||
'release_thread': None,
|
||||
'description': '',
|
||||
'id': 'FSO',
|
||||
'packages': [],
|
||||
}
|
||||
|
||||
platforms = {
|
||||
'Linux': 'linux',
|
||||
'MacOSX': 'macosx',
|
||||
'Win32-SSE2': 'windows',
|
||||
'Win64-SSE2': 'windows',
|
||||
'Win32-AVX': 'windows',
|
||||
'Win64-AVX': 'windows'
|
||||
}
|
||||
|
||||
envs = {
|
||||
'Linux': 'linux && x86_64', # Linux only has 64bit builds
|
||||
'MacOSX': 'macosx',
|
||||
'Win32-SSE2': 'windows',
|
||||
'Win64-SSE2': 'windows && x86_64',
|
||||
'Win32-AVX': 'windows && avx',
|
||||
'Win64-AVX': 'windows && avx && x86_64'
|
||||
}
|
||||
|
||||
subdirs = {
|
||||
'Win32-SSE2': 'x86',
|
||||
'Win64-SSE2': 'x64',
|
||||
'Win32-AVX': 'x86_avx',
|
||||
'Win64-AVX': 'x64_avx'
|
||||
}
|
||||
|
||||
|
||||
def render_nebula_release(version, stability, files, config):
|
||||
meta = metadata.copy()
|
||||
meta['version'] = str(version)
|
||||
meta['stability'] = stability # This can be one of ('stable', 'rc', 'nightly')
|
||||
|
||||
for file in files:
|
||||
if file.content_hashes is None:
|
||||
# The extraction probably failed which is why we don't have any hashes
|
||||
continue
|
||||
|
||||
group = file.group
|
||||
|
||||
# release.py sets subgroup but nightly.py doesn't which means we have to normalize group here.
|
||||
if file.subgroup:
|
||||
group += '-' + file.subgroup
|
||||
|
||||
pkg = {
|
||||
'name': group,
|
||||
'notes': '',
|
||||
'is_vp': False,
|
||||
'files': [{
|
||||
'dest': platforms[group] + '/' + subdirs.get(group, ''),
|
||||
'filesize': file.size,
|
||||
'checksum': ['sha256', file.hash],
|
||||
'urls': [file.url] + file.mirrors,
|
||||
'filename': file.name
|
||||
}],
|
||||
'environment': envs.get(group),
|
||||
'filelist': [],
|
||||
'status': 'required',
|
||||
'folder': None,
|
||||
'dependencies': [],
|
||||
'executables': []
|
||||
}
|
||||
|
||||
for fn, checksum in file.content_hashes:
|
||||
if group in subdirs:
|
||||
dest_fn = subdirs[group] + '/' + fn
|
||||
else:
|
||||
dest_fn = fn
|
||||
|
||||
# If the group is a known platform then we put the binaries into a separate subfolder for each platform
|
||||
if group in platforms:
|
||||
dest_fn = platforms[group] + '/' + dest_fn
|
||||
|
||||
pkg['filelist'].append({
|
||||
'orig_name': fn,
|
||||
'checksum': ('sha256', checksum),
|
||||
'archive': file.name,
|
||||
'filename': dest_fn
|
||||
})
|
||||
|
||||
if group == 'Linux' and fn.endswith('.AppImage'):
|
||||
if 'qtfred' in fn:
|
||||
if '-FASTDBG' in fn:
|
||||
label = 'QtFRED Debug'
|
||||
else:
|
||||
label = 'QtFRED'
|
||||
|
||||
else:
|
||||
if '-FASTDBG' in fn:
|
||||
label = 'Fast Debug'
|
||||
else:
|
||||
label = None
|
||||
|
||||
props = {
|
||||
"x64": True, # All Linux builds are 64-bit
|
||||
"sse2": True, # Linux builds are forced to compile with SSE2 but not AVX
|
||||
"avx": False,
|
||||
"avx2": False,
|
||||
}
|
||||
|
||||
pkg['executables'].append({
|
||||
'file': dest_fn,
|
||||
'label': label,
|
||||
'properties': props,
|
||||
})
|
||||
elif group == 'MacOSX' and fn.startswith(os.path.basename(fn) + '.app/'):
|
||||
if 'qtfred' in fn:
|
||||
if '-FASTDBG' in fn:
|
||||
label = 'QtFRED Debug'
|
||||
else:
|
||||
label = 'QtFRED'
|
||||
else:
|
||||
if '-FASTDBG' in fn:
|
||||
label = 'Fast Debug'
|
||||
else:
|
||||
label = None
|
||||
|
||||
props = {
|
||||
"x64": True, # All Mac builds are 64-bit
|
||||
"sse2": True, # There are no forced options on mac but 64-bit always implies SSE2 so we set that here
|
||||
"avx": False,
|
||||
"avx2": False,
|
||||
}
|
||||
|
||||
pkg['executables'].append({
|
||||
'file': dest_fn,
|
||||
'label': label,
|
||||
'properties': props,
|
||||
})
|
||||
elif group.startswith('Win') and fn.endswith('.exe'):
|
||||
if 'fred2' in fn:
|
||||
if '-FASTDBG' in fn:
|
||||
label = 'FRED2 Debug'
|
||||
else:
|
||||
label = 'FRED2'
|
||||
|
||||
elif 'qtfred' in fn:
|
||||
if '-FASTDBG' in fn:
|
||||
label = 'QtFRED Debug'
|
||||
else:
|
||||
label = 'QtFRED'
|
||||
|
||||
else:
|
||||
if '-FASTDBG' in fn:
|
||||
label = 'Fast Debug'
|
||||
else:
|
||||
label = None
|
||||
|
||||
props = {
|
||||
"x64": "x64" in fn,
|
||||
"sse2": "SSE2" in fn or "AVX" in fn, # AVX implies SSE2
|
||||
"avx": "AVX" in fn, # This conveniently also covers the AVX2 case since AVX2 implies AVX
|
||||
"avx2": "AVX2" in fn,
|
||||
}
|
||||
|
||||
pkg['executables'].append({
|
||||
'file': dest_fn,
|
||||
'label': label,
|
||||
'properties': props,
|
||||
})
|
||||
|
||||
meta["packages"].append(pkg)
|
||||
|
||||
return meta
|
||||
|
||||
|
||||
@retry_multi(5)
|
||||
def nebula_request(session, kind, path, **kwargs):
|
||||
uri = "https://fsnebula.org/api/1/{}".format(path)
|
||||
|
||||
request_args = {
|
||||
"timeout": GLOBAL_TIMEOUT
|
||||
}
|
||||
request_args.update(kwargs)
|
||||
|
||||
return session.request(kind, uri, **request_args)
|
||||
|
||||
|
||||
def submit_release(meta, config):
|
||||
try:
|
||||
with requests.Session() as session:
|
||||
print('Logging into Nebula...')
|
||||
result = nebula_request(session, 'post', 'login', data={
|
||||
'user': config['nebula']['user'],
|
||||
'password': config['nebula']['password']
|
||||
})
|
||||
|
||||
if result.status_code != 200:
|
||||
print('Login failed!')
|
||||
return False
|
||||
|
||||
data = result.json()
|
||||
if not data['result']:
|
||||
print('Login failed!')
|
||||
return False
|
||||
|
||||
print('Submitting release...')
|
||||
result = nebula_request(session, 'post', 'mod/release', headers={
|
||||
'X-KN-TOKEN': data['token']
|
||||
}, json=meta)
|
||||
|
||||
if result.status_code != 200:
|
||||
print('Request failed!')
|
||||
return False
|
||||
|
||||
data = result.json()
|
||||
if not data['result']:
|
||||
print('ERROR: ' + data['reason'])
|
||||
return False
|
||||
|
||||
print('Success!')
|
||||
return True
|
||||
except Exception:
|
||||
exc_type, exc_value, exc_traceback = sys.exc_info()
|
||||
traceback.print_exception(exc_type, exc_value, exc_traceback)
|
||||
return False
|
||||
@@ -1,27 +0,0 @@
|
||||
Here is the nightly for ${date} - Revision ${revision}
|
||||
|
||||
% if not success:
|
||||
[b][color=red]At least one of the nightly builds failed![/color][/b]
|
||||
% endif
|
||||
% for file in files:
|
||||
|
||||
|
||||
Group: ${file.group}
|
||||
[url=${file.url}]${file.name}[/url] \
|
||||
%for mirror in file.mirrors:
|
||||
%if loop.first:
|
||||
(\
|
||||
%endif
|
||||
[url=${mirror}]Mirror[/url]\
|
||||
%if loop.last:
|
||||
)\
|
||||
%else:
|
||||
, \
|
||||
%endif
|
||||
%endfor
|
||||
|
||||
% endfor
|
||||
|
||||
[code]
|
||||
${log}
|
||||
[/code]
|
||||
@@ -1,68 +0,0 @@
|
||||
|
||||
<%def name="build(file)">[url=${file.url}]${file.filename}[/url]</%def>
|
||||
|
||||
[b]Change log:[/b] (chronologically ordered)
|
||||
PLACEHOLDER
|
||||
|
||||
[b]Deprecations:[/b]
|
||||
PLACEHOLDER
|
||||
|
||||
Deprecations are a mechanism in FSO where a certain feature or aspect of the engine has changed or is no longer supported. Since this would normally break existing mods we have the mod table feature "[tt]$Target Version:[/tt]" with which a mod can specify what version of FSO it was developed with. The features listed above will be removed or changed when the target version of a mod is at least the version released in this post.
|
||||
|
||||
[size=5pt]Previous [url=https://www.hard-light.net/forums/index.php?topic=97293.0]21.0 Release Thread[/url][/size]
|
||||
|
||||
Launchers, if you don't have one already:
|
||||
[b]All platforms: [/b] For every day use, we recommend [url=https://www.hard-light.net/forums/index.php?topic=94068.0]Knossos[/url], an integrated solution for downloading and launching mods.
|
||||
|
||||
[hidden=Alternative Launchers]
|
||||
Cross-platform: [url=http://www.hard-light.net/forums/index.php?topic=89162]wxLauncher 0.12.x Test Build[/url] (ongoing project for a unified launcher, you should upgrade to the latest RC/test build if you have not yet)
|
||||
[b]Important:[/b] For best compatibility with FSO 3.8 and later you should use at least wxLauncher 0.12.
|
||||
|
||||
Windows: [url=http://scp.fsmods.net/files/Launcher55g.zip]Launcher 5.5g[/url] ([url=http://scp.indiegames.us/builds/Launcher55g.zip]Mirror[/url]) ([url=http://www.mediafire.com/?wdvzn7hhhzh418m]Mirror[/url]) Not compatible with Windows 8+, use wxLauncher above
|
||||
OS X: Soulstorm's [url=http://www.hard-light.net/forums/index.php/topic,51391.0.html]OS X Launcher 3.0[/url]
|
||||
Linux: [url=http://www.hard-light.net/forums/index.php/topic,53206.0.html]YAL[/url] or [url=http://www.hard-light.net/wiki/index.php/Fs2_open_on_Linux/Graphics_Settings]by hand[/url] or whatever you can figure out.[/hidden]
|
||||
|
||||
[img]http://scp.indiegames.us/img/windows-icon.png[/img] [color=green][size=12pt]Windows (32/64-bit)[/size][/color]
|
||||
[size=8pt]Compiled using GitHub Actions on Windows Server 2019 (10.0.17763), Visual Studio Enterprise 2019[/size]
|
||||
|
||||
[b]64-bit:[/b] ${build(groups["Win64"].mainFile)}
|
||||
|
||||
[b]32-bit:[/b] ${build(groups["Win32"].mainFile)}
|
||||
[size=8pt]This one is based on the SSE2 Optimizations from the MSVC Compiler.[/size]
|
||||
|
||||
[hidden=Alternative builds]
|
||||
|
||||
[b]64-bit AVX:[/b] ${build(groups["Win64"].subFiles["AVX"])}
|
||||
[size=8pt]This one is based on the AVX Optimizations from the MSVC Compiler (fastest build if your CPU supports AVX instructions).[/size]
|
||||
|
||||
|
||||
[b]32-bit AVX:[/b] ${build(groups["Win32"].subFiles["AVX"])}
|
||||
[size=8pt]This one is based on the AVX Optimizations from the MSVC Compiler.[/size]
|
||||
|
||||
[b]What are those SSE, SSE2 and AVX builds I keep seeing everywhere?[/b]
|
||||
[url=http://www.hard-light.net/forums/index.php?topic=65628.0]Your answer is in this topic.[/url]
|
||||
Don't want to deal with that? Use [url=https://www.hard-light.net/forums/index.php?topic=94068.0]Knossos[/url] and it will download the best build specifically for your PC!
|
||||
[/hidden]
|
||||
|
||||
[img]http://scp.indiegames.us/img/linux-icon.png[/img] [color=green][size=12pt]Linux 64-bit[/size][/color]
|
||||
[size=8pt]Compiled with Ubuntu 16.04 LTS 64-bit, GCC 5[/size]
|
||||
${build(groups["Linux"].mainFile)}
|
||||
|
||||
These builds use a mechanism called [url=http://appimage.org/]AppImage[/url] which should allow these builds to run on most Linux distributions. However, we recommend that you compile your own builds which will result in less issues.
|
||||
Alternatively, if there is a package in your software repository then you should use that. If you are the maintainer of such a package for a distribution then let us know and we will include that here.
|
||||
|
||||
|
||||
[img]http://scp.indiegames.us/img/mac-icon.png[/img] [color=green][size=12pt]OS X[/size][/color]
|
||||
[b][color=red]Not available[/color][/b] We recently lost access to our Mac CI environment which we usually used for compiling these builds so for the time being, there will be no builds for this OS.
|
||||
|
||||
[hidden=TrackIR Users]
|
||||
[size=12pt]Important!![/size]
|
||||
An external DLL is required for FSO to use TrackIR functions. The following DLL is simply unpacked in to your main FreeSpace2 root dir.
|
||||
TrackIR is only supported on Windows.
|
||||
[url=http://www.mediafire.com/download.php?4zw024zrh44etse]TrackIR SCP DLL[/url] ([url=http://scp.fsmods.net/builds/scptrackir.zip]Mirror[/url]) ([url=http://scp.indiegames.us/builds/scptrackir.zip]Mirror[/url])[/hidden]
|
||||
|
||||
Known issues:
|
||||
[list]
|
||||
[li][url=https://github.com/scp-fs2open/fs2open.github.com/issues]Github issues[/url] and [url=https://github.com/scp-fs2open/fs2open.github.com/pulls]pending pull requests[/url][/li]
|
||||
[li]See the list of [url=http://scp.indiegames.us/mantis/search.php?project_id=1&status_id%5B%5D=10&status_id%5B%5D=20&status_id%5B%5D=30&status_id%5B%5D=40&status_id%5B%5D=50&priority_id%5B%5D=40&priority_id%5B%5D=50&priority_id%5B%5D=60&sticky_issues=on&sortby=last_updated&dir=DESC&per_page=200&hide_status_id=-2]Fix for next release[/url] bugs - mark a bug as an elevated priority (high, urgent, immediate) to get it included in that filter.[/li]
|
||||
[/list]
|
||||
@@ -1,3 +0,0 @@
|
||||
Mako==1.1.5
|
||||
requests==2.26.0
|
||||
semantic-version==2.8.5
|
||||
@@ -1,46 +0,0 @@
|
||||
# miscellaneous utilities
|
||||
|
||||
import os
|
||||
import time
|
||||
from functools import wraps
|
||||
|
||||
from requests import RequestException
|
||||
|
||||
GLOBAL_TIMEOUT = 30
|
||||
|
||||
def retry_multi(max_retries):
|
||||
"""!
|
||||
@brief Decorator - Retry a function `max_retries` times.
|
||||
|
||||
@param [in] `max_retries` Maximum number of times to retry the decorated function before giving up
|
||||
|
||||
@details Intended for use with functions from the `request` module, only catches `RequestException`'s
|
||||
@note This has been copied from https://stackoverflow.com/a/23892489
|
||||
"""
|
||||
|
||||
def retry(func):
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
num_retries = 0
|
||||
while num_retries <= max_retries:
|
||||
try:
|
||||
ret = func(*args, **kwargs)
|
||||
break
|
||||
except RequestException:
|
||||
if num_retries == max_retries:
|
||||
raise
|
||||
num_retries += 1
|
||||
time.sleep(5)
|
||||
return ret
|
||||
|
||||
return wrapper
|
||||
|
||||
return retry
|
||||
|
||||
|
||||
def expand_config_vars(config):
|
||||
"""
|
||||
@brief Expands the shell variable for the repo string from `config`
|
||||
"""
|
||||
|
||||
config["git"]["repo"] = os.path.expandvars(config["git"]["repo"])
|
||||
@@ -3,18 +3,9 @@
|
||||
set -ex
|
||||
|
||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
sudo add-apt-repository -y "ppa:msulikowski/valgrind" # For fixing a bug with valgrind 3.11 which does not recognize the rdrand instruction
|
||||
|
||||
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add -
|
||||
sudo add-apt-repository -y 'deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main'
|
||||
|
||||
sudo apt-get -yq update
|
||||
# Nothing to do here
|
||||
:
|
||||
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
# Nothing to do here
|
||||
:
|
||||
elif [ "$TRAVIS_OS_NAME" = "windows" ]; then
|
||||
# Nothing to do here
|
||||
:
|
||||
fi
|
||||
+13
-20
@@ -2,32 +2,33 @@
|
||||
|
||||
set -ex
|
||||
|
||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
mkdir -p /tmp/builds
|
||||
if [ "$RELEASE_BUILD" = true ]; then
|
||||
# Package the source code in release builds
|
||||
PARENT_DIR="$(basename "$PWD")"
|
||||
(cd .. && tar -czvf /tmp/builds/$PACKAGE_NAME-source-Unix.tar.gz --exclude-vcs "$PARENT_DIR")
|
||||
fi
|
||||
fi
|
||||
|
||||
mkdir -p build
|
||||
cd build
|
||||
|
||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
if [ "$RELEASE_BUILD" = true ]; then
|
||||
PARENT_DIR="$(basename $PWD)"
|
||||
(cd .. && tar -czvf /tmp/builds/$PACKAGE_NAME-source-Unix.tar.gz --exclude-vcs "$PARENT_DIR")
|
||||
fi
|
||||
|
||||
CXXFLAGS="-m64 -mtune=generic -mfpmath=sse -msse -msse2 -pipe -Wno-unknown-pragmas"
|
||||
CFLAGS="-m64 -mtune=generic -mfpmath=sse -msse -msse2 -pipe -Wno-unknown-pragmas"
|
||||
|
||||
if [[ "$CC" =~ ^clang.*$ ]]; then
|
||||
CXXFLAGS="$CXXFLAGS -stdlib=libc++"
|
||||
fi
|
||||
|
||||
export CXXFLAGS
|
||||
export CFLAGS
|
||||
CMAKE="cmake -G Ninja -DFSO_FATAL_WARNINGS=ON $CMAKE_OPTIONS"
|
||||
CMAKE="cmake -G Ninja -DFSO_FATAL_WARNINGS=ON"
|
||||
if [ "$BUILD_DEPLOYMENT" = true ]; then
|
||||
for config in $BUILD_CONFIGS
|
||||
do
|
||||
mkdir -p $config
|
||||
cd $config
|
||||
eval $CMAKE -DFSO_INSTALL_DEBUG_FILES=ON -DCMAKE_BUILD_TYPE=$config -DCMAKE_INSTALL_PREFIX="/tmp/release/$config" \
|
||||
-DFSO_BUILD_APPIMAGE=ON -DFSO_BUILD_INCLUDED_LIBS=ON -DFFMPEG_USE_PRECOMPILED=ON -DFSO_BUILD_QTFRED=OFF ../..
|
||||
-DFSO_BUILD_APPIMAGE=ON -DAPPIMAGE_ASSISTANT="$HOME/AppImageAssistant" \
|
||||
-DFSO_BUILD_INCLUDED_LIBS=ON -DFFMPEG_USE_PRECOMPILED=ON ../..
|
||||
cd ..
|
||||
done
|
||||
else
|
||||
@@ -37,14 +38,6 @@ elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
if [ "$BUILD_DEPLOYMENT" = true ]; then
|
||||
cmake -G "Xcode" -DFSO_FATAL_WARNINGS=ON -DFSO_INSTALL_DEBUG_FILES=ON -DCMAKE_INSTALL_PREFIX="/tmp/release" ..
|
||||
else
|
||||
cmake -G "Xcode" $CMAKE_OPTIONS ..
|
||||
fi
|
||||
elif [ "$TRAVIS_OS_NAME" = "windows" ]; then
|
||||
if [ "$CMAKE_GENERATOR" = "Ninja" ]; then
|
||||
cmake -DFSO_USE_SPEECH="OFF" -DFSO_FATAL_WARNINGS="ON" -DFSO_USE_VOICEREC="OFF" -DFSO_BUILD_TESTS="ON" \
|
||||
-DFSO_BUILD_FRED2="OFF" -G "$CMAKE_GENERATOR" ..
|
||||
else
|
||||
cmake -DFSO_USE_SPEECH="ON" -DFSO_FATAL_WARNINGS="ON" -DFSO_USE_VOICEREC="OFF" -DFSO_BUILD_TESTS="ON" \
|
||||
-DMSVC_SIMD_INSTRUCTIONS=SSE2 -DFSO_BUILD_FRED2="ON" -G "$CMAKE_GENERATOR" -T "$CMAKE_TOOLSET" ..
|
||||
cmake -G "Xcode" ..
|
||||
fi
|
||||
fi
|
||||
@@ -58,11 +58,6 @@ if [ "$BUILD_DEPLOYMENT" = true ]; then
|
||||
echo "Skipping non-release configuration";
|
||||
exit 0;
|
||||
fi
|
||||
|
||||
if [ "$TRAVIS_OS_NAME" = "windows" ]; then
|
||||
echo "Skipping non-release platform"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
export RELEASE_BUILD
|
||||
|
||||
+22
-57
@@ -10,62 +10,27 @@ if [[ ! "$(curl -V)" == *"sftp"* ]]; then
|
||||
|
||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
|
||||
if [ -f ~/curl_cache/curl*.deb ]; then
|
||||
cd ~/curl_cache
|
||||
sudo dpkg -i libcurl3*.deb
|
||||
sudo dpkg -i curl*.deb
|
||||
else
|
||||
# Since the Travis CI people are not capable of enabling SSH/SCP support for their libcurl we need to build that manually...
|
||||
# These commands are based on the tutorial from here: http://zeroset.mnim.org/2013/03/14/sftp-support-for-curl-in-ubuntu-12-10-quantal-quetzal-and-later/
|
||||
mkdir /tmp/curl
|
||||
cd /tmp/curl
|
||||
sudo apt-get update
|
||||
sudo apt-get install build-essential debhelper libssh2-1-dev libgnutls-dev libidn11-dev libkrb5-dev libldap2-dev libnss3-dev librtmp-dev libtool openssh-server quilt
|
||||
apt-get source curl
|
||||
sudo apt-get build-dep curl
|
||||
# Since the Travis CI people are not capable of enabling SSH/SCP support for their libcurl we need to build that manually...
|
||||
# These commands are based on the tutorial from here: http://zeroset.mnim.org/2013/03/14/sftp-support-for-curl-in-ubuntu-12-10-quantal-quetzal-and-later/
|
||||
mkdir /tmp/curl
|
||||
cd /tmp/curl
|
||||
sudo apt-get update
|
||||
sudo apt-get install build-essential debhelper libssh2-1-dev libgnutls-dev libidn11-dev libkrb5-dev libldap2-dev libnss3-dev librtmp-dev libtool openssh-server quilt
|
||||
apt-get source curl
|
||||
sudo apt-get build-dep curl
|
||||
|
||||
cd curl-*
|
||||
export DEB_BUILD_OPTIONS="nocheck"
|
||||
sudo dpkg-buildpackage -uc -us -j"$(grep -c ^processor /proc/cpuinfo)"
|
||||
cd curl-*
|
||||
export DEB_BUILD_OPTIONS="nocheck"
|
||||
sudo dpkg-buildpackage -uc -us -j"$(grep -c ^processor /proc/cpuinfo)"
|
||||
|
||||
cd ..
|
||||
dpkg -l | grep curl
|
||||
ls -al
|
||||
|
||||
if [ ! -d ~/curl_cache ]; then
|
||||
mkdir ~/curl_cache
|
||||
fi
|
||||
|
||||
cp libcurl3*.deb curl*.deb ~/curl_cache
|
||||
|
||||
sudo dpkg -i libcurl3*.deb
|
||||
sudo dpkg -i curl*.deb
|
||||
fi
|
||||
cd ..
|
||||
dpkg -l | grep curl
|
||||
ls -al
|
||||
sudo dpkg -i libcurl3*.deb
|
||||
sudo dpkg -i curl*.deb
|
||||
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
brew install libssh2
|
||||
|
||||
if [ -d ~/curl_cache/curl ]; then
|
||||
cd ~/curl_cache/curl
|
||||
sudo make install
|
||||
else
|
||||
mkdir /tmp/curl
|
||||
cd /tmp/curl
|
||||
|
||||
curl -LO "https://curl.haxx.se/download/curl-7.64.0.tar.bz2"
|
||||
tar -xjf curl-7.64.0.tar.bz2
|
||||
|
||||
cd curl-7.64.0
|
||||
./configure --disable-debug --disable-dependency-tracking --disable-silent-rules --with-libssh2 --with-darwinssl --without-ca-bundle --without-ca-path
|
||||
make -j"$(sysctl hw.logicalcpu | cut -d " " -f 2)"
|
||||
|
||||
if [ ! -d ~/curl_cache ]; then
|
||||
mkdir ~/curl_cache
|
||||
fi
|
||||
|
||||
cp -a . ~/curl_cache/curl
|
||||
sudo make install
|
||||
fi
|
||||
export PATH=/usr/local/bin:$PATH
|
||||
brew install curl --with-libssh2
|
||||
export PATH="/usr/local/opt/curl/bin:$PATH"
|
||||
fi
|
||||
|
||||
# After
|
||||
@@ -77,13 +42,13 @@ cd /tmp/builds
|
||||
|
||||
for file in *; do
|
||||
if [ "$TEST_BUILD" = true ]; then
|
||||
# Upload to datacorder
|
||||
curl -k "sftp://porphyrion.feralhosting.com/www/datacorder.porphyrion.feralhosting.com/public_html/builds/test/$VERSION_NAME/" --user "$DATACORDER_USER:$DATACORDER_PASSWORD" -T "$file" --ftp-create-dirs
|
||||
# Upload to fs2downloads
|
||||
curl -k "ftp://swc.fs2downloads.com/swc.fs2downloads.com/builds/test/$VERSION_NAME/" --user "$FS2DOWNLOADS_USER:$FS2DOWNLOADS_PASSWORD" -T "$file" --ftp-create-dirs
|
||||
else
|
||||
# Upload to indiegames
|
||||
curl -k "sftp://scp.indiegames.us/~/public_html/builds/nightly/$VERSION_NAME/" --user "$INDIEGAMES_USER:$INDIEGAMES_PASSWORD" -T "$file" --ftp-create-dirs
|
||||
|
||||
# Upload to datacorder
|
||||
curl -k "sftp://porphyrion.feralhosting.com/~/www/datacorder.porphyrion.feralhosting.com/public_html/builds/nightly/$VERSION_NAME/" --user "$DATACORDER_USER:$DATACORDER_PASSWORD" -T "$file" --ftp-create-dirs
|
||||
# Upload to fs2downloads
|
||||
curl -k "ftp://swc.fs2downloads.com/swc.fs2downloads.com/builds/nightly/$VERSION_NAME/" --user "$FS2DOWNLOADS_USER:$FS2DOWNLOADS_PASSWORD" -T "$file" --ftp-create-dirs
|
||||
fi
|
||||
done
|
||||
+10
-26
@@ -1,47 +1,31 @@
|
||||
#!/usr/bin/env bash
|
||||
#!/usr/bin/env sh
|
||||
|
||||
set -ex
|
||||
|
||||
FILENAME=
|
||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
if [ ! -d "$HOME/cmake-3.8/bin" ]; then
|
||||
if [ ! -d "$HOME/cmake/bin" ]; then
|
||||
# If the cache does not currently contain CMake then download and install it
|
||||
mkdir -p $HOME/cmake-3.8/
|
||||
FILENAME=cmake-3.4.3-Linux-x86_64
|
||||
|
||||
wget -O /tmp/cmake.tar.gz --no-check-certificate https://cmake.org/files/v3.8/cmake-3.8.2-Linux-x86_64.tar.gz
|
||||
tar -xzf /tmp/cmake.tar.gz -C $HOME/cmake-3.8/ --strip-components=1
|
||||
mkdir -p $HOME/cmake/
|
||||
|
||||
wget -O /tmp/cmake.tar.gz --no-check-certificate https://www.cmake.org/files/v3.4/$FILENAME.tar.gz
|
||||
tar -xzf /tmp/cmake.tar.gz -C $HOME/cmake/ --strip-components=1
|
||||
fi
|
||||
export PATH=$HOME/cmake-3.8/bin:$PATH
|
||||
export PATH=$HOME/cmake/bin:$PATH
|
||||
|
||||
cd $HOME
|
||||
|
||||
if [ "${BUILD_DEPLOYMENT}" = true ]; then
|
||||
wget -O appimagetool -c "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage" # (64-bit)
|
||||
chmod a+x ./appimagetool
|
||||
|
||||
wget -O linuxdeployqt -c "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" # (64-bit)
|
||||
chmod a+x ./linuxdeployqt
|
||||
fi
|
||||
|
||||
sudo apt-get -yq install valgrind
|
||||
|
||||
if [[ "$CC" = "clang-9" ]]; then
|
||||
sudo apt-get -yq install clang-9 clang-tidy-9
|
||||
fi
|
||||
|
||||
if [[ "$CC" = "clang-4.0" ]]; then
|
||||
# Fix a header bug present in ubuntu...
|
||||
sudo ln -s /usr/include/libcxxabi/__cxxabi_config.h /usr/include/c++/v1/__cxxabi_config.h
|
||||
wget -c "https://github.com/probonopd/AppImageKit/releases/download/5/AppImageAssistant" # (64-bit)
|
||||
chmod a+x ./AppImageAssistant
|
||||
fi
|
||||
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
gem install xcpretty
|
||||
|
||||
brew update
|
||||
brew outdated cmake || brew upgrade cmake
|
||||
elif [ "$TRAVIS_OS_NAME" = "windows" ]; then
|
||||
choco install mingw ninja
|
||||
fi
|
||||
|
||||
cmake --version
|
||||
+1
-34
@@ -8,40 +8,7 @@ if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
for config in $BUILD_CONFIGS
|
||||
do
|
||||
cd "$config"
|
||||
|
||||
# Compile all targets
|
||||
ninja all
|
||||
|
||||
# Install Freespace2 targets
|
||||
cmake -DCMAKE_INSTALL_PREFIX=/tmp/release/$config/fso -DCOMPONENT=Unspecified -P cmake_install.cmake
|
||||
cmake -DCMAKE_INSTALL_PREFIX=/tmp/release/$config/fso -DCOMPONENT=Freespace2 -P cmake_install.cmake
|
||||
|
||||
# We need to be a bit creative for determining the AppImage name since we don't want to hard-code the name
|
||||
FILENAME="$(find /tmp/release/$config/fso/bin -name 'fs2_open_*' -type f -printf "%f\n").AppImage"
|
||||
$HOME/appimagetool -n /tmp/release/$config/fso "/tmp/release/$config/fso/$FILENAME"
|
||||
|
||||
: <<'END'
|
||||
# Install qtFRED targets
|
||||
cmake -DCMAKE_INSTALL_PREFIX=/tmp/release/$config/qtfred/usr -DCOMPONENT=Unspecified -P cmake_install.cmake
|
||||
cmake -DCMAKE_INSTALL_PREFIX=/tmp/release/$config/qtfred/usr -DCOMPONENT=qtFRED -P cmake_install.cmake
|
||||
|
||||
PREV="$(pwd)"
|
||||
cd /tmp/release/$config/qtfred
|
||||
|
||||
unset QTDIR; unset QT_PLUGIN_PATH; unset LD_LIBRARY_PATH
|
||||
$HOME/linuxdeployqt usr/qtfred.desktop -bundle-non-qt-libs
|
||||
# Move our AppRun script to the right location
|
||||
mv usr/AppRun AppRun
|
||||
|
||||
echo "Embed newer libstdc++ for distros that don't come with it (ubuntu 14.04)";
|
||||
mkdir -p usr/optional/; mkdir -p usr/optional/libstdc++/;
|
||||
cp /usr/lib/x86_64-linux-gnu/libstdc++.so.6 ./usr/optional/libstdc++/;
|
||||
|
||||
$HOME/appimagetool -n . "$(find /tmp/release/$config/qtfred/usr/bin -name 'qtfred_*' -type f -printf "%f\n").AppImage"
|
||||
|
||||
cd "$PREV"
|
||||
END
|
||||
|
||||
ninja appimage
|
||||
cd ..
|
||||
done
|
||||
|
||||
|
||||
+4
-14
@@ -5,26 +5,16 @@ set -e
|
||||
cd build
|
||||
|
||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
ninja -k 20 all
|
||||
ninja all
|
||||
|
||||
if [ "$CONFIGURATION" = "Debug" ]; then
|
||||
valgrind --leak-check=full --error-exitcode=1 --gen-suppressions=all \
|
||||
--suppressions="$TRAVIS_BUILD_DIR/ci/travis/valgrind.supp" ./bin/unittests --gtest_shuffle
|
||||
else
|
||||
./bin/unittests --gtest_shuffle
|
||||
fi
|
||||
valgrind --leak-check=full --error-exitcode=1 --gen-suppressions=all \
|
||||
--suppressions="$TRAVIS_BUILD_DIR/ci/travis/valgrind.supp" ./bin/unittests --gtest_shuffle
|
||||
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
cmake --build . --config "$CONFIGURATION" | tee build.log | xcpretty
|
||||
XCODE_RET=${PIPESTATUS[0]}
|
||||
if [ "$XCODE_RET" -ne "0" ]; then
|
||||
tar -cvzf build.log.tar.gz build.log
|
||||
curl --upload-file build.log.tar.gz "https://keep.sh"
|
||||
curl --upload-file build.log.tar.gz "https://transfer.sh/build.log.tar.gz"
|
||||
exit $XCODE_RET
|
||||
fi
|
||||
elif [ "$TRAVIS_OS_NAME" = "windows" ]; then
|
||||
if [ "$CMAKE_GENERATOR" = "Ninja" ]; then
|
||||
cmake --build . --config "$CONFIGURATION"
|
||||
else
|
||||
cmake --build . --config "$CONFIGURATION" -- /verbosity:minimal
|
||||
fi
|
||||
fi
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
liblsan Invalid read
|
||||
Memcheck:Addr8
|
||||
obj:/usr/lib64/liblsan.so.0.0.0
|
||||
obj:/usr/lib64/liblsan.so.0.0.0
|
||||
obj:/usr/lib64/liblsan.so.0.0.0
|
||||
obj:*
|
||||
obj:*
|
||||
obj:*
|
||||
}
|
||||
{
|
||||
Travis memleak
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: definite
|
||||
fun:malloc
|
||||
fun:_dl_signal_error
|
||||
fun:_dl_open
|
||||
fun:dlopen_doit
|
||||
fun:_dl_catch_error
|
||||
fun:_dlerror_run
|
||||
fun:dlopen@@GLIBC_2.2.5
|
||||
obj:/usr/lib/x86_64-linux-gnu/libmirclient.so.7
|
||||
fun:call_init.part.0
|
||||
fun:call_init
|
||||
fun:_dl_init
|
||||
fun:dl_open_worker
|
||||
fun:_dl_catch_error
|
||||
}
|
||||
@@ -1,6 +1,4 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=FreeSpace Open
|
||||
Exec=$<TARGET_FILE_NAME:Freespace2>
|
||||
Icon=app_icon
|
||||
Categories=Game;
|
||||
Icon=app_icon.png
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
HERE=$(dirname $(readlink -f "${0}"))
|
||||
export LD_LIBRARY_PATH="${HERE}"/lib:"$LD_LIBRARY_PATH"
|
||||
exec "${HERE}"/bin/$<TARGET_FILE_NAME:Freespace2> $@
|
||||
"${HERE}"/bin/$<TARGET_FILE_NAME:Freespace2> $@
|
||||
@@ -1,3 +1,17 @@
|
||||
|
||||
include(WriteCompilerDetectionHeader)
|
||||
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED 11)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
|
||||
set(REQUIRED_CXX_FEATURES cxx_rvalue_references cxx_nullptr)
|
||||
|
||||
get_property(CMAKE_CXX_KNOWN_FEATURES GLOBAL PROPERTY CMAKE_CXX_KNOWN_FEATURES)
|
||||
|
||||
write_compiler_detection_header(
|
||||
FILE "${GENERATED_SOURCE_DIR}/scp_compiler_detection.h"
|
||||
PREFIX SCP
|
||||
COMPILERS AppleClang Clang GNU MSVC
|
||||
FEATURES ${CMAKE_CXX_KNOWN_FEATURES}
|
||||
VERSION 3.2
|
||||
)
|
||||
@@ -6,16 +6,18 @@ configure_file("${CMAKE_CURRENT_LIST_DIR}/AppRun.in" "${CMAKE_CURRENT_BINARY_DIR
|
||||
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/AppRun-$<CONFIG>"
|
||||
INPUT "${CMAKE_CURRENT_BINARY_DIR}/AppRun.gen")
|
||||
|
||||
install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/AppRun-$<CONFIG>" DESTINATION "." RENAME "AppRun"
|
||||
COMPONENT "Freespace2")
|
||||
install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/AppRun-$<CONFIG>" DESTINATION "." RENAME "AppRun")
|
||||
|
||||
|
||||
configure_file("${CMAKE_CURRENT_LIST_DIR}/AppImage.desktop.in" "${CMAKE_CURRENT_BINARY_DIR}/AppImage.desktop.gen" @ONLY)
|
||||
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/AppImage-$<CONFIG>.desktop"
|
||||
INPUT "${CMAKE_CURRENT_BINARY_DIR}/AppImage.desktop.gen")
|
||||
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/AppImage-$<CONFIG>.desktop" DESTINATION "." RENAME "fso.desktop"
|
||||
COMPONENT "Freespace2")
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/AppImage-$<CONFIG>.desktop" DESTINATION "." RENAME "fso.desktop")
|
||||
|
||||
install(FILES "${CMAKE_SOURCE_DIR}/freespace2/resources/app_icon.png" DESTINATION "."
|
||||
COMPONENT "Freespace2")
|
||||
install(FILES "${CMAKE_SOURCE_DIR}/freespace2/resources/app_icon.png" DESTINATION ".")
|
||||
|
||||
add_custom_target(appimage
|
||||
COMMAND "${APPIMAGE_ASSISTANT}" "${CMAKE_INSTALL_PREFIX}" "${CMAKE_INSTALL_PREFIX}/fs2_open_${FSO_BINARY_SUFFIX}.AppImage")
|
||||
|
||||
add_dependencies(appimage install)
|
||||
@@ -1,37 +0,0 @@
|
||||
option(ENABLE_CLANG_TIDY "Enable source code checking using clang-tidy" OFF)
|
||||
|
||||
find_program(
|
||||
CLANG_TIDY_EXE
|
||||
NAMES "clang-tidy"
|
||||
DOC "Path to clang-tidy executable"
|
||||
)
|
||||
|
||||
function(enable_clang_tidy target)
|
||||
# Not enabled in this configuration
|
||||
endfunction()
|
||||
|
||||
if(NOT ENABLE_CLANG_TIDY)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS "${CLANG_TIDY_EXE}")
|
||||
message(SEND_ERROR "clang-tidy: Could not find clang-tidy executable (value of variable is \"${CLANG_TIDY_EXE}\".")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(CMAKE_VERSION VERSION_LESS "3.6.0")
|
||||
message(SEND_ERROR "Clang-tidy support requires CMake 3.6")
|
||||
return()
|
||||
endif()
|
||||
|
||||
message(STATUS "clang-tidy: Using \"${CLANG_TIDY_EXE}\"")
|
||||
|
||||
function(enable_clang_tidy target)
|
||||
SET(TIDY_OPTIONS "${CLANG_TIDY_EXE}")
|
||||
if(FSO_FATAL_WARNINGS)
|
||||
set(TIDY_OPTIONS "${TIDY_OPTIONS};-warnings-as-errors=*")
|
||||
endif()
|
||||
|
||||
set_target_properties(${target} PROPERTIES CXX_CLANG_TIDY "${TIDY_OPTIONS}")
|
||||
endfunction()
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ if(DOXYGEN_FOUND)
|
||||
FILE(TO_NATIVE_PATH ${OUTPUT_DIR} OUTPUT_DIR)
|
||||
SET(OUTPUT_DIR \"${OUTPUT_DIR}\")
|
||||
|
||||
SET(INPUTS "${CMAKE_CURRENT_SOURCE_DIR}/code" "${CMAKE_CURRENT_SOURCE_DIR}/freespace2" "${CMAKE_CURRENT_SOURCE_DIR}/fred2" "${CMAKE_CURRENT_SOURCE_DIR}/wxfred2" "${CMAKE_CURRENT_SOURCE_DIR}/qtfred")
|
||||
SET(INPUTS "${CMAKE_CURRENT_SOURCE_DIR}/code" "${CMAKE_CURRENT_SOURCE_DIR}/freespace2" "${CMAKE_CURRENT_SOURCE_DIR}/fred2" "${CMAKE_CURRENT_SOURCE_DIR}/wxfred2")
|
||||
|
||||
SET(INPUT_DIRS)
|
||||
FOREACH(DIR IN LISTS INPUTS)
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
|
||||
set(_EMBEDD_FILE_BASE_DIR "${CMAKE_CURRENT_LIST_DIR}")
|
||||
|
||||
function(target_embed_files _target)
|
||||
set(options)
|
||||
set(oneValueArgs RELATIVE_TO PATH_TYPE_PREFIX)
|
||||
set(multiValueArgs FILES)
|
||||
cmake_parse_arguments(EMBED "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
if (NOT DEFINED EMBED_RELATIVE_TO)
|
||||
set(EMBED_RELATIVE_TO "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
endif()
|
||||
if (NOT IS_ABSOLUTE "${EMBED_RELATIVE_TO}")
|
||||
get_filename_component(EMBED_RELATIVE_TO "${EMBED_RELATIVE_TO}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
endif()
|
||||
|
||||
foreach (file ${EMBED_FILES})
|
||||
get_filename_component(_absoluteFile "${file}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
file(RELATIVE_PATH _pathType "${EMBED_RELATIVE_TO}" "${_absoluteFile}")
|
||||
get_filename_component(_pathType ${_pathType} DIRECTORY)
|
||||
if (DEFINED EMBED_PATH_TYPE_PREFIX)
|
||||
if (_pathType)
|
||||
set(_pathType "${EMBED_PATH_TYPE_PREFIX}/${_pathType}")
|
||||
else()
|
||||
# Avoid trailing / when we are in the same directory
|
||||
set(_pathType "${EMBED_PATH_TYPE_PREFIX}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (NOT _pathType)
|
||||
# If it is still empty then we need to work around yet another annoying CMake behavior where it ignores
|
||||
# "empty" property strings
|
||||
set(_pathType ".")
|
||||
endif()
|
||||
|
||||
set_property(TARGET ${_target} APPEND PROPERTY EMBEDDED_FILES "${_absoluteFile}")
|
||||
set_property(TARGET ${_target} APPEND PROPERTY EMBEDDED_FILES_BASE_DIR "${EMBED_RELATIVE_TO}")
|
||||
set_property(TARGET ${_target} APPEND PROPERTY EMBEDDED_FILES_PATH_TYPE "${_pathType}")
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
function(handle_embedded_files _target)
|
||||
get_target_property(_filesToEmbed ${_target} EMBEDDED_FILES)
|
||||
get_target_property(_baseDirs ${_target} EMBEDDED_FILES_BASE_DIR)
|
||||
get_target_property(_pathTypes ${_target} EMBEDDED_FILES_PATH_TYPE)
|
||||
|
||||
SET(DEF_OUT_FILES)
|
||||
|
||||
set(INCLUDE_LIST)
|
||||
set(ARRAY_ELEMENTS)
|
||||
|
||||
list(LENGTH _filesToEmbed _numFiles)
|
||||
|
||||
FOREACH(i RANGE ${_numFiles})
|
||||
# Why must CMake always do the unexpected thing? The foreach variant includes the last index as opposed to every
|
||||
# other sensible language which does not include it...
|
||||
if (i GREATER_EQUAL _numFiles)
|
||||
break()
|
||||
endif()
|
||||
|
||||
list(GET _filesToEmbed ${i} _filePath)
|
||||
list(GET _baseDirs ${i} _baseDir)
|
||||
list(GET _pathTypes ${i} _pathType)
|
||||
|
||||
if (_pathType STREQUAL ".")
|
||||
# Handle the workaround we had to do for empty path types
|
||||
set(_pathType "")
|
||||
endif()
|
||||
|
||||
file(RELATIVE_PATH _relativeFilePath "${_baseDir}" "${_filePath}")
|
||||
SET(_outputBasePath "${CMAKE_CURRENT_BINARY_DIR}/embedded_files/${_relativeFilePath}")
|
||||
|
||||
# For some reason this is needed...
|
||||
get_filename_component(_outputDirectory ${_outputBasePath} DIRECTORY)
|
||||
file(MAKE_DIRECTORY ${_outputDirectory})
|
||||
|
||||
# Retrieve the path type name from the relative path
|
||||
file(TO_NATIVE_PATH "${_pathType}" _pathType)
|
||||
if (MINGW)
|
||||
# There is a bug in CMake where it thinks MinGW uses forward slashes for paths but we need backslashes for Windows builds
|
||||
string(REPLACE "/" "\\" _pathType "${_pathType}")
|
||||
endif()
|
||||
# Properly escape back slashes in strings
|
||||
string(REPLACE "\\" "\\\\" _pathType "${_pathType}")
|
||||
|
||||
get_filename_component(FILE_NAME "${_relativeFilePath}" NAME)
|
||||
|
||||
string(MAKE_C_IDENTIFIER "${_relativeFilePath}" FIELD_NAME)
|
||||
|
||||
set(HEADER_FILE "${_outputBasePath}.h")
|
||||
set(SOURCE_FILE "${_outputBasePath}.cpp")
|
||||
|
||||
set(ALL_OUTPUTS "${HEADER_FILE}" "${SOURCE_FILE}")
|
||||
set(FIELD_NAME "Embedded_${FIELD_NAME}")
|
||||
|
||||
set(INCLUDE_LIST "${INCLUDE_LIST}\n#include \"${HEADER_FILE}\"")
|
||||
set(ARRAY_ELEMENTS "${ARRAY_ELEMENTS}\n\t{ \"${_pathType}\", \"${FILE_NAME}\" , ${FIELD_NAME} , ${FIELD_NAME}_size },")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${ALL_OUTPUTS}
|
||||
COMMAND embedfile "${_filePath}" "${_outputBasePath}" "${FIELD_NAME}"
|
||||
MAIN_DEPENDENCY "${_filePath}"
|
||||
COMMENT "Generating string file for ${_filePath}"
|
||||
)
|
||||
|
||||
list(APPEND DEF_OUT_FILES ${ALL_OUTPUTS})
|
||||
ENDFOREACH()
|
||||
|
||||
configure_file("${_EMBEDD_FILE_BASE_DIR}/embedded_files.inc.in" "${CMAKE_CURRENT_BINARY_DIR}/embedded_files/embedded_files.inc")
|
||||
target_include_directories(${_target} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/embedded_files")
|
||||
target_sources(${_target} PRIVATE ${DEF_OUT_FILES})
|
||||
source_group("Generated Files\\Embedded Files" FILES ${DEF_OUT_FILES})
|
||||
endfunction()
|
||||
@@ -3,7 +3,7 @@ INCLUDE(util)
|
||||
|
||||
MESSAGE(STATUS "Configuring UNIX specific things and stuff...")
|
||||
|
||||
target_compile_definitions(platform INTERFACE SCP_UNIX USE_OPENAL _REENTRANT)
|
||||
target_compile_definitions(platform INTERFACE SCP_UNIX USE_OPENAL)
|
||||
|
||||
# Set RPATH
|
||||
set(CMAKE_SKIP_BUILD_RPATH TRUE)
|
||||
|
||||
@@ -8,7 +8,7 @@ SET(WIN32_LIBS
|
||||
odbccp32
|
||||
vfw32
|
||||
winmm
|
||||
ws2_32
|
||||
wsock32
|
||||
psapi
|
||||
)
|
||||
|
||||
@@ -20,8 +20,8 @@ target_link_libraries(platform INTERFACE ${WIN32_LIBS})
|
||||
|
||||
target_compile_definitions(platform INTERFACE WIN32 USE_OPENAL _WINDOWS)
|
||||
|
||||
# Specify minimum Windows version for the headers (currently this is Vista)
|
||||
target_compile_definitions(platform INTERFACE NTDDI_VERSION=0x06000000 _WIN32_WINNT=0x0600)
|
||||
# Specify minimum Windows version for the headers (currently this is XP)
|
||||
target_compile_definitions(platform INTERFACE NTDDI_VERSION=0x05010000 _WIN32_WINNT=0x0501)
|
||||
|
||||
SET(EXE_GUI_TYPE WIN32)
|
||||
set(PLATFORM_WINDOWS TRUE CACHE INTERNAL "" FORCE)
|
||||
+10
-10
@@ -10,8 +10,8 @@ include(CheckSymbolExists)
|
||||
include(CheckCXXSymbolExists)
|
||||
include(CheckTypeSize)
|
||||
|
||||
CHECK_INCLUDE_FILE("execinfo.h" SCP_HAVE_EXECINFO_H)
|
||||
CHECK_INCLUDE_FILE_CXX("cxxabi.h" SCP_HAVE_CXXAPI_H)
|
||||
CHECK_INCLUDE_FILE("execinfo.h" HAVE_EXECINFO_H)
|
||||
CHECK_INCLUDE_FILE_CXX("cxxabi.h" HAVE_CXXAPI_H)
|
||||
|
||||
CHECK_TYPE_SIZE("max_align_t" MAX_ALIGN_T)
|
||||
|
||||
@@ -21,6 +21,8 @@ endif()
|
||||
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES "cstddef")
|
||||
CHECK_TYPE_SIZE("std::max_align_t" STD_MAX_ALIGN_T LANGUAGE CXX)
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES "type_traits")
|
||||
CHECK_TYPE_SIZE("std::is_trivially_copyable<int>" STD_IS_TRIVIALLY_COPYABLE LANGUAGE CXX)
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES)
|
||||
|
||||
CHECK_TYPE_SIZE("char32_t" CHAR32_T LANGUAGE CXX)
|
||||
@@ -29,17 +31,15 @@ CHECK_TYPE_SIZE("U'b'" UNICODE_CHAR_LITERAL LANGUAGE CXX)
|
||||
set(CMAKE_REQUIRED_FLAGS)
|
||||
|
||||
|
||||
CHECK_FUNCTION_EXISTS(strcasecmp SCP_HAVE_STRCASECMP)
|
||||
CHECK_FUNCTION_EXISTS(strncasecmp SCP_HAVE_STRNCASECMP)
|
||||
CHECK_FUNCTION_EXISTS(strcasecmp HAVE_STRCASECMP)
|
||||
CHECK_FUNCTION_EXISTS(strncasecmp HAVE_STRNCASECMP)
|
||||
|
||||
CHECK_FUNCTION_EXISTS(_stricmp SCP_HAVE__STRICMP)
|
||||
CHECK_FUNCTION_EXISTS(_strnicmp SCP_HAVE__STRNICMP)
|
||||
CHECK_FUNCTION_EXISTS(_stricmp HAVE__STRICMP)
|
||||
CHECK_FUNCTION_EXISTS(_strnicmp HAVE__STRNICMP)
|
||||
|
||||
CHECK_FUNCTION_EXISTS(strlwr SCP_HAVE_STRLWR)
|
||||
CHECK_FUNCTION_EXISTS(strlwr HAVE_STRLWR)
|
||||
|
||||
CHECK_INCLUDE_FILE("strings.h" SCP_HAVE_STRINGS_H)
|
||||
|
||||
check_symbol_exists(snprintf "stdio.h" SCP_HAVE_SNPRINTF)
|
||||
CHECK_INCLUDE_FILE("strings.h" HAVE_STRINGS_H)
|
||||
|
||||
set(PLATFORM_CHECK_HEADER "${GENERATED_SOURCE_DIR}/platformChecks.h")
|
||||
CONFIGURE_FILE(${CMAKE_CURRENT_LIST_DIR}/platformChecks.h.in "${PLATFORM_CHECK_HEADER}")
|
||||
+13
-13
@@ -3,26 +3,26 @@
|
||||
#define __PLATFORM_CHECKS_H__
|
||||
#pragma once
|
||||
|
||||
#cmakedefine SCP_HAVE_EXECINFO_H
|
||||
#cmakedefine SCP_HAVE_CXXAPI_H
|
||||
#cmakedefine SCP_HAVE_MAX_ALIGN_T
|
||||
#cmakedefine SCP_HAVE_STD_MAX_ALIGN_T
|
||||
#cmakedefine HAVE_EXECINFO_H
|
||||
#cmakedefine HAVE_CXXAPI_H
|
||||
#cmakedefine HAVE_MAX_ALIGN_T
|
||||
#cmakedefine HAVE_STD_MAX_ALIGN_T
|
||||
|
||||
#cmakedefine HAVE_STD_IS_TRIVIALLY_COPYABLE
|
||||
#cmakedefine HAVE_STD_IS_TRIVIALLY_COPYABLE_ARRAY
|
||||
|
||||
#cmakedefine01 IS_64BIT
|
||||
|
||||
#cmakedefine01 SCP_HAVE_STRCASECMP
|
||||
#cmakedefine01 SCP_HAVE_STRNCASECMP
|
||||
#cmakedefine01 SCP_HAVE__STRICMP
|
||||
#cmakedefine01 SCP_HAVE__STRNICMP
|
||||
#cmakedefine01 HAVE_STRCASECMP
|
||||
#cmakedefine01 HAVE_STRNCASECMP
|
||||
#cmakedefine01 HAVE__STRICMP
|
||||
#cmakedefine01 HAVE__STRNICMP
|
||||
|
||||
#cmakedefine01 SCP_HAVE_STRLWR
|
||||
#cmakedefine01 HAVE_STRLWR
|
||||
|
||||
#cmakedefine01 SCP_HAVE_STRINGS_H
|
||||
#cmakedefine01 HAVE_STRINGS_H
|
||||
|
||||
#cmakedefine01 HAVE_CHAR32_T
|
||||
#cmakedefine01 HAVE_UNICODE_CHAR_LITERAL
|
||||
|
||||
#cmakedefine01 SCP_HAVE_SNPRINTF
|
||||
#cmakedefine01 SCP_HAVE__SNPRINTF
|
||||
|
||||
#endif // __PLATFORM_CHECKS_H__
|
||||
@@ -9,6 +9,8 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -funroll-loops -fsigned-char -Wno-
|
||||
# Omit "conversion from string literal to 'char *' is deprecated" warnings.
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-write-strings")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-function")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated -Wno-char-subscripts")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcolor-diagnostics")
|
||||
|
||||
@@ -7,8 +7,6 @@ MESSAGE(STATUS "Doing configuration specific to clang...")
|
||||
option(CLANG_ENABLE_LEAK_CHECK "Enable -fsanitize=leak" OFF)
|
||||
option(CLANG_ENABLE_ADDRESS_SANITIZER "Enable -fsanitize=address" OFF)
|
||||
|
||||
option(CLANG_USE_LIBCXX "Use libc++" OFF)
|
||||
|
||||
# These are the default values
|
||||
set(C_BASE_FLAGS "-march=native -pipe")
|
||||
set(CXX_BASE_FLAGS "-march=native -pipe")
|
||||
@@ -21,11 +19,6 @@ if(DEFINED ENV{CFLAGS})
|
||||
set(C_BASE_FLAGS $ENV{CFLAGS})
|
||||
endif()
|
||||
|
||||
if (CLANG_USE_LIBCXX)
|
||||
set(CXX_BASE_FLAGS "${CXX_BASE_FLAGS} -stdlib=libc++")
|
||||
target_link_libraries(compiler INTERFACE "c++" "c++abi")
|
||||
endif()
|
||||
|
||||
# Initialize with an empty string to make sure we always get a clean start
|
||||
set(COMPILER_FLAGS "")
|
||||
|
||||
@@ -73,17 +66,21 @@ set(COMPILER_FLAGS "${COMPILER_FLAGS} ${SANITIZE_FLAGS}")
|
||||
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wformat-security")
|
||||
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wno-unused-function")
|
||||
|
||||
# Dear Clang, please tell us if a function does not return a value since that part of the standard is stupid!
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wreturn-type")
|
||||
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wno-char-subscripts")
|
||||
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wno-unused-parameter")
|
||||
|
||||
check_cxx_compiler_flag(-Wshift-negative-value SUPPORTS_SHIFT_NEGATIVE_VALUE)
|
||||
if(SUPPORTS_SHIFT_NEGATIVE_VALUE)
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wno-shift-negative-value")
|
||||
endif()
|
||||
|
||||
set(COMPILER_FLAGS_RELEASE "-O2 -Wno-unused-variable -Wno-unused-parameter")
|
||||
set(COMPILER_FLAGS_RELEASE "-O2 -Wno-unused-variable")
|
||||
|
||||
set(COMPILER_FLAGS_DEBUG "-O0 -g -Wshadow")
|
||||
|
||||
@@ -100,14 +97,6 @@ set(CMAKE_C_FLAGS_DEBUG ${COMPILER_FLAGS_DEBUG})
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS "")
|
||||
|
||||
if(DEFINED ENV{LDFLAGS})
|
||||
set(CMAKE_EXE_LINKER_FLAGS $ENV{LDFLAGS})
|
||||
endif()
|
||||
|
||||
if (CLANG_USE_LIBCXX)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lc++abi")
|
||||
endif()
|
||||
|
||||
if (SANITIZE_FLAGS)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${SANITIZE_FLAGS}")
|
||||
endif()
|
||||
@@ -122,14 +111,3 @@ endif()
|
||||
|
||||
# Always define this to make sure that the fixed width format macros are available
|
||||
target_compile_definitions(compiler INTERFACE __STDC_FORMAT_MACROS)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR MINGW)
|
||||
# GNU ar: Create thin archive files.
|
||||
# Requires binutils-2.19 or later.
|
||||
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> qcTP <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
set(CMAKE_C_ARCHIVE_APPEND "<CMAKE_AR> qTP <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> qcTP <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
set(CMAKE_CXX_ARCHIVE_APPEND "<CMAKE_AR> qTP <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
endif()
|
||||
|
||||
target_link_libraries(compiler INTERFACE m)
|
||||
+13
-57
@@ -8,8 +8,6 @@ MESSAGE(STATUS "Doing configuration specific to gcc...")
|
||||
option(GCC_ENABLE_LEAK_CHECK "Enable -fsanitize=leak" OFF)
|
||||
option(GCC_ENABLE_ADDRESS_SANITIZER "Enable -fsanitize=address" OFF)
|
||||
option(GCC_ENABLE_SANITIZE_UNDEFINED "Enable -fsanitize=undefined" OFF)
|
||||
option(GCC_USE_GOLD "Use the gold linker instead of the standard linker" OFF)
|
||||
option(GCC_GENERATE_GDB_INDEX "Adds linker option to generate the gdb index for debug builds" OFF)
|
||||
|
||||
# These are the default values
|
||||
set(C_BASE_FLAGS "-march=native -pipe")
|
||||
@@ -25,21 +23,6 @@ endif()
|
||||
|
||||
# Initialize with an empty string to make sure we always get a clean start
|
||||
set(COMPILER_FLAGS "")
|
||||
set(LINKER_FLAGS "")
|
||||
|
||||
# Don't ignore user-set LDFLAGS
|
||||
if(DEFINED ENV{LDFLAGS})
|
||||
set(LINKER_FLAGS $ENV{LDFLAGS})
|
||||
endif()
|
||||
|
||||
if (GCC_USE_GOLD)
|
||||
OPTION(GCC_INCREMENTAL_LINKING "Use incremental linking" OFF)
|
||||
set(LINKER_FLAGS "${LINKER_FLAGS} -fuse-ld=gold")
|
||||
|
||||
if (GCC_INCREMENTAL_LINKING)
|
||||
set(LINKER_FLAGS "${LINKER_FLAGS} -fno-use-linker-plugin -Wl,-z,norelro -Wl,--incremental")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# This is a slight hack since our flag setup is a bit more complicated
|
||||
_enable_extra_compiler_warnings_flags()
|
||||
@@ -47,11 +30,9 @@ set(COMPILER_FLAGS "${COMPILER_FLAGS} ${_flags}")
|
||||
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -funroll-loops -fsigned-char -Wno-unknown-pragmas")
|
||||
|
||||
if (NOT GCC_INCREMENTAL_LINKING)
|
||||
# Place each function and data in its own section so the linker can
|
||||
# perform dead code elimination
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -fdata-sections -ffunction-sections")
|
||||
endif()
|
||||
# Place each function and data in its own section so the linker can
|
||||
# perform dead code elimination
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -fdata-sections -ffunction-sections")
|
||||
|
||||
if ("${CMAKE_GENERATOR}" STREQUAL "Ninja")
|
||||
# Force color diagnostics for Ninja generator
|
||||
@@ -97,27 +78,20 @@ set(COMPILER_FLAGS "${COMPILER_FLAGS} ${SANITIZE_FLAGS}")
|
||||
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wformat-security")
|
||||
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wno-unused-function")
|
||||
|
||||
# Dear GCC, please tell us if a function does not return a value since that part of the standard is stupid!
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wreturn-type")
|
||||
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wno-deprecated -Wno-char-subscripts")
|
||||
|
||||
# These two warnings cause a lot of false-positives in the FSO code base
|
||||
check_cxx_compiler_flag(-Wstringop-truncation SUPPORTS_STRINGOP_TRUNCATION)
|
||||
if(SUPPORTS_STRINGOP_TRUNCATION)
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wno-stringop-truncation")
|
||||
endif()
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wno-unused-parameter")
|
||||
|
||||
check_cxx_compiler_flag(-Wstringop-overflow SUPPORTS_STRINGOP_OVERFLOW)
|
||||
if(SUPPORTS_STRINGOP_TRUNCATION)
|
||||
set(COMPILER_FLAGS "${COMPILER_FLAGS} -Wno-stringop-overflow")
|
||||
endif()
|
||||
|
||||
set(COMPILER_FLAGS_RELEASE "-O2 -Wno-unused-variable -Wno-unused-but-set-variable -Wno-array-bounds -Wno-empty-body -Wno-clobbered -Wno-unused-parameter")
|
||||
set(COMPILER_FLAGS_RELEASE "-O2 -Wno-unused-variable -Wno-unused-but-set-variable -Wno-array-bounds -Wno-empty-body -Wno-clobbered")
|
||||
|
||||
set(COMPILER_FLAGS_DEBUG "-O0 -g -Wshadow")
|
||||
|
||||
# Always use the base flags and add our compiler flags at the back
|
||||
# Always use the base flags and add our compiler flags at the bacl
|
||||
set(CMAKE_CXX_FLAGS "${CXX_BASE_FLAGS} ${COMPILER_FLAGS}")
|
||||
set(CMAKE_C_FLAGS "${C_BASE_FLAGS} ${COMPILER_FLAGS}")
|
||||
|
||||
@@ -127,11 +101,10 @@ set(CMAKE_C_FLAGS_RELEASE ${COMPILER_FLAGS_RELEASE})
|
||||
set(CMAKE_CXX_FLAGS_DEBUG ${COMPILER_FLAGS_DEBUG})
|
||||
set(CMAKE_C_FLAGS_DEBUG ${COMPILER_FLAGS_DEBUG})
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${LINKER_FLAGS}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "")
|
||||
|
||||
IF (MINGW)
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static -static-libgcc -static-libstdc++ -Wl,--enable-auto-import")
|
||||
target_compile_definitions(compiler INTERFACE __USE_MINGW_ANSI_STDIO=1)
|
||||
ENDIF(MINGW)
|
||||
|
||||
if (SANITIZE_FLAGS)
|
||||
@@ -140,25 +113,17 @@ endif()
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "-g")
|
||||
|
||||
if (GCC_GENERATE_GDB_INDEX)
|
||||
# For pure debug binaries, generate a gdb index for better debugging
|
||||
SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -Wl,--gdb-index")
|
||||
endif()
|
||||
|
||||
IF(NOT MINGW)
|
||||
SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -rdynamic")
|
||||
# Allow the linker to perform dead code elimination; this is considered
|
||||
# experimental for COFF and PE formats and thus disabled for Windows builds
|
||||
# (https://sourceware.org/binutils/docs/ld/Options.html)
|
||||
if (NOT GCC_INCREMENTAL_LINKING AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "SunOS")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
|
||||
endif()
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
|
||||
ENDIF(NOT MINGW)
|
||||
|
||||
IF(${CMAKE_SYSTEM_NAME} MATCHES "SunOS")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-zignore")
|
||||
ENDIF()
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "-Wl,-zignore")
|
||||
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "SunOS")
|
||||
|
||||
if (FSO_FATAL_WARNINGS)
|
||||
# Make warnings fatal if the right variable is set
|
||||
@@ -166,13 +131,4 @@ if (FSO_FATAL_WARNINGS)
|
||||
endif()
|
||||
|
||||
# Always define this to make sure that the fixed width format macros are available
|
||||
target_compile_definitions(compiler INTERFACE __STDC_FORMAT_MACROS=1)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR MINGW)
|
||||
# GNU ar: Create thin archive files.
|
||||
# Requires binutils-2.19 or later.
|
||||
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> qcTP <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
set(CMAKE_C_ARCHIVE_APPEND "<CMAKE_AR> qTP <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> qcTP <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
set(CMAKE_CXX_ARCHIVE_APPEND "<CMAKE_AR> qTP <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
endif()
|
||||
target_compile_definitions(compiler INTERFACE __STDC_FORMAT_MACROS)
|
||||
+10
-11
@@ -36,24 +36,21 @@ set(WARNING_FLAGS
|
||||
/wd4592 # "symbol will be dynamically initialized" is being generated by a compiler bug, see https://stackoverflow.com/a/34027257 for an explanation - m!m
|
||||
$<$<CONFIG:Release>:/wd4101> # In release mode there are unreferenced variables because debug needs them
|
||||
/wd4995 # "'vsprintf': name was marked as #pragma deprecated" is being caused by our custom definition of vsprintf. I have no idea what causes this or how to fix it - m!m
|
||||
/wd4723 # "potential divide by 0" is caused by some code that definitely will not divide by zero - m!m
|
||||
/wd4121 # "alignment of a member was sensitive to packing" happens in a Windows header - m!m
|
||||
)
|
||||
|
||||
target_compile_options(compiler INTERFACE ${WARNING_FLAGS})
|
||||
|
||||
# Base
|
||||
set(CMAKE_C_FLAGS "/MP /GS- /analyze- /Zc:wchar_t /errorReport:prompt /Zc:forScope /Gd /EHsc /nologo /Zm200")
|
||||
set(CMAKE_CXX_FLAGS "/MP /GS- /analyze- /Zc:wchar_t /errorReport:prompt /Zc:forScope /Gd /EHsc /nologo /Zm200")
|
||||
set(CMAKE_C_FLAGS "/MP /GS- /analyze- /Zc:wchar_t /errorReport:prompt /WX- /Zc:forScope /Gd /EHsc /nologo /Zm200")
|
||||
set(CMAKE_CXX_FLAGS "/MP /GS- /analyze- /Zc:wchar_t /errorReport:prompt /WX- /Zc:forScope /Gd /EHsc /nologo /Zm200")
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS "/MANIFEST /DYNAMICBASE:NO /SAFESEH:NO /ERRORREPORT:PROMPT /NOLOGO")
|
||||
set(CMAKE_STATIC_LINKER_FLAGS "")
|
||||
|
||||
# Release
|
||||
set(CMAKE_C_FLAGS_RELEASE "/GL /Gy- /Ox /Ot /Ob2 /fp:precise /GF /Oy /Oi /Zi /W3")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "/GL /Gy- /Ox /Ot /Ob2 /fp:precise /GF /Oy /Oi /Zi /W3")
|
||||
# /DEBUG:FULL so that we get PDBs which is needed for debugging crashdumps
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/OPT:REF /LTCG /INCREMENTAL:NO /DEBUG:FULL")
|
||||
set(CMAKE_C_FLAGS_RELEASE "/GL /W2 /Gy- /Ox /Ot /Ob2 /fp:precise /GF /Oy /Oi /Zi /W3")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "/GL /W2 /Gy- /Ox /Ot /Ob2 /fp:precise /GF /Oy /Oi /Zi /W3")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/OPT:REF /LTCG /INCREMENTAL:NO")
|
||||
set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "/LTCG")
|
||||
|
||||
globally_enable_extra_compiler_warnings()
|
||||
@@ -65,6 +62,8 @@ if (MSVC_RELEASE_DEBUGGING)
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Zo")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zo")
|
||||
endif()
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /DEBUG")
|
||||
endif()
|
||||
|
||||
IF(MSVC_USE_RUNTIME_DLL)
|
||||
@@ -136,9 +135,9 @@ else()
|
||||
ENDIF()
|
||||
endif()
|
||||
|
||||
target_compile_definitions(compiler INTERFACE _CRT_SECURE_NO_DEPRECATE _CRT_SECURE_NO_WARNINGS _SECURE_SCL=0 NOMINMAX
|
||||
"$<$<CONFIG:FastDebug>:_ITERATOR_DEBUG_LEVEL=0>" _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING)
|
||||
|
||||
target_compile_definitions(compiler INTERFACE _CRT_SECURE_NO_DEPRECATE
|
||||
_CRT_SECURE_NO_WARNINGS _SECURE_SCL=0 NOMINMAX "$<$<CONFIG:FastDebug>:_ITERATOR_DEBUG_LEVEL=0>")
|
||||
|
||||
if (FSO_FATAL_WARNINGS)
|
||||
# Make warnings fatal if the right variable is set
|
||||
target_compile_options(compiler INTERFACE "/WX")
|
||||
|
||||
@@ -17,9 +17,6 @@ ELSE("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
MESSAGE(STATUS "No special handling for this compiler present, good luck!")
|
||||
ENDIF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
target_link_libraries(compiler INTERFACE Threads::Threads)
|
||||
|
||||
# Copy release settings to FastDebug
|
||||
set(CMAKE_C_FLAGS_FASTDEBUG "${CMAKE_C_FLAGS_RELEASE}")
|
||||
set(CMAKE_CXX_FLAGS_FASTDEBUG "${CMAKE_CXX_FLAGS_RELEASE}")
|
||||
|
||||
+7
-55
@@ -10,7 +10,7 @@ FUNCTION(ADD_IMPORTED_LIB NAME INCLUDES LIBS)
|
||||
|
||||
target_link_libraries(${NAME} INTERFACE "${LIBS}")
|
||||
|
||||
target_include_directories(${NAME} SYSTEM INTERFACE "${INCLUDES}")
|
||||
target_include_directories(${NAME} INTERFACE "${INCLUDES}")
|
||||
ENDFUNCTION(ADD_IMPORTED_LIB)
|
||||
|
||||
MACRO(PKG_CONFIG_LIB_RESOLVE NAME OUTVAR)
|
||||
@@ -140,34 +140,12 @@ macro(set_if_not_defined VAR VALUE)
|
||||
endif()
|
||||
endmacro(set_if_not_defined)
|
||||
|
||||
function(set_precompiled_header _target _headerPath)
|
||||
if (COMMAND target_precompile_headers)
|
||||
target_compile_definitions(${_target} PRIVATE CMAKE_PCH)
|
||||
target_precompile_headers(${_target} PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:${_headerPath}>")
|
||||
else()
|
||||
if (ENABLE_COTIRE)
|
||||
message("${_headerPath}")
|
||||
set_target_properties(${_target} PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "${_headerPath}")
|
||||
macro(configure_cotire target)
|
||||
# Disable unity build as it doesn't work well for us
|
||||
set_target_properties(${target} PROPERTIES COTIRE_ADD_UNITY_BUILD FALSE)
|
||||
|
||||
# Disable unity build as it doesn't work well for us
|
||||
set_target_properties(${_target} PROPERTIES COTIRE_ADD_UNITY_BUILD FALSE)
|
||||
|
||||
cotire(${_target})
|
||||
else()
|
||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
target_compile_options(${_target} PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:-include${_headerPath}>")
|
||||
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||
target_compile_options(${_target} PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:/FI ${_headerPath}>")
|
||||
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
target_compile_options(${_target} PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:-include${_headerPath}>")
|
||||
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
|
||||
target_compile_options(${_target} PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:-include${_headerPath}>")
|
||||
ELSE()
|
||||
MESSAGE("Unknown compiler for global includes. This will probably break the build.")
|
||||
ENDIF()
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
cotire(${target})
|
||||
endmacro(configure_cotire)
|
||||
|
||||
macro(add_target_copy_files)
|
||||
foreach(file ${ARGN})
|
||||
@@ -204,7 +182,7 @@ function(detect_simd_instructions _out_var)
|
||||
endfunction()
|
||||
|
||||
function (check_linker_flag _flag _out_var)
|
||||
SET(CMAKE_REQUIRED_LINK_OPTIONS "${_flag}")
|
||||
SET(CMAKE_REQUIRED_FLAGS "${_flag}")
|
||||
CHECK_C_COMPILER_FLAG("" ${_out_var})
|
||||
endfunction(check_linker_flag)
|
||||
|
||||
@@ -218,22 +196,6 @@ function(suppress_warnings _target)
|
||||
endif()
|
||||
endfunction(suppress_warnings)
|
||||
|
||||
# Suppresses warnings for the specified files
|
||||
function(suppress_file_warnings)
|
||||
if (MSVC)
|
||||
set_source_files_properties(
|
||||
${ARGN}
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS "/W0")
|
||||
else()
|
||||
# Assume everything else uses GCC style options
|
||||
set_source_files_properties(
|
||||
${ARGN}
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS "-w")
|
||||
endif()
|
||||
endfunction(suppress_file_warnings)
|
||||
|
||||
|
||||
function(list_target_dependencies _target _out_var)
|
||||
set(out_list)
|
||||
@@ -261,13 +223,3 @@ function(list_target_dependencies _target _out_var)
|
||||
list(REMOVE_DUPLICATES out_list)
|
||||
set(${_out_var} ${out_list} PARENT_SCOPE)
|
||||
endfunction(list_target_dependencies)
|
||||
|
||||
macro(add_file_folder FOLDER_NAME)
|
||||
string(MAKE_C_IDENTIFIER "${FOLDER_NAME}" VARIABLE_NAME)
|
||||
set(files_${VARIABLE_NAME} ${files_${VARIABLE_NAME}} ${ARGN})
|
||||
|
||||
string(REPLACE "/" "\\" FIXED_FOLDER_FILE "${FOLDER_NAME}")
|
||||
|
||||
source_group("${FIXED_FOLDER_FILE}" FILES ${ARGN})
|
||||
set(source_files ${source_files} ${ARGN})
|
||||
endmacro(add_file_folder)
|
||||
+4
-4
@@ -6,9 +6,9 @@ if (EXISTS "${PROJECT_SOURCE_DIR}/version_override.cmake")
|
||||
include("${PROJECT_SOURCE_DIR}/version_override.cmake")
|
||||
endif()
|
||||
|
||||
set_if_not_defined(FSO_VERSION_MAJOR 22)
|
||||
set_if_not_defined(FSO_VERSION_MINOR 1)
|
||||
set_if_not_defined(FSO_VERSION_BUILD 0)
|
||||
set_if_not_defined(FSO_VERSION_MAJOR 3)
|
||||
set_if_not_defined(FSO_VERSION_MINOR 8)
|
||||
set_if_not_defined(FSO_VERSION_BUILD 1)
|
||||
|
||||
# A numeric revision e.g. the CI build number
|
||||
set_if_not_defined(FSO_VERSION_REVISION 0)
|
||||
@@ -49,4 +49,4 @@ IF (NOT "${FSO_BUILD_POSTFIX}" STREQUAL "")
|
||||
ENDIF()
|
||||
|
||||
set(CONFIG_POSTFIX "$<$<CONFIG:Release>:>$<$<CONFIG:Debug>:-DEBUG>$<$<CONFIG:FastDebug>:-FASTDBG>")
|
||||
set(FSO_BINARY_SUFFIX "${FSO_BINARY_SUFFIX}${CONFIG_POSTFIX}")
|
||||
set(FSO_BINARY_SUFFIX "${FSO_BINARY_SUFFIX}${CONFIG_POSTFIX}")
|
||||
+10
-54
@@ -1,12 +1,13 @@
|
||||
|
||||
include(util)
|
||||
|
||||
INCLUDE(source_groups.cmake)
|
||||
|
||||
INCLUDE(voice_rec.cmake)
|
||||
|
||||
ADD_LIBRARY(code STATIC ${source_files} ${VOICE_REC_FILES})
|
||||
ADD_LIBRARY(code STATIC ${file_root} ${VOICE_REC_FILES})
|
||||
|
||||
target_compile_features(code PUBLIC cxx_std_11)
|
||||
target_compile_features(code PUBLIC ${REQUIRED_CXX_FEATURES})
|
||||
|
||||
INCLUDE(default_files.cmake)
|
||||
|
||||
if (MSVC)
|
||||
target_compile_definitions(code PUBLIC "PDB_DEBUGGING=1")
|
||||
@@ -18,21 +19,16 @@ TARGET_INCLUDE_DIRECTORIES(code PUBLIC ${FREESPACE_HEADERS})
|
||||
TARGET_INCLUDE_DIRECTORIES(code PUBLIC ${GENERATED_SOURCE_DIR})
|
||||
TARGET_INCLUDE_DIRECTORIES(code PUBLIC ${GENERATED_SOURCE_DIR}/code)
|
||||
|
||||
if (FSO_BUILD_WITH_OPENGL)
|
||||
target_link_libraries(code PUBLIC OpenGL)
|
||||
endif()
|
||||
target_link_libraries(code PUBLIC OpenGL)
|
||||
|
||||
TARGET_LINK_LIBRARIES(code PUBLIC openal)
|
||||
TARGET_LINK_LIBRARIES(code PUBLIC ${LUA_LIBS})
|
||||
TARGET_LINK_LIBRARIES(code PUBLIC ${PNG_LIBS})
|
||||
TARGET_LINK_LIBRARIES(code PUBLIC ${JPEG_LIBS})
|
||||
TARGET_LINK_LIBRARIES(code PUBLIC lz4)
|
||||
|
||||
TARGET_LINK_LIBRARIES(code PUBLIC sdl2)
|
||||
|
||||
if (FSO_BUILD_WITH_FFMPEG)
|
||||
TARGET_LINK_LIBRARIES(code PUBLIC ffmpeg)
|
||||
endif()
|
||||
TARGET_LINK_LIBRARIES(code PUBLIC ffmpeg)
|
||||
|
||||
TARGET_LINK_LIBRARIES(code PUBLIC utfcpp)
|
||||
|
||||
@@ -41,22 +37,6 @@ TARGET_LINK_LIBRARIES(code PUBLIC compiler)
|
||||
|
||||
target_link_libraries(code PUBLIC md5)
|
||||
|
||||
target_link_libraries(code PUBLIC discord-rpc)
|
||||
|
||||
target_link_libraries(code PUBLIC libRocket)
|
||||
|
||||
target_link_libraries(code PUBLIC pcp)
|
||||
|
||||
if (FSO_BUILD_WITH_VULKAN)
|
||||
target_link_libraries(code PUBLIC vulkan-hpp)
|
||||
endif()
|
||||
|
||||
target_link_libraries(code PUBLIC parsers)
|
||||
|
||||
target_link_libraries(code PUBLIC mdns)
|
||||
|
||||
enable_clang_tidy(code)
|
||||
|
||||
IF (FSO_USE_SPEECH)
|
||||
find_package(Speech REQUIRED)
|
||||
target_link_libraries(code PUBLIC speech)
|
||||
@@ -64,10 +44,6 @@ ENDIF(FSO_USE_SPEECH)
|
||||
|
||||
TARGET_LINK_LIBRARIES(code PUBLIC jansson)
|
||||
|
||||
target_link_libraries(code PUBLIC variant)
|
||||
|
||||
target_link_libraries(code PUBLIC any)
|
||||
|
||||
# Headers for standalone "gui" on UNIX
|
||||
IF(UNIX)
|
||||
TARGET_LINK_LIBRARIES(code PUBLIC ${MONGOOSE_LIBS})
|
||||
@@ -79,33 +55,13 @@ IF(FSO_BUILD_TOOLS)
|
||||
ADD_SUBDIRECTORY(cfileextractor)
|
||||
ENDIF(FSO_BUILD_TOOLS)
|
||||
|
||||
if (FSO_RELEASE_LOGGING)
|
||||
target_compile_definitions(code PUBLIC SCP_RELEASE_LOGGING)
|
||||
endif()
|
||||
set_target_properties(code PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "prefix_header.h")
|
||||
|
||||
if (FSO_BUILD_WITH_FFMPEG)
|
||||
target_compile_definitions(code PUBLIC WITH_FFMPEG)
|
||||
endif()
|
||||
if (FSO_BUILD_WITH_OPENGL)
|
||||
target_compile_definitions(code PUBLIC WITH_OPENGL)
|
||||
endif()
|
||||
if (FSO_BUILD_WITH_VULKAN)
|
||||
target_compile_definitions(code PUBLIC WITH_VULKAN)
|
||||
endif()
|
||||
|
||||
include(shaders.cmake)
|
||||
|
||||
target_embed_files(code FILES ${default_files_files} RELATIVE_TO "def_files")
|
||||
|
||||
handle_embedded_files(code)
|
||||
|
||||
set_precompiled_header(code "${CMAKE_CURRENT_SOURCE_DIR}/prefix_header.h")
|
||||
include(util)
|
||||
configure_cotire(code)
|
||||
|
||||
# Ensure that Xcode generates debug symbols on macOS for Debug builds
|
||||
set_target_properties(code PROPERTIES XCODE_ATTRIBUTE_GCC_GENERATE_DEBUGGING_SYMBOLS[variant=Debug] "YES")
|
||||
set_target_properties(code PROPERTIES XCODE_ATTRIBUTE_COPY_PHASE_STRIP[variant=Debug] "NO")
|
||||
set_target_properties(code PROPERTIES XCODE_ATTRIBUTE_STRIP_INSTALLED_PRODUCT[variant=Debug] "NO")
|
||||
set_target_properties(code PROPERTIES XCODE_ATTRIBUTE_GCC_SYMBOLS_PRIVATE_EXTERN[variant=Debug] "NO")
|
||||
|
||||
# Prevent GCC warnings in third-party BitOp... see GitHub #4366
|
||||
suppress_file_warnings(scripting/lua/bitop/bit.c)
|
||||
@@ -1,8 +0,0 @@
|
||||
|
||||
#include "Action.h"
|
||||
|
||||
namespace actions {
|
||||
|
||||
Action::~Action() = default;
|
||||
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
|
||||
namespace actions {
|
||||
|
||||
enum class ActionResult
|
||||
{
|
||||
Finished,
|
||||
Errored,
|
||||
Wait
|
||||
};
|
||||
|
||||
class Action {
|
||||
public:
|
||||
virtual ~Action() = 0;
|
||||
|
||||
virtual ActionResult execute(ProgramLocals& locals) const = 0;
|
||||
|
||||
virtual std::unique_ptr<Action> clone() const = 0;
|
||||
};
|
||||
|
||||
} // namespace actions
|
||||
@@ -1,21 +0,0 @@
|
||||
|
||||
#include "ActionDefinition.h"
|
||||
|
||||
namespace actions {
|
||||
|
||||
ActionDefinition::ActionDefinition(SCP_string name, SCP_vector<ActionParameter> parameters)
|
||||
: m_name(std::move(name)), m_parameters(std::move(parameters))
|
||||
{
|
||||
}
|
||||
ActionDefinition::~ActionDefinition() = default;
|
||||
|
||||
const SCP_string& ActionDefinition::getName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
const SCP_vector<ActionParameter>& ActionDefinition::getParameters() const
|
||||
{
|
||||
return m_parameters;
|
||||
}
|
||||
|
||||
} // namespace actions
|
||||
@@ -1,33 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "Action.h"
|
||||
|
||||
#include "actions/expression/ActionExpression.h"
|
||||
#include "actions/expression/Value.h"
|
||||
|
||||
namespace actions {
|
||||
|
||||
struct ActionParameter {
|
||||
SCP_string name;
|
||||
expression::ValueType type;
|
||||
};
|
||||
|
||||
class ActionDefinition {
|
||||
public:
|
||||
ActionDefinition(SCP_string name, SCP_vector<ActionParameter> parameters);
|
||||
virtual ~ActionDefinition();
|
||||
|
||||
const SCP_string& getName() const;
|
||||
const SCP_vector<actions::ActionParameter>& getParameters() const;
|
||||
|
||||
virtual flagset<ProgramContextFlags> getRequiredContext() const = 0;
|
||||
|
||||
virtual std::unique_ptr<Action> createAction(
|
||||
const SCP_unordered_map<SCP_string, expression::ActionExpression>& parameterExpressions) const = 0;
|
||||
|
||||
private:
|
||||
SCP_string m_name;
|
||||
SCP_vector<ActionParameter> m_parameters;
|
||||
};
|
||||
|
||||
} // namespace actions
|
||||
@@ -1,145 +0,0 @@
|
||||
|
||||
#include "ActionDefinitionManager.h"
|
||||
|
||||
#include "BuiltinActionDefinition.h"
|
||||
|
||||
#include "actions/types/MoveToSubmodel.h"
|
||||
#include "actions/types/ParticleEffectAction.h"
|
||||
#include "actions/types/PlaySoundAction.h"
|
||||
#include "actions/types/SetDirectionAction.h"
|
||||
#include "actions/types/SetPositionAction.h"
|
||||
#include "actions/types/WaitAction.h"
|
||||
#include "utils/join_string.h"
|
||||
|
||||
namespace actions {
|
||||
namespace {
|
||||
|
||||
void parseActionParameters(const SCP_vector<ActionParameter>& params,
|
||||
SCP_unordered_map<SCP_string, expression::ActionExpression>& parameterExpressions,
|
||||
const expression::ParseContext& context)
|
||||
{
|
||||
// We do not impose a set order of the parameters so we need to do something similar to the outer loop and
|
||||
// check for every possibility in a loop.
|
||||
for (size_t i = 0; i < params.size(); ++i) {
|
||||
// We might be doing some empty loops here in case of errors but there is a bound so this will finish
|
||||
// eventually
|
||||
for (const auto& parameter : params) {
|
||||
// Do not check for parameters which we already found
|
||||
if (parameterExpressions.find(parameter.name) != parameterExpressions.end()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto paramString = "+" + parameter.name + ":";
|
||||
|
||||
if (!optional_string(paramString.c_str())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// We found our parameter!
|
||||
parameterExpressions[parameter.name] =
|
||||
expression::ActionExpression::parseFromTable(parameter.type, context);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
const ActionDefinitionManager& ActionDefinitionManager::instance()
|
||||
{
|
||||
static const ActionDefinitionManager manager;
|
||||
return manager;
|
||||
}
|
||||
void ActionDefinitionManager::addDefinition(std::unique_ptr<ActionDefinition> def)
|
||||
{
|
||||
m_definitions.push_back(std::move(def));
|
||||
}
|
||||
std::unique_ptr<Action> ActionDefinitionManager::parseAction(const flagset<ProgramContextFlags>& context_flags,
|
||||
const expression::ParseContext& context) const
|
||||
{
|
||||
// We search through all definitions for every time we want to check for an action. This is not the most efficient
|
||||
// way to handle this since it results in an O(n^2) runtime. A better alternative would be to either construct a
|
||||
// regex with all the accepted actions as alternatives (although runtime of this is also doubtful) or peek at the
|
||||
// next token, extract the relevant part (The stuff between "+" and ":") and then look that up in a map. Then we
|
||||
// would get down to O(n).
|
||||
// Since this only happens at parse time, this is good enough for now.
|
||||
for (const auto& actionDef : m_definitions) {
|
||||
const auto parseString = "+" + actionDef->getName() + ":";
|
||||
|
||||
if (!optional_string(parseString.c_str())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SCP_unordered_map<SCP_string, expression::ActionExpression> parameterExpressions;
|
||||
const auto& params = actionDef->getParameters();
|
||||
|
||||
if (params.size() == 1) {
|
||||
// Single parameters are expected to be placed directly after the action name
|
||||
parameterExpressions[params.front().name] =
|
||||
expression::ActionExpression::parseFromTable(params.front().type, context);
|
||||
} else {
|
||||
parseActionParameters(params, parameterExpressions, context);
|
||||
|
||||
if (parameterExpressions.size() != params.size()) {
|
||||
SCP_vector<ActionParameter> missingParameters;
|
||||
std::copy_if(params.cbegin(),
|
||||
params.cend(),
|
||||
std::back_inserter(missingParameters),
|
||||
[¶meterExpressions](const ActionParameter& param) {
|
||||
const auto iter = parameterExpressions.find(param.name);
|
||||
return iter == parameterExpressions.cend();
|
||||
});
|
||||
|
||||
SCP_vector<SCP_string> missingParameterNames;
|
||||
std::transform(missingParameters.cbegin(),
|
||||
missingParameters.cend(),
|
||||
std::back_inserter(missingParameterNames),
|
||||
[](const ActionParameter& param) { return "+" + param.name; });
|
||||
|
||||
const auto namesList = util::join_container(missingParameterNames, ", ");
|
||||
|
||||
error_display(0, "Missing parameters for action '%s': %s", parseString.c_str(), namesList.c_str());
|
||||
|
||||
// Fix up the parameter list so that we can continue parsing
|
||||
for (const auto& missingParam : missingParameters) {
|
||||
parameterExpressions[missingParam.name] = expression::ActionExpression();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto actionInstance = actionDef->createAction(parameterExpressions);
|
||||
|
||||
const auto requiredFlags = actionDef->getRequiredContext();
|
||||
|
||||
if ((context_flags & requiredFlags) != requiredFlags) {
|
||||
// We are missing at least one context flag so this action is not valid here. We still return the action
|
||||
// here though since that is the only way we can keep parsing the table without throwing random error
|
||||
// messages at the user. However, this will trigger an Assertion (in debug) or crashes when the action is
|
||||
// actually run later.
|
||||
error_display(0,
|
||||
"The action %s is not available in the current context. This will lead to an Assertion failure when "
|
||||
"this action is triggered.",
|
||||
parseString.c_str());
|
||||
}
|
||||
|
||||
return actionInstance;
|
||||
}
|
||||
|
||||
return std::unique_ptr<Action>();
|
||||
}
|
||||
ActionDefinitionManager::ActionDefinitionManager()
|
||||
{
|
||||
addDefinition(
|
||||
std::unique_ptr<ActionDefinition>(new BuiltinActionDefinition<types::MoveToSubmodel>("Move To Subobject")));
|
||||
addDefinition(std::unique_ptr<ActionDefinition>(
|
||||
new BuiltinActionDefinition<types::ParticleEffectAction>("Start Particle Effect")));
|
||||
addDefinition(
|
||||
std::unique_ptr<ActionDefinition>(new BuiltinActionDefinition<types::PlaySoundAction>("Play 3D Sound")));
|
||||
addDefinition(
|
||||
std::unique_ptr<ActionDefinition>(new BuiltinActionDefinition<types::SetDirectionAction>("Set Direction")));
|
||||
addDefinition(
|
||||
std::unique_ptr<ActionDefinition>(new BuiltinActionDefinition<types::SetPositionAction>("Set Position")));
|
||||
addDefinition(std::unique_ptr<ActionDefinition>(new BuiltinActionDefinition<types::WaitAction>("Wait")));
|
||||
}
|
||||
|
||||
} // namespace actions
|
||||
@@ -1,29 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "ActionDefinition.h"
|
||||
|
||||
namespace actions {
|
||||
|
||||
class ActionDefinitionManager {
|
||||
public:
|
||||
// This type is supposed to be global so it may not be copied
|
||||
ActionDefinitionManager(const ActionDefinitionManager&) = delete;
|
||||
ActionDefinitionManager& operator=(const ActionDefinitionManager&) = delete;
|
||||
|
||||
ActionDefinitionManager(ActionDefinitionManager&&) noexcept = default;
|
||||
ActionDefinitionManager& operator=(ActionDefinitionManager&&) noexcept = default;
|
||||
|
||||
std::unique_ptr<Action> parseAction(const flagset<ProgramContextFlags>& context_flags,
|
||||
const expression::ParseContext& context) const;
|
||||
|
||||
static const ActionDefinitionManager& instance();
|
||||
|
||||
private:
|
||||
ActionDefinitionManager();
|
||||
|
||||
void addDefinition(std::unique_ptr<ActionDefinition> def);
|
||||
|
||||
SCP_vector<std::unique_ptr<ActionDefinition>> m_definitions;
|
||||
};
|
||||
|
||||
} // namespace actions
|
||||
@@ -1,37 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "ActionDefinition.h"
|
||||
|
||||
#include "expression/Value.h"
|
||||
|
||||
namespace actions {
|
||||
|
||||
template <typename TAction>
|
||||
class BuiltinActionDefinition : public ActionDefinition {
|
||||
using ActionValueType = typename TAction::ValueType;
|
||||
|
||||
public:
|
||||
BuiltinActionDefinition(SCP_string name)
|
||||
: ActionDefinition(std::move(name), {{"parameter", expression::ValueTypeTraits<ActionValueType>::type}})
|
||||
{
|
||||
}
|
||||
~BuiltinActionDefinition() override = default;
|
||||
|
||||
flagset<ProgramContextFlags> getRequiredContext() const override
|
||||
{
|
||||
return flagset<ProgramContextFlags>(TAction::getRequiredExecutionContextFlags());
|
||||
}
|
||||
|
||||
std::unique_ptr<Action> createAction(
|
||||
const SCP_unordered_map<SCP_string, expression::ActionExpression>& parameterExpressions) const override
|
||||
{
|
||||
const auto paramIter = parameterExpressions.find("parameter");
|
||||
|
||||
// This should have been caught earlier
|
||||
Assertion(paramIter != parameterExpressions.cend(), "Could not find built-in parameter!");
|
||||
|
||||
return std::unique_ptr<Action>(new TAction(paramIter->second.template asTyped<ActionValueType>()));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace actions
|
||||
@@ -1,174 +0,0 @@
|
||||
|
||||
#include "Program.h"
|
||||
|
||||
#include "Action.h"
|
||||
|
||||
#include "actions/ActionDefinitionManager.h"
|
||||
#include "executor/global_executors.h"
|
||||
#include "tracing/Monitor.h"
|
||||
#include "tracing/categories.h"
|
||||
#include "tracing/tracing.h"
|
||||
|
||||
namespace {
|
||||
using namespace actions;
|
||||
|
||||
tracing::Monitor<int> RunningProgramsMonitor("RunningPrograms", 0);
|
||||
|
||||
struct ProgramRunner {
|
||||
tracing::RunningCounter runningCounter{RunningProgramsMonitor};
|
||||
|
||||
ProgramInstance instance;
|
||||
|
||||
explicit ProgramRunner(const ProgramInstance& _instance) : instance(_instance) {}
|
||||
|
||||
executor::Executor::CallbackResult operator()()
|
||||
{
|
||||
TRACE_SCOPE(tracing::ProgramStepOne);
|
||||
|
||||
auto res = instance.step();
|
||||
|
||||
switch (res) {
|
||||
case ProgramState::Running:
|
||||
// If the program is still running then we need to reschedule our execution
|
||||
return executor::Executor::CallbackResult::Reschedule;
|
||||
case ProgramState::Done:
|
||||
case ProgramState::Errored:
|
||||
default:
|
||||
return executor::Executor::CallbackResult::Done;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace actions {
|
||||
|
||||
ProgramInstance::ProgramInstance(const actions::Program* program) : _program(program) {}
|
||||
|
||||
ProgramState ProgramInstance::step()
|
||||
{
|
||||
if (!_locals.host.IsValid()) {
|
||||
return ProgramState::Done;
|
||||
}
|
||||
|
||||
auto& actions = _program->getActions();
|
||||
|
||||
for (; _currentInstruction < actions.size(); ++_currentInstruction) {
|
||||
auto& action = actions[_currentInstruction];
|
||||
|
||||
auto result = action->execute(_locals);
|
||||
|
||||
if (result == ActionResult::Errored) {
|
||||
return ProgramState::Errored;
|
||||
}
|
||||
|
||||
if (result == ActionResult::Wait) {
|
||||
// Action is not done yet, call again next frame
|
||||
return ProgramState::Running;
|
||||
}
|
||||
|
||||
// Action finished, run next action in program
|
||||
}
|
||||
|
||||
// End of program reached, we are done now
|
||||
return ProgramState::Done;
|
||||
}
|
||||
ProgramLocals& ProgramInstance::locals()
|
||||
{
|
||||
return _locals;
|
||||
}
|
||||
const ProgramLocals& ProgramInstance::locals() const
|
||||
{
|
||||
return _locals;
|
||||
}
|
||||
|
||||
const SCP_vector<std::unique_ptr<actions::Action>>& Program::getActions() const
|
||||
{
|
||||
return _actions;
|
||||
}
|
||||
|
||||
Program::Program() = default;
|
||||
|
||||
ProgramInstance Program::newInstance() const
|
||||
{
|
||||
return ProgramInstance(this);
|
||||
}
|
||||
|
||||
void Program::parseActions(const flagset<ProgramContextFlags>& context_flags, const expression::ParseContext& context)
|
||||
{
|
||||
while (true) {
|
||||
auto action = ActionDefinitionManager::instance().parseAction(context_flags, context);
|
||||
|
||||
if (!action) {
|
||||
break;
|
||||
}
|
||||
|
||||
_actions.push_back(std::move(action));
|
||||
}
|
||||
}
|
||||
|
||||
Program::Program(const Program& other) { *this = other; }
|
||||
Program& Program::operator=(const Program& other)
|
||||
{
|
||||
_actions.clear();
|
||||
_actions.reserve(other._actions.size());
|
||||
|
||||
for (auto& action : other._actions) {
|
||||
_actions.emplace_back(action->clone());
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Program& Program::operator=(Program&&) noexcept = default;
|
||||
Program::Program(Program&&) noexcept = default;
|
||||
|
||||
bool ProgramSet::isEmpty() const
|
||||
{
|
||||
return _programs.empty();
|
||||
}
|
||||
|
||||
ProgramSet::ProgramSet() = default;
|
||||
|
||||
ProgramSet::ProgramSet(const flagset<ProgramContextFlags>& context_flags) : _contextFlags(context_flags) {}
|
||||
|
||||
void ProgramSet::start(object* objp, const vec3d* local_pos, const matrix* local_orient, int submodel) const
|
||||
{
|
||||
if (_contextFlags[ProgramContextFlags::HasObject]) {
|
||||
Assertion(objp != nullptr, "Invalid object pointer supplied.");
|
||||
}
|
||||
if (_contextFlags[ProgramContextFlags::HasSubobject]) {
|
||||
Assertion(submodel >= 0, "Invalid subobject supplied.");
|
||||
}
|
||||
|
||||
for (const auto& prog : _programs) {
|
||||
auto instance = prog.newInstance();
|
||||
|
||||
instance.locals().host = object_h(objp);
|
||||
instance.locals().localPosition = *local_pos;
|
||||
instance.locals().localOrient = *local_orient;
|
||||
instance.locals().hostSubobject = submodel;
|
||||
instance.locals().variables = getDefaultTableVariables();
|
||||
|
||||
// Just use the executor system to take care of running this program
|
||||
executor::OnSimulationExecutor->post(ProgramRunner(instance));
|
||||
}
|
||||
}
|
||||
|
||||
ProgramSet ProgramSet::parseProgramSet(const char* tag, const flagset<ProgramContextFlags>& context_flags)
|
||||
{
|
||||
ProgramSet set(context_flags);
|
||||
|
||||
const auto parseContext = getTableParseContext();
|
||||
|
||||
while (optional_string(tag)) {
|
||||
Program p;
|
||||
p.parseActions(context_flags, parseContext);
|
||||
|
||||
set._programs.push_back(std::move(p));
|
||||
}
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
} // namespace actions
|
||||
@@ -1,112 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
#include "Action.h"
|
||||
#include "common.h"
|
||||
|
||||
namespace actions {
|
||||
|
||||
class Program;
|
||||
class ProgramSet;
|
||||
|
||||
enum class ProgramState
|
||||
{
|
||||
Running,
|
||||
Done,
|
||||
Errored
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief An instance of a program execution
|
||||
*
|
||||
* A program instance contains all information related to a single execution of a program. A program instance is
|
||||
* independent from other instances. Local variables used by actions are stored in a specific structure which can be
|
||||
* used by actions to keep track of state in this specific instance.
|
||||
*/
|
||||
class ProgramInstance {
|
||||
size_t _currentInstruction = 0;
|
||||
ProgramLocals _locals;
|
||||
const Program* _program = nullptr;
|
||||
|
||||
public:
|
||||
explicit ProgramInstance(const Program* program);
|
||||
|
||||
ProgramState step();
|
||||
|
||||
ProgramLocals& locals();
|
||||
const ProgramLocals& locals() const;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A program specified in a table
|
||||
*
|
||||
* A program is a sequential collection of Actions which are executed in sequence.
|
||||
*/
|
||||
class Program {
|
||||
SCP_vector<std::unique_ptr<Action>> _actions;
|
||||
|
||||
public:
|
||||
Program();
|
||||
|
||||
Program(const Program& other);
|
||||
Program& operator=(const Program& other);
|
||||
|
||||
Program(Program&& other) noexcept;
|
||||
Program& operator=(Program&& other) noexcept;
|
||||
|
||||
const SCP_vector<std::unique_ptr<actions::Action>>& getActions() const;
|
||||
|
||||
/**
|
||||
* @brief Creates a new program instance from this program
|
||||
*
|
||||
* The program instance is initialized to its initial values.
|
||||
*
|
||||
* @return The new program instance
|
||||
*/
|
||||
ProgramInstance newInstance() const;
|
||||
|
||||
void parseActions(const flagset<ProgramContextFlags>& context_flags, const expression::ParseContext& context);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A set of parsed programs
|
||||
*
|
||||
* Programs are parsed in sets of zero or more programs to make it possible for the content creator to split up
|
||||
* programs.
|
||||
*/
|
||||
class ProgramSet {
|
||||
flagset<ProgramContextFlags> _contextFlags;
|
||||
|
||||
SCP_vector<Program> _programs;
|
||||
|
||||
public:
|
||||
ProgramSet();
|
||||
explicit ProgramSet(const flagset<ProgramContextFlags>& context_flags);
|
||||
|
||||
bool isEmpty() const;
|
||||
|
||||
/**
|
||||
* @brief Starts the execution of all programs within this set with the specified parameters
|
||||
* @param objp The object on which this program is executed
|
||||
* @param local_pos The local position relative to the object or the subsystem if specified
|
||||
* @param local_orien The local orientation relative to the object or the subsystem if specified
|
||||
* @param submodel The submodel of the model to which this program is attached to.
|
||||
*/
|
||||
void start(object* objp, const vec3d* local_pos, const matrix* local_orient, int submodel = -1) const;
|
||||
|
||||
/**
|
||||
* @brief Parses a program set of zero or more programs
|
||||
*
|
||||
* The tag is entirely optional and if it doesn't appear in the current table then an empty set will be returned
|
||||
* which does nothing if started.
|
||||
*
|
||||
* @param tag The tag which is required before a program can be specified
|
||||
* @param context_flags A set of flags which specify in which environment the program will be used. This is used
|
||||
* mainly for validating the used actions.
|
||||
* @return The parsed program set.
|
||||
*/
|
||||
static ProgramSet parseProgramSet(const char* tag, const flagset<ProgramContextFlags>& context_flags = {});
|
||||
};
|
||||
|
||||
} // namespace actions
|
||||
@@ -1,27 +0,0 @@
|
||||
|
||||
#include "common.h"
|
||||
|
||||
namespace actions {
|
||||
|
||||
expression::ParseContext getTableParseContext()
|
||||
{
|
||||
expression::ParseContext ctx;
|
||||
|
||||
auto& locals = ctx.variables.addScope("locals");
|
||||
|
||||
locals.addMember("position", expression::ValueType::Vector);
|
||||
locals.addMember("direction", expression::ValueType::Vector);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
expression::ProgramVariables getDefaultTableVariables()
|
||||
{
|
||||
expression::ProgramVariables vars;
|
||||
|
||||
vars.setValue({"locals", "position"}, expression::Value(vmd_zero_vector));
|
||||
vars.setValue({"locals", "direction"}, expression::Value(vmd_zero_vector));
|
||||
|
||||
return vars;
|
||||
}
|
||||
|
||||
} // namespace actions
|
||||
@@ -1,59 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "globalincs/flagset.h"
|
||||
|
||||
#include "actions/expression/ParseContext.h"
|
||||
#include "actions/expression/ProgramVariables.h"
|
||||
#include "math/vecmat.h"
|
||||
#include "object/object.h"
|
||||
|
||||
class object;
|
||||
class ship_subsys;
|
||||
|
||||
namespace actions {
|
||||
|
||||
struct ProgramLocals {
|
||||
object_h host;
|
||||
vec3d localPosition = vmd_zero_vector;
|
||||
matrix localOrient = vmd_identity_matrix;
|
||||
int hostSubobject = -1;
|
||||
|
||||
int waitTimestamp = 0;
|
||||
|
||||
expression::ProgramVariables variables;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A list of flags for altering the program parsing behavior
|
||||
*
|
||||
* This should be used for differentiating between different program environments when validating the program (e.g. a
|
||||
* particle effect requires an object host).
|
||||
*/
|
||||
// clang-format off
|
||||
FLAG_LIST(ProgramContextFlags) {
|
||||
HasObject = 0, //!< The program will be started with an object host
|
||||
HasSubobject, //!< The program will be started with a subobject host
|
||||
|
||||
NUM_VALUES
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
/**
|
||||
* @brief Constructs the "table" parse context
|
||||
*
|
||||
* This is the context that is available when parsing a program from an external table (e.g. ships or weapons).
|
||||
*
|
||||
* @return The parse context
|
||||
*/
|
||||
expression::ParseContext getTableParseContext();
|
||||
|
||||
/**
|
||||
* @brief Gets a program variables instance initialized with the default values
|
||||
*
|
||||
* The values are consistent with what is required for the default table parse context;
|
||||
*
|
||||
* @return The program variables
|
||||
*/
|
||||
expression::ProgramVariables getDefaultTableVariables();
|
||||
|
||||
} // namespace actions
|
||||
@@ -1,66 +0,0 @@
|
||||
|
||||
#include "ActionExpression.h"
|
||||
|
||||
#include "ExpressionParser.h"
|
||||
#include "TypeDefinition.h"
|
||||
|
||||
#include "actions/expression/nodes/AbstractExpression.h"
|
||||
|
||||
namespace actions {
|
||||
namespace expression {
|
||||
namespace {
|
||||
|
||||
SCP_string getTypeName(ValueType type)
|
||||
{
|
||||
const auto& typeDef = TypeDefinition::forValueType(type);
|
||||
return typeDef.getName();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ActionExpression ActionExpression::parseFromTable(ValueType expectedReturnType, const ParseContext& context)
|
||||
{
|
||||
SCP_string expressionText;
|
||||
|
||||
stuff_string(expressionText, F_NAME);
|
||||
|
||||
ExpressionParser parser(expressionText);
|
||||
|
||||
auto expression = parser.parse(context);
|
||||
|
||||
if (!expression) {
|
||||
error_display(0, "Failed to parse action expression:\n%s", parser.getErrorText().c_str());
|
||||
return ActionExpression();
|
||||
}
|
||||
|
||||
auto type = expression->getExpressionType();
|
||||
|
||||
// Check if the type this evaluates to matches what we expect
|
||||
if (!checkTypeWithImplicitConversion(type, expectedReturnType)) {
|
||||
error_display(0,
|
||||
"Expression evaluates to type <%s> but <%s> was expected!",
|
||||
getTypeName(type).c_str(),
|
||||
getTypeName(expectedReturnType).c_str());
|
||||
return ActionExpression();
|
||||
}
|
||||
|
||||
// Everything is valid
|
||||
return ActionExpression(expression);
|
||||
}
|
||||
|
||||
Value ActionExpression::execute(const ProgramVariables& variables) const
|
||||
{
|
||||
// Do not crash on invalid expressions
|
||||
if (!isValid()) {
|
||||
return Value();
|
||||
}
|
||||
|
||||
return m_expression->execute(variables);
|
||||
}
|
||||
bool ActionExpression::isValid() const
|
||||
{
|
||||
return m_expression != nullptr;
|
||||
}
|
||||
|
||||
} // namespace expression
|
||||
} // namespace actions
|
||||
@@ -1,83 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "ParseContext.h"
|
||||
#include "ProgramVariables.h"
|
||||
#include "TypeDefinition.h"
|
||||
|
||||
#include "parse/parselo.h"
|
||||
|
||||
namespace actions {
|
||||
namespace expression {
|
||||
namespace nodes {
|
||||
class AbstractExpression;
|
||||
}
|
||||
template <typename T>
|
||||
class TypedActionExpression;
|
||||
|
||||
/**
|
||||
* @brief An expression that can be executed to compute a value at runtime
|
||||
*
|
||||
* This is the basis of having dynamic values in actions by allowing mods to specify complex expressions that make use
|
||||
* of variables and functions for computing their values at runtime.
|
||||
*/
|
||||
class ActionExpression {
|
||||
public:
|
||||
ActionExpression() = default;
|
||||
|
||||
Value execute(const ProgramVariables& variables) const;
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
template <typename T>
|
||||
TypedActionExpression<T> asTyped() const;
|
||||
|
||||
static ActionExpression parseFromTable(ValueType expectedReturnType, const ParseContext& context);
|
||||
|
||||
protected:
|
||||
explicit ActionExpression(std::shared_ptr<nodes::AbstractExpression> expression)
|
||||
: m_expression(std::move(expression))
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<nodes::AbstractExpression> m_expression;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief An action expression with a specific type specified at compile time
|
||||
*
|
||||
* This is most useful for built-in actions that have the required type fixed at compile time.
|
||||
*
|
||||
* @tparam T The type of the expression value.
|
||||
*/
|
||||
template <typename T>
|
||||
class TypedActionExpression {
|
||||
public:
|
||||
explicit TypedActionExpression(ActionExpression expression) : m_expression(std::move(expression)) {}
|
||||
|
||||
T execute(const ProgramVariables& variables) const
|
||||
{
|
||||
// Do not crash on invalid expressions
|
||||
if (!m_expression.isValid()) {
|
||||
return T();
|
||||
}
|
||||
|
||||
return m_expression.execute(variables).template get<T>();
|
||||
}
|
||||
|
||||
static TypedActionExpression<T> parseFromTable(const ParseContext& context)
|
||||
{
|
||||
return ActionExpression::parseFromTable(ValueTypeTraits<T>::type, context).template asTyped<T>();
|
||||
}
|
||||
|
||||
private:
|
||||
ActionExpression m_expression;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
TypedActionExpression<T> ActionExpression::asTyped() const
|
||||
{
|
||||
return TypedActionExpression<T>(*this);
|
||||
}
|
||||
|
||||
} // namespace expression
|
||||
} // namespace actions
|
||||
@@ -1,194 +0,0 @@
|
||||
|
||||
#include "ExpressionParser.h"
|
||||
|
||||
#include "actions/expression/nodes/FunctionCallExpression.h"
|
||||
#include "actions/expression/nodes/LiteralExpression.h"
|
||||
#include "actions/expression/nodes/RandomRangeExpression.h"
|
||||
#include "actions/expression/nodes/VariableReferenceExpression.h"
|
||||
#include "actions/expression/nodes/VectorConstructorExpression.h"
|
||||
#include "libs/antlr/ErrorListener.h"
|
||||
|
||||
PUSH_SUPPRESS_WARNINGS
|
||||
#include "action_expression/generated/ActionExpressionLexer.h"
|
||||
#include "action_expression/generated/ActionExpressionParser.h"
|
||||
#include "action_expression/generated/ActionExpressionVisitor.h"
|
||||
POP_SUPPRESS_WARNINGS
|
||||
|
||||
namespace actions {
|
||||
namespace expression {
|
||||
|
||||
namespace {
|
||||
|
||||
class ExpressionBuilderVisitor : public ActionExpressionVisitor {
|
||||
public:
|
||||
antlrcpp::Any visitExpression_main(ActionExpressionParser::Expression_mainContext* context) override
|
||||
{
|
||||
return visit(context->expression());
|
||||
}
|
||||
antlrcpp::Any visitExpression(ActionExpressionParser::ExpressionContext* context) override
|
||||
{
|
||||
if (context->value_expression() != nullptr) {
|
||||
return visit(context->value_expression());
|
||||
}
|
||||
if (context->parenthesis_expression()) {
|
||||
return visit(context->parenthesis_expression());
|
||||
}
|
||||
if (context->random_range_expression()) {
|
||||
return visit(context->random_range_expression());
|
||||
}
|
||||
if (context->variable_reference_expression()) {
|
||||
return visit(context->variable_reference_expression());
|
||||
}
|
||||
|
||||
// This is an operator so treat it as one.
|
||||
antlr4::Token* operatorTok;
|
||||
SCP_string operatorText;
|
||||
if (context->PLUS() != nullptr) {
|
||||
operatorTok = context->PLUS()->getSymbol();
|
||||
operatorText = context->PLUS()->getText();
|
||||
} else {
|
||||
operatorTok = context->MINUS()->getSymbol();
|
||||
operatorText = context->MINUS()->getText();
|
||||
}
|
||||
|
||||
const auto leftExpr = visit(context->expression(0)).as<std::shared_ptr<nodes::AbstractExpression>>();
|
||||
const auto rightExpr = visit(context->expression(1)).as<std::shared_ptr<nodes::AbstractExpression>>();
|
||||
|
||||
auto operatorExpression = std::make_shared<nodes::FunctionCallExpression>(operatorTok,
|
||||
true,
|
||||
std::move(operatorText),
|
||||
SCP_vector<std::shared_ptr<nodes::AbstractExpression>>{leftExpr, rightExpr});
|
||||
return std::static_pointer_cast<nodes::AbstractExpression>(operatorExpression);
|
||||
}
|
||||
antlrcpp::Any visitVariable_reference_expression(
|
||||
ActionExpressionParser::Variable_reference_expressionContext* context) override
|
||||
{
|
||||
const auto identifiers = context->IDENTIFIER();
|
||||
|
||||
SCP_vector<SCP_string> partNames;
|
||||
partNames.reserve(identifiers.size());
|
||||
|
||||
std::transform(identifiers.begin(),
|
||||
identifiers.end(),
|
||||
std::back_inserter(partNames),
|
||||
[](antlr4::tree::TerminalNode* node) { return node->getText(); });
|
||||
|
||||
SCP_vector<antlr4::Token*> partTokens;
|
||||
partTokens.reserve(identifiers.size());
|
||||
|
||||
std::transform(identifiers.begin(),
|
||||
identifiers.end(),
|
||||
std::back_inserter(partTokens),
|
||||
[](antlr4::tree::TerminalNode* node) { return node->getSymbol(); });
|
||||
|
||||
auto expression =
|
||||
std::make_shared<nodes::VariableReferenceExpression>(std::move(partNames), std::move(partTokens));
|
||||
return std::static_pointer_cast<nodes::AbstractExpression>(expression);
|
||||
}
|
||||
antlrcpp::Any visitRandom_range_expression(ActionExpressionParser::Random_range_expressionContext* context) override
|
||||
{
|
||||
auto expression = std::make_shared<nodes::RandomRangeExpression>(context->RAND_L_PAREN()->getSymbol(),
|
||||
visit(context->expression(0)).as<std::shared_ptr<nodes::AbstractExpression>>(),
|
||||
visit(context->expression(1)).as<std::shared_ptr<nodes::AbstractExpression>>());
|
||||
return std::static_pointer_cast<nodes::AbstractExpression>(expression);
|
||||
}
|
||||
antlrcpp::Any visitLiteral_expression(ActionExpressionParser::Literal_expressionContext* context) override
|
||||
{
|
||||
std::shared_ptr<nodes::LiteralExpression> expression;
|
||||
|
||||
if (context->FLOAT() != nullptr) {
|
||||
expression = std::make_shared<nodes::LiteralExpression>(context->FLOAT()->getSymbol(),
|
||||
Value(std::stof(context->FLOAT()->getText())));
|
||||
} else if (context->INT() != nullptr) {
|
||||
expression = std::make_shared<nodes::LiteralExpression>(context->INT()->getSymbol(),
|
||||
Value(std::stoi(context->INT()->getText())));
|
||||
} else {
|
||||
const auto idText = context->STRING()->getText();
|
||||
|
||||
// Cut off the first and last characters since those are the < > braces
|
||||
expression = std::make_shared<nodes::LiteralExpression>(context->STRING()->getSymbol(),
|
||||
Value(idText.substr(1, idText.size() - 2)));
|
||||
}
|
||||
|
||||
return std::static_pointer_cast<nodes::AbstractExpression>(expression);
|
||||
}
|
||||
antlrcpp::Any visitParenthesis_expression(ActionExpressionParser::Parenthesis_expressionContext* context) override
|
||||
{
|
||||
return visit(context->expression());
|
||||
}
|
||||
antlrcpp::Any visitValue_expression(ActionExpressionParser::Value_expressionContext* context) override
|
||||
{
|
||||
return visitChildren(context);
|
||||
}
|
||||
antlrcpp::Any visitVec3d_constructor(ActionExpressionParser::Vec3d_constructorContext* context) override
|
||||
{
|
||||
auto xExpression = visit(context->expression(0)).as<std::shared_ptr<nodes::AbstractExpression>>();
|
||||
auto yExpression = visit(context->expression(1)).as<std::shared_ptr<nodes::AbstractExpression>>();
|
||||
auto zExpression = visit(context->expression(2)).as<std::shared_ptr<nodes::AbstractExpression>>();
|
||||
|
||||
auto expression = std::make_shared<nodes::VectorConstructorExpression>(context->L_PAREN()->getSymbol(),
|
||||
xExpression,
|
||||
yExpression,
|
||||
zExpression);
|
||||
|
||||
return std::static_pointer_cast<nodes::AbstractExpression>(expression);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
ExpressionParser::ExpressionParser(SCP_string expressionText) : m_expressionText(std::move(expressionText)) {}
|
||||
|
||||
std::shared_ptr<nodes::AbstractExpression> ExpressionParser::parse(const ParseContext& context)
|
||||
{
|
||||
antlr4::ANTLRInputStream input(m_expressionText);
|
||||
ActionExpressionLexer lexer(&input);
|
||||
antlr4::CommonTokenStream tokens(&lexer);
|
||||
|
||||
::ActionExpressionParser parser(&tokens);
|
||||
// By default we log to stderr which we do not want
|
||||
parser.removeErrorListeners();
|
||||
libs::antlr::ErrorListener errListener;
|
||||
parser.addErrorListener(&errListener);
|
||||
|
||||
antlr4::tree::ParseTree* tree = parser.expression_main();
|
||||
|
||||
std::shared_ptr<nodes::AbstractExpression> exprReturn;
|
||||
if (errListener.diagnostics.empty()) {
|
||||
// Only do semantic checking if syntax is valid
|
||||
ExpressionBuilderVisitor builder;
|
||||
exprReturn = tree->accept(&builder).as<std::shared_ptr<nodes::AbstractExpression>>();
|
||||
|
||||
if (!exprReturn->validate(&parser, context)) {
|
||||
exprReturn = nullptr;
|
||||
} else {
|
||||
exprReturn->validationDone();
|
||||
}
|
||||
}
|
||||
|
||||
if (!errListener.diagnostics.empty()) {
|
||||
SCP_stringstream outStream;
|
||||
for (const auto& diag : errListener.diagnostics) {
|
||||
SCP_string tokenUnderline;
|
||||
if (diag.tokenLength > 1) {
|
||||
tokenUnderline = SCP_string(diag.tokenLength - 1, '~');
|
||||
}
|
||||
outStream << m_expressionText << "\n"
|
||||
<< SCP_string(diag.columnInLine, ' ') << "^" << tokenUnderline << "\n"
|
||||
<< diag.errorMessage << "\n";
|
||||
}
|
||||
|
||||
m_errorText = outStream.str();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return exprReturn;
|
||||
}
|
||||
|
||||
const SCP_string& ExpressionParser::getErrorText() const
|
||||
{
|
||||
return m_errorText;
|
||||
}
|
||||
|
||||
} // namespace expression
|
||||
} // namespace actions
|
||||
@@ -1,27 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "actions/expression/nodes/AbstractExpression.h"
|
||||
|
||||
#include "globalincs/pstypes.h"
|
||||
|
||||
#include "ParseContext.h"
|
||||
|
||||
namespace actions {
|
||||
namespace expression {
|
||||
|
||||
class ExpressionParser {
|
||||
public:
|
||||
ExpressionParser(SCP_string expressionText);
|
||||
|
||||
std::shared_ptr<nodes::AbstractExpression> parse(const ParseContext& context);
|
||||
|
||||
const SCP_string& getErrorText() const;
|
||||
|
||||
private:
|
||||
SCP_string m_expressionText;
|
||||
|
||||
SCP_string m_errorText;
|
||||
};
|
||||
|
||||
} // namespace expression
|
||||
} // namespace actions
|
||||
@@ -1,90 +0,0 @@
|
||||
|
||||
#include "FunctionManager.h"
|
||||
|
||||
#include "TypeDefinition.h"
|
||||
|
||||
#include "math/vecmat.h"
|
||||
|
||||
namespace actions {
|
||||
namespace expression {
|
||||
namespace {
|
||||
template <typename T>
|
||||
Value value_plus(const SCP_vector<Value>& parameters)
|
||||
{
|
||||
return Value(parameters[0].get<T>() + parameters[1].get<T>());
|
||||
}
|
||||
template <typename T>
|
||||
Value value_minus(const SCP_vector<Value>& parameters)
|
||||
{
|
||||
return Value(parameters[0].get<T>() - parameters[1].get<T>());
|
||||
}
|
||||
} // namespace
|
||||
|
||||
const FunctionManager& FunctionManager::instance()
|
||||
{
|
||||
static const FunctionManager manager;
|
||||
return manager;
|
||||
}
|
||||
void FunctionManager::addOperator(const SCP_string& name,
|
||||
std::initializer_list<ValueType> parameterTypes,
|
||||
ValueType returnType,
|
||||
FunctionImplementation implementation)
|
||||
{
|
||||
m_operators[name].push_back({name, parameterTypes, returnType, std::move(implementation)});
|
||||
}
|
||||
const FunctionDefinition* FunctionManager::findOperator(const SCP_string& name,
|
||||
const SCP_vector<ValueType>& parameters) const
|
||||
{
|
||||
const auto iter = m_operators.find(name);
|
||||
|
||||
if (iter == m_operators.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Prefer exact matches
|
||||
for (const auto& funcDef : iter->second) {
|
||||
if (funcDef.parameterTypes == parameters) {
|
||||
return &funcDef;
|
||||
}
|
||||
}
|
||||
|
||||
// Now check if there are matches with implicit conversions
|
||||
for (const auto& funcDef : iter->second) {
|
||||
// Reject functions with different amount of elements
|
||||
if (funcDef.parameterTypes.size() != parameters.size()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto funcParamIter = funcDef.parameterTypes.cbegin();
|
||||
auto actualParamIter = parameters.cbegin();
|
||||
|
||||
bool match = true;
|
||||
for (; funcParamIter != funcDef.parameterTypes.cend(); ++funcParamIter, ++actualParamIter) {
|
||||
if (!checkTypeWithImplicitConversion(*actualParamIter, *funcParamIter)) {
|
||||
// Also doesn't match with implicit conversions
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (match) {
|
||||
return &funcDef;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FunctionManager::FunctionManager()
|
||||
{
|
||||
addOperator("+", {ValueType::Integer, ValueType::Integer}, ValueType::Integer, value_plus<int>);
|
||||
addOperator("+", {ValueType::Float, ValueType::Float}, ValueType::Float, value_plus<float>);
|
||||
addOperator("+", {ValueType::Vector, ValueType::Vector}, ValueType::Vector, value_plus<vec3d>);
|
||||
|
||||
addOperator("-", {ValueType::Integer, ValueType::Integer}, ValueType::Integer, value_minus<int>);
|
||||
addOperator("-", {ValueType::Float, ValueType::Float}, ValueType::Float, value_minus<float>);
|
||||
addOperator("-", {ValueType::Vector, ValueType::Vector}, ValueType::Vector, value_minus<vec3d>);
|
||||
}
|
||||
|
||||
} // namespace expression
|
||||
} // namespace actions
|
||||
@@ -1,45 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "Value.h"
|
||||
|
||||
namespace actions {
|
||||
namespace expression {
|
||||
|
||||
using FunctionImplementation = std::function<Value(const SCP_vector<Value>& parameters)>;
|
||||
|
||||
struct FunctionDefinition {
|
||||
SCP_string name;
|
||||
|
||||
SCP_vector<ValueType> parameterTypes;
|
||||
|
||||
ValueType returnType;
|
||||
|
||||
FunctionImplementation implementation;
|
||||
};
|
||||
|
||||
class FunctionManager {
|
||||
public:
|
||||
// This type is supposed to be global so it may not be copied
|
||||
FunctionManager(const FunctionManager&) = delete;
|
||||
FunctionManager& operator=(const FunctionManager&) = delete;
|
||||
|
||||
FunctionManager(FunctionManager&&) noexcept = default;
|
||||
FunctionManager& operator=(FunctionManager&&) noexcept = default;
|
||||
|
||||
void addOperator(const SCP_string& name,
|
||||
std::initializer_list<ValueType> parameterTypes,
|
||||
ValueType returnType,
|
||||
FunctionImplementation implementation);
|
||||
|
||||
const FunctionDefinition* findOperator(const SCP_string& name, const SCP_vector<ValueType>& parameterTypes) const;
|
||||
|
||||
static const FunctionManager& instance();
|
||||
|
||||
private:
|
||||
FunctionManager();
|
||||
|
||||
SCP_unordered_map<SCP_string, SCP_vector<FunctionDefinition>> m_operators;
|
||||
};
|
||||
|
||||
} // namespace expression
|
||||
} // namespace actions
|
||||
@@ -1,13 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "ProgramVariables.h"
|
||||
|
||||
namespace actions {
|
||||
namespace expression {
|
||||
|
||||
struct ParseContext {
|
||||
ProgramVariablesDefinition variables;
|
||||
};
|
||||
|
||||
} // namespace expression
|
||||
} // namespace actions
|
||||
@@ -1,61 +0,0 @@
|
||||
|
||||
#include "ProgramVariables.h"
|
||||
|
||||
namespace actions {
|
||||
namespace expression {
|
||||
|
||||
ProgramVariablesDefinition& ProgramVariablesDefinition::addScope(const SCP_string& name)
|
||||
{
|
||||
auto scope = std::unique_ptr<ProgramVariablesDefinition>(new ProgramVariablesDefinition());
|
||||
|
||||
auto scopePtr = scope.get();
|
||||
|
||||
m_scopes.insert(std::make_pair(name, std::move(scope)));
|
||||
|
||||
return *scopePtr;
|
||||
}
|
||||
void ProgramVariablesDefinition::addMember(const SCP_string& name, ValueType type)
|
||||
{
|
||||
m_memberTypes[name] = type;
|
||||
}
|
||||
ProgramVariablesDefinition* ProgramVariablesDefinition::getScope(const SCP_string& name) const
|
||||
{
|
||||
const auto iter = m_scopes.find(name);
|
||||
|
||||
if (iter == m_scopes.cend()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return iter->second.get();
|
||||
}
|
||||
ValueType ProgramVariablesDefinition::getMemberType(const SCP_string& name) const
|
||||
{
|
||||
const auto iter = m_memberTypes.find(name);
|
||||
|
||||
if (iter == m_memberTypes.cend()) {
|
||||
return ValueType::Invalid;
|
||||
}
|
||||
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
Value ProgramVariables::getValue(std::initializer_list<const char*> memberPathParts) const
|
||||
{
|
||||
return getValue<decltype(memberPathParts)>(memberPathParts);
|
||||
}
|
||||
void ProgramVariables::setValue(std::initializer_list<const char*> memberPathParts, Value value)
|
||||
{
|
||||
setValue<decltype(memberPathParts)>(memberPathParts, std::move(value));
|
||||
}
|
||||
Value ProgramVariables::getValue(const SCP_string& fullMemberName) const
|
||||
{
|
||||
const auto iter = m_values.find(fullMemberName);
|
||||
|
||||
// This should have been validated earlier
|
||||
Assertion(iter != m_values.end(), "Could not find member %s in variables!", fullMemberName.c_str());
|
||||
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
} // namespace expression
|
||||
} // namespace actions
|
||||
@@ -1,61 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "Value.h"
|
||||
|
||||
#include "utils/join_string.h"
|
||||
|
||||
namespace actions {
|
||||
namespace expression {
|
||||
|
||||
struct ProgramVariables {
|
||||
public:
|
||||
template <typename TContainer>
|
||||
static SCP_string getMemberName(const TContainer& memberPathParts)
|
||||
{
|
||||
return util::join_container(memberPathParts, ".");
|
||||
}
|
||||
|
||||
template <typename TContainer>
|
||||
Value getValue(const TContainer& memberPathParts) const
|
||||
{
|
||||
const auto name = getMemberName(memberPathParts);
|
||||
|
||||
return getValue(name);
|
||||
}
|
||||
|
||||
Value getValue(std::initializer_list<const char*> memberPathParts) const;
|
||||
|
||||
Value getValue(const SCP_string& fullMemberName) const;
|
||||
|
||||
template <typename TContainer>
|
||||
void setValue(const TContainer& memberPathParts, Value value)
|
||||
{
|
||||
const auto name = getMemberName(memberPathParts);
|
||||
|
||||
m_values[name] = std::move(value);
|
||||
}
|
||||
|
||||
void setValue(std::initializer_list<const char*> memberPathParts, Value value);
|
||||
|
||||
private:
|
||||
SCP_unordered_map<SCP_string, Value> m_values;
|
||||
};
|
||||
|
||||
class ProgramVariablesDefinition {
|
||||
public:
|
||||
ProgramVariablesDefinition& addScope(const SCP_string& name);
|
||||
|
||||
void addMember(const SCP_string& name, ValueType type);
|
||||
|
||||
ProgramVariablesDefinition* getScope(const SCP_string& name) const;
|
||||
|
||||
ValueType getMemberType(const SCP_string& name) const;
|
||||
|
||||
private:
|
||||
SCP_unordered_map<SCP_string, std::unique_ptr<ProgramVariablesDefinition>> m_scopes;
|
||||
|
||||
SCP_unordered_map<SCP_string, ValueType> m_memberTypes;
|
||||
};
|
||||
|
||||
} // namespace expression
|
||||
} // namespace actions
|
||||
@@ -1,60 +0,0 @@
|
||||
|
||||
#include "TypeDefinition.h"
|
||||
|
||||
namespace actions {
|
||||
namespace expression {
|
||||
|
||||
// Integers can be safely converted to floats (for the most part)
|
||||
TypeDefinition TypeDefinition::s_integer("Integer", {ValueType::Float});
|
||||
// No implicit conversions here
|
||||
TypeDefinition TypeDefinition::s_float("Float", {});
|
||||
TypeDefinition TypeDefinition::s_vector("Vector", {});
|
||||
// Identifiers are a technicality needed for making non-math values work but they have no further use other than their
|
||||
// string content
|
||||
TypeDefinition TypeDefinition::s_identifier("Identifier", {});
|
||||
|
||||
TypeDefinition::TypeDefinition(SCP_string name, SCP_vector<actions::expression::ValueType> allowedImplicitConversion)
|
||||
: m_name(std::move(name)), m_allowedImplicitConversions(std::move(allowedImplicitConversion))
|
||||
{
|
||||
}
|
||||
|
||||
const SCP_string& TypeDefinition::getName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
const SCP_vector<actions::expression::ValueType>& TypeDefinition::getAllowedImplicitConversions() const
|
||||
{
|
||||
return m_allowedImplicitConversions;
|
||||
}
|
||||
const TypeDefinition& TypeDefinition::forValueType(ValueType type)
|
||||
{
|
||||
switch (type) {
|
||||
case ValueType::Integer:
|
||||
return s_integer;
|
||||
case ValueType::Float:
|
||||
return s_float;
|
||||
case ValueType::Vector:
|
||||
return s_vector;
|
||||
case ValueType::String:
|
||||
return s_identifier;
|
||||
default:
|
||||
UNREACHABLE("Invalid value type!");
|
||||
return s_integer; // Make compiler happy
|
||||
}
|
||||
}
|
||||
|
||||
bool checkTypeWithImplicitConversion(ValueType currentType, ValueType expectedType)
|
||||
{
|
||||
if (currentType == expectedType) {
|
||||
// No need to consider implicit conversions;
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto& currentTypeDef = TypeDefinition::forValueType(currentType);
|
||||
const auto& allowedConversions = currentTypeDef.getAllowedImplicitConversions();
|
||||
|
||||
// For now, no transitiv conversions are allowed
|
||||
return std::find(allowedConversions.cbegin(), allowedConversions.cend(), expectedType) != allowedConversions.cend();
|
||||
}
|
||||
} // namespace expression
|
||||
} // namespace actions
|
||||
Loaded 100 of 2062 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user