summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--include/godot_cpp/classes/wrapped.hpp198
-rw-r--r--include/godot_cpp/core/memory.hpp23
-rw-r--r--src/core/memory.cpp11
-rw-r--r--test/SConstruct11
-rwxr-xr-xtest/generate_xcframework.sh7
-rw-r--r--test/project/bin/libgdexample.macos.template_debug.framework/Resources/Info.plist (renamed from test/project/bin/libgdexample.osx.template_debug.framework/Resources/Info.plist)0
-rw-r--r--test/project/bin/libgdexample.macos.template_release.framework/Resources/Info.plist (renamed from test/project/bin/libgdexample.osx.template_release.framework/Resources/Info.plist)0
-rw-r--r--test/project/example.gdextension16
-rw-r--r--test/project/project.godot1
-rw-r--r--tools/godotcpp.py22
11 files changed, 170 insertions, 123 deletions
diff --git a/.gitignore b/.gitignore
index 7c87766..d4b5748 100644
--- a/.gitignore
+++ b/.gitignore
@@ -191,3 +191,7 @@ godot.creator.*
# compile commands (https://clang.llvm.org/docs/JSONCompilationDatabase.html)
compile_commands.json
+
+# Python development
+.venv
+venv
diff --git a/include/godot_cpp/classes/wrapped.hpp b/include/godot_cpp/classes/wrapped.hpp
index af2ce4c..f8f921b 100644
--- a/include/godot_cpp/classes/wrapped.hpp
+++ b/include/godot_cpp/classes/wrapped.hpp
@@ -365,105 +365,109 @@ public:
_gde_binding_create_callback, \
_gde_binding_free_callback, \
_gde_binding_reference_callback, \
- };
+ }; \
+ \
+private:
// Don't use this for your classes, use GDCLASS() instead.
-#define GDEXTENSION_CLASS_ALIAS(m_class, m_alias_for, m_inherits) \
-private: \
- inline static ::godot::internal::EngineClassRegistration<m_class> _gde_engine_class_registration_helper; \
- void operator=(const m_class &p_rval) {} \
- \
-protected: \
- virtual const GDExtensionInstanceBindingCallbacks *_get_bindings_callbacks() const override { \
- return &_gde_binding_callbacks; \
- } \
- \
- m_class(const char *p_godot_class) : m_inherits(p_godot_class) {} \
- m_class(GodotObject *p_godot_object) : m_inherits(p_godot_object) {} \
- \
- static void (*_get_bind_methods())() { \
- return nullptr; \
- } \
- \
- static void (Wrapped::*_get_notification())(int) { \
- return nullptr; \
- } \
- \
- static bool (Wrapped::*_get_set())(const ::godot::StringName &p_name, const Variant &p_property) { \
- return nullptr; \
- } \
- \
- static bool (Wrapped::*_get_get())(const ::godot::StringName &p_name, Variant &r_ret) const { \
- return nullptr; \
- } \
- \
- static inline bool has_get_property_list() { \
- return false; \
- } \
- \
- static void (Wrapped::*_get_get_property_list())(List<PropertyInfo> * p_list) const { \
- return nullptr; \
- } \
- \
- static bool (Wrapped::*_get_property_can_revert())(const ::godot::StringName &p_name) const { \
- return nullptr; \
- } \
- \
- static bool (Wrapped::*_get_property_get_revert())(const ::godot::StringName &p_name, Variant &) const { \
- return nullptr; \
- } \
- \
- static void (Wrapped::*_get_validate_property())(::godot::PropertyInfo & p_property) const { \
- return nullptr; \
- } \
- \
- static String (Wrapped::*_get_to_string())() const { \
- return nullptr; \
- } \
- \
-public: \
- typedef m_class self_type; \
- \
- static void initialize_class() {} \
- \
- static ::godot::StringName &get_class_static() { \
- static ::godot::StringName string_name = ::godot::StringName(#m_alias_for); \
- return string_name; \
- } \
- \
- static ::godot::StringName &get_parent_class_static() { \
- return m_inherits::get_class_static(); \
- } \
- \
- static GDExtensionObjectPtr create(void *data) { \
- return nullptr; \
- } \
- \
- static GDExtensionClassInstancePtr recreate(void *data, GDExtensionObjectPtr obj) { \
- return nullptr; \
- } \
- \
- static void free(void *data, GDExtensionClassInstancePtr ptr) { \
- } \
- \
- static void *_gde_binding_create_callback(void *p_token, void *p_instance) { \
- /* Do not call memnew here, we don't want the post-initializer to be called */ \
- return new ("") m_class((GodotObject *)p_instance); \
- } \
- static void _gde_binding_free_callback(void *p_token, void *p_instance, void *p_binding) { \
- /* Explicitly call the deconstructor to ensure proper lifecycle for non-trivial members */ \
- reinterpret_cast<m_class *>(p_binding)->~m_class(); \
- Memory::free_static(reinterpret_cast<m_class *>(p_binding)); \
- } \
- static GDExtensionBool _gde_binding_reference_callback(void *p_token, void *p_instance, GDExtensionBool p_reference) { \
- return true; \
- } \
- static constexpr GDExtensionInstanceBindingCallbacks _gde_binding_callbacks = { \
- _gde_binding_create_callback, \
- _gde_binding_free_callback, \
- _gde_binding_reference_callback, \
- }; \
- m_class() : m_class(#m_alias_for) {}
+#define GDEXTENSION_CLASS_ALIAS(m_class, m_alias_for, m_inherits) /******************************************************************************************************************/ \
+private: \
+ inline static ::godot::internal::EngineClassRegistration<m_class> _gde_engine_class_registration_helper; \
+ void operator=(const m_class &p_rval) {} \
+ \
+protected: \
+ virtual const GDExtensionInstanceBindingCallbacks *_get_bindings_callbacks() const override { \
+ return &_gde_binding_callbacks; \
+ } \
+ \
+ m_class(const char *p_godot_class) : m_inherits(p_godot_class) {} \
+ m_class(GodotObject *p_godot_object) : m_inherits(p_godot_object) {} \
+ \
+ static void (*_get_bind_methods())() { \
+ return nullptr; \
+ } \
+ \
+ static void (Wrapped::*_get_notification())(int) { \
+ return nullptr; \
+ } \
+ \
+ static bool (Wrapped::*_get_set())(const ::godot::StringName &p_name, const Variant &p_property) { \
+ return nullptr; \
+ } \
+ \
+ static bool (Wrapped::*_get_get())(const ::godot::StringName &p_name, Variant &r_ret) const { \
+ return nullptr; \
+ } \
+ \
+ static inline bool has_get_property_list() { \
+ return false; \
+ } \
+ \
+ static void (Wrapped::*_get_get_property_list())(List<PropertyInfo> * p_list) const { \
+ return nullptr; \
+ } \
+ \
+ static bool (Wrapped::*_get_property_can_revert())(const ::godot::StringName &p_name) const { \
+ return nullptr; \
+ } \
+ \
+ static bool (Wrapped::*_get_property_get_revert())(const ::godot::StringName &p_name, Variant &) const { \
+ return nullptr; \
+ } \
+ \
+ static void (Wrapped::*_get_validate_property())(::godot::PropertyInfo & p_property) const { \
+ return nullptr; \
+ } \
+ \
+ static String (Wrapped::*_get_to_string())() const { \
+ return nullptr; \
+ } \
+ \
+public: \
+ typedef m_class self_type; \
+ \
+ static void initialize_class() {} \
+ \
+ static ::godot::StringName &get_class_static() { \
+ static ::godot::StringName string_name = ::godot::StringName(#m_alias_for); \
+ return string_name; \
+ } \
+ \
+ static ::godot::StringName &get_parent_class_static() { \
+ return m_inherits::get_class_static(); \
+ } \
+ \
+ static GDExtensionObjectPtr create(void *data) { \
+ return nullptr; \
+ } \
+ \
+ static GDExtensionClassInstancePtr recreate(void *data, GDExtensionObjectPtr obj) { \
+ return nullptr; \
+ } \
+ \
+ static void free(void *data, GDExtensionClassInstancePtr ptr) { \
+ } \
+ \
+ static void *_gde_binding_create_callback(void *p_token, void *p_instance) { \
+ /* Do not call memnew here, we don't want the post-initializer to be called */ \
+ return new ("", "") m_class((GodotObject *)p_instance); \
+ } \
+ static void _gde_binding_free_callback(void *p_token, void *p_instance, void *p_binding) { \
+ /* Explicitly call the deconstructor to ensure proper lifecycle for non-trivial members */ \
+ reinterpret_cast<m_class *>(p_binding)->~m_class(); \
+ Memory::free_static(reinterpret_cast<m_class *>(p_binding)); \
+ } \
+ static GDExtensionBool _gde_binding_reference_callback(void *p_token, void *p_instance, GDExtensionBool p_reference) { \
+ return true; \
+ } \
+ static constexpr GDExtensionInstanceBindingCallbacks _gde_binding_callbacks = { \
+ _gde_binding_create_callback, \
+ _gde_binding_free_callback, \
+ _gde_binding_reference_callback, \
+ }; \
+ m_class() : m_class(#m_alias_for) {} \
+ \
+private:
// Don't use this for your classes, use GDCLASS() instead.
#define GDEXTENSION_CLASS(m_class, m_inherits) GDEXTENSION_CLASS_ALIAS(m_class, m_class, m_inherits)
diff --git a/include/godot_cpp/core/memory.hpp b/include/godot_cpp/core/memory.hpp
index 548f330..97a2b13 100644
--- a/include/godot_cpp/core/memory.hpp
+++ b/include/godot_cpp/core/memory.hpp
@@ -44,20 +44,21 @@
#define PAD_ALIGN 16 //must always be greater than this at much
#endif
-void *operator new(size_t p_size, const char *p_description); ///< operator new that takes a description and uses MemoryStaticPool
-void *operator new(size_t p_size, void *(*p_allocfunc)(size_t p_size)); ///< operator new that takes a description and uses MemoryStaticPool
-void *operator new(size_t p_size, void *p_pointer, size_t check, const char *p_description); ///< operator new that takes a description and uses a pointer to the preallocated memory
+// p_dummy argument is added to avoid conflicts with the engine functions when both engine and GDExtension are built as a static library on iOS.
+void *operator new(size_t p_size, const char *p_dummy, const char *p_description); ///< operator new that takes a description and uses MemoryStaticPool
+void *operator new(size_t p_size, const char *p_dummy, void *(*p_allocfunc)(size_t p_size)); ///< operator new that takes a description and uses MemoryStaticPool
+void *operator new(size_t p_size, const char *p_dummy, void *p_pointer, size_t check, const char *p_description); ///< operator new that takes a description and uses a pointer to the preallocated memory
-_ALWAYS_INLINE_ void *operator new(size_t p_size, void *p_pointer, size_t check, const char *p_description) {
+_ALWAYS_INLINE_ void *operator new(size_t p_size, const char *p_dummy, void *p_pointer, size_t check, const char *p_description) {
return p_pointer;
}
#ifdef _MSC_VER
// When compiling with VC++ 2017, the above declarations of placement new generate many irrelevant warnings (C4291).
// The purpose of the following definitions is to muffle these warnings, not to provide a usable implementation of placement delete.
-void operator delete(void *p_mem, const char *p_description);
-void operator delete(void *p_mem, void *(*p_allocfunc)(size_t p_size));
-void operator delete(void *p_mem, void *p_pointer, size_t check, const char *p_description);
+void operator delete(void *p_mem, const char *p_dummy, const char *p_description);
+void operator delete(void *p_mem, const char *p_dummy, void *(*p_allocfunc)(size_t p_size));
+void operator delete(void *p_mem, const char *p_dummy, void *p_pointer, size_t check, const char *p_description);
#endif
namespace godot {
@@ -85,10 +86,10 @@ _ALWAYS_INLINE_ T *_post_initialize(T *p_obj) {
#define memrealloc(m_mem, m_size) ::godot::Memory::realloc_static(m_mem, m_size)
#define memfree(m_mem) ::godot::Memory::free_static(m_mem)
-#define memnew(m_class) ::godot::_post_initialize(new ("") m_class)
+#define memnew(m_class) ::godot::_post_initialize(new ("", "") m_class)
-#define memnew_allocator(m_class, m_allocator) ::godot::_post_initialize(new (m_allocator::alloc) m_class)
-#define memnew_placement(m_placement, m_class) ::godot::_post_initialize(new (m_placement, sizeof(m_class), "") m_class)
+#define memnew_allocator(m_class, m_allocator) ::godot::_post_initialize(new ("", m_allocator::alloc) m_class)
+#define memnew_placement(m_placement, m_class) ::godot::_post_initialize(new ("", m_placement, sizeof(m_class), "") m_class)
// Generic comparator used in Map, List, etc.
template <class T>
@@ -154,7 +155,7 @@ T *memnew_arr_template(size_t p_elements, const char *p_descr = "") {
/* call operator new */
for (size_t i = 0; i < p_elements; i++) {
- new (&elems[i], sizeof(T), p_descr) T;
+ new ("", &elems[i], sizeof(T), p_descr) T;
}
}
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 80e71ec..8118511 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -103,28 +103,29 @@ _GlobalNil _GlobalNilClass::_nil;
} // namespace godot
-void *operator new(size_t p_size, const char *p_description) {
+// p_dummy argument is added to avoid conflicts with the engine functions when both engine and GDExtension are built as a static library on iOS.
+void *operator new(size_t p_size, const char *p_dummy, const char *p_description) {
return godot::Memory::alloc_static(p_size);
}
-void *operator new(size_t p_size, void *(*p_allocfunc)(size_t p_size)) {
+void *operator new(size_t p_size, const char *p_dummy, void *(*p_allocfunc)(size_t p_size)) {
return p_allocfunc(p_size);
}
using namespace godot;
#ifdef _MSC_VER
-void operator delete(void *p_mem, const char *p_description) {
+void operator delete(void *p_mem, const char *p_dummy, const char *p_description) {
ERR_PRINT("Call to placement delete should not happen.");
CRASH_NOW();
}
-void operator delete(void *p_mem, void *(*p_allocfunc)(size_t p_size)) {
+void operator delete(void *p_mem, const char *p_dummy, void *(*p_allocfunc)(size_t p_size)) {
ERR_PRINT("Call to placement delete should not happen.");
CRASH_NOW();
}
-void operator delete(void *p_mem, void *p_pointer, size_t check, const char *p_description) {
+void operator delete(void *p_mem, const char *p_dummy, void *p_pointer, size_t check, const char *p_description) {
ERR_PRINT("Call to placement delete should not happen.");
CRASH_NOW();
}
diff --git a/test/SConstruct b/test/SConstruct
index 1732ecd..9c25917 100644
--- a/test/SConstruct
+++ b/test/SConstruct
@@ -23,6 +23,17 @@ if env["platform"] == "macos":
),
source=sources,
)
+elif env["platform"] == "ios":
+ if env["ios_simulator"]:
+ library = env.StaticLibrary(
+ "project/bin/libgdexample.{}.{}.simulator.a".format(env["platform"], env["target"]),
+ source=sources,
+ )
+ else:
+ library = env.StaticLibrary(
+ "project/bin/libgdexample.{}.{}.a".format(env["platform"], env["target"]),
+ source=sources,
+ )
else:
library = env.SharedLibrary(
"project/bin/libgdexample{}{}".format(env["suffix"], env["SHLIBSUFFIX"]),
diff --git a/test/generate_xcframework.sh b/test/generate_xcframework.sh
new file mode 100755
index 0000000..7adddff
--- /dev/null
+++ b/test/generate_xcframework.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+scons arch=universal ios_simulator=yes platform=ios target=$1 $2
+scons arch=arm64 ios_simulator=no platform=ios target=$1 $2
+
+xcodebuild -create-xcframework -library ./project/bin/libgdexample.ios.$1.a -library ./project/bin/libgdexample.ios.$1.simulator.a -output ./project/bin/libgdexample.ios.$1.xcframework
+xcodebuild -create-xcframework -library ../bin/libgodot-cpp.ios.$1.arm64.a -library ../bin/libgodot-cpp.ios.$1.universal.simulator.a -output ./project/bin/libgodot-cpp.ios.$1.xcframework
diff --git a/test/project/bin/libgdexample.osx.template_debug.framework/Resources/Info.plist b/test/project/bin/libgdexample.macos.template_debug.framework/Resources/Info.plist
index fbdbd20..fbdbd20 100644
--- a/test/project/bin/libgdexample.osx.template_debug.framework/Resources/Info.plist
+++ b/test/project/bin/libgdexample.macos.template_debug.framework/Resources/Info.plist
diff --git a/test/project/bin/libgdexample.osx.template_release.framework/Resources/Info.plist b/test/project/bin/libgdexample.macos.template_release.framework/Resources/Info.plist
index b3bc3ca..b3bc3ca 100644
--- a/test/project/bin/libgdexample.osx.template_release.framework/Resources/Info.plist
+++ b/test/project/bin/libgdexample.macos.template_release.framework/Resources/Info.plist
diff --git a/test/project/example.gdextension b/test/project/example.gdextension
index 30279e6..4f599ce 100644
--- a/test/project/example.gdextension
+++ b/test/project/example.gdextension
@@ -11,8 +11,14 @@ windows.debug.x86_32 = "res://bin/libgdexample.windows.template_debug.x86_32.dll
windows.release.x86_32 = "res://bin/libgdexample.windows.template_release.x86_32.dll"
windows.debug.x86_64 = "res://bin/libgdexample.windows.template_debug.x86_64.dll"
windows.release.x86_64 = "res://bin/libgdexample.windows.template_release.x86_64.dll"
+windows.debug.arm64 = "res://bin/libgdexample.windows.template_debug.arm64.dll"
+windows.release.arm64 = "res://bin/libgdexample.windows.template_release.arm64.dll"
+linux.debug.x86_32 = "res://bin/libgdexample.linux.template_debug.x86_32.so"
+linux.release.x86_32 = "res://bin/libgdexample.linux.template_release.x86_32.so"
linux.debug.x86_64 = "res://bin/libgdexample.linux.template_debug.x86_64.so"
linux.release.x86_64 = "res://bin/libgdexample.linux.template_release.x86_64.so"
+linux.debug.arm32 = "res://bin/libgdexample.linux.template_debug.arm32.so"
+linux.release.arm32 = "res://bin/libgdexample.linux.template_release.arm32.so"
linux.debug.arm64 = "res://bin/libgdexample.linux.template_debug.arm64.so"
linux.release.arm64 = "res://bin/libgdexample.linux.template_release.arm64.so"
linux.debug.rv64 = "res://bin/libgdexample.linux.template_debug.rv64.so"
@@ -21,5 +27,15 @@ android.debug.x86_64 = "res://bin/libgdexample.android.template_debug.x86_64.so"
android.release.x86_64 = "res://bin/libgdexample.android.template_release.x86_64.so"
android.debug.arm64 = "res://bin/libgdexample.android.template_debug.arm64.so"
android.release.arm64 = "res://bin/libgdexample.android.template_release.arm64.so"
+ios.debug = "res://bin/libgdexample.ios.template_debug.xcframework"
+ios.release = "res://bin/libgdexample.ios.template_release.xcframework"
web.debug.wasm32 = "res://bin/libgdexample.web.template_debug.wasm32.wasm"
web.release.wasm32 = "res://bin/libgdexample.web.template_release.wasm32.wasm"
+
+[dependencies]
+ios.debug = {
+ "res://bin/libgodot-cpp.ios.template_debug.xcframework": ""
+}
+ios.release = {
+ "res://bin/libgodot-cpp.ios.template_release.xcframework": ""
+}
diff --git a/test/project/project.godot b/test/project/project.godot
index 3ed679b..4f51c07 100644
--- a/test/project/project.godot
+++ b/test/project/project.godot
@@ -21,4 +21,5 @@ paths=["res://example.gdextension"]
[rendering]
+textures/vram_compression/import_etc2_astc=true
environment/defaults/default_environment="res://default_env.tres"
diff --git a/tools/godotcpp.py b/tools/godotcpp.py
index 8e7e1c6..fcf4dd7 100644
--- a/tools/godotcpp.py
+++ b/tools/godotcpp.py
@@ -179,7 +179,7 @@ def options(opts, env):
BoolVariable(
key="use_hot_reload",
help="Enable the extra accounting required to support hot reload.",
- default=(env.get("target", "template_debug") != "template_release"),
+ default=env.get("use_hot_reload", None),
)
)
@@ -245,9 +245,20 @@ def generate(env):
print("Building for architecture " + env["arch"] + " on platform " + env["platform"])
+ if env.get("use_hot_reload") is None:
+ env["use_hot_reload"] = env["target"] != "template_release"
if env["use_hot_reload"]:
env.Append(CPPDEFINES=["HOT_RELOAD_ENABLED"])
+ tool = Tool(env["platform"], toolpath=["tools"])
+
+ if tool is None or not tool.exists(env):
+ raise ValueError("Required toolchain not found for platform " + env["platform"])
+
+ tool.generate(env)
+ target_tool = Tool("targets", toolpath=["tools"])
+ target_tool.generate(env)
+
# Disable exception handling. Godot doesn't use exceptions anywhere, and this
# saves around 20% of binary size and very significant build time.
if env["disable_exceptions"]:
@@ -258,15 +269,6 @@ def generate(env):
elif env.get("is_msvc", False):
env.Append(CXXFLAGS=["/EHsc"])
- tool = Tool(env["platform"], toolpath=["tools"])
-
- if tool is None or not tool.exists(env):
- raise ValueError("Required toolchain not found for platform " + env["platform"])
-
- tool.generate(env)
- target_tool = Tool("targets", toolpath=["tools"])
- target_tool.generate(env)
-
# Require C++17
if env.get("is_msvc", False):
env.Append(CXXFLAGS=["/std:c++17"])