Browse Source

Switch to C++20

glibc compatibility remains the same.

We now use Clang 18 and static libc++ for the Aarch64 build.
Linux x86 and x86_64 builds now use GCC 13.
development
Gleb Mazovetskiy 3 years ago
parent
commit
9701101634
  1. 37
      .github/workflows/Linux_aarch64.yml
  2. 26
      .github/workflows/Linux_x86.yml
  3. 20
      .github/workflows/Linux_x86_64.yml
  4. 2
      .github/workflows/Linux_x86_64_test.yml
  5. 27
      CMake/platforms/aarch64-linux-gnu-clang-static-libc++.toolchain.cmake
  6. 1
      CMake/platforms/aarch64-linux-gnu.toolchain.cmake
  7. 10
      CMake/platforms/debian-cross-pkg-config.sh
  8. 5
      CMakeLists.txt
  9. 16
      Packaging/nix/debian-cross-aarch64-prep.sh
  10. 16
      Packaging/nix/debian-cross-i386-prep.sh
  11. 14
      Packaging/nix/debian-host-prep.sh
  12. 43
      Source/towners.cpp
  13. 4
      Source/towners.h

37
.github/workflows/Linux_aarch64.yml

@ -29,19 +29,40 @@ jobs:
with:
fetch-depth: 0
- name: Create Build Environment
# Work around the somewhat broken packages in the GitHub Actions Ubuntu 20.04 image.
# https://github.com/actions/runner-images/issues/4620#issuecomment-981333260
- name: Work around broken packages
run: sudo apt-get -y install --allow-downgrades libpcre2-8-0=10.34-7
- name: Add clang repo
run: |
wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | sudo tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc
sudo tee /etc/apt/sources.list.d/clang.list <<LIST
deb [arch=amd64,arm64] http://apt.llvm.org/focal/ llvm-toolchain-focal main
deb-src http://apt.llvm.org/focal/ llvm-toolchain-focal main
LIST
# Installs dependencies, including arm64 libraries (runs `sudo apt-get update` as part of it)
- name: Install dependencies
run: Packaging/nix/debian-cross-aarch64-prep.sh --no-gcc
- name: Install clang-18
run: |
# Work around the somewhat broken packages in the GitHub Actions Ubuntu 20.04 image.
# https://github.com/actions/runner-images/issues/4620#issuecomment-981333260
sudo apt-get -y install --allow-downgrades libpcre2-8-0=10.34-7
Packaging/nix/debian-cross-aarch64-prep.sh
sudo apt-get install -yq --no-install-recommends clang-18 lld-18 libc++-18-dev:arm64 \
libgcc-10-dev-arm64-cross binutils-aarch64-linux-gnu && \
sudo update-alternatives --install \
/usr/bin/clang++ clang++ /usr/bin/clang++-18 200 && \
sudo update-alternatives --install \
/usr/bin/clang clang /usr/bin/clang-18 200 \
--slave /usr/bin/lld lld /usr/bin/lld-18 \
--slave /usr/bin/ld.lld ld.lld /usr/bin/ld.lld-18
- name: Cache CMake build folder
uses: actions/cache@v3
with:
path: build
key: ${{ github.workflow }}-v2-${{ github.sha }}
restore-keys: ${{ github.workflow }}-v2-
key: ${{ github.workflow }}-v6-${{ github.sha }}
restore-keys: ${{ github.workflow }}-v6-
- name: Build
working-directory: ${{github.workspace}}
@ -51,7 +72,7 @@ jobs:
# We set DEVILUTIONX_SYSTEM_LIBFMT=OFF because its soversion changes frequently.
# We set DEVILUTIONX_SYSTEM_SIMPLEINI=OFF because we require v4.19+, still missing from many distributions.
run: |
cmake -S. -Bbuild -DCMAKE_TOOLCHAIN_FILE=../CMake/platforms/aarch64-linux-gnu.toolchain.cmake \
cmake -S. -Bbuild -DCMAKE_TOOLCHAIN_FILE=../CMake/platforms/aarch64-linux-gnu-clang-static-libc++.toolchain.cmake \
-DCMAKE_BUILD_TYPE=${{env.CMAKE_BUILD_TYPE}} -DCMAKE_INSTALL_PREFIX=/usr -DCPACK=ON \
-DDEVILUTIONX_SYSTEM_LIBFMT=OFF -DDEVILUTIONX_SYSTEM_SIMPLEINI=OFF && \
cmake --build build -j $(getconf _NPROCESSORS_ONLN) --target package

