Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: How to build JSFML  (Read 18457 times)

0 Members and 1 Guest are viewing this topic.

pdinklag

  • Sr. Member
  • ****
  • Posts: 330
  • JSFML Developer
    • View Profile
    • JSFML Website
How to build JSFML
« on: January 29, 2012, 06:46:23 am »
The guide to build JSFML has been moved to the Github Wiki: https://github.com/pdinklag/JSFML/wiki/Building-JSFML

Discussion should still happen here. :)
« Last Edit: August 27, 2012, 11:39:05 am by pdinklag »
JSFML - The Java binding to SFML.

pdinklag

  • Sr. Member
  • ****
  • Posts: 330
  • JSFML Developer
    • View Profile
    • JSFML Website
How to build JSFML
« Reply #1 on: January 29, 2012, 04:59:07 pm »
I finished the build targets for Linux, concluding my mission to setup a complete building toolchain. Mac OS X is not on the list of targeted systems yet.
JSFML - The Java binding to SFML.

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4328
    • View Profile
    • Email
How to build JSFML
« Reply #2 on: January 30, 2012, 09:31:05 pm »
I'm currently trying to make it work on Mac but I have some trouble.

I edited the root ant script to add a Mac OS X target, added SFML's binaries to JSFML/sfml/bin/macosx_universal and finally modified SFMLNative.java to add these binaries to nativeLibs (in loadNativeLibraries).

Then I run "ant jar" in both root directory and example directory. However, running "java -jar jsfml-examples.jar" always gives me the following error :
Code: [Select]
Exception in thread "main" java.lang.UnsatisfiedLinkError: Could not find native library in the classpath: macosx_universal/libsfml-system.dylib
at org.jsfml.window.ContextSettings.<clinit>(Unknown Source)
at org.jsfml.examples.scene.Standalone.main(Unknown Source)


From the code and this error I understood that there is something wrong with nativeLibPath and PROPERTY_JSFML_BIN.

So I've got a few questions for you, pdinklag :

    - Am I supposed to do something specific with PROPERTY_JSFML_BIN ? ("$export jsfml.bin=/some/path" maybe ?) I'm not sure to understand the purpose of this property.

    - for windows and linux you add "linux_x64/libjsfml.so" to nativeLibs. What is this library ? I can't find it. I guess I'm supposed to do something similar
    on Mac but I couldn't find any lead in the ant script and the other sources.

    - if I copy the binaries to ~/.jsfml I get a new exception :
Code: [Select]
$ java -jar jsfml-examples.jar
objc[49496]: Class SFApplication is implemented in both /Users/marcoantognini/.jsfml/macosx_universal/libsfml-window.dylib and /usr/local/lib/libsfml-window.2.dylib. One of the two will be used. Which one is undefined.
objc[49496]: Class SFOpenGLView is implemented in both /Users/marcoantognini/.jsfml/macosx_universal/libsfml-window.dylib and /usr/local/lib/libsfml-window.2.dylib. One of the two will be used. Which one is undefined.
objc[49496]: Class SFWindow is implemented in both /Users/marcoantognini/.jsfml/macosx_universal/libsfml-window.dylib and /usr/local/lib/libsfml-window.2.dylib. One of the two will be used. Which one is undefined.
objc[49496]: Class SFWindowController is implemented in both /Users/marcoantognini/.jsfml/macosx_universal/libsfml-window.dylib and /usr/local/lib/libsfml-window.2.dylib. One of the two will be used. Which one is undefined.
objc[49496]: Class SFViewController is implemented in both /Users/marcoantognini/.jsfml/macosx_universal/libsfml-window.dylib and /usr/local/lib/libsfml-window.2.dylib. One of the two will be used. Which one is undefined.
Exception in thread "main" java.lang.UnsatisfiedLinkError: org.jsfml.SFMLNative.nativeInit()V
at org.jsfml.SFMLNative.nativeInit(Native Method)
at org.jsfml.SFMLNative.loadNativeLibraries(Unknown Source)
at org.jsfml.SFMLNativeObject.<clinit>(Unknown Source)
at ShortExample.main(Unknown Source)

