Make GDNative work on Android
The changes include work done to ensure that GDNative apps and Nim integration specifically can run on Android. The changes have been tested on our WIP game, which uses godot-nim and depends on several third-party .so libs, and Platformer demo to ensure nothing got broken. - .so libraries are exported to lib/ folder in .apk, instead of assets/, because that's where Android expects them to be and it resolves the library name into "lib/<ABI>/<name>", where <ABI> is the ABI matching the current device. So we establish the convention that Android .so files in the project must be located in the folder corresponding to the ABI they were compiled for. - Godot callbacks (event handlers) are now called from the same thread from which Main::iteration is called. It is also what Godot now considers to be the main thread, because Main::setup is also called from there. This makes threading on Android more consistent with other platforms, making the code that depends on Thread::get_main_id more portable (GDNative has such code). - Sizes of GDNative API types have been fixed to work on 32-bit platforms.
This commit is contained in:
@@ -40,7 +40,7 @@
|
||||
const String init_symbol = "godot_gdnative_init";
|
||||
const String terminate_symbol = "godot_gdnative_terminate";
|
||||
|
||||
String GDNativeLibrary::platform_names[NUM_PLATFORMS] = {
|
||||
String GDNativeLibrary::platform_names[NUM_PLATFORMS + 1] = {
|
||||
"X11_32bit",
|
||||
"X11_64bit",
|
||||
"Windows_32bit",
|
||||
@@ -48,11 +48,15 @@ String GDNativeLibrary::platform_names[NUM_PLATFORMS] = {
|
||||
"OSX",
|
||||
|
||||
"Android",
|
||||
"iOS",
|
||||
|
||||
"WebAssembly"
|
||||
"iOS_32bit",
|
||||
"iOS_64bit",
|
||||
|
||||
"WebAssembly",
|
||||
|
||||
""
|
||||
};
|
||||
String GDNativeLibrary::platform_lib_ext[NUM_PLATFORMS] = {
|
||||
String GDNativeLibrary::platform_lib_ext[NUM_PLATFORMS + 1] = {
|
||||
"so",
|
||||
"so",
|
||||
"dll",
|
||||
@@ -60,21 +64,30 @@ String GDNativeLibrary::platform_lib_ext[NUM_PLATFORMS] = {
|
||||
"dylib",
|
||||
|
||||
"so",
|
||||
|
||||
"dylib",
|
||||
"dylib",
|
||||
|
||||
"wasm"
|
||||
"wasm",
|
||||
|
||||
""
|
||||
};
|
||||
|
||||
// TODO(karroffel): make this actually do the right thing.
|
||||
GDNativeLibrary::Platform GDNativeLibrary::current_platform =
|
||||
#if defined(X11_ENABLED)
|
||||
X11_64BIT;
|
||||
(sizeof(void *) == 8 ? X11_64BIT : X11_32BIT);
|
||||
#elif defined(WINDOWS_ENABLED)
|
||||
WINDOWS_64BIT;
|
||||
(sizeof(void *) == 8 ? WINDOWS_64BIT : WINDOWS_32BIT);
|
||||
#elif defined(OSX_ENABLED)
|
||||
OSX;
|
||||
#elif defined(IPHONE_ENABLED)
|
||||
(sizeof(void *) == 8 ? IOS_64BIT : IOS_32BIT);
|
||||
#elif defined(ANDROID_ENABLED)
|
||||
ANDROID;
|
||||
#elif defined(JAVASCRIPT_ENABLED)
|
||||
WASM;
|
||||
#else
|
||||
X11_64BIT; // need a sensible default..
|
||||
NUM_PLATFORMS;
|
||||
#endif
|
||||
|
||||
GDNativeLibrary::GDNativeLibrary()
|
||||
@@ -151,7 +164,10 @@ String GDNativeLibrary::get_library_path(StringName p_platform) const {
|
||||
}
|
||||
|
||||
String GDNativeLibrary::get_active_library_path() const {
|
||||
return library_paths[GDNativeLibrary::current_platform];
|
||||
if (GDNativeLibrary::current_platform != NUM_PLATFORMS) {
|
||||
return library_paths[GDNativeLibrary::current_platform];
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
GDNative::GDNative() {
|
||||
|
||||
@@ -48,11 +48,17 @@ class GDNativeLibrary : public Resource {
|
||||
// NOTE(karroffel): I heard OSX 32 bit is dead, so 64 only
|
||||
OSX,
|
||||
|
||||
// TODO(karroffel): all different android versions and archs
|
||||
// Android .so files must be located in directories corresponding to Android ABI names:
|
||||
// https://developer.android.com/ndk/guides/abis.html
|
||||
// Android runtime will select the matching library depending on the device.
|
||||
// The value here must simply point to the .so name, for example:
|
||||
// "res://libmy_gdnative.so" or "libmy_gdnative.so",
|
||||
// while in the project the actual paths can be "lib/android/armeabi-v7a/libmy_gdnative.so",
|
||||
// "lib/android/arm64-v8a/libmy_gdnative.so".
|
||||
ANDROID,
|
||||
|
||||
// TODO(karroffe): all different iOS versions and archs
|
||||
IOS,
|
||||
IOS_32BIT,
|
||||
IOS_64BIT,
|
||||
|
||||
// TODO(karroffel): figure out how to deal with web stuff at all...
|
||||
WASM,
|
||||
@@ -64,10 +70,9 @@ class GDNativeLibrary : public Resource {
|
||||
|
||||
};
|
||||
|
||||
static String platform_names[NUM_PLATFORMS];
|
||||
static String platform_lib_ext[NUM_PLATFORMS];
|
||||
static String platform_names[NUM_PLATFORMS + 1];
|
||||
static String platform_lib_ext[NUM_PLATFORMS + 1];
|
||||
|
||||
// TODO(karroffel): make this actually do something lol.
|
||||
static Platform current_platform;
|
||||
|
||||
String library_paths[NUM_PLATFORMS];
|
||||
|
||||
@@ -37,7 +37,7 @@ extern "C" {
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define GODOT_ARRAY_SIZE 8
|
||||
#define GODOT_ARRAY_SIZE sizeof(void *)
|
||||
|
||||
#ifndef GODOT_CORE_API_GODOT_ARRAY_TYPE_DEFINED
|
||||
#define GODOT_CORE_API_GODOT_ARRAY_TYPE_DEFINED
|
||||
|
||||
@@ -36,7 +36,7 @@ extern "C" {
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define GODOT_DICTIONARY_SIZE 8
|
||||
#define GODOT_DICTIONARY_SIZE sizeof(void *)
|
||||
|
||||
#ifndef GODOT_CORE_API_GODOT_DICTIONARY_TYPE_DEFINED
|
||||
#define GODOT_CORE_API_GODOT_DICTIONARY_TYPE_DEFINED
|
||||
|
||||
@@ -56,7 +56,7 @@ extern "C" {
|
||||
#define GDAPI GDCALLINGCONV
|
||||
#endif
|
||||
#else
|
||||
#define GDCALLINGCONV __attribute__((sysv_abi))
|
||||
#define GDCALLINGCONV __attribute__((sysv_abi, visibility("default")))
|
||||
#define GDAPI GDCALLINGCONV
|
||||
#endif
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ extern "C" {
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define GODOT_NODE_PATH_SIZE 8
|
||||
#define GODOT_NODE_PATH_SIZE sizeof(void *)
|
||||
|
||||
#ifndef GODOT_CORE_API_GODOT_NODE_PATH_TYPE_DEFINED
|
||||
#define GODOT_CORE_API_GODOT_NODE_PATH_TYPE_DEFINED
|
||||
|
||||
@@ -38,7 +38,7 @@ extern "C" {
|
||||
|
||||
/////// PoolByteArray
|
||||
|
||||
#define GODOT_POOL_BYTE_ARRAY_SIZE 8
|
||||
#define GODOT_POOL_BYTE_ARRAY_SIZE sizeof(void *)
|
||||
|
||||
#ifndef GODOT_CORE_API_GODOT_POOL_BYTE_ARRAY_TYPE_DEFINED
|
||||
#define GODOT_CORE_API_GODOT_POOL_BYTE_ARRAY_TYPE_DEFINED
|
||||
@@ -49,7 +49,7 @@ typedef struct {
|
||||
|
||||
/////// PoolIntArray
|
||||
|
||||
#define GODOT_POOL_INT_ARRAY_SIZE 8
|
||||
#define GODOT_POOL_INT_ARRAY_SIZE sizeof(void *)
|
||||
|
||||
#ifndef GODOT_CORE_API_GODOT_POOL_INT_ARRAY_TYPE_DEFINED
|
||||
#define GODOT_CORE_API_GODOT_POOL_INT_ARRAY_TYPE_DEFINED
|
||||
@@ -60,7 +60,7 @@ typedef struct {
|
||||
|
||||
/////// PoolRealArray
|
||||
|
||||
#define GODOT_POOL_REAL_ARRAY_SIZE 8
|
||||
#define GODOT_POOL_REAL_ARRAY_SIZE sizeof(void *)
|
||||
|
||||
#ifndef GODOT_CORE_API_GODOT_POOL_REAL_ARRAY_TYPE_DEFINED
|
||||
#define GODOT_CORE_API_GODOT_POOL_REAL_ARRAY_TYPE_DEFINED
|
||||
@@ -71,7 +71,7 @@ typedef struct {
|
||||
|
||||
/////// PoolStringArray
|
||||
|
||||
#define GODOT_POOL_STRING_ARRAY_SIZE 8
|
||||
#define GODOT_POOL_STRING_ARRAY_SIZE sizeof(void *)
|
||||
|
||||
#ifndef GODOT_CORE_API_GODOT_POOL_STRING_ARRAY_TYPE_DEFINED
|
||||
#define GODOT_CORE_API_GODOT_POOL_STRING_ARRAY_TYPE_DEFINED
|
||||
@@ -82,7 +82,7 @@ typedef struct {
|
||||
|
||||
/////// PoolVector2Array
|
||||
|
||||
#define GODOT_POOL_VECTOR2_ARRAY_SIZE 8
|
||||
#define GODOT_POOL_VECTOR2_ARRAY_SIZE sizeof(void *)
|
||||
|
||||
#ifndef GODOT_CORE_API_GODOT_POOL_VECTOR2_ARRAY_TYPE_DEFINED
|
||||
#define GODOT_CORE_API_GODOT_POOL_VECTOR2_ARRAY_TYPE_DEFINED
|
||||
@@ -93,7 +93,7 @@ typedef struct {
|
||||
|
||||
/////// PoolVector3Array
|
||||
|
||||
#define GODOT_POOL_VECTOR3_ARRAY_SIZE 8
|
||||
#define GODOT_POOL_VECTOR3_ARRAY_SIZE sizeof(void *)
|
||||
|
||||
#ifndef GODOT_CORE_API_GODOT_POOL_VECTOR3_ARRAY_TYPE_DEFINED
|
||||
#define GODOT_CORE_API_GODOT_POOL_VECTOR3_ARRAY_TYPE_DEFINED
|
||||
@@ -104,7 +104,7 @@ typedef struct {
|
||||
|
||||
/////// PoolColorArray
|
||||
|
||||
#define GODOT_POOL_COLOR_ARRAY_SIZE 8
|
||||
#define GODOT_POOL_COLOR_ARRAY_SIZE sizeof(void *)
|
||||
|
||||
#ifndef GODOT_CORE_API_GODOT_POOL_COLOR_ARRAY_TYPE_DEFINED
|
||||
#define GODOT_CORE_API_GODOT_POOL_COLOR_ARRAY_TYPE_DEFINED
|
||||
|
||||
@@ -36,7 +36,7 @@ extern "C" {
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define GODOT_RID_SIZE 8
|
||||
#define GODOT_RID_SIZE sizeof(void *)
|
||||
|
||||
#ifndef GODOT_CORE_API_GODOT_RID_TYPE_DEFINED
|
||||
#define GODOT_CORE_API_GODOT_RID_TYPE_DEFINED
|
||||
|
||||
@@ -37,7 +37,7 @@ extern "C" {
|
||||
#include <stdint.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#define GODOT_STRING_SIZE 8
|
||||
#define GODOT_STRING_SIZE sizeof(void *)
|
||||
|
||||
#ifndef GODOT_CORE_API_GODOT_STRING_TYPE_DEFINED
|
||||
#define GODOT_CORE_API_GODOT_STRING_TYPE_DEFINED
|
||||
|
||||
@@ -36,7 +36,7 @@ extern "C" {
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define GODOT_VARIANT_SIZE 24
|
||||
#define GODOT_VARIANT_SIZE (16 + sizeof(void *))
|
||||
|
||||
#ifndef GODOT_CORE_API_GODOT_VARIANT_TYPE_DEFINED
|
||||
#define GODOT_CORE_API_GODOT_VARIANT_TYPE_DEFINED
|
||||
|
||||
@@ -58,7 +58,7 @@ extern "C" {
|
||||
#define GDAPI GDCALLINGCONV
|
||||
#endif
|
||||
#else
|
||||
#define GDCALLINGCONV __attribute__((sysv_abi))
|
||||
#define GDCALLINGCONV __attribute__((sysv_abi, visibility("default")))
|
||||
#define GDAPI GDCALLINGCONV
|
||||
#endif
|
||||
|
||||
|
||||
@@ -994,6 +994,8 @@ void NativeScriptLanguage::init_library(const Ref<GDNativeLibrary> &lib) {
|
||||
#endif
|
||||
// See if this library was "registered" already.
|
||||
const String &lib_path = lib->get_active_library_path();
|
||||
ERR_EXPLAIN(lib->get_name() + " does not have a library for the current platform");
|
||||
ERR_FAIL_COND(lib_path.length() == 0);
|
||||
Map<String, Ref<GDNative> >::Element *E = library_gdnatives.find(lib_path);
|
||||
|
||||
if (!E) {
|
||||
|
||||
Reference in New Issue
Block a user