Compare commits
7 Commits
5685f73962
...
6a73abc560
Author | SHA1 | Date |
---|---|---|
David Snopek | 6a73abc560 | |
MJacred | 2cc967787a | |
Rémi Verschelde | 631cd5fe37 | |
Alex Drozd | 731a10a4ea | |
Thaddeus Crews | a1ae58448c | |
Thaddeus Crews | 805cdde0b7 | |
Fredia Huya-Kouadio | 29335d8f5c |
|
@ -191,3 +191,7 @@ godot.creator.*
|
||||||
|
|
||||||
# compile commands (https://clang.llvm.org/docs/JSONCompilationDatabase.html)
|
# compile commands (https://clang.llvm.org/docs/JSONCompilationDatabase.html)
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
|
|
||||||
|
# Python development
|
||||||
|
.venv
|
||||||
|
venv
|
||||||
|
|
|
@ -57,7 +57,7 @@ first-party `godot-cpp` extension.
|
||||||
Some compatibility breakage is to be expected as GDExtension and `godot-cpp`
|
Some compatibility breakage is to be expected as GDExtension and `godot-cpp`
|
||||||
get more used, documented, and critical issues get resolved. See the
|
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)
|
[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
|
for a list of known issues, and be sure to provide feedback on issues and PRs
|
||||||
which affect your use of this extension.
|
which affect your use of this extension.
|
||||||
|
|
||||||
|
|
|
@ -325,97 +325,105 @@ public:
|
||||||
_gde_binding_create_callback, \
|
_gde_binding_create_callback, \
|
||||||
_gde_binding_free_callback, \
|
_gde_binding_free_callback, \
|
||||||
_gde_binding_reference_callback, \
|
_gde_binding_reference_callback, \
|
||||||
};
|
}; \
|
||||||
|
\
|
||||||
|
private:
|
||||||
|
|
||||||
// Don't use this for your classes, use GDCLASS() instead.
|
// Don't use this for your classes, use GDCLASS() instead.
|
||||||
#define GDEXTENSION_CLASS_ALIAS(m_class, m_alias_for, m_inherits) \
|
#define GDEXTENSION_CLASS_ALIAS(m_class, m_alias_for, m_inherits) /******************************************************************************************************************/ \
|
||||||
private: \
|
private: \
|
||||||
inline static ::godot::internal::EngineClassRegistration<m_class> _gde_engine_class_registration_helper; \
|
inline static ::godot::internal::EngineClassRegistration<m_class> _gde_engine_class_registration_helper; \
|
||||||
void operator=(const m_class &p_rval) {} \
|
void operator=(const m_class &p_rval) {} \
|
||||||
\
|
\
|
||||||
protected: \
|
protected: \
|
||||||
virtual const GDExtensionInstanceBindingCallbacks *_get_bindings_callbacks() const override { \
|
virtual const GDExtensionInstanceBindingCallbacks *_get_bindings_callbacks() const override { \
|
||||||
return &_gde_binding_callbacks; \
|
return &_gde_binding_callbacks; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
m_class(const char *p_godot_class) : m_inherits(p_godot_class) {} \
|
m_class(const char *p_godot_class) : m_inherits(p_godot_class) {} \
|
||||||
m_class(GodotObject *p_godot_object) : m_inherits(p_godot_object) {} \
|
m_class(GodotObject *p_godot_object) : m_inherits(p_godot_object) {} \
|
||||||
\
|
\
|
||||||
static void (*_get_bind_methods())() { \
|
static void (*_get_bind_methods())() { \
|
||||||
return nullptr; \
|
return nullptr; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static void (Wrapped::*_get_notification())(int) { \
|
static void (Wrapped::*_get_notification())(int) { \
|
||||||
return nullptr; \
|
return nullptr; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static bool (Wrapped::*_get_set())(const ::godot::StringName &p_name, const Variant &p_property) { \
|
static bool (Wrapped::*_get_set())(const ::godot::StringName &p_name, const Variant &p_property) { \
|
||||||
return nullptr; \
|
return nullptr; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static bool (Wrapped::*_get_get())(const ::godot::StringName &p_name, Variant &r_ret) const { \
|
static bool (Wrapped::*_get_get())(const ::godot::StringName &p_name, Variant &r_ret) const { \
|
||||||
return nullptr; \
|
return nullptr; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static void (Wrapped::*_get_get_property_list())(List<PropertyInfo> * p_list) const { \
|
static inline bool has_get_property_list() { \
|
||||||
return nullptr; \
|
return false; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static bool (Wrapped::*_get_property_can_revert())(const ::godot::StringName &p_name) const { \
|
static void (Wrapped::*_get_get_property_list())(List<PropertyInfo> * p_list) const { \
|
||||||
return nullptr; \
|
return nullptr; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static bool (Wrapped::*_get_property_get_revert())(const ::godot::StringName &p_name, Variant &) const { \
|
static bool (Wrapped::*_get_property_can_revert())(const ::godot::StringName &p_name) const { \
|
||||||
return nullptr; \
|
return nullptr; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static String (Wrapped::*_get_to_string())() const { \
|
static bool (Wrapped::*_get_property_get_revert())(const ::godot::StringName &p_name, Variant &) const { \
|
||||||
return nullptr; \
|
return nullptr; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
public: \
|
static void (Wrapped::*_get_validate_property())(::godot::PropertyInfo & p_property) const { \
|
||||||
typedef m_class self_type; \
|
return nullptr; \
|
||||||
\
|
} \
|
||||||
static void initialize_class() {} \
|
\
|
||||||
\
|
static String (Wrapped::*_get_to_string())() const { \
|
||||||
static ::godot::StringName &get_class_static() { \
|
return nullptr; \
|
||||||
static ::godot::StringName string_name = ::godot::StringName(#m_alias_for); \
|
} \
|
||||||
return string_name; \
|
\
|
||||||
} \
|
public: \
|
||||||
\
|
typedef m_class self_type; \
|
||||||
static ::godot::StringName &get_parent_class_static() { \
|
\
|
||||||
return m_inherits::get_class_static(); \
|
static void initialize_class() {} \
|
||||||
} \
|
\
|
||||||
\
|
static ::godot::StringName &get_class_static() { \
|
||||||
static GDExtensionObjectPtr create(void *data) { \
|
static ::godot::StringName string_name = ::godot::StringName(#m_alias_for); \
|
||||||
return nullptr; \
|
return string_name; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static GDExtensionClassInstancePtr recreate(void *data, GDExtensionObjectPtr obj) { \
|
static ::godot::StringName &get_parent_class_static() { \
|
||||||
return nullptr; \
|
return m_inherits::get_class_static(); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static void free(void *data, GDExtensionClassInstancePtr ptr) { \
|
static GDExtensionObjectPtr create(void *data) { \
|
||||||
} \
|
return nullptr; \
|
||||||
\
|
} \
|
||||||
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 */ \
|
static void free(void *data, GDExtensionClassInstancePtr ptr) { \
|
||||||
return new ("") m_class((GodotObject *)p_instance); \
|
} \
|
||||||
} \
|
\
|
||||||
static void _gde_binding_free_callback(void *p_token, void *p_instance, void *p_binding) { \
|
static void *_gde_binding_create_callback(void *p_token, void *p_instance) { \
|
||||||
/* Explicitly call the deconstructor to ensure proper lifecycle for non-trivial members */ \
|
/* Do not call memnew here, we don't want the post-initializer to be called */ \
|
||||||
reinterpret_cast<m_class *>(p_binding)->~m_class(); \
|
return new ("") m_class((GodotObject *)p_instance); \
|
||||||
Memory::free_static(reinterpret_cast<m_class *>(p_binding)); \
|
} \
|
||||||
} \
|
static void _gde_binding_free_callback(void *p_token, void *p_instance, void *p_binding) { \
|
||||||
static GDExtensionBool _gde_binding_reference_callback(void *p_token, void *p_instance, GDExtensionBool p_reference) { \
|
/* Explicitly call the deconstructor to ensure proper lifecycle for non-trivial members */ \
|
||||||
return true; \
|
reinterpret_cast<m_class *>(p_binding)->~m_class(); \
|
||||||
} \
|
Memory::free_static(reinterpret_cast<m_class *>(p_binding)); \
|
||||||
static constexpr GDExtensionInstanceBindingCallbacks _gde_binding_callbacks = { \
|
} \
|
||||||
_gde_binding_create_callback, \
|
static GDExtensionBool _gde_binding_reference_callback(void *p_token, void *p_instance, GDExtensionBool p_reference) { \
|
||||||
_gde_binding_free_callback, \
|
return true; \
|
||||||
_gde_binding_reference_callback, \
|
} \
|
||||||
}; \
|
static constexpr GDExtensionInstanceBindingCallbacks _gde_binding_callbacks = { \
|
||||||
m_class() : m_class(#m_alias_for) {}
|
_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.
|
// 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)
|
#define GDEXTENSION_CLASS(m_class, m_inherits) GDEXTENSION_CLASS_ALIAS(m_class, m_class, m_inherits)
|
||||||
|
|
|
@ -11,20 +11,32 @@ def options(opts):
|
||||||
"21",
|
"21",
|
||||||
)
|
)
|
||||||
opts.Add(
|
opts.Add(
|
||||||
"ANDROID_NDK_ROOT",
|
"ANDROID_HOME",
|
||||||
"Path to your Android NDK installation. By default, uses ANDROID_NDK_ROOT from your defined environment variables.",
|
"Path to your Android SDK installation. By default, uses ANDROID_HOME from your defined environment variables.",
|
||||||
os.environ.get("ANDROID_NDK_ROOT", None),
|
os.environ.get("ANDROID_HOME", os.environ.get("ANDROID_SDK_ROOT")),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def exists(env):
|
def exists(env):
|
||||||
return "ANDROID_NDK_ROOT" in os.environ or "ANDROID_NDK_ROOT" in ARGUMENTS
|
return get_android_ndk_root(env) is not None
|
||||||
|
|
||||||
|
|
||||||
|
# This must be kept in sync with the value in https://github.com/godotengine/godot/blob/master/platform/android/detect.py#L58.
|
||||||
|
def get_ndk_version():
|
||||||
|
return "23.2.8568313"
|
||||||
|
|
||||||
|
|
||||||
|
def get_android_ndk_root(env):
|
||||||
|
if env["ANDROID_HOME"]:
|
||||||
|
return env["ANDROID_HOME"] + "/ndk/" + get_ndk_version()
|
||||||
|
else:
|
||||||
|
return os.environ.get("ANDROID_NDK_ROOT")
|
||||||
|
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
if "ANDROID_NDK_ROOT" not in env:
|
if get_android_ndk_root(env) is None:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"To build for Android, ANDROID_NDK_ROOT must be defined. Please set ANDROID_NDK_ROOT to the root folder of your Android NDK installation."
|
"To build for Android, the path to the NDK must be defined. Please set ANDROID_HOME to the root folder of your Android SDK installation."
|
||||||
)
|
)
|
||||||
|
|
||||||
if env["arch"] not in ("arm64", "x86_64", "arm32", "x86_32"):
|
if env["arch"] not in ("arm64", "x86_64", "arm32", "x86_32"):
|
||||||
|
@ -40,7 +52,7 @@ def generate(env):
|
||||||
env["android_api_level"] = "21"
|
env["android_api_level"] = "21"
|
||||||
|
|
||||||
# Setup toolchain
|
# Setup toolchain
|
||||||
toolchain = env["ANDROID_NDK_ROOT"] + "/toolchains/llvm/prebuilt/"
|
toolchain = get_android_ndk_root(env) + "/toolchains/llvm/prebuilt/"
|
||||||
if sys.platform == "win32" or sys.platform == "msys":
|
if sys.platform == "win32" or sys.platform == "msys":
|
||||||
toolchain += "windows"
|
toolchain += "windows"
|
||||||
import platform as pltfm
|
import platform as pltfm
|
||||||
|
|
|
@ -239,6 +239,15 @@ def generate(env):
|
||||||
|
|
||||||
print("Building for architecture " + env["arch"] + " on platform " + env["platform"])
|
print("Building for architecture " + env["arch"] + " on platform " + env["platform"])
|
||||||
|
|
||||||
|
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
|
# Disable exception handling. Godot doesn't use exceptions anywhere, and this
|
||||||
# saves around 20% of binary size and very significant build time.
|
# saves around 20% of binary size and very significant build time.
|
||||||
if env["disable_exceptions"]:
|
if env["disable_exceptions"]:
|
||||||
|
@ -249,15 +258,6 @@ def generate(env):
|
||||||
elif env.get("is_msvc", False):
|
elif env.get("is_msvc", False):
|
||||||
env.Append(CXXFLAGS=["/EHsc"])
|
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
|
# Require C++17
|
||||||
if env.get("is_msvc", False):
|
if env.get("is_msvc", False):
|
||||||
env.Append(CXXFLAGS=["/std:c++17"])
|
env.Append(CXXFLAGS=["/std:c++17"])
|
||||||
|
|
Loading…
Reference in New Issue