views:

396

answers:

2

I have a problem with some JNI code. I'm getting the following error printed in the console from a OS X 10.4.11 (PPC) machine (it works fine on newer versions of OS X 10.5+)

dyld: lazy symbol binding failed: Symbol not found: _objc_setProperty
  Referenced from: /Path/to/my/lib/libMylib32.jnilib
  Expected in: /usr/lib/libobjc.A.dylib

dyld: Symbol not found: _objc_setProperty
  Referenced from: /Path/to/my/lib/libMylib32.jnilib
  Expected in: /usr/lib/libobjc.A.dylib

I have another jnilib which works fine that runs before this one in the program. The error seems to be saying I'm missing some core objective c "stuff". The other jnilib which is working on 10.4.11 uses just 1 .m file and doesn't use objective c properties (it uses NSMutableArray, NSDictionary, CFPreferences and so on). The one which doesn't work on 10.4.11 is more complex makes use of some objective c classes with properites I wrote.

Maybe I'm not compiling my code correctly or maybe properties aren't supported?

I have a shell script which compiles the jnilib. It's practically the same as the one which works as far as I can tell. I have another section for compiling the 64 bit jnilib above this in the script but the 32 bit one is being used for 10.4.11.

COCOA_HEADERS=/System/Library/Frameworks/Cocoa.framework/Headers
BITS=32
JAVA_HEADERS=/System/Library/Frameworks/JavaVM.framework/Versions/1.5/Headers
MAC_SDK=/Developer/SDKs/MacOSX10.4u.sdk
CFLAGS="-fPIC -arch i386 -arch ppc"
LIB_NAME=${LIB_PREFIX}${BITS}.jnilib
MAC_LIB_OUTPUT=/path/to/my/output/folder/${LIB_NAME}
DYLIB_ARCH="-arch i386 -arch ppc"

rm *.o
#Compile for 1.5 32bit Java
gcc -v -std=gnu99 -c ${CFLAGS} -isysroot ${MAC_SDK} -I${JAVA_HEADERS} -I${COCOA_HEADERS} ${SOURCE_FILES}
# Make the library file from the object files (*.o)
gcc -v -dynamiclib -o ${MAC_LIB_OUTPUT} *.o  -framework JavaVM -framework Cocoa ${DYLIB_ARCH}

I appreciate your answers and ideas on how to debug this one. Thanks!

+1  A: 

Use Xcode. It supports Java, and it's designed to handle things like supporting old versions of Mac OS X. In Xcode, you would set your SDKROOT to macosx10.4u (Mac OS X, 10.4 with universal binary support) and MACOSX_DEPLOYMENT_TARGET to 10.4, and Xcode will tell the linker where to get the right versions of the frameworks.

If you insist on building with a shell script, then you'll need to do that yourself. You're currently using the system versions.

Peter Hosey
But I'll still have to convert to not use objective c properties right? So, it just uses Objective C 1.0 features for pre leopard support like Mark is saying? Also, are you talking about using the JNI template from XCode? I tried using the JNI template but I found it a bit cumbersome since I didn't really need/want to use javah and I couldn't figure out how to customize the project/settings. I was able to find some examples of Mac JNI in open source projects and the ones I looked at use make or shell scripts so that's what I ended up doing. I still write the code in XCode.
Cal
“But I'll still have to convert to not use objective c properties right? So, it just uses Objective C 1.0 features for pre leopard support like Mark is saying?” Right; you can't use anything from Objective-C 2.0 on Tiger.
Peter Hosey
“I still write the code in XCode.” Using Xcode as only a text editor doesn't get you the conveniences of its build system.
Peter Hosey
I agree and think it would be better if I could setup the build from XCode (if I could figure it out) but for now your suggestion about MACOSX_DEPLOYMENT_TARGET=10.4 was helpful. GCC prints warnings about the use of properties like this MenuActionTarget.h:17: warning: Mac OS X version 10.5 or later is needed for use of property. Thanks.
Cal
+1  A: 

Properties are a new Objective-C 2 feature Apple site and that only runs on OSX 10.5 and above. Thus I suspect the C code will only run on 10.5

You will have to write the C code targeting older versions of OSX. For details see Apple docs This includes non Xcode ways

Mark