So I'm doing some work writing JNI bindings and I've run into an issue. I was initially instructed to do all my development in a Windows XP environment (I am used to developing in a Linux environment). This was a little weird at first, but I was able to make things work.
Now that I've got everything working in Windows I've received a request to get it working on OS X, and I've run into a wall.
What worked on Windows -
cl -I"<path to my java folder>\Java\jdk1.6.0_13\include" -I"<path to my java folder>\Java\jdk1.6.0_13\include\win32" -LD <my program name>.c -Fe<my program name>.dll libMyLibrary.lib
This command takes my source file, compiles it against a library file, instructing the compiler to search a few folders in my java directory for header files (this is necessary for JNI function) and it produces a .dll
What I need to do -
I need to do the same thing as above, but in OS X, I can compile a simple JNI program with the following commands:
cc -c -o HelloWorld.o HelloWorld.c -I /System/Library/Frameworks/JavaVM.framework/Home/include
cc -bundle -o libHelloWorld.jnilib HelloWorld.o
I can also compile a nomral c function using the library I used with Windows XP as follows
cc -o <file name> <file name>.c libmyLibrary.a -lcurl -lexpat
What is frustrating is that I can compile non-JNI code that uses my library on OSX, and I can compile simple JNI programs that don't use any libraries, but I can seem to figure out how to compile a piece of native JNI code that also uses a library...
Can anyone point me in the right direction?
Issues with C compilation
Started by Shadowsoal, Jun 05 2009 10:17 AM
12 replies to this topic
#1
Posted 05 June 2009 - 10:17 AM
|
|
|
#2
Posted 05 June 2009 - 10:41 AM
I realized I hadn't pointed out what I'd tried and what kind of error I was getting...
I have tried to merge what worked for normal JNI compilation and normal C function which uses a library and I got this:
$ cc -c -I/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home/include -o <Source file name>.o <Source file name>.c
$ cc -bundle -o lib<Source file name>.jnilib <Source file name>.o libMyLibrary.a -lcurl -lexpat
The first command executes with just a warning (assigning a signed int into an unsigned int, which is intentional)
The second command produces the following errors:
Undefined symbols:
"__LOGGING", referenced from:
__LOGGING$non_lazy_ptr in libMyLibrary.a(cqi.o)
"_LOGSTREAM", referenced from:
_LOGSTREAM$non_lazy_ptr in lib<Source file name>.a(cqi.o)
ld: symbol(s) not found
collect2: ld returned 1 exit status
I highly doubt there's a source level error since I can compile this library against another program which makes all the same calls, it's just not a JNI program.
I'm sure I'm just building this program incorrectly...
I have tried to merge what worked for normal JNI compilation and normal C function which uses a library and I got this:
$ cc -c -I/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home/include -o <Source file name>.o <Source file name>.c
$ cc -bundle -o lib<Source file name>.jnilib <Source file name>.o libMyLibrary.a -lcurl -lexpat
The first command executes with just a warning (assigning a signed int into an unsigned int, which is intentional)
The second command produces the following errors:
Undefined symbols:
"__LOGGING", referenced from:
__LOGGING$non_lazy_ptr in libMyLibrary.a(cqi.o)
"_LOGSTREAM", referenced from:
_LOGSTREAM$non_lazy_ptr in lib<Source file name>.a(cqi.o)
ld: symbol(s) not found
collect2: ld returned 1 exit status
I highly doubt there's a source level error since I can compile this library against another program which makes all the same calls, it's just not a JNI program.
I'm sure I'm just building this program incorrectly...
#3
Posted 05 June 2009 - 04:59 PM
Have you tried gcc? I think you're missing a library that you need to specify with the -l flag.
#4
Posted 06 June 2009 - 08:08 AM
Part of the point is that I should be able to compile with cc, if I can compile a normal JNI program, and I can compile a program which utilizes my library, there isn't really a reason I shouldn't be able to compile a JNI function which uses my library.
Also, I downloaded GCC for OS X and as far as I could tell it has the exact same flags described under --help, so that didn't help much.
Also, I downloaded GCC for OS X and as far as I could tell it has the exact same flags described under --help, so that didn't help much.
#5
Posted 06 June 2009 - 10:33 AM
The problem is that cc may have different features than gcc, even if it has the same compiler options. Varying levels of compliance with the standard, or feature integration for upcoming features. There are more differences that compiler options.
#6
Posted 06 June 2009 - 10:42 AM
Testing with gcc I found I got identical errors.
#7
Posted 06 June 2009 - 11:50 AM
Try getting rid of the -c option on the first line. If you get different errors then you're doing something wrong with the linker's arguments. If you get the same errors then you're forgetting to pass an extra library or something.
#8
Posted 08 June 2009 - 05:23 AM
I removed the -c and rolled it all into one line.
$ gcc -o libHelloWorld.jnilib HelloWorld.c -I /System/Library/Frameworks/JavaVM.framework/Home/include -bundle
Works just fine, and produces a native C library which works with java code.
$ gcc -I/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home/include -o libSourceFile.jnilib SourceFile.c libMyLibrary.a -lcurl -lexpat -bundle
SourceFile.c: In function ‘jstrTOstr’:
SourceFile.c:62: warning: pointer targets in assignment differ in signedness
Undefined symbols:
"__LOGGING", referenced from:
__LOGGING$non_lazy_ptr in libMyLibrary.a(cqiMyLibrary.o)
"_LOGSTREAM", referenced from:
_LOGSTREAM$non_lazy_ptr in libMyLibrary.a(cqiMyLibrary.o)
ld: symbol(s) not found
collect2: ld returned 1 exit status
$
Is what I get when I try it with my real code... Does anyone have any ideas?
$ gcc -o libHelloWorld.jnilib HelloWorld.c -I /System/Library/Frameworks/JavaVM.framework/Home/include -bundle
Works just fine, and produces a native C library which works with java code.
$ gcc -I/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home/include -o libSourceFile.jnilib SourceFile.c libMyLibrary.a -lcurl -lexpat -bundle
SourceFile.c: In function ‘jstrTOstr’:
SourceFile.c:62: warning: pointer targets in assignment differ in signedness
Undefined symbols:
"__LOGGING", referenced from:
__LOGGING$non_lazy_ptr in libMyLibrary.a(cqiMyLibrary.o)
"_LOGSTREAM", referenced from:
_LOGSTREAM$non_lazy_ptr in libMyLibrary.a(cqiMyLibrary.o)
ld: symbol(s) not found
collect2: ld returned 1 exit status
$
Is what I get when I try it with my real code... Does anyone have any ideas?
#9
Posted 08 June 2009 - 12:20 PM
Try adding something like -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home/lib
#10
Posted 08 June 2009 - 12:26 PM
$ gcc -I/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home/include -o libSourceFile.jnilib SourceFile.c libMyLibrary.a -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home/lib -lcurl -lexpat -bundle
SourceFile.c: In function ‘jstrTOstr’:
SourceFile.c:62: warning: pointer targets in assignment differ in signedness
ld: in /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home/lib, can't map file, errno=22
collect2: ld returned 1 exit status
That's what I end up with after adding the -L <path> flag, I feel like I'm getting closer
SourceFile.c: In function ‘jstrTOstr’:
SourceFile.c:62: warning: pointer targets in assignment differ in signedness
ld: in /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home/lib, can't map file, errno=22
collect2: ld returned 1 exit status
That's what I end up with after adding the -L <path> flag, I feel like I'm getting closer
#11
Posted 08 June 2009 - 12:35 PM
So that probably means that you're providing the wrong path. Dig around in the directory tree for the lib folder (might be library or something like that).
#12
Posted 08 June 2009 - 12:43 PM
I realized there shouldn't be a space between -L and the path (in the same way I don't have one between -I and the path)
After changing that I get...
$ gcc -I/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home/include -o libSourceFile.jnilib SourceFile.c libMyLibrary.a -L/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home/lib -lcurl -lexpat -bundle
SourceFile.c: In function ‘jstrTOstr’:
SourceFile.c:62: warning: pointer targets in assignment differ in signedness
Undefined symbols:
"__LOGGING", referenced from:
__LOGGING$non_lazy_ptr in libMyLibrary.a(cqiMyLibrary.o)
"_LOGSTREAM", referenced from:
_LOGSTREAM$non_lazy_ptr in libMyLibrary.a(cqiMyLibrary.o)
ld: symbol(s) not found
collect2: ld returned 1 exit status
$
The same error...
It was suggested on another forum that both the JNI and my library define something as LOGGING and that at link time I'm getting a name collision.
After changing that I get...
$ gcc -I/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home/include -o libSourceFile.jnilib SourceFile.c libMyLibrary.a -L/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home/lib -lcurl -lexpat -bundle
SourceFile.c: In function ‘jstrTOstr’:
SourceFile.c:62: warning: pointer targets in assignment differ in signedness
Undefined symbols:
"__LOGGING", referenced from:
__LOGGING$non_lazy_ptr in libMyLibrary.a(cqiMyLibrary.o)
"_LOGSTREAM", referenced from:
_LOGSTREAM$non_lazy_ptr in libMyLibrary.a(cqiMyLibrary.o)
ld: symbol(s) not found
collect2: ld returned 1 exit status
$
The same error...
It was suggested on another forum that both the JNI and my library define something as LOGGING and that at link time I'm getting a name collision.


Sign In
Create Account

Back to top









