From e8b6887b3679a6e817834f7eb057aeca425dda55 Mon Sep 17 00:00:00 2001
From: Thaddeus Crews <repiteo@outlook.com>
Date: Sat, 4 Nov 2023 16:53:09 -0500
Subject: [PATCH 01/17] =?UTF-8?q?Add=20missing=20int=E2=86=92Variant=20con?=
 =?UTF-8?q?versions?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

(cherry picked from commit bcac96c8c272d9d4c60fb781974e80db1cb19527)
---
 include/godot_cpp/variant/variant.hpp | 14 +++++++++++++-
 src/variant/variant.cpp               | 16 ++++++++++++++++
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/include/godot_cpp/variant/variant.hpp b/include/godot_cpp/variant/variant.hpp
index 0a2b3d140..575c224ec 100644
--- a/include/godot_cpp/variant/variant.hpp
+++ b/include/godot_cpp/variant/variant.hpp
@@ -154,10 +154,18 @@ class Variant {
 	Variant(int64_t v);
 	Variant(int32_t v) :
 			Variant(static_cast<int64_t>(v)) {}
-	Variant(uint32_t v) :
+	Variant(int16_t v) :
+			Variant(static_cast<int64_t>(v)) {}
+	Variant(int8_t v) :
 			Variant(static_cast<int64_t>(v)) {}
 	Variant(uint64_t v) :
 			Variant(static_cast<int64_t>(v)) {}
+	Variant(uint32_t v) :
+			Variant(static_cast<int64_t>(v)) {}
+	Variant(uint16_t v) :
+			Variant(static_cast<int64_t>(v)) {}
+	Variant(uint8_t v) :
+			Variant(static_cast<int64_t>(v)) {}
 	Variant(double v);
 	Variant(float v) :
 			Variant((double)v) {}
@@ -209,8 +217,12 @@ class Variant {
 	operator bool() const;
 	operator int64_t() const;
 	operator int32_t() const;
+	operator int16_t() const;
+	operator int8_t() const;
 	operator uint64_t() const;
 	operator uint32_t() const;
+	operator uint16_t() const;
+	operator uint8_t() const;
 	operator double() const;
 	operator float() const;
 	operator String() const;
diff --git a/src/variant/variant.cpp b/src/variant/variant.cpp
index db15be119..945d6f406 100644
--- a/src/variant/variant.cpp
+++ b/src/variant/variant.cpp
@@ -268,6 +268,14 @@ Variant::operator int32_t() const {
 	return static_cast<int32_t>(operator int64_t());
 }
 
+Variant::operator int16_t() const {
+	return static_cast<int16_t>(operator int64_t());
+}
+
+Variant::operator int8_t() const {
+	return static_cast<int8_t>(operator int64_t());
+}
+
 Variant::operator uint64_t() const {
 	return static_cast<uint64_t>(operator int64_t());
 }
@@ -276,6 +284,14 @@ Variant::operator uint32_t() const {
 	return static_cast<uint32_t>(operator int64_t());
 }
 
+Variant::operator uint16_t() const {
+	return static_cast<uint16_t>(operator int64_t());
+}
+
+Variant::operator uint8_t() const {
+	return static_cast<uint8_t>(operator int64_t());
+}
+
 Variant::operator double() const {
 	double result;
 	to_type_constructor[FLOAT](&result, _native_ptr());

From 92449b46e1a27e7dd197dc1854daaad560cc8b6f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= <rverschelde@gmail.com>
Date: Mon, 20 Nov 2023 23:23:17 +0100
Subject: [PATCH 02/17] CI: Install Android NDK r23c explicitly

It has just been removed from the Ubuntu 20.04 default install,
breaking our CI setup.

Also, sets Emscripten version to 3.1.39, as done upstream.
Newer versions actually break dynamic library support.

(cherry picked from commit eea33b413361ef023cddfaa03d9f5acb60538006)
---
 .github/workflows/ci.yml | 23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 0ee04d908..c9560e9c3 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -65,7 +65,7 @@ jobs:
             platform: android
             artifact-name: godot-cpp-android-arm64-release
             artifact-path: bin/libgodot-cpp.android.template_release.arm64.a
-            flags: ANDROID_NDK_ROOT=$ANDROID_NDK_LATEST_HOME arch=arm64
+            flags: arch=arm64
             run-tests: false
             cache-name: android-arm64
 
@@ -88,7 +88,7 @@ jobs:
 
     env:
       SCONS_CACHE: ${{ github.workspace }}/.scons-cache/
-      EM_VERSION: 3.1.45
+      EM_VERSION: 3.1.39
       EM_CACHE_FOLDER: "emsdk-cache"
 
     steps:
@@ -108,11 +108,12 @@ jobs:
         with:
           python-version: '3.x'
 
-      - name: Linux dependencies
-        if: ${{ matrix.platform == 'linux' }}
-        run: |
-          sudo apt-get update -qq
-          sudo apt-get install -qqq build-essential pkg-config
+      - name: Android dependencies
+        if: ${{ matrix.platform == 'android' }}
+        uses: nttld/setup-ndk@v1
+        with:
+          ndk-version: r23c
+          link-to-sdk: true
 
       - name: Web dependencies
         if: ${{ matrix.platform == 'web' }}
@@ -121,16 +122,16 @@ jobs:
           version: ${{env.EM_VERSION}}
           actions-cache-folder: ${{env.EM_CACHE_FOLDER}}
 
-      - name: Install scons
-        run: |
-          python -m pip install scons==4.0.0
-
       - name: Setup MinGW for Windows/MinGW build
         if: ${{ matrix.platform == 'windows' && matrix.flags == 'use_mingw=yes' }}
         uses: egor-tensin/setup-mingw@v2
         with:
           version: 12.2.0
 
+      - name: Install scons
+        run: |
+          python -m pip install scons==4.0.0
+
       - name: Generate godot-cpp sources only
         run: |
           scons platform=${{ matrix.platform }} build_library=no ${{ matrix.flags }}

From b622b11df3bc6ee96f9a99e74ae38f96889d91b3 Mon Sep 17 00:00:00 2001
From: bruvzg <7645683+bruvzg@users.noreply.github.com>
Date: Wed, 22 Nov 2023 14:14:41 +0200
Subject: [PATCH 03/17] [iOS] Fix initialisation/termination of multiple
 statically linked extensions.

(cherry picked from commit adc9def046b1f871d58163adc959e78db131324a)
---
 include/godot_cpp/godot.hpp | 32 ++++++++++---
 src/godot.cpp               | 90 ++++++++++++++++++++++++++++---------
 2 files changed, 95 insertions(+), 27 deletions(-)

diff --git a/include/godot_cpp/godot.hpp b/include/godot_cpp/godot.hpp
index 1478403b2..0b7dd4a83 100644
--- a/include/godot_cpp/godot.hpp
+++ b/include/godot_cpp/godot.hpp
@@ -187,26 +187,44 @@ enum ModuleInitializationLevel {
 	MODULE_INITIALIZATION_LEVEL_CORE = GDEXTENSION_INITIALIZATION_CORE,
 	MODULE_INITIALIZATION_LEVEL_SERVERS = GDEXTENSION_INITIALIZATION_SERVERS,
 	MODULE_INITIALIZATION_LEVEL_SCENE = GDEXTENSION_INITIALIZATION_SCENE,
-	MODULE_INITIALIZATION_LEVEL_EDITOR = GDEXTENSION_INITIALIZATION_EDITOR
+	MODULE_INITIALIZATION_LEVEL_EDITOR = GDEXTENSION_INITIALIZATION_EDITOR,
+	MODULE_INITIALIZATION_LEVEL_MAX
 };
 
 class GDExtensionBinding {
 public:
 	using Callback = void (*)(ModuleInitializationLevel p_level);
 
-	static Callback init_callback;
-	static Callback terminate_callback;
-	static GDExtensionInitializationLevel minimum_initialization_level;
-	static GDExtensionBool init(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization);
+	struct InitData {
+		GDExtensionInitializationLevel minimum_initialization_level = GDEXTENSION_INITIALIZATION_CORE;
+		Callback init_callback = nullptr;
+		Callback terminate_callback = nullptr;
+	};
+
+	class InitDataList {
+		int data_count = 0;
+		int data_capacity = 0;
+		InitData **data = nullptr;
+
+	public:
+		void add(InitData *p_cb);
+		~InitDataList();
+	};
+
+	static bool api_initialized;
+	static int level_initialized[MODULE_INITIALIZATION_LEVEL_MAX];
+	static InitDataList initdata;
+	static GDExtensionBool init(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, InitData *p_init_data, GDExtensionInitialization *r_initialization);
 
 public:
-	static void initialize_level(void *userdata, GDExtensionInitializationLevel p_level);
-	static void deinitialize_level(void *userdata, GDExtensionInitializationLevel p_level);
+	static void initialize_level(void *p_userdata, GDExtensionInitializationLevel p_level);
+	static void deinitialize_level(void *p_userdata, GDExtensionInitializationLevel p_level);
 
 	class InitObject {
 		GDExtensionInterfaceGetProcAddress get_proc_address;
 		GDExtensionClassLibraryPtr library;
 		GDExtensionInitialization *initialization;
+		mutable InitData *init_data = nullptr;
 
 	public:
 		InitObject(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization);
diff --git a/src/godot.cpp b/src/godot.cpp
index 14214c0d2..b40049f9c 100644
--- a/src/godot.cpp
+++ b/src/godot.cpp
@@ -189,9 +189,9 @@ GDExtensionInterfaceEditorRemovePlugin gdextension_interface_editor_remove_plugi
 
 } // namespace internal
 
-GDExtensionBinding::Callback GDExtensionBinding::init_callback = nullptr;
-GDExtensionBinding::Callback GDExtensionBinding::terminate_callback = nullptr;
-GDExtensionInitializationLevel GDExtensionBinding::minimum_initialization_level = GDEXTENSION_INITIALIZATION_CORE;
+bool GDExtensionBinding::api_initialized = false;
+int GDExtensionBinding::level_initialized[MODULE_INITIALIZATION_LEVEL_MAX] = { 0 };
+GDExtensionBinding::InitDataList GDExtensionBinding::initdata;
 
 #define ERR_PRINT_EARLY(m_msg) \
 	internal::gdextension_interface_print_error(m_msg, FUNCTION_STR, __FILE__, __LINE__, false)
@@ -218,7 +218,20 @@ typedef struct {
 	GDExtensionInterfacePrintErrorWithMessage print_error_with_message;
 } LegacyGDExtensionInterface;
 
-GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) {
+GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, InitData *p_init_data, GDExtensionInitialization *r_initialization) {
+	if (!p_init_data || !p_init_data->init_callback) {
+		ERR_FAIL_V_MSG(false, "Initialization callback must be defined.");
+	}
+
+	if (api_initialized) {
+		r_initialization->initialize = initialize_level;
+		r_initialization->deinitialize = deinitialize_level;
+		r_initialization->userdata = p_init_data;
+		r_initialization->minimum_initialization_level = p_init_data->minimum_initialization_level;
+
+		return true;
+	}
+
 	// Make sure we weren't passed the legacy struct.
 	uint32_t *raw_interface = (uint32_t *)(void *)p_get_proc_address;
 	if (raw_interface[0] == 4 && raw_interface[1] == 0) {
@@ -401,59 +414,96 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
 
 	r_initialization->initialize = initialize_level;
 	r_initialization->deinitialize = deinitialize_level;
-	r_initialization->minimum_initialization_level = minimum_initialization_level;
-
-	ERR_FAIL_NULL_V_MSG(init_callback, false, "Initialization callback must be defined.");
+	r_initialization->userdata = p_init_data;
+	r_initialization->minimum_initialization_level = p_init_data->minimum_initialization_level;
 
 	Variant::init_bindings();
 	godot::internal::register_engine_classes();
 
+	api_initialized = true;
 	return true;
 }
 
 #undef LOAD_PROC_ADDRESS
 #undef ERR_PRINT_EARLY
 
-void GDExtensionBinding::initialize_level(void *userdata, GDExtensionInitializationLevel p_level) {
+void GDExtensionBinding::initialize_level(void *p_userdata, GDExtensionInitializationLevel p_level) {
+	ERR_FAIL_COND(static_cast<ModuleInitializationLevel>(p_level) >= MODULE_INITIALIZATION_LEVEL_MAX);
 	ClassDB::current_level = p_level;
 
-	if (init_callback) {
-		init_callback(static_cast<ModuleInitializationLevel>(p_level));
+	InitData *init_data = static_cast<InitData *>(p_userdata);
+	if (init_data && init_data->init_callback) {
+		init_data->init_callback(static_cast<ModuleInitializationLevel>(p_level));
 	}
 
-	ClassDB::initialize(p_level);
+	if (level_initialized[p_level] == 0) {
+		ClassDB::initialize(p_level);
+	}
+	level_initialized[p_level]++;
 }
 
-void GDExtensionBinding::deinitialize_level(void *userdata, GDExtensionInitializationLevel p_level) {
+void GDExtensionBinding::deinitialize_level(void *p_userdata, GDExtensionInitializationLevel p_level) {
+	ERR_FAIL_COND(static_cast<ModuleInitializationLevel>(p_level) >= MODULE_INITIALIZATION_LEVEL_MAX);
 	ClassDB::current_level = p_level;
 
-	if (terminate_callback) {
-		terminate_callback(static_cast<ModuleInitializationLevel>(p_level));
+	InitData *init_data = static_cast<InitData *>(p_userdata);
+	if (init_data && init_data->terminate_callback) {
+		init_data->terminate_callback(static_cast<ModuleInitializationLevel>(p_level));
+	}
+
+	level_initialized[p_level]--;
+	if (level_initialized[p_level] == 0) {
+		EditorPlugins::deinitialize(p_level);
+		ClassDB::deinitialize(p_level);
+	}
+}
+
+void GDExtensionBinding::InitDataList::add(InitData *p_data) {
+	if (data_count == data_capacity) {
+		void *new_ptr = realloc(data, sizeof(InitData *) * (data_capacity + 32));
+		if (new_ptr) {
+			data = (InitData **)(new_ptr);
+			data_capacity += 32;
+		} else {
+			ERR_FAIL_MSG("Unable to allocate memory for extension callbacks.");
+		}
 	}
+	data[data_count++] = p_data;
+}
 
-	EditorPlugins::deinitialize(p_level);
-	ClassDB::deinitialize(p_level);
+GDExtensionBinding::InitDataList::~InitDataList() {
+	for (int i = 0; i < data_count; i++) {
+		if (data[i]) {
+			delete data[i];
+		}
+	}
+	if (data) {
+		free(data);
+	}
 }
+
 GDExtensionBinding::InitObject::InitObject(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) {
 	get_proc_address = p_get_proc_address;
 	library = p_library;
 	initialization = r_initialization;
+	init_data = new InitData();
+	GDExtensionBinding::initdata.add(init_data);
 }
 
 void GDExtensionBinding::InitObject::register_initializer(Callback p_init) const {
-	GDExtensionBinding::init_callback = p_init;
+	init_data->init_callback = p_init;
 }
 
 void GDExtensionBinding::InitObject::register_terminator(Callback p_terminate) const {
-	GDExtensionBinding::terminate_callback = p_terminate;
+	init_data->terminate_callback = p_terminate;
 }
 
 void GDExtensionBinding::InitObject::set_minimum_library_initialization_level(ModuleInitializationLevel p_level) const {
-	GDExtensionBinding::minimum_initialization_level = static_cast<GDExtensionInitializationLevel>(p_level);
+	init_data->minimum_initialization_level = static_cast<GDExtensionInitializationLevel>(p_level);
 }
 
 GDExtensionBool GDExtensionBinding::InitObject::init() const {
-	return GDExtensionBinding::init(get_proc_address, library, initialization);
+	return GDExtensionBinding::init(get_proc_address, library, init_data, initialization);
 }
 
 } // namespace godot

From cd904155a86fc2a76286b88e3a6ee12149be0ebe Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Wed, 22 Nov 2023 19:10:15 +0000
Subject: [PATCH 04/17] Bump mymindstorm/setup-emsdk from 12 to 13

Bumps [mymindstorm/setup-emsdk](https://github.com/mymindstorm/setup-emsdk) from 12 to 13.
- [Release notes](https://github.com/mymindstorm/setup-emsdk/releases)
- [Commits](https://github.com/mymindstorm/setup-emsdk/compare/v12...v13)

---
updated-dependencies:
- dependency-name: mymindstorm/setup-emsdk
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
(cherry picked from commit 78bf5a42edae13abcce2c413a3000085c545a11f)
---
 .github/workflows/ci.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index c9560e9c3..4bb1af34d 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -117,7 +117,7 @@ jobs:
 
       - name: Web dependencies
         if: ${{ matrix.platform == 'web' }}
-        uses: mymindstorm/setup-emsdk@v12
+        uses: mymindstorm/setup-emsdk@v13
         with:
           version: ${{env.EM_VERSION}}
           actions-cache-folder: ${{env.EM_CACHE_FOLDER}}

From 51aeda7437ee3dd991daca1413998aab1fa416e2 Mon Sep 17 00:00:00 2001
From: DmitriySalnikov <salnikov.mine@yandex.ru>
Date: Thu, 23 Nov 2023 00:08:13 +0300
Subject: [PATCH 05/17] [Scons] Set the minimum Android API level to 21

(cherry picked from commit 79d2a9c4563cb768f508cc3f791c66c7cc57d379)
---
 tools/android.py | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/tools/android.py b/tools/android.py
index 0e6885515..95efa679d 100644
--- a/tools/android.py
+++ b/tools/android.py
@@ -8,7 +8,7 @@ def options(opts):
     opts.Add(
         "android_api_level",
         "Target Android API level",
-        "18" if "32" in ARGUMENTS.get("arch", "arm64") else "21",
+        "21",
     )
     opts.Add(
         "ANDROID_NDK_ROOT",
@@ -35,11 +35,9 @@ def generate(env):
         my_spawn.configure(env)
 
     # Validate API level
-    api_level = int(env["android_api_level"])
-    if "64" in env["arch"] and api_level < 21:
-        print("WARN: 64-bit Android architectures require an API level of at least 21; setting android_api_level=21")
+    if int(env["android_api_level"]) < 21:
+        print("WARNING: minimum supported Android target api is 21. Forcing target api 21.")
         env["android_api_level"] = "21"
-        api_level = 21
 
     # Setup toolchain
     toolchain = env["ANDROID_NDK_ROOT"] + "/toolchains/llvm/prebuilt/"

From 6bb4b1d3218f141a77245b673434b32d84da76b9 Mon Sep 17 00:00:00 2001
From: Bytzo <bytzo@bytzo.net>
Date: Wed, 25 Oct 2023 23:57:13 -0700
Subject: [PATCH 06/17] Prevent CMake from always including debug symbols

(cherry picked from commit db884e9b1d91300da91d1e82be2effda270401ec)
---
 CMakeLists.txt | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index c413cecc9..bf09ba3bf 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -99,10 +99,8 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
 
 	add_definitions(-DNOMINMAX)
 else()  # GCC/Clang
-	set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -g")
-
 	if(CMAKE_BUILD_TYPE MATCHES Debug)
-		set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -fno-omit-frame-pointer -O0")
+		set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -fno-omit-frame-pointer -O0 -g")
 	else()
 		set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -O3")
 	endif(CMAKE_BUILD_TYPE MATCHES Debug)

From d5a2e8e7975bc738312c11c2ea2ead133473c1a1 Mon Sep 17 00:00:00 2001
From: LAK132 <lakridesagain@gmail.com>
Date: Sat, 11 Nov 2023 23:29:33 +1030
Subject: [PATCH 07/17] Fix file list issues when trying to build with meson
 via cmake

(cherry picked from commit 39c139c8143d3dfb1595ea812f1cf0c08ef9b4fe)
---
 CMakeLists.txt       | 1 +
 binding_generator.py | 4 +---
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index bf09ba3bf..1076e8f20 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -132,6 +132,7 @@ endif()
 execute_process(COMMAND "${Python3_EXECUTABLE}" "-c" "import binding_generator; binding_generator.print_file_list(\"${GODOT_GDEXTENSION_API_FILE}\", \"${CMAKE_CURRENT_BINARY_DIR}\", headers=True, sources=True)"
 	WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
 	OUTPUT_VARIABLE GENERATED_FILES_LIST
+	OUTPUT_STRIP_TRAILING_WHITESPACE
 )
 
 add_custom_command(OUTPUT ${GENERATED_FILES_LIST}
diff --git a/binding_generator.py b/binding_generator.py
index 18db9fd0d..d11d4bbad 100644
--- a/binding_generator.py
+++ b/binding_generator.py
@@ -135,9 +135,7 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
 
 
 def print_file_list(api_filepath, output_dir, headers=False, sources=False):
-    end = ";"
-    for f in get_file_list(api_filepath, output_dir, headers, sources):
-        print(f, end=end)
+    print(*get_file_list(api_filepath, output_dir, headers, sources), sep=";", end=None)
 
 
 def scons_emit_files(target, source, env):

From b1bd58d7da56166a4982c9bc4916966d00ed5d9b Mon Sep 17 00:00:00 2001
From: David Snopek <dsnopek@gmail.com>
Date: Wed, 29 Nov 2023 11:50:48 -0600
Subject: [PATCH 08/17] Send NOTIFICATION_POSTINITIALIZE to extension classes

(cherry picked from commit 20c4e843b09b7263078c23ec635198feae03c227)
---
 src/classes/wrapped.cpp |  6 ++++++
 test/project/main.gd    |  5 +++++
 test/src/example.cpp    | 15 +++++++++++++++
 test/src/example.h      |  7 +++++++
 4 files changed, 33 insertions(+)

diff --git a/src/classes/wrapped.cpp b/src/classes/wrapped.cpp
index 2c5e1b607..8a2092c1e 100644
--- a/src/classes/wrapped.cpp
+++ b/src/classes/wrapped.cpp
@@ -50,6 +50,12 @@ void Wrapped::_postinitialize() {
 		godot::internal::gdextension_interface_object_set_instance(_owner, reinterpret_cast<GDExtensionConstStringNamePtr>(extension_class), this);
 	}
 	godot::internal::gdextension_interface_object_set_instance_binding(_owner, godot::internal::token, this, _get_bindings_callbacks());
+	if (extension_class) {
+		Object *obj = dynamic_cast<Object *>(this);
+		if (obj) {
+			obj->notification(Object::NOTIFICATION_POSTINITIALIZE);
+		}
+	}
 }
 
 Wrapped::Wrapped(const StringName p_godot_class) {
diff --git a/test/project/main.gd b/test/project/main.gd
index eb8dbb9de..e0b186bb2 100644
--- a/test/project/main.gd
+++ b/test/project/main.gd
@@ -169,6 +169,11 @@ func _ready():
 	get_viewport().push_input(event)
 	assert_equal(custom_signal_emitted, ["_input: H", 72])
 
+	# Check NOTIFICATION_POST_INITIALIZED, both when created from GDScript and godot-cpp.
+	var new_example_ref = ExampleRef.new()
+	assert_equal(new_example_ref.was_post_initialized(), true)
+	assert_equal(example.test_post_initialize(), true)
+
 	exit_with_status()
 
 func _on_Example_custom_signal(signal_name, value):
diff --git a/test/src/example.cpp b/test/src/example.cpp
index 475eed2bc..848f50352 100644
--- a/test/src/example.cpp
+++ b/test/src/example.cpp
@@ -23,10 +23,18 @@ int ExampleRef::get_id() const {
 	return id;
 }
 
+void ExampleRef::_notification(int p_what) {
+	if (p_what == NOTIFICATION_POSTINITIALIZE) {
+		post_initialized = true;
+	}
+}
+
 void ExampleRef::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_id", "id"), &ExampleRef::set_id);
 	ClassDB::bind_method(D_METHOD("get_id"), &ExampleRef::get_id);
 
+	ClassDB::bind_method(D_METHOD("was_post_initialized"), &ExampleRef::was_post_initialized);
+
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "id"), "set_id", "get_id");
 }
 
@@ -161,6 +169,7 @@ void Example::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("return_last_rpc_arg"), &Example::return_last_rpc_arg);
 
 	ClassDB::bind_method(D_METHOD("def_args", "a", "b"), &Example::def_args, DEFVAL(100), DEFVAL(200));
+	ClassDB::bind_method(D_METHOD("test_post_initialize"), &Example::test_post_initialize);
 
 	ClassDB::bind_static_method("Example", D_METHOD("test_static", "a", "b"), &Example::test_static);
 	ClassDB::bind_static_method("Example", D_METHOD("test_static2"), &Example::test_static2);
@@ -426,6 +435,12 @@ Vector4 Example::get_v4() const {
 	return Vector4(1.2, 3.4, 5.6, 7.8);
 }
 
+bool Example::test_post_initialize() const {
+	Ref<ExampleRef> new_example_ref;
+	new_example_ref.instantiate();
+	return new_example_ref->was_post_initialized();
+}
+
 // Virtual function override.
 bool Example::_has_point(const Vector2 &point) const {
 	Label *label = get_node<Label>("Label");
diff --git a/test/src/example.h b/test/src/example.h
index cab7d22f6..d0130765b 100644
--- a/test/src/example.h
+++ b/test/src/example.h
@@ -35,16 +35,21 @@ class ExampleRef : public RefCounted {
 	static int last_id;
 
 	int id;
+	bool post_initialized = false;
 
 protected:
 	static void _bind_methods();
 
+	void _notification(int p_what);
+
 public:
 	ExampleRef();
 	~ExampleRef();
 
 	void set_id(int p_id);
 	int get_id() const;
+
+	bool was_post_initialized() const { return post_initialized; }
 };
 
 class ExampleMin : public Control {
@@ -148,6 +153,8 @@ class Example : public Control {
 	Vector2 get_custom_position() const;
 	Vector4 get_v4() const;
 
+	bool test_post_initialize() const;
+
 	// Static method.
 	static int test_static(int p_a, int p_b);
 	static void test_static2();

From e9273e85281d534e59359ee3ca40f080d74466af Mon Sep 17 00:00:00 2001
From: David Snopek <dsnopek@gmail.com>
Date: Thu, 30 Nov 2023 15:20:08 -0600
Subject: [PATCH 09/17] Avoid error from -Werror=type-limits on GCC 11

(cherry picked from commit cad5be53b1dd81416d644ef5002c85951f07adcc)
---
 src/godot.cpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/godot.cpp b/src/godot.cpp
index b40049f9c..1621b2052 100644
--- a/src/godot.cpp
+++ b/src/godot.cpp
@@ -264,7 +264,12 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
 	} else if (internal::godot_version.minor != GODOT_VERSION_MINOR) {
 		compatible = internal::godot_version.minor > GODOT_VERSION_MINOR;
 	} else {
+#if GODOT_VERSION_PATCH > 0
 		compatible = internal::godot_version.patch >= GODOT_VERSION_PATCH;
+#else
+		// Prevent -Wtype-limits warning due to unsigned comparison.
+		compatible = true;
+#endif
 	}
 	if (!compatible) {
 		// We need to use snprintf() here because vformat() uses Variant, and we haven't loaded

From 2e42c7020e6c67ea55edee384710332c0d442a18 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= <rverschelde@gmail.com>
Date: Fri, 1 Dec 2023 10:45:02 +0100
Subject: [PATCH 10/17] CMake: Remove hardcoded warnings list and forcing
 -Werror on library builds

The CMake buildsystem should be completely reviewed to properly match
what is done by SCons, instead of making its own arbitrary decisions on
how godot-cpp should be compiled.

Currently the SCons setup doesn't include warning options, so CMake
shouldn't either. Options similar to upstream Godot's SCons setup could
be added, and then replicated for CMake.

(cherry picked from commit 41517eacb1115e5020af8c305492f6c77ffa89bc)
---
 CMakeLists.txt      | 11 -----------
 test/CMakeLists.txt | 22 ----------------------
 2 files changed, 33 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1076e8f20..a9603ab6d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -47,11 +47,6 @@ option(GODOT_CPP_WARNING_AS_ERROR "Treat warnings as errors" OFF)
 # Add path to modules
 list( APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/" )
 
-# Check if we are building ourself or being included
-if(${PROJECT_NAME} STREQUAL ${CMAKE_PROJECT_NAME})
-    set(GODOT_CPP_BUILDING_SELF ON)
-endif()
-
 # Set some helper variables for readability
 set( compiler_is_clang "$<OR:$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:Clang>>" )
 set( compiler_is_gnu "$<CXX_COMPILER_ID:GNU>" )
@@ -158,12 +153,6 @@ add_library(godot::cpp ALIAS ${PROJECT_NAME})
 
 include(GodotCompilerWarnings)
 
-# Treat warnings as errors if we are building ourself
-if(GODOT_CPP_BUILDING_SELF)
-    unset( GODOT_CPP_WARNING_AS_ERROR CACHE )
-    set_warning_as_error()
-endif()
-
 target_compile_features(${PROJECT_NAME}
 	PRIVATE
 		cxx_std_17
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 9d692e6a6..a17b9aacd 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -59,31 +59,9 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
 
 else()
 
-#elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
-	# using Clang
-#elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
-	# using GCC and maybe MinGW?
-
 	set(GODOT_LINKER_FLAGS "-static-libgcc -static-libstdc++ -Wl,-R,'$$ORIGIN'")
 
-	# Hmm.. maybe to strikt?
 	set(GODOT_COMPILE_FLAGS "-fPIC -g -Wwrite-strings")
-	set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wchar-subscripts -Wcomment -Wdisabled-optimization")
-	set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wformat -Wformat=2 -Wformat-security -Wformat-y2k")
-	set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wimport -Winit-self -Winline -Winvalid-pch -Werror")
-	set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wmissing-braces -Wmissing-format-attribute")
-	set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wmissing-include-dirs -Wmissing-noreturn -Wpacked -Wpointer-arith")
-	set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wredundant-decls -Wreturn-type -Wsequence-point")
-	set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wswitch -Wswitch-enum -Wtrigraphs")
-	set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wuninitialized -Wunknown-pragmas -Wunreachable-code -Wunused-label")
-	set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wunused-value -Wvariadic-macros -Wvolatile-register-var -Wno-error=attributes")
-
-	# -Wshadow -Wextra -Wall -Weffc++ -Wfloat-equal -Wstack-protector -Wunused-parameter -Wsign-compare -Wunused-variable -Wcast-align
-	# -Wunused-function -Wstrict-aliasing -Wstrict-aliasing=2 -Wmissing-field-initializers
-
-	if(NOT CMAKE_SYSTEM_NAME STREQUAL "Android")
-		set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wno-ignored-attributes")
-	endif()
 
 	if(CMAKE_BUILD_TYPE MATCHES Debug)
 		set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -fno-omit-frame-pointer -O0")

From 756190705e8a233149e513b207ef2381ab2132ff Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Wed, 6 Dec 2023 19:33:16 +0000
Subject: [PATCH 11/17] Bump actions/setup-python from 4 to 5

Bumps [actions/setup-python](https://github.com/actions/setup-python) from 4 to 5.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
(cherry picked from commit a7becb43e6e560e0679416d7c2abb7ae8194a539)
---
 .github/workflows/ci.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 4bb1af34d..ada01e93b 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -104,7 +104,7 @@ jobs:
         continue-on-error: true
 
       - name: Set up Python (for SCons)
-        uses: actions/setup-python@v4
+        uses: actions/setup-python@v5
         with:
           python-version: '3.x'
 

From 49098fbdc71ffe8e3293ee57cdf401e2b06c6c03 Mon Sep 17 00:00:00 2001
From: Aaron Franke <arnfranke@yahoo.com>
Date: Sun, 17 Dec 2023 11:45:31 -0600
Subject: [PATCH 12/17] Allow detecting when building as a GDExtension

(cherry picked from commit e17c7bf53060c7f1d34246af68b1d103dd8c01f7)
---
 tools/godotcpp.py | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tools/godotcpp.py b/tools/godotcpp.py
index 925b214d0..4ab18cd3c 100644
--- a/tools/godotcpp.py
+++ b/tools/godotcpp.py
@@ -267,6 +267,9 @@ def generate(env):
     if env["precision"] == "double":
         env.Append(CPPDEFINES=["REAL_T_IS_DOUBLE"])
 
+    # Allow detecting when building as a GDExtension.
+    env.Append(CPPDEFINES=["GDEXTENSION"])
+
     # Suffix
     suffix = ".{}.{}".format(env["platform"], env["target"])
     if env.dev_build:

From 82475b215b40f0831a9a3be882a6bce7a6d9d73f Mon Sep 17 00:00:00 2001
From: ArchLinus <archlinus123@gmail.com>
Date: Fri, 29 Dec 2023 09:32:14 -0500
Subject: [PATCH 13/17] Add an error message if android NDK is not installed

(cherry picked from commit 718d0baea3e310391c6feb5b61b8e2dda6a08533)
---
 tools/android.py | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/tools/android.py b/tools/android.py
index 95efa679d..f9bfe2b41 100644
--- a/tools/android.py
+++ b/tools/android.py
@@ -52,6 +52,12 @@ def generate(env):
     elif sys.platform == "darwin":
         toolchain += "darwin-x86_64"
         env.Append(LINKFLAGS=["-shared"])
+
+    if not os.path.exists(toolchain):
+        print("ERROR: Could not find NDK toolchain at " + toolchain + ".")
+        print("Make sure NDK version " + get_ndk_version() + " is installed.")
+        env.Exit(1)
+
     env.PrependENVPath("PATH", toolchain + "/bin")  # This does nothing half of the time, but we'll put it here anyways
 
     # Get architecture info

From 1c03aa774665d101ee708a6941225d67346ebea4 Mon Sep 17 00:00:00 2001
From: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com>
Date: Sat, 6 Jan 2024 20:54:57 +0100
Subject: [PATCH 14/17] Add missing `OP_POWER` operator to `Variant`

(cherry picked from commit f037a697eb2ce45d63840dfe87c48212d7cbf09e)
---
 binding_generator.py                  | 1 +
 include/godot_cpp/variant/variant.hpp | 1 +
 2 files changed, 2 insertions(+)

diff --git a/binding_generator.py b/binding_generator.py
index d11d4bbad..79b54136a 100644
--- a/binding_generator.py
+++ b/binding_generator.py
@@ -2334,6 +2334,7 @@ def get_operator_id_name(op):
         "unary-": "negate",
         "unary+": "positive",
         "%": "module",
+        "**": "power",
         "<<": "shift_left",
         ">>": "shift_right",
         "&": "bit_and",
diff --git a/include/godot_cpp/variant/variant.hpp b/include/godot_cpp/variant/variant.hpp
index 575c224ec..7b82d5eb3 100644
--- a/include/godot_cpp/variant/variant.hpp
+++ b/include/godot_cpp/variant/variant.hpp
@@ -122,6 +122,7 @@ class Variant {
 		OP_NEGATE,
 		OP_POSITIVE,
 		OP_MODULE,
+		OP_POWER,
 		// bitwise
 		OP_SHIFT_LEFT,
 		OP_SHIFT_RIGHT,

From dde0bbb93d33ebf7b8550da93ce5773d76b30053 Mon Sep 17 00:00:00 2001
From: Daylily-Zeleen <daylily-zeleen@foxmail.com>
Date: Sun, 7 Jan 2024 15:24:02 +0800
Subject: [PATCH 15/17] Remove "godot" namespace when binding global constants.

(cherry picked from commit bd40a94424ca91bc2d2bc76f2a02ac7f8bd5d3cf)
---
 binding_generator.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/binding_generator.py b/binding_generator.py
index 79b54136a..aa77a5cb0 100644
--- a/binding_generator.py
+++ b/binding_generator.py
@@ -1716,9 +1716,9 @@ def generate_global_constant_binds(api, output_dir):
             continue
 
         if enum_def["is_bitfield"]:
-            header.append(f'VARIANT_BITFIELD_CAST(godot::{enum_def["name"]});')
+            header.append(f'VARIANT_BITFIELD_CAST({enum_def["name"]});')
         else:
-            header.append(f'VARIANT_ENUM_CAST(godot::{enum_def["name"]});')
+            header.append(f'VARIANT_ENUM_CAST({enum_def["name"]});')
 
     # Variant::Type is not a global enum, but only one line, it is worth to place in this file instead of creating new file.
     header.append(f"VARIANT_ENUM_CAST(godot::Variant::Type);")

From 6884ca9be0ed9c50bc1b46e5c68d963aecb2a9eb Mon Sep 17 00:00:00 2001
From: nightblade9 <nightbladecodes@gmail.com>
Date: Sun, 7 Jan 2024 18:53:34 -0500
Subject: [PATCH 16/17] Update README.md with basic pre-requisites

(cherry picked from commit ee169b201bc4461accfe31668f7795bf317fbae2)
---
 README.md | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index c36e89252..e86c7c488 100644
--- a/README.md
+++ b/README.md
@@ -73,7 +73,10 @@ so formatting is done before your changes are submitted.
 
 ## Getting started
 
-It's a bit similar to what it was for 3.x but also a bit different.
+You need the same C++ pre-requisites installed that are required for the `godot` repository. Follow the [official build instructions for your target platform](https://docs.godotengine.org/en/latest/contributing/development/compiling/index.html#building-for-target-platforms).
+
+Getting started with GDExtensions is a bit similar to what it was for 3.x but also a bit different.
+
 This new approach is much more akin to how core Godot modules are structured.
 
 Compiling this repository generates a static library to be linked with your shared lib,

From 2cc967787a8e7ed2c6adc495d1f4cbdff902d958 Mon Sep 17 00:00:00 2001
From: MJacred <loesch.benny92@gmx.de>
Date: Mon, 22 Jan 2024 10:50:27 +0100
Subject: [PATCH 17/17] Update README: fix godot-cpp issue tracker url

(cherry picked from commit 8a535d0ecc473e9c8221342363bb295c11ba6bd5)
---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index e86c7c488..b11628408 100644
--- a/README.md
+++ b/README.md
@@ -57,7 +57,7 @@ first-party `godot-cpp` extension.
 Some compatibility breakage is to be expected as GDExtension and `godot-cpp`
 get more used, documented, and critical issues get resolved. See the
 [Godot issue tracker](https://github.com/godotengine/godot/issues?q=is%3Aissue+is%3Aopen+label%3Atopic%3Agdextension)
-and the [godot-cpp issue tracker](https://github.com/godotengine/godot/issues)
+and the [godot-cpp issue tracker](https://github.com/godotengine/godot-cpp/issues)
 for a list of known issues, and be sure to provide feedback on issues and PRs
 which affect your use of this extension.
 