Just to be sure, nativeInit is defined as Java_org_jsfml_SFMLNative_nativeInit in C++, right ?

- "One of the two will be used. Which one is undefined." warning happens because libsfml-window.dylib was loaded twice. In fact, if I do not add any lib to nativeLibs and remove the following condition, then I "only" get the exception without the warnings.
Code: [Select]
           if (nativeLibs.size() == 0) {
                throw new JSFMLException("Unsupported operating system: " + osName + " " + osArch);
            }

[/list]
SFML / OS X developer

pdinklag

  • Sr. Member
  • ****
  • Posts: 330
  • JSFML Developer
    • View Profile
    • JSFML Website
How to build JSFML
« Reply #3 on: January 30, 2012, 10:54:09 pm »
Nice you're going for it! :)

Quote from: "Hiura"
Am I supposed to do something specific with PROPERTY_JSFML_BIN ?

That property I believe can safely be ignored. I realized that I will not want people to tamper with it. :) I should probably remove it to avoid this type of confusion.

SFMLNative checks the classpath for the "bin" folder, from which it will load the libraries specified after OS and architecture detection. Note that load order is very important here, but this doesn't seem to be your problem. From there, it will extract the binaries to the user .jsfml directory. This way I can contain all binaries for all systems in a single file and people don't have to bother.

Quote from: "Hiura"
for windows and linux you add "linux_x64/libjsfml.so" to nativeLibs. What is this library ? I can't find it.

JSFML also has C++ sources which do the actual delegation to SFML, and those are compiled and linked into jsfml.dll / libjsfml.so using the "win32", "win64", "linux32" and "linux64" targets in the ant buildfile. You will need to compile those sources into a dylib as well.

Code: [Select]
Exception in thread "main" java.lang.UnsatisfiedLinkError: org.jsfml.SFMLNative.nativeInit()V
   at org.jsfml.SFMLNative.nativeInit(Native Method)
   at org.jsfml.SFMLNative.loadNativeLibraries(Unknown Source)
   at org.jsfml.SFMLNativeObject.<clinit>(Unknown Source)
   at ShortExample.main(Unknown Source)

This is the missing libjsfml.dylib you need to create from the C++ sources.

Quote from: "Hiura"
Just to be sure, nativeInit is defined as Java_org_jsfml_SFMLNative_nativeInit in C++, right ?

Yes.

Quote from: "Hiura"
"One of the two will be used. Which one is undefined." warning happens because libsfml-window.dylib was loaded twice.

Why does that happen? I'm not sure how Mac OS X's Java ticks concerning libraries, but my guess is that if you load libsfml-graphics.dylib, it automatically loads the dependencies before that (it doesn't do that on Windows and Linux). Try removing the "libsfml-window.dylib" from the nativeLibs list and see what happens.

I guess you used some kind of "make install" when building SFML? It's not good if it suddenly uses a dylib from elsewhere, this might cause bad incompatibilities. Not sure what we can do about this.
JSFML - The Java binding to SFML.

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4328
    • View Profile
    • Email
How to build JSFML
« Reply #4 on: January 31, 2012, 03:27:53 pm »
Quote from: "pdinklag"
That property I believe can safely be ignored.
Ok.

Quote from: "pdinklag"
Note that load order is very important here, but this doesn't seem to be your problem.
No, it's not an issue on Mac from my experience.

Quote from: "pdinklag"
You will need to compile those sources into a dylib as well.
I did but then I 'ant clean'd it -.- . (Apple recommends to call them jnilib but this is the same as dylib.)

Quote from: "pdinklag"
Why does that happen? I'm not sure how Mac OS X's Java ticks concerning libraries
In fact this has nothing to do with Java. It's how Objective-C works when two classes with the same name are loaded from two libraries.

Quote from: "pdinklag"
Try removing the "libsfml-window.dylib" from the nativeLibs list and see what happens.
It indeed does remove the warnings.



So, I made some progress ( I essentially added the jnilib to nativeLibs ) but have a bad news for you : here is the output of the example.

Code: [Select]
$ java -jar jsfml-examples.jar
Cannot create a window from a worker thread. (OS X limitation)


No window appears (because none is created) but the music is played.
This is a restriction on SFML. I'll see what I can do to make things work.

I'll let you know when I find something.
SFML / OS X developer

pdinklag

  • Sr. Member
  • ****
  • Posts: 330
  • JSFML Developer
    • View Profile
    • JSFML Website
How to build JSFML
« Reply #5 on: January 31, 2012, 03:40:09 pm »
Good to see it working! (well, kindof)

Be careful with audio. SFML does not allow a manual shutdown of the AudioDevice and the JVM termination does not seem to invoke static destructors, so the AudioDevice never gets destroyed and the OpenAL thread keeps running until you kill the Java process. I'm just mentioning this in case you start wondering why the process won't end. ;)

