Skip to content

Commit

Permalink
Core: Support c++20 compilation
Browse files Browse the repository at this point in the history
• Technically c++23 as well, albeit to a *much* lesser extent because it's not officially released
  • Loading branch information
Repiteo committed Oct 22, 2024
1 parent b3bcb2d commit 90c5451
Show file tree
Hide file tree
Showing 86 changed files with 345 additions and 398 deletions.
2 changes: 1 addition & 1 deletion .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ SpacesInLineCommentPrefix:
# InEmptyParentheses: false
# Other: false
# SpacesInSquareBrackets: false
Standard: c++17
Standard: c++20
# StatementAttributeLikeMacros:
# - Q_EMIT
# StatementMacros:
Expand Down
14 changes: 13 additions & 1 deletion .github/workflows/linux_builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ concurrency:

jobs:
build-linux:
runs-on: ubuntu-20.04
runs-on: ${{ matrix.os || 'ubuntu-20.04' }}
name: ${{ matrix.name }}
strategy:
fail-fast: false
Expand Down Expand Up @@ -71,6 +71,18 @@ jobs:
# Skip 2GiB artifact speeding up action.
artifact: false

- name: Editor with C++20 (target=editor, tests=yes, dev_build=yes, cpp_standard=20)
cache-name: linux-editor-cpp20
target: editor
tests: true
sconsflags: dev_build=yes cpp_standard=20
bin: ./bin/godot.linuxbsd.editor.dev.x86_64
build-mono: false
# Skip 2GiB artifact speeding up action.
artifact: false
# Ensure a later version of Ubuntu for full C++20 support.
os: ubuntu-24.04