26
.github/workflows/Linux_x86.yml

@ -29,19 +29,31 @@ jobs:
with:
fetch-depth: 0
- name: Create Build Environment
# Work around the somewhat broken packages in the GitHub Actions Ubuntu 20.04 image.
# https://github.com/actions/runner-images/issues/4620#issuecomment-981333260
- name: Work around broken packages
run: sudo apt-get -y install --allow-downgrades libpcre2-8-0=10.34-7
- name: Add gcc repo
run: sudo add-apt-repository ppa:ubuntu-toolchain-r/test
# Installs dependencies, including x86 libraries (runs `sudo apt-get update` as part of it)
- name: Install dependencies
run: Packaging/nix/debian-cross-i386-prep.sh --no-gcc
- name: Install gcc-13
run: |
# Work around the somewhat broken packages in the GitHub Actions Ubuntu 20.04 image.
# https://github.com/actions/runner-images/issues/4620#issuecomment-981333260
sudo apt-get -y install --allow-downgrades libpcre2-8-0=10.34-7
Packaging/nix/debian-cross-i386-prep.sh
sudo apt-get install -yq --no-install-recommends gcc-13 g++-13 g++-13-multilib && \
sudo update-alternatives --install \
/usr/bin/gcc gcc /usr/bin/gcc-13 13 \
--slave /usr/bin/g++ g++ /usr/bin/g++-13
- name: Cache CMake build folder
uses: actions/cache@v3
with:
path: build
key: ${{ github.workflow }}-v3-${{ github.sha }}
restore-keys: ${{ github.workflow }}-v3-
key: ${{ github.workflow }}-v5-${{ github.sha }}
restore-keys: ${{ github.workflow }}-v5-
- name: Build
working-directory: ${{github.workspace}}

20
.github/workflows/Linux_x86_64.yml

@ -29,15 +29,29 @@ jobs:
with:
fetch-depth: 0
- name: Add gcc repo
run: sudo add-apt-repository ppa:ubuntu-toolchain-r/test
# Installs dependencies and runs `sudo apt-get update` as part of it.
- name: Install dependencies
run: Packaging/nix/debian-host-prep.sh --no-gcc
- name: Install gcc-13
run: |
sudo apt-get install -yq --no-install-recommends gcc-13 g++-13 && \
sudo update-alternatives --install \
/usr/bin/gcc gcc /usr/bin/gcc-13 13 \
--slave /usr/bin/g++ g++ /usr/bin/g++-13
- name: Create Build Environment
run: Packaging/nix/debian-host-prep.sh
run: Packaging/nix/debian-host-prep.sh --no-gcc
- name: Cache CMake build folder
uses: actions/cache@v3
with:
path: build
key: ${{ github.workflow }}-v2-${{ github.sha }}
restore-keys: ${{ github.workflow }}-v2-
key: ${{ github.workflow }}-v5-${{ github.sha }}
restore-keys: ${{ github.workflow }}-v5-
- name: Build
working-directory: ${{github.workspace}}

2
.github/workflows/Linux_x86_64_test.yml

@ -18,7 +18,7 @@ concurrency:
jobs:
build:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3

27
CMake/platforms/aarch64-linux-gnu-clang-static-libc++.toolchain.cmake