Good luck with that window issue. Mac support would be sweet!
JSFML - The Java binding to SFML.

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4328
    • View Profile
    • Email
How to build JSFML
« Reply #6 on: February 01, 2012, 12:38:52 am »
Well, I've some bad news : I modified SFML source code to let the user create a window from a worker thread but I crashed as I expected. Apple documentation says a window must be created from the main thread - that's why I disabled doing so in a worker thread in the first place.

Code: [Select]
$ java -jar jsfml-examples.jar
Cannot create a window from a worker thread. (OS X limitation)
Segmentation fault: 11

with a call stack directly link to the window in cocoa api.

Now, I don't know enough Java's API but you might be able to help me : how can I force the execution of some function on the main thread ?

Beside this issue,
Quote
I guess you used some kind of "make install" when building SFML? It's not good if it suddenly uses a dylib from elsewhere, this might cause bad incompatibilities. Not sure what we can do about this.
I tried to use JSFML after removing all SFML binaries from my system except from .jsfml. Unfortunately this doesn't work :

 
Code: [Select]
$ java -jar jsfml-examples.jar
Exception in thread "main" java.lang.UnsatisfiedLinkError: /Users/marcoantognini/.jsfml/macosx_universal/libjsfml.jnilib:  Library not loaded: @executable_path/../Frameworks/libsfml-system.2.dylib   Referenced from: /Users/marcoantognini/.jsfml/macosx_universal/libjsfml.jnilib   Reason: image not found
at org.jsfml.window.ContextSettings.<clinit>(Unknown Source)
at org.jsfml.examples.scene.Standalone.main(Unknown Source)

It appears that the jnilib will try to load libsfml-system.dylib even if it was loaded by Java manually. This means that the users must install SFML in the default location.
I consider this is not an issue, at least not when SFML 2.0 will be officially released : everybody will then have the same version of SFML thus avoiding incompatibility issues.

I fork your repository here so you can see my work if necessary.
SFML / OS X developer

pdinklag

  • Sr. Member
  • ****
  • Posts: 330
  • JSFML Developer
    • View Profile
    • JSFML Website
How to build JSFML
« Reply #7 on: February 01, 2012, 07:49:49 am »
I have never run into these kinds of problems, but I will read about it.
Normal Java Swing GUIs do work, right? They (the Java developers) must have found a way to create windows, so I believe it must be possible somehow.

If not, there is a plan B. That plan would be to not feature dedicated RenderWindows under JSFML on Mac OS X. Instead, one could create a simple Swing frame and put a RenderCanvas on it (planned for JSFML 1.x). I suppose that on Mac OS X, the RenderWindow(HANDLE) constructor works even in a worker thread?

Quote from: "Hiura"
It appears that the jnilib will try to load libsfml-system.dylib even if it was loaded by Java manually. This means that the users must install SFML in the default location.

Can you try running Java with the following command line argument?
Code: [Select]
-Djava.library.path=/Users/marcoantognini/.jsfml/

The java.library.path System property is used for locating dynamic libraries if they are not loaded manually using an absolute path. I tried to avoid that, because I kept running into issues with it, but it would still be a very nice solution.
JSFML - The Java binding to SFML.

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4328
    • View Profile
    • Email
How to build JSFML
« Reply #8 on: February 01, 2012, 10:14:29 am »
Quote from: "pdinklag"
Normal Java Swing GUIs do work, right? They (the Java developers) must have found a way to create windows, so I believe it must be possible somehow.
I'll try to look how things work. Maybe I missed something in Apple doc about JNI.

