sjc / godot-game-services

Godot native plugins for iOS Game Center and Android Google Play Game Services
MIT License
11 stars 3 forks source link

Undefined symbol: _OBJC_CLASS_$_GameServicesHelper in Godot 4 #4

Closed i-Madsen closed 8 months ago

i-Madsen commented 8 months ago

Hi there,

I've been trying to update your plugin to use with Godot 4 (as well as add additional GameCenter calls), but I'm running into some problems in XCode. (My fork: [https://github.com/i-Madsen/godot4-game-services])

I'm able to build the plugin with my changes into a static library and copy it into my Godot project and export it, but then I get these errors when trying to build that in XCode:

ld: warning: Could not find or use auto-linked framework 'CoreAudioTypes' Undefined symbols for architecture arm64: "_OBJCCLASS$_GameServicesHelper", referenced from: objc-class-ref in gameservices.a(gameservices.o) "ClassDB::bind_methodfi(unsigned int, MethodBind, char const, Variant const**, int)", referenced from: GameServices::_bind_methods() in gameservices.a(gameservices.o) ld: symbol(s) not found for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

Any ideas what would cause this?

sjc commented 8 months ago

Could you provide a description of how you're building the plugin?

i-Madsen commented 8 months ago

Inside of ios-gamecenter folder, I'm running: ./scripts/release_static_library.sh 4.0

Release_static_library.sh current looks like this:

#!/bin/bash

PLUGIN="gameservices"

# Compile Plugin
./scripts/generate_static_library.sh $PLUGIN release $1
./scripts/generate_static_library.sh $PLUGIN release_debug $1
mv ./bin/${PLUGIN}.release_debug.a ./bin/${PLUGIN}.debug.a

# Move to release folder
rm -rf ./bin/release
mkdir ./bin/release
rm -rf ./bin/release/${PLUGIN}/${PLUGIN}/bin
mkdir -p ./bin/release/${PLUGIN}/${PLUGIN}/bin
#rm -rf ./bin/release/${PLUGIN}/admob/lib
#mkdir -p ./bin/release/${PLUGIN}/admob/lib

# Move Plugin
mv ./bin/${PLUGIN}.{release,debug}.a ./bin/release/${PLUGIN}/${PLUGIN}/bin
cp ./plugin/${PLUGIN}/config/${PLUGIN}.gdip ./bin/release/${PLUGIN}

#touch ./bin/release/${PLUGIN}/admob/lib/PUT_HERE_ADMOB_SDK

and generate_static_library.sh:

#!/bin/bash

# Compile static libraries

# ARM64 Device
scons target=$2 arch=arm64 plugin=$1 version=$3
# x86_64 Simulator
scons target=$2 arch=x86_64 simulator=yes plugin=$1 version=$3

# Creating a fat libraries for device and simulator
# lib<plugin>.<arch>-<simulator|iphone>.<release|debug|release_debug>.a
lipo -create "./bin/lib$1.x86_64-simulator.$2.a" \
    "./bin/lib$1.arm64-iphone.$2.a" \
    -output "./bin/$1.$2.a"

(Then dragging the gameservices folder created in bin into my godot project under ios/plugins - I'm not exporting for android right now.)

sjc commented 8 months ago

Which Godot header files are you using?

i-Madsen commented 8 months ago

I just checked and at the time the headers were extracted from Godot 4.0.5. Also just tried rebuilding with headers from 4.2.1 (which is what my game project is using), but when I get to the point of attempting to build the game project in XCode the main error still persists:

ld: warning: Could not find or use auto-linked framework 'CoreAudioTypes'
Undefined symbols for architecture arm64:
  "_OBJC_CLASS_$_GameServicesHelper", referenced from:
      objc-class-ref in gameservices.a(gameservices.o)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

It does look like it got rid of the bind_method error however.

Also I should note, to build the plugin I've been copying 'platform_config.h' into godot/core from godot/platforms/ios to fix this:

godot/core/typedefs.h:41:10:{41:10-41:29}: fatal error: 'platform_config.h' file not found [1]
 #include "platform_config.h"

Not sure if there's a better way to go about that since it's from the engine headers?

sjc commented 8 months ago

The root issue seems to be that the scons build isn't including GameServicesHelper.m, mainly because it's only gathering .mm (Objective-C++) source files. I'm not sure why its behaviour has changed, but I'm certain it was working before.

I suggest renaming GameServicesHelper.m to GameServicesHelper.mm. After doing this and rebuilding the missing classes are now in the library:

% nm gameservices.debug.a | grep Helper
gameservices.debug.a(GameServicesHelper.o):
0000000000000420 t -[GameServicesHelper .cxx_destruct]
000000000000040c t -[GameServicesHelper currentLeaderboardID]
0000000000000194 t -[GameServicesHelper gameCenterViewControllerDidFinish:]
0000000000000000 t -[GameServicesHelper initWithGameServices:]
0000000000000044 t -[GameServicesHelper presentViewController:]
0000000000000118 t -[GameServicesHelper presentViewController:forLeaderboardID:]
00000000000003fc t -[GameServicesHelper services]
0000000000000418 t -[GameServicesHelper setCurrentLeaderboardID:]
0000000000000404 t -[GameServicesHelper setServices:]
00000000000004d0 S _OBJC_CLASS_$_GameServicesHelper
0000000000000fbc S _OBJC_IVAR_$_GameServicesHelper._currentLeaderboardID
0000000000000fb8 S _OBJC_IVAR_$_GameServicesHelper._services
00000000000004f8 S _OBJC_METACLASS_$_GameServicesHelper
0000000000000d10 s __OBJC_$_INSTANCE_METHODS_GameServicesHelper
0000000000000df0 s __OBJC_$_INSTANCE_VARIABLES_GameServicesHelper
0000000000000e38 s __OBJC_$_PROP_LIST_GameServicesHelper
0000000000000cb0 s __OBJC_CLASS_PROTOCOLS_$_GameServicesHelper
0000000000000ea0 s __OBJC_CLASS_RO_$_GameServicesHelper
0000000000000cc8 s __OBJC_METACLASS_RO_$_GameServicesHelper
00000000000001ec t ___56-[GameServicesHelper gameCenterViewControllerDidFinish:]_block_invoke
                 U _OBJC_CLASS_$_GameServicesHelper
i-Madsen commented 8 months ago

Awesome, that did the trick and got it to build.

Thank you for the help!