@ -0,0 +1,27 @@
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(triple aarch64-linux-gnu)
set(CMAKE_C_COMPILER "/usr/bin/clang")
set(CMAKE_C_COMPILER_TARGET "${triple}")
set(CMAKE_CXX_COMPILER "/usr/bin/clang++")
set(CMAKE_CXX_FLAGS_INIT "-stdlib=libc++")
set(CMAKE_CXX_COMPILER_TARGET "${triple}")
set(CMAKE_ASM_COMPILER "/usr/bin/clang")
set(CMAKE_ASM_COMPILER_TARGET "${triple}")
set(CMAKE_EXE_LINKER_FLAGS_INIT "-fuse-ld=/usr/bin/ld.lld -static-libstdc++ -static-libgcc")
set(CMAKE_FIND_ROOT_PATH "/usr/aarch64-linux-gnu;/usr")
set(CMAKE_LIBRARY_ARCHITECTURE "${triple}")
set(CMAKE_STRIP "/usr/bin/aarch64-linux-gnu-strip")
set(PKG_CONFIG_EXECUTABLE "${CMAKE_CURRENT_LIST_DIR}/aarch64-linux-gnu-pkg-config" CACHE STRING "Path to pkg-config")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE arm64)

1
CMake/platforms/aarch64-linux-gnu.toolchain.cmake

@ -7,6 +7,7 @@ set(CMAKE_CXX_COMPILER "/usr/bin/aarch64-linux-gnu-g++")
set(CMAKE_FIND_ROOT_PATH "/usr/aarch64-linux-gnu;/usr")
set(CMAKE_LIBRARY_ARCHITECTURE aarch64-linux-gnu)
set(CMAKE_STRIP "/usr/bin/aarch64-linux-gnu-strip")
set(PKG_CONFIG_EXECUTABLE "${CMAKE_CURRENT_LIST_DIR}/aarch64-linux-gnu-pkg-config" CACHE STRING "Path to pkg-config")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)

10
CMake/platforms/debian-cross-pkg-config.sh

@ -14,11 +14,13 @@ if [ x"${PKG_CONFIG_LIBDIR+set}" = x ]; then
# Normalized multiarch path if any, e.g. i386-linux-gnu for i386
multiarch="`dpkg-architecture -t"${triplet}" -qDEB_HOST_MULTIARCH 2>/dev/null`"
# Native multiarch path
native_multiarch="$(cat /usr/lib/pkg-config.multiarch)"
if [ -f /usr/lib/pkg-config.multiarch ]; then
native_multiarch="$(cat /usr/lib/pkg-config.multiarch)"
# This can be used for native builds as well, in that case, just exec pkg-config "$@" directly.
if [ "$native_multiarch" = "$multiarch" ]; then
exec pkg-config "$@"
# This can be used for native builds as well, in that case, just exec pkg-config "$@" directly.
if [ "$native_multiarch" = "$multiarch" ]; then
exec pkg-config "$@"
fi
fi
PKG_CONFIG_LIBDIR="/usr/local/${triplet}/lib/pkgconfig"

5
CMakeLists.txt

@ -293,12 +293,9 @@ if(GPERF)
endif()
endif()
# Despite setting C++ standard to 20, features from this version are not being used.
# DevilutionX is compatible with C++ 17.
# Here we set it to 20 only to take advantage of the fmt::format build time errors.
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # for clang-tidy
set(CMAKE_THREAD_PREFER_PTHREAD ON)
set(THREADS_PREFER_PTHREAD_FLAG ON)

16
Packaging/nix/debian-cross-aarch64-prep.sh