Quote from: "pdinklag"
I suppose that on Mac OS X, the RenderWindow(HANDLE) constructor works even in a worker thread?

Yes, it does.


Quote from: "pdinklag"
Can you try running Java with the following command line argument?
Code: [Select]
-Djava.library.path=/Users/marcoantognini/.jsfml/

Unfortunately, it didn't work. Same with
Code: [Select]
-Djava.library.path=/Users/marcoantognini/.jsfml/macosx_universal/
 :?
SFML / OS X developer

pdinklag

  • Sr. Member
  • ****
  • Posts: 330
  • JSFML Developer
    • View Profile
    • JSFML Website
How to build JSFML
« Reply #9 on: February 01, 2012, 01:53:22 pm »
It appears to me that the depdendency's full path is written into the jnilib when it is linked. Do you have any influence on that?
JSFML - The Java binding to SFML.

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4328
    • View Profile
    • Email
How to build JSFML
« Reply #10 on: February 01, 2012, 03:19:30 pm »
Yes, you're right!

I can use install_name_tool to play with that but this is only a minor issue compared to the window creation.
SFML / OS X developer

pdinklag

  • Sr. Member
  • ****
  • Posts: 330
  • JSFML Developer
    • View Profile
    • JSFML Website
How to build JSFML
« Reply #11 on: February 01, 2012, 04:01:00 pm »
Still it's much more convenient if that's out of the way! :)
I will try and do some research on the window thing myself in a bunch, see what I can find out.
JSFML - The Java binding to SFML.

pdinklag

  • Sr. Member
  • ****
  • Posts: 330
  • JSFML Developer
    • View Profile
    • JSFML Website
How to build JSFML
« Reply #12 on: February 01, 2012, 04:57:27 pm »
Found this:
http://stackoverflow.com/questions/3976342/running-swt-based-cross-platform-jar-properly-on-a-mac

In short, try adding this command line argument:
Code: [Select]
-XstartOnFirstThread

Apparently, this can cause trouble on other systems, so we'll have to think of something here. But let's see if this does the trick first. I'm not too sure about that, since I could not get any information on this flag outside a SWT context. JSFML is not a SWT application.
JSFML - The Java binding to SFML.

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4328
    • View Profile
    • Email
How to build JSFML
« Reply #13 on: February 02, 2012, 07:00:04 pm »
I tired some stuff directly in SFML yesterday but only succeed to break the C++ examples.  :roll:


Quote
In short, try adding this command line argument:

Code: [Select]
-XstartOnFirstThread
IT WORKS !  :D

By the way, the example is really cool! I added 1'600 entities without getting any slowdown (run with ~ 60 FPS as expected).

I'll work on the dylib and update my fork. I'll keep you informed when I get something publishable.
SFML / OS X developer

pdinklag

  • Sr. Member
  • ****
  • Posts: 330
  • JSFML Developer
    • View Profile
    • JSFML Website
How to build JSFML
« Reply #14 on: February 02, 2012, 07:23:09 pm »
Hah, awesome! :D

Well yeah, sort it out and file a pull request or something. I haven't worked with those yet but I think I can handle them.

One little request: I noticed you called it "macosx_universal", I believe because Mac OS X always runs on one and the same architecture and not on 32bit or 64bit. I'd say just leave the "_universal" part.

Apart from that, great to know Mac OS X is on the list. :) When it's time to pack up a release of JSFML 1.0 I'll let you know, then you can send me the libjsfml.dylib and I can put it into the final jar. Going to add you to the credits later.

BTW, did you try auto-extraction again? It would be cool if that worked. I can explain how to test it properly if you haven't worked it out yet.
There is one problem left to solve really. On Mac OS X, any JSFML will have to be started using
Code: [Select]
-Djava.library.path=~/.jsfml/macosx -XstartOnFirstThread
However, this cannot be done from within Java because they are JVM flags.

EDIT:
Things are probably way easier if I just give you access to the repo. There's no reason not to trust you, I guess. ;) Let's see if I can get that done...
JSFML - The Java binding to SFML.