tags:

views:

108

answers:

2

I am trying to compile a JNI library which uses carbon from the command line.

If I don't -I/System/.../JavaVM.Framework/Headers/, It can't find any of the jni types, and gives errors.

If I just -I/System/.../FlatCarbon.framework/Headers but don't "-framework Carbon", it compiles fine, but the linker gives an error about an undefined symbol.

If I compile with -framework Carbon, it works fine, but it turns out that the -I.../FlatCarbon.framework/Headers/ was entirely unnecessary! It works the same with or without it. Now, everything up till now makes sense, except for what follows:

If I -framework JavaVM, but don't include the header directory, then can't find the jni types!

It seems utterly inconsistent. For one framework, the -I is required, and the -framework is optional, for the other, the -framework is required, and the -I is optional. How is this so? Could someone explain how the -framework option works? Is JavaVM a special case?

I am partially posting this question out of curiosity, but also to help anyone else who was searching for a similar solution, because at least with my google-fu, I wasn't able to find anything explaining frameworks from the command line, or how to link to system libraries with gcc on the command line. gcc --help doesn't even document -framework, and everything I could find was about developing with xcode.

+1  A: 

framework are considered for both compilation and linking. I don't know anything about java, but maybe your problem is related to bundles vs. framework: multiple frameworks can be included in a bundle, for example. A framework may contain other frameworks as well.

Unfortunately, those kind of mac-specific stuff is usually not documented in man pages.

David Cournapeau
+1  A: 

"-framework" is sufficient for both the compile stage and the linking stage. I am guessing your JNI code is not correctly referencing the jni.h header (probably missing the reference to the enclosing JavaVM framework).

Code like:

#include <JavaVM/jni.h>

JNIEXPORT jstring JNICALL Java_SomeClass_getStr(JNIEnv *env, jobject obj)
{
    jstring javaName = (*env)->NewString(env, (jchar *)"ana", (jsize)3);
    return javaName;
}

Gets compiled with:

gcc -dynamiclib My.c -o My.o -framework JavaVM
diciu