- name: Template w/ Mono (target=template_release, tests=yes)
cache-name: linux-template-mono
target: template_release
Expand Down
61 changes: 51 additions & 10 deletions SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ opts.Add(BoolVariable("debug_paths_relative", "Make file paths in debug symbols
opts.Add(EnumVariable("lto", "Link-time optimization (production builds)", "none", ("none", "auto", "thin", "full")))
opts.Add(BoolVariable("production", "Set defaults to build Godot for use in production", False))
opts.Add(BoolVariable("threads", "Enable threading support", True))
opts.Add(EnumVariable("cpp_standard", "Set the C++ standard (Experimental)", "17", ("17", "20", "23")))

# Components
opts.Add(BoolVariable("deprecated", "Enable compatibility code for deprecated and removed features", True))
Expand Down Expand Up @@ -643,14 +644,28 @@ cc_version = methods.get_compiler_version(env)
cc_version_major = cc_version["major"]
cc_version_minor = cc_version["minor"]
cc_version_metadata1 = cc_version["metadata1"]
cpp_std = int(env["cpp_standard"])

if cc_version_major == -1:
print_warning(
"Couldn't detect compiler version, skipping version checks. "
"Build may fail if the compiler doesn't support C++17 fully."
f"Build may fail if the compiler doesn't support C++{cpp_std} fully."
)
elif cpp_std == 23:
print_warning(
"Using an experimental C++ standard, skipping version checks. "
"Build may fail if the compiler doesn't support the latest C++ fully."
)
elif methods.using_gcc(env):
if cc_version_major < 9:
if cpp_std == 20 and cc_version_major < 12:
print_error(
"Detected GCC version older than 12, which does not fully support "
"C++20. Supported versions are GCC 12 and later. Use a newer GCC "
'version, or Clang 17 or later by passing "use_llvm=yes" to the '
"SCons command line."
)
Exit(255)
elif cpp_std == 17 and cc_version_major < 9:
print_error(
"Detected GCC version older than 9, which does not fully support "
"C++17, or has bugs when compiling Godot. Supported versions are 9 "
Expand All @@ -674,13 +689,27 @@ elif methods.using_clang(env):
# in https://en.wikipedia.org/wiki/Xcode#Toolchain_versions
if env["platform"] == "macos" or env["platform"] == "ios":
vanilla = methods.is_vanilla_clang(env)
if vanilla and cc_version_major < 6:
if cpp_std == 20 and vanilla and cc_version_major < 17:
print_error(
"Detected Clang version older than 17, which does not fully support "
"C++20. Supported versions are Clang 17 and later."
)
Exit(255)
# XCode started defaulting to c++20 in XCode 14, despite their equivalent Clang
# being 14. Assume 14 as the "minimum" version, but full support is uncertain.
elif cpp_std == 20 and not vanilla and cc_version_major < 14:
print_error(
"Detected Apple Clang version older than 14, which does not fully "
'support C++20. "Supported" versions are Apple Clang 14 and later.'
)
Exit(255)
elif cpp_std == 17 and vanilla and cc_version_major < 6:
print_error(
"Detected Clang version older than 6, which does not fully support "
"C++17. Supported versions are Clang 6 and later."
)
Exit(255)
elif not vanilla and cc_version_major < 10:
elif cpp_std == 17 and not vanilla and cc_version_major < 10:
print_error(
"Detected Apple Clang version older than 10, which does not fully "
"support C++17. Supported versions are Apple Clang 10 and later."
Expand All @@ -691,7 +720,13 @@ elif methods.using_clang(env):
"Apple Clang < 12 doesn't support -ffile-prefix-map, disabling `debug_paths_relative` option."
)
env["debug_paths_relative"] = False
elif cc_version_major < 6:
elif cpp_std == 20 and cc_version_major < 17:
print_error(
"Detected Clang version older than 17, which does not fully support "
"C++20. Supported versions are Clang 17 and later."
)
Exit(255)
elif cpp_std == 17 and cc_version_major < 6:
print_error(
"Detected Clang version older than 6, which does not fully support "
"C++17. Supported versions are Clang 6 and later."
Expand All @@ -703,19 +738,25 @@ elif methods.using_clang(env):
elif env.msvc:
# Ensure latest minor builds of Visual Studio 2017/2019.
# https://github.com/godotengine/godot/pull/94995#issuecomment-2336464574
if cc_version_major == 16 and cc_version_minor < 11:
if cpp_std == 20 and cc_version_major < 16:
print_error(
"Detected Visual Studio version older than 2019, which does not fully "
"support C++20. Supported versions are Visual Studio 2019 and later."
)
Exit(255)
elif cc_version_major == 16 and cc_version_minor < 11:
print_error(
"Detected Visual Studio 2019 version older than 16.11, which has bugs "
"when compiling Godot. Use a newer VS2019 version, or VS2022."
)
Exit(255)
if cc_version_major == 15 and cc_version_minor < 9:
elif cc_version_major == 15 and cc_version_minor < 9:
print_error(
"Detected Visual Studio 2017 version older than 15.9, which has bugs "
"when compiling Godot. Use a newer VS2017 version, or VS2019/VS2022."
)
Exit(255)
if cc_version_major < 15:
elif cc_version_major < 15:
print_error(
"Detected Visual Studio 2015 or earlier, which is unsupported in Godot. "
"Supported versions are Visual Studio 2017 and later."
Expand Down Expand Up @@ -801,11 +842,11 @@ if not env.msvc:
# Specifying GNU extensions support explicitly, which are supported by
# both GCC and Clang. Both currently default to gnu17 and gnu++17.
env.Prepend(CFLAGS=["-std=gnu17"])
env.Prepend(CXXFLAGS=["-std=gnu++17"])
env.Prepend(CXXFLAGS=[f"-std=gnu++{cpp_std if cpp_std <= 20 else '2b'}"])
else:
# MSVC started offering C standard support with Visual Studio 2019 16.8, which covers all
# of our supported VS2019 & VS2022 versions; VS2017 will only pass the C++ standard.
env.Prepend(CXXFLAGS=["/std:c++17"])
env.Prepend(CXXFLAGS=[f"/std:c++{cpp_std if cpp_std <= 20 else 'latest'}"])
if cc_version_major < 16:
print_warning("Visual Studio 2017 cannot specify a C-Standard.")
else:
Expand Down
4 changes: 2 additions & 2 deletions core/io/image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -873,7 +873,7 @@ static void _scale_bilinear(const uint8_t *__restrict p_src, uint8_t *__restrict

for (uint32_t i = 0; i < p_dst_height; i++) {
// Add 0.5 in order to interpolate based on pixel center
uint32_t src_yofs_up_fp = (i + 0.5) * p_src_height * FRAC_LEN / p_dst_height;
uint32_t src_yofs_up_fp = (i + 0.5) * p_src_height * (int)FRAC_LEN / p_dst_height;
// Calculate nearest src pixel center above current, and truncate to get y index
uint32_t src_yofs_up = src_yofs_up_fp >= FRAC_HALF ? (src_yofs_up_fp - FRAC_HALF) >> FRAC_BITS : 0;
uint32_t src_yofs_down = (src_yofs_up_fp + FRAC_HALF) >> FRAC_BITS;
Expand All @@ -888,7 +888,7 @@ static void _scale_bilinear(const uint8_t *__restrict p_src, uint8_t *__restrict
uint32_t y_ofs_down = src_yofs_down * p_src_width * CC;

for (uint32_t j = 0; j < p_dst_width; j++) {
uint32_t src_xofs_left_fp = (j + 0.5) * p_src_width * FRAC_LEN / p_dst_width;
uint32_t src_xofs_left_fp = (j + 0.5) * p_src_width * (int)FRAC_LEN / p_dst_width;
uint32_t src_xofs_left = src_xofs_left_fp >= FRAC_HALF ? (src_xofs_left_fp - FRAC_HALF) >> FRAC_BITS : 0;
uint32_t src_xofs_right = (src_xofs_left_fp + FRAC_HALF) >> FRAC_BITS;
if (src_xofs_right >= p_src_width) {
Expand Down
17 changes: 3 additions & 14 deletions core/io/ip_address.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,21 +64,10 @@ struct IPAddress {
}
return true;
}
INEQUALITY_OPERATOR(const IPAddress &)

bool operator!=(const IPAddress &p_ip) const {
if (p_ip.valid != valid) {
return true;
}
if (!valid) {
return true;
}
for (int i = 0; i < 4; i++) {
if (field32[i] != p_ip.field32[i]) {
return true;
}
}
return false;
}
bool operator==(const String &p_ip) const { return operator==(IPAddress(p_ip)); }
INEQUALITY_OPERATOR(const String &)

void clear();
bool is_wildcard() const { return wildcard; }
Expand Down
4 changes: 0 additions & 4 deletions core/math/aabb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,6 @@ bool AABB::operator==(const AABB &p_rval) const {
return ((position == p_rval.position) && (size == p_rval.size));
}

bool AABB::operator!=(const AABB &p_rval) const {
return ((position != p_rval.position) || (size != p_rval.size));
}

void AABB::merge_with(const AABB &p_aabb) {
#ifdef MATH_CHECKS
if (unlikely(size.x < 0 || size.y < 0 || size.z < 0 || p_aabb.size.x < 0 || p_aabb.size.y < 0 || p_aabb.size.z < 0)) {
Expand Down
2 changes: 1 addition & 1 deletion core/math/aabb.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ struct [[nodiscard]] AABB {
void set_size(const Vector3 &p_size) { size = p_size; }

bool operator==(const AABB &p_rval) const;
bool operator!=(const AABB &p_rval) const;
INEQUALITY_OPERATOR(const AABB &)

bool is_equal_approx(const AABB &p_aabb) const;
bool is_finite() const;
Expand Down
2 changes: 1 addition & 1 deletion core/math/audio_frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
#include "core/math/vector2.h"
#include "core/typedefs.h"

static inline float undenormalize(volatile float f) {
static inline float undenormalize(float f) {
union {
uint32_t i;
float f;
Expand Down
4 changes: 0 additions & 4 deletions core/math/basis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -710,10 +710,6 @@ bool Basis::operator==(const Basis &p_matrix) const {
return true;
}

bool Basis::operator!=(const Basis &p_matrix) const {
return (!(*this == p_matrix));
}

Basis::operator String() const {
return "[X: " + get_column(0).operator String() +
", Y: " + get_column(1).operator String() +
Expand Down
2 changes: 1 addition & 1 deletion core/math/basis.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ struct [[nodiscard]] Basis {
bool is_finite() const;

bool operator==(const Basis &p_matrix) const;
bool operator!=(const Basis &p_matrix) const;
INEQUALITY_OPERATOR(const Basis &)

_FORCE_INLINE_ Vector3 xform(const Vector3 &p_vector) const;
_FORCE_INLINE_ Vector3 xform_inv(const Vector3 &p_vector) const;
Expand Down
2 changes: 1 addition & 1 deletion core/math/bvh_abb.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ struct BVH_ABB {
POINT neg_max;

bool operator==(const BVH_ABB &o) const { return (min == o.min) && (neg_max == o.neg_max); }
bool operator!=(const BVH_ABB &o) const { return (*this == o) == false; }
INEQUALITY_OPERATOR(const BVH_ABB &)

void set(const POINT &_min, const POINT &_max) {
min = _min;
Expand Down
2 changes: 1 addition & 1 deletion core/math/bvh_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ struct BVHHandle {
void set_id(uint32_t p_id) { _data = p_id; }

bool operator==(const BVHHandle &p_h) const { return _data == p_h._data; }
bool operator!=(const BVHHandle &p_h) const { return (*this == p_h) == false; }
INEQUALITY_OPERATOR(const BVHHandle &)
};

// helper class to make iterative versions of recursive functions
Expand Down
4 changes: 1 addition & 3 deletions core/math/color.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,7 @@ struct [[nodiscard]] Color {
bool operator==(const Color &p_color) const {
return (r == p_color.r && g == p_color.g && b == p_color.b && a == p_color.a);
}
bool operator!=(const Color &p_color) const {
return (r != p_color.r || g != p_color.g || b != p_color.b || a != p_color.a);
}
INEQUALITY_OPERATOR(const Color &)

Color operator+(const Color &p_color) const;
void operator+=(const Color &p_color);
Expand Down
5 changes: 2 additions & 3 deletions core/math/convex_hull.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
* - adapted to Godot's code style
* - replaced Bullet's types (e.g. vectors) with Godot's
* - replaced custom Pool implementation with PagedAllocator
* - replaced Point32's inequality operator with macro
*/

/*
Expand Down Expand Up @@ -139,9 +140,7 @@ class ConvexHullInternal {
return (x == b.x) && (y == b.y) && (z == b.z);
}

bool operator!=(const Point32 &b) const {
return (x != b.x) || (y != b.y) || (z != b.z);
}
INEQUALITY_OPERATOR(const Point32 &)

bool is_zero() {
return (x == 0) && (y == 0) && (z == 0);
Expand Down
6 changes: 1 addition & 5 deletions core/math/plane.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ struct [[nodiscard]] Plane {
bool is_finite() const;

_FORCE_INLINE_ bool operator==(const Plane &p_plane) const;
_FORCE_INLINE_ bool operator!=(const Plane &p_plane) const;
INEQUALITY_OPERATOR(const Plane &)
operator String() const;

_FORCE_INLINE_ Plane() {}
Expand Down Expand Up @@ -129,8 +129,4 @@ bool Plane::operator==(const Plane &p_plane) const {
return normal == p_plane.normal && d == p_plane.d;
}

bool Plane::operator!=(const Plane &p_plane) const {
return normal != p_plane.normal || d != p_plane.d;
}

#endif // PLANE_H
5 changes: 1 addition & 4 deletions core/math/projection.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,7 @@ struct [[nodiscard]] Projection {
}
return true;
}

bool operator!=(const Projection &p_cam) const {
return !(*this == p_cam);
}
INEQUALITY_OPERATOR(const Projection &)

real_t get_lod_multiplier() const;

Expand Down
6 changes: 1 addition & 5 deletions core/math/quaternion.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ struct [[nodiscard]] Quaternion {
_FORCE_INLINE_ Quaternion operator/(real_t p_s) const;

_FORCE_INLINE_ bool operator==(const Quaternion &p_quaternion) const;
_FORCE_INLINE_ bool operator!=(const Quaternion &p_quaternion) const;
INEQUALITY_OPERATOR(const Quaternion &)

operator String() const;

Expand Down Expand Up @@ -221,10 +221,6 @@ bool Quaternion::operator==(const Quaternion &p_quaternion) const {
return x == p_quaternion.x && y == p_quaternion.y && z == p_quaternion.z && w == p_quaternion.w;
}

bool Quaternion::operator!=(const Quaternion &p_quaternion) const {
return x != p_quaternion.x || y != p_quaternion.y || z != p_quaternion.z || w != p_quaternion.w;
}

_FORCE_INLINE_ Quaternion operator*(real_t p_real, const Quaternion &p_quaternion) {
return p_quaternion * p_real;
}
Expand Down
4 changes: 4 additions & 0 deletions core/math/rect2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ bool Rect2::is_finite() const {
return position.is_finite() && size.is_finite();
}

bool Rect2::operator==(const Rect2i &p_rect) const {
return position == p_rect.get_position() && size == p_rect.get_position();
}

bool Rect2::intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2 *r_pos, Point2 *r_normal) const {
#ifdef MATH_CHECKS
if (unlikely(size.x < 0 || size.y < 0)) {
Expand Down
4 changes: 3 additions & 1 deletion core/math/rect2.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,9 @@ struct [[nodiscard]] Rect2 {
bool is_finite() const;

bool operator==(const Rect2 &p_rect) const { return position == p_rect.position && size == p_rect.size; }
bool operator!=(const Rect2 &p_rect) const { return position != p_rect.position || size != p_rect.size; }
INEQUALITY_OPERATOR(const Rect2 &)
bool operator==(const Rect2i &p_rect) const;
INEQUALITY_OPERATOR(const Rect2i &)

inline Rect2 grow(real_t p_amount) const {
Rect2 g = *this;
Expand Down
2 changes: 1 addition & 1 deletion core/math/rect2i.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ struct [[nodiscard]] Rect2i {
}

bool operator==(const Rect2i &p_rect) const { return position == p_rect.position && size == p_rect.size; }
bool operator!=(const Rect2i &p_rect) const { return position != p_rect.position || size != p_rect.size; }
INEQUALITY_OPERATOR(const Rect2i &)

Rect2i grow(int p_amount) const {
Rect2i g = *this;
Expand Down
Loading

0 comments on commit 90c5451

Please sign in to comment.