@ -18,8 +18,18 @@ LIST
cat /etc/apt/sources.list
fi
PACKAGES=(
cmake git smpq gettext dpkg-cross libc-dev-arm64-cross
libsdl2-dev:arm64 libsdl2-image-dev:arm64 libsodium-dev:arm64
libsimpleini-dev:arm64 libpng-dev:arm64 libbz2-dev:arm64 libfmt-dev:arm64
)
if (( $# < 1 )) || [[ "$1" != --no-gcc ]]; then
PACKAGES+=(crossbuild-essential-arm64)
fi
sudo dpkg --add-architecture arm64
sudo apt-get update
sudo apt-get install -y cmake git smpq gettext crossbuild-essential-arm64 \
libsdl2-dev:arm64 libsdl2-image-dev:arm64 libsodium-dev:arm64 \
libsimpleini-dev:arm64 libpng-dev:arm64 libbz2-dev:arm64 libfmt-dev:arm64
sudo apt-get install -y "${PACKAGES[@]}"

16
Packaging/nix/debian-cross-i386-prep.sh

@ -2,9 +2,17 @@
set -euo pipefail
set -x
PACKAGES=(
cmake git smpq gettext
libsdl2-dev:i386 libsdl2-image-dev:i386 libsodium-dev:i386
libpng-dev:i386 libbz2-dev:i386 libfmt-dev:i386
)
if (( $# < 1 )) || [[ "$1" != --no-gcc ]]; then
PACKAGES+=(g++-multilib)
fi
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install --ignore-hold -y \
cmake g++-multilib git smpq gettext \
libsdl2-dev:i386 libsdl2-image-dev:i386 libsodium-dev:i386 \
libpng-dev:i386 libbz2-dev:i386 libfmt-dev:i386
sudo apt-get install --ignore-hold -y "${PACKAGES[@]}"

14
Packaging/nix/debian-host-prep.sh

@ -2,7 +2,15 @@
set -euo pipefail
set -x
sudo apt-get update
sudo apt-get install -y \
rpm pkg-config cmake g++ git smpq gettext libsdl2-dev libsdl2-image-dev libsodium-dev \
PACKAGES=(
rpm pkg-config cmake git smpq gettext libsdl2-dev libsdl2-image-dev libsodium-dev
libpng-dev libbz2-dev libfmt-dev
)
if (( $# < 1 )) || [[ "$1" != --no-gcc ]]; then
PACKAGES+=(g++)
fi
sudo apt-get update
sudo apt-get install -y "${PACKAGES[@]}"

43
Source/towners.cpp

@ -77,8 +77,7 @@ void InitSmith(Towner &towner, const TownerData &townerData)
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3
// clang-format on
};
towner.animOrder = AnimOrder;
towner.animOrderSize = sizeof(AnimOrder);
towner.animOrder = { AnimOrder };
LoadTownerAnimations(towner, "towners\\smith\\smithn", 16, 3);
towner.name = _("Griswold the Blacksmith");
towner.gossip = PickRandomlyAmong({ TEXT_GRISWOLD2, TEXT_GRISWOLD3, TEXT_GRISWOLD4, TEXT_GRISWOLD5, TEXT_GRISWOLD6, TEXT_GRISWOLD7, TEXT_GRISWOLD8, TEXT_GRISWOLD9, TEXT_GRISWOLD10, TEXT_GRISWOLD12, TEXT_GRISWOLD13 });
@ -100,8 +99,7 @@ void InitBarOwner(Towner &towner, const TownerData &townerData)
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
// clang-format on
};
towner.animOrder = AnimOrder;
towner.animOrderSize = sizeof(AnimOrder);
towner.animOrder = { AnimOrder };
LoadTownerAnimations(towner, "towners\\twnf\\twnfn", 16, 3);
towner.name = _("Ogden the Tavern owner");
towner.gossip = PickRandomlyAmong({ TEXT_OGDEN2, TEXT_OGDEN3, TEXT_OGDEN4, TEXT_OGDEN5, TEXT_OGDEN6, TEXT_OGDEN8, TEXT_OGDEN9, TEXT_OGDEN10 });
@ -110,8 +108,7 @@ void InitBarOwner(Towner &towner, const TownerData &townerData)
void InitTownDead(Towner &towner, const TownerData &townerData)
{
towner._tAnimWidth = 96;
towner.animOrder = nullptr;
towner.animOrderSize = 0;
towner.animOrder = {};
LoadTownerAnimations(towner, "towners\\butch\\deadguy", 8, 6);
towner.name = _("Wounded Townsman");
}
@ -132,8 +129,7 @@ void InitWitch(Towner &towner, const TownerData &townerData)
0, 1, 0, 18, 17, 18, 0, 1, 0, 1, 2
// clang-format on
};
towner.animOrder = AnimOrder;
towner.animOrderSize = sizeof(AnimOrder);
towner.animOrder = { AnimOrder };
LoadTownerAnimations(towner, "towners\\townwmn1\\witch", 19, 6);
towner.name = _("Adria the Witch");
towner.gossip = PickRandomlyAmong({ TEXT_ADRIA2, TEXT_ADRIA3, TEXT_ADRIA4, TEXT_ADRIA5, TEXT_ADRIA6, TEXT_ADRIA7, TEXT_ADRIA8, TEXT_ADRIA9, TEXT_ADRIA10, TEXT_ADRIA12, TEXT_ADRIA13 });
@ -142,8 +138,7 @@ void InitWitch(Towner &towner, const TownerData &townerData)
void InitBarmaid(Towner &towner, const TownerData &townerData)
{
towner._tAnimWidth = 96;
towner.animOrder = nullptr;
towner.animOrderSize = 0;
towner.animOrder = {};
LoadTownerAnimations(towner, "towners\\townwmn1\\wmnn", 18, 6);
towner.name = _("Gillian the Barmaid");
towner.gossip = PickRandomlyAmong({ TEXT_GILLIAN2, TEXT_GILLIAN3, TEXT_GILLIAN4, TEXT_GILLIAN5, TEXT_GILLIAN6, TEXT_GILLIAN7, TEXT_GILLIAN9, TEXT_GILLIAN10 });
@ -152,8 +147,7 @@ void InitBarmaid(Towner &towner, const TownerData &townerData)
void InitBoy(Towner &towner, const TownerData &townerData)
{
towner._tAnimWidth = 96;
towner.animOrder = nullptr;
towner.animOrderSize = 0;
towner.animOrder = {};
LoadTownerAnimations(towner, "towners\\townboy\\pegkid1", 20, 6);
towner.name = _("Wirt the Peg-legged boy");
towner.gossip = PickRandomlyAmong({ TEXT_WIRT2, TEXT_WIRT3, TEXT_WIRT4, TEXT_WIRT5, TEXT_WIRT6, TEXT_WIRT7, TEXT_WIRT8, TEXT_WIRT9, TEXT_WIRT11, TEXT_WIRT12 });
@ -175,8 +169,7 @@ void InitHealer(Towner &towner, const TownerData &townerData)
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19
// clang-format on
};
towner.animOrder = AnimOrder;
towner.animOrderSize = sizeof(AnimOrder);
towner.animOrder = { AnimOrder };
LoadTownerAnimations(towner, "towners\\healer\\healer", 20, 6);
towner.name = _("Pepin the Healer");
towner.gossip = PickRandomlyAmong({ TEXT_PEPIN2, TEXT_PEPIN3, TEXT_PEPIN4, TEXT_PEPIN5, TEXT_PEPIN6, TEXT_PEPIN7, TEXT_PEPIN9, TEXT_PEPIN10, TEXT_PEPIN11 });
@ -193,8 +186,7 @@ void InitTeller(Towner &towner, const TownerData &townerData)
13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
// clang-format on
};
towner.animOrder = AnimOrder;
towner.animOrderSize = sizeof(AnimOrder);
towner.animOrder = { AnimOrder };
LoadTownerAnimations(towner, "towners\\strytell\\strytell", 25, 3);
towner.name = _("Cain the Elder");
towner.gossip = PickRandomlyAmong({ TEXT_STORY2, TEXT_STORY3, TEXT_STORY4, TEXT_STORY5, TEXT_STORY6, TEXT_STORY7, TEXT_STORY9, TEXT_STORY10, TEXT_STORY11 });
@ -210,8 +202,7 @@ void InitDrunk(Towner &towner, const TownerData &townerData)
0, 1, 2, 3, 4, 4, 4, 3, 2, 1
// clang-format on
};
towner.animOrder = AnimOrder;
towner.animOrderSize = sizeof(AnimOrder);
towner.animOrder = { AnimOrder };
LoadTownerAnimations(towner, "towners\\drunk\\twndrunk", 18, 3);
towner.name = _("Farnham the Drunk");
towner.gossip = PickRandomlyAmong({ TEXT_FARNHAM2, TEXT_FARNHAM3, TEXT_FARNHAM4, TEXT_FARNHAM5, TEXT_FARNHAM6, TEXT_FARNHAM8, TEXT_FARNHAM9, TEXT_FARNHAM10, TEXT_FARNHAM11, TEXT_FARNHAM12, TEXT_FARNHAM13 });
@ -220,8 +211,7 @@ void InitDrunk(Towner &towner, const TownerData &townerData)
void InitCows(Towner &towner, const TownerData &townerData)
{
towner._tAnimWidth = 128;
towner.animOrder = nullptr;
towner.animOrderSize = 0;
towner.animOrder = {};
NewTownerAnim(towner, (*CowSprites)[static_cast<size_t>(townerData.dir)], 12, 3);
towner._tAnimFrame = GenerateRnd(11);
@ -246,8 +236,7 @@ void InitCows(Towner &towner, const TownerData &townerData)
void InitFarmer(Towner &towner, const TownerData &townerData)
{
towner._tAnimWidth = 96;
towner.animOrder = nullptr;
towner.animOrderSize = 0;
towner.animOrder = {};
LoadTownerAnimations(towner, "towners\\farmer\\farmrn2", 15, 3);
towner.name = _("Lester the farmer");
}
@ -259,8 +248,7 @@ void InitCowFarmer(Towner &towner, const TownerData &townerData)
celPath = "towners\\farmer\\mfrmrn2";
}
towner._tAnimWidth = 96;
towner.animOrder = nullptr;
towner.animOrderSize = 0;
towner.animOrder = {};
LoadTownerAnimations(towner, celPath, 15, 3);
towner.name = _("Complete Nut");
}
@ -268,8 +256,7 @@ void InitCowFarmer(Towner &towner, const TownerData &townerData)
void InitGirl(Towner &towner, const TownerData &townerData)
{
towner._tAnimWidth = 96;
towner.animOrder = nullptr;
towner.animOrderSize = 0;
towner.animOrder = {};
LoadTownerAnimations(towner, "towners\\girl\\girlw1", 20, 6);
towner.name = _("Celia");
}
@ -887,9 +874,9 @@ void ProcessTowners()
towner._tAnimCnt = 0;
if (towner.animOrderSize > 0) {
if (!towner.animOrder.empty()) {
towner._tAnimFrameCnt++;
if (towner._tAnimFrameCnt > towner.animOrderSize - 1)
if (towner._tAnimFrameCnt > towner.animOrder.size() - 1)
towner._tAnimFrameCnt = 0;
towner._tAnimFrame = towner.animOrder[towner._tAnimFrameCnt];

4
Source/towners.h

@ -8,6 +8,7 @@
#include <cstddef>
#include <cstdint>
#include <memory>
#include <span>
#include <string_view>
#include "items.h"
@ -39,7 +40,7 @@ struct Towner {
OptionalOwnedClxSpriteList ownedAnim;
OptionalClxSpriteList anim;
/** Specifies the animation frame sequence. */
const uint8_t *animOrder; // unowned
std::span<const uint8_t> animOrder;
void (*talk)(Player &player, Towner &towner);
std::string_view name;
@ -58,7 +59,6 @@ struct Towner {
/** Current frame of animation. */
uint8_t _tAnimFrame;
uint8_t _tAnimFrameCnt;
uint8_t animOrderSize;
_talker_id _ttype;
[[nodiscard]] ClxSprite currentSprite() const

Loading…
Cancel
Save