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

Author Topic: [SOLVED] How to use SFML.NET on linux/mono?  (Read 14363 times)

0 Members and 1 Guest are viewing this topic.

mkalex777

  • Full Member
  • ***
  • Posts: 206
    • View Profile
[SOLVED] How to use SFML.NET on linux/mono?
« on: September 26, 2015, 09:25:27 pm »
Hi guys,

Can anyone help me to run my application on linux mono.
Does SFML.NET supports it? What I need to setup in order to use SFML.NET on linux?
Thanks
« Last Edit: October 06, 2015, 10:08:47 pm by mkalex777 »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
How to use SFML.NET on linux/mono?
« Reply #1 on: September 27, 2015, 12:22:25 pm »
Did you even try to do something? Did you google how Mono works on Linux? etc

You know a programmers "job" is to solve problems, which also involves trying things, instead of running to the forum with everything unknown.
« Last Edit: September 27, 2015, 12:24:19 pm by eXpl0it3r »
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

mkalex777

  • Full Member
  • ***
  • Posts: 206
    • View Profile
Re: How to use SFML.NET on linux/mono?
« Reply #2 on: September 28, 2015, 09:21:08 pm »
Did you even try to do something? Did you google how Mono works on Linux? etc

yes, I got the following:
qa@DEBIAN7:~/Documents/Proto$ mono Proto.exe
[ERROR] FATAL UNHANDLED EXCEPTION: System.DllNotFoundException: csfml-graphics-2
  at (wrapper managed-to-native) SFML.Graphics.Font:sfFont_createFromFile (string)
  at SFML.Graphics.Font..ctor (System.String filename) [0x00000] in <filename unknown>:0
  at Proto.Game.LoadResources () [0x00000] in <filename unknown>:0
  at Proto.Game.Init () [0x00000] in <filename unknown>:0
  at Proto.Game.Run (System.String[] args) [0x00000] in <filename unknown>:0
  at Proto.Program.Main (System.String[] args) [0x00000] in <filename unknown>:0
 

I placed all required files, include sfml-net assemblies and CSFML libraries from Linux download package.
But it didn't works.

My WinForms app works ok on this machine (it actually uses DirectX, but it switch to GDI+ if DirectX assemblies is not available)
« Last Edit: September 28, 2015, 09:24:43 pm by mkalex777 »

Dejan Geci

  • Newbie
  • *
  • Posts: 19
    • View Profile
Re: How to use SFML.NET on linux/mono?
« Reply #3 on: September 29, 2015, 01:42:56 pm »
Haven't tried running it on Linux, but you probably have a DLL mapping issue. Basically, your app is looking for '.dll' files, but actual libraries for Linux end in '.so'. Check out this link: http://stackoverflow.com/questions/23448259/sfml-net-cant-locate-native-library-on-linux

You need to create a config file with dllmap for your app.

mkalex777

  • Full Member
  • ***
  • Posts: 206
    • View Profile
Re: How to use SFML.NET on linux/mono?
« Reply #4 on: September 29, 2015, 08:14:18 pm »
Haven't tried running it on Linux, but you probably have a DLL mapping issue. Basically, your app is looking for '.dll' files, but actual libraries for Linux end in '.so'. Check out this link: http://stackoverflow.com/questions/23448259/sfml-net-cant-locate-native-library-on-linux

You need to create a config file with dllmap for your app.

Thanks dude.
I have too small experience with linux/mono and it's the thing that I didn't know before.
Looks like exacly what I need. I will try it later.

mkalex777

  • Full Member
  • ***
  • Posts: 206
    • View Profile
Re: How to use SFML.NET on linux/mono?
« Reply #5 on: October 05, 2015, 05:22:10 pm »
I tried to add dll mapping, but it still didn't works...

I added the following:
    <dllmap dll="csfml-audio-2" target="libcsfml-audio.so.2.3"/>
    <dllmap dll="csfml-graphics-2" target="libcsfml-graphics.so.2.3"/>
    <dllmap dll="csfml-system-2" target="libcsfml-system.so.2.3"/>
    <dllmap dll="csfml-window-2" target="libcsfml-window.so.2.3"/>
    <dllmap dll="csfml-network-2" target="libcsfml-network.so.2.3"/>
 

And there is still the same error:
qa@DEBIAN7:~/Documents/Proto$ mono Proto.exe
[ERROR] FATAL UNHANDLED EXCEPTION: System.DllNotFoundException: csfml-graphics-2
  at (wrapper managed-to-native) SFML.Graphics.Font:sfFont_createFromFile (string)
  at SFML.Graphics.Font..ctor (System.String filename) [0x00000] in <filename unknown>:0
  at Proto.Game.LoadResources () [0x00000] in <filename unknown>:0
  at Proto.Game.Init () [0x00000] in <filename unknown>:0
  at Proto.Game.Run (System.String[] args) [0x00000] in <filename unknown>:0
  at Proto.Program.Main (System.String[] args) [0x00000] in <filename unknown>:0
 

I tried to add config file for each dll, as mentioned here: http://en.sfml-dev.org/forums/index.php?topic=12998.0
For example: sfmlnet-graphics-2.dll.config
&#65279;<?xml version="1.0"?>

<configuration>
    <dllmap os="linux" dll="csfml-window-2" target="libcsfml-window.so.2.2"/>
    <dllmap os="linux" dll="csfml-system-2" target="libcsfml-system.so.2.2"/>
    <dllmap os="linux" dll="csfml-graphics-2" target="libcsfml-graphics.so.2.2"/>
    <dllmap os="linux" dll="csfml-audio-2" target="libcsfml-audio.so.2.2"/>
</configuration>
 

And it cause the following error:
qa@DEBIAN7:~/Documents/Proto$ mono Proto.exe
[ERROR] FATAL UNHANDLED EXCEPTION: System.DllNotFoundException: libcsfml-graphics.so.2.2
  at (wrapper managed-to-native) SFML.Graphics.Font:sfFont_createFromFile (string)
  at SFML.Graphics.Font..ctor (System.String filename) [0x00000] in <filename unknown>:0
  at Proto.Game.LoadResources () [0x00000] in <filename unknown>:0
  at Proto.Game.Init () [0x00000] in <filename unknown>:0
  at Proto.Game.Run (System.String[] args) [0x00000] in <filename unknown>:0
  at Proto.Program.Main (System.String[] args) [0x00000] in <filename unknown>:0
 

So, now it understand that it mapped to libcsfml-graphics.so.2.2, but still cannot load it.
All *.so already has execution permission

Any idea on how to fix it?
« Last Edit: October 05, 2015, 05:55:04 pm by mkalex777 »

scellow

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: How to use SFML.NET on linux/mono?
« Reply #6 on: October 05, 2015, 09:27:14 pm »
Make sure your *.config files are located next to your sfmlnet-*.dll's

Also try the full path of your native lib /usr/lib/libcsfml-*.so.2.3

EDIT:

Make sure you installed both smlf and csfml packages !!

mkalex777

  • Full Member
  • ***
  • Posts: 206
    • View Profile
Re: How to use SFML.NET on linux/mono?
« Reply #7 on: October 05, 2015, 11:48:37 pm »
Make sure your *.config files are located next to your sfmlnet-*.dll's

Also try the full path of your native lib /usr/lib/libcsfml-*.so.2.3

EDIT:

Make sure you installed both smlf and csfml packages !!

its already near sfmlnet dll, I tried full path, tried to set environment variable as recommended in some answers, tried different versions.
I even tried to install package with apt-get install, but it's very old (1.6).
I tried to run it with trace option to find the reason why it cannot find the library. But the mono didn't show such info.
No way - it just didn't works...  :(

mkalex777

  • Full Member
  • ***
  • Posts: 206
    • View Profile
Re: How to use SFML.NET on linux/mono?
« Reply #8 on: October 06, 2015, 02:08:43 pm »
I've investigated the problem more deep and found the following issues in SFML.NET:

1) DllImport uses explicit ".dll" extension, so mono runtime attempts to load "csfml-audio-2.dll.so" instead of "csfml-audio-2.so"

To support both platforms, there is need to remove all ".dll" extension from all DllImport attributes.
With such modification, the appropriate library will be automatically resolved (on windows platform will be automatically added ".dll" extension, on linux platform will be automatically added ".so" extension)

Here is an output with MONO_LOG_LEVEL=debug:

Mono: Image addref sfmlnet-audio-2[0x97e0e30] -> /home/qa/Documents/Proto/sfmlnet-audio-2.dll[0x97e05b0]: 2
Mono: Assembly sfmlnet-audio-2[0x97e0e30] added to domain Proto.exe, ref_count=1
Mono: AOT failed to load AOT module /home/qa/Documents/Proto/sfmlnet-audio-2.dll.so: /home/qa/Documents/Proto/sfmlnet-audio-2.dll.so: cannot open shared object file: No such file or directory

<...>

Mono: Assembly Ref addref sfmlnet-audio-2[0x97e0e30] -> mscorlib[0x9786b50]: 9
Mono: DllImport attempting to load: 'libcsfml-audio.so.2'.
Mono: DllImport loading library: '/home/qa/Documents/Proto/libcsfml-audio.so.2'.
Mono: DllImport error loading library 'libsfml-audio.so.2.2.0: cannot open shared object file: No such file or directory'.

 

2) I cannot run my app, because "libcsfml-audio.so.2" requires "libsfml-audio.so.2.2.0". I tried to find it in download section, but it is missing. So, the required reference should be added into CSFML binary package.

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: How to use SFML.NET on linux/mono?
« Reply #9 on: October 06, 2015, 02:55:10 pm »
1) DllImport uses explicit ".dll" extension, so mono runtime attempts to load "csfml-audio-2.dll.so" instead of "csfml-audio-2.so"

This is not an issue, this is why dll mapping exists. You already proved my point showing that the map is working (or was).

[ERROR] FATAL UNHANDLED EXCEPTION: System.DllNotFoundException: libcsfml-graphics.so.2.2

2) I cannot run my app, because "libcsfml-audio.so.2" requires "libsfml-audio.so.2.2.0". I tried to find it in download section, but it is missing. So, the required reference should be added into CSFML binary package.

This is why I haven't bothered to reply to this thread before, you have no idea how to setup basic stuff on linux and I can't be bothered to explain the basics of installing libs. You need to be able to compile a simple C program that runs correctly (proves that CSFML is installed correctly) before you can even think of using SFML.Net.

Make sure you installed both smlf and csfml packages !!

Pretty much this sums it up, CSFML depends on SFML.

its already near sfmlnet dll

This isn't how libs work on linux, they must be installed.
« Last Edit: October 06, 2015, 03:00:47 pm by zsbzsb »
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

mkalex777

  • Full Member
  • ***
  • Posts: 206
    • View Profile
Re: How to use SFML.NET on linux/mono?
« Reply #10 on: October 06, 2015, 05:26:25 pm »
1) DllImport uses explicit ".dll" extension, so mono runtime attempts to load "csfml-audio-2.dll.so" instead of "csfml-audio-2.so"

This is not an issue, this is why dll mapping exists. You already proved my point showing that the map is working (or was).

[ERROR] FATAL UNHANDLED EXCEPTION: System.DllNotFoundException: libcsfml-graphics.so.2.2

Actually it's an issue, because without ".dll" postfix in DllImport it will works by default with no needs for any mappings. ;) So it's the reason why I mention it. I think it will be better if SFML.NET will works with no need of some kind of magic with renaming/copying couple of files from different sources and playing with configuration files in guessing game to guess what kind of name was really used by developer of this library...

This is why I haven't bothered to reply to this thread before, you have no idea how to setup basic stuff on linux and I can't be bothered to explain the basics of installing libs. You need to be able to compile a simple C program that runs correctly (proves that CSFML is installed correctly) before you can even think of using SFML.Net.

I'm windows platform developer, so all thing related to linux is not so clear for me. I just asking for a help. Is it really so hard to explain what I need to get it run on linux?

By the way, I fixed logging and playing with configs and binaries for a little, now I have the following log from app:
=== 2015-10-06T18:30:12 ===

[INFO ] OS:           Unix 3.2.0.4 (3.2.0.4)
[INFO ] CLR:          4.0.30319.1
[INFO ] System:       x32 (Unix)
[INFO ] Process:      x32
[INFO ] Cpu cores:    2
[INFO ] Command line: /home/qa/Documents/Proto/Proto.exe
[TRACE] Loading x32/sfmlnet-audio-2.dll...
[TRACE] Loading x32/sfmlnet-window-2.dll...
[TRACE] Loading x32/sfmlnet-graphics-2.dll...
[Fatal] DllNotFoundException: libcsfml-graphics.so.2
  at (wrapper managed-to-native) SFML.Graphics.Font:sfFont_createFromFile (string)
  at SFML.Graphics.Font..ctor (System.String filename) [0x00000] in <filename unknown>:0
  at Proto.Game.LoadResources () [0x00000] in <filename unknown>:0
  at Proto.Game.Init () [0x00000] in <filename unknown>:0
  at Proto.Game.Run (System.String[] args) [0x00000] in <filename unknown>:0
  at Proto.Program.RunSafe (System.String[] args) [0x00000] in <filename unknown>:0
  at Proto.Program.Main (System.String[] args) [0x00000] in <filename unknown>:0
 

and the following log from mono:
Mono: DllImport attempting to load: 'libcsfml-audio.so.2.2.0'.
Mono: DllImport loading library: '/home/qa/Documents/Proto/x32/libcsfml-audio.so.2.2.0'.
Mono: DllImport error loading library 'libsfml-audio.so.2.2.0: cannot open shared object file: No such file or directory'.
 

So, now the problem is that "libsfml-audio.so.2.2.0" is missing.
I have no idea where I can download it, because it is missing from download page.
So, I tried to rename "libsfml-audio.so.2.3.2" (taken from download section here) to "libsfml-audio.so.2.2.0".

But anyway it cannot be loaded:
Mono: DllImport attempting to load: 'libcsfml-audio.so.2.2.0'.
Mono: DllImport loading library: '/home/qa/Documents/Proto/x32/libcsfml-audio.so.2.2.0'.
Mono: DllImport error loading library 'libsfml-audio.so.2.2.0: cannot open shared object file: No such file or directory'.
 

Actually file "libsfml-audio.so.2.2.0" exists and it placed together with "libcsfml-audio.so.2.2.0".
Is it means that SFML 2.3.2 is incompatible with CSFML 2.2?

Update: With help of google cache I found SFML 2.2 binaries here: http://www.sfml-dev.org/download/sfml/2.2/

it seems that sfml audio now initialized OK, but sfml-graphics is still not.

Here is ldd result:
qa@DEBIAN7:~/Documents/Proto$ LD_LIBRARY_PATH="/home/qa/Documents/Proto/x32" ldd x32/libcsfml-graphics.so.2.2.0
x32/libcsfml-graphics.so.2.2.0: /lib/i386-linux-gnu/i686/cmov/libc.so.6: version `GLIBC_2.15' not found (required by /home/qa/Documents/Proto/x32/libsfml-window.so.2.2.0)
        linux-gate.so.1 =>  (0xb7718000)
        libsfml-graphics.so.2.2.0 => /home/qa/Documents/Proto/x32/libsfml-graphics.so.2.2.0 (0xb76b8000)
        libsfml-window.so.2.2.0 => /home/qa/Documents/Proto/x32/libsfml-window.so.2.2.0 (0xb769f000)
        libsfml-system.so.2.2.0 => /home/qa/Documents/Proto/x32/libsfml-system.so.2.2.0 (0xb7691000)
        libstdc++.so.6 => /usr/lib/i386-linux-gnu/libstdc++.so.6 (0xb7592000)
        libgcc_s.so.1 => /lib/i386-linux-gnu/libgcc_s.so.1 (0xb7575000)
        libc.so.6 => /lib/i386-linux-gnu/i686/cmov/libc.so.6 (0xb7410000)
        libGLEW.so.1.10 => not found
        libGL.so.1 => /usr/lib/i386-linux-gnu/libGL.so.1 (0xb73b5000)
        libfreetype.so.6 => /usr/lib/i386-linux-gnu/libfreetype.so.6 (0xb7319000)
        libjpeg.so.8 => /usr/lib/i386-linux-gnu/libjpeg.so.8 (0xb72e0000)
        libm.so.6 => /lib/i386-linux-gnu/i686/cmov/libm.so.6 (0xb72ba000)
        libX11.so.6 => /usr/lib/i386-linux-gnu/libX11.so.6 (0xb7182000)
        libXrandr.so.2 => /usr/lib/i386-linux-gnu/libXrandr.so.2 (0xb7179000)
        libudev.so.1 => not found
        libpthread.so.0 => /lib/i386-linux-gnu/i686/cmov/libpthread.so.0 (0xb7160000)
        librt.so.1 => /lib/i386-linux-gnu/i686/cmov/librt.so.1 (0xb7157000)
        /lib/ld-linux.so.2 (0xb7719000)
        libglapi.so.0 => /usr/lib/i386-linux-gnu/libglapi.so.0 (0xb7141000)
        libXext.so.6 => /usr/lib/i386-linux-gnu/libXext.so.6 (0xb712e000)
        libXdamage.so.1 => /usr/lib/i386-linux-gnu/libXdamage.so.1 (0xb712b000)
        libXfixes.so.3 => /usr/lib/i386-linux-gnu/libXfixes.so.3 (0xb7125000)
        libX11-xcb.so.1 => /usr/lib/i386-linux-gnu/libX11-xcb.so.1 (0xb7123000)
        libxcb-glx.so.0 => /usr/lib/i386-linux-gnu/libxcb-glx.so.0 (0xb710a000)
        libxcb.so.1 => /usr/lib/i386-linux-gnu/libxcb.so.1 (0xb70e6000)
        libXxf86vm.so.1 => /usr/lib/i386-linux-gnu/libXxf86vm.so.1 (0xb70e0000)
        libdrm.so.2 => /usr/lib/i386-linux-gnu/libdrm.so.2 (0xb70d2000)
        libdl.so.2 => /lib/i386-linux-gnu/i686/cmov/libdl.so.2 (0xb70ce000)
        libz.so.1 => /lib/i386-linux-gnu/libz.so.1 (0xb70b5000)
        libXrender.so.1 => /usr/lib/i386-linux-gnu/libXrender.so.1 (0xb70aa000)
        libXau.so.6 => /usr/lib/i386-linux-gnu/libXau.so.6 (0xb70a7000)
        libXdmcp.so.6 => /usr/lib/i386-linux-gnu/libXdmcp.so.6 (0xb70a1000)
 
« Last Edit: October 06, 2015, 06:37:00 pm by mkalex777 »

mkalex777

  • Full Member
  • ***
  • Posts: 206
    • View Profile
Re: How to use SFML.NET on linux/mono?
« Reply #11 on: October 06, 2015, 10:02:44 pm »
Yes! I did it!  :D

I build SFML 2.2 from sources with help of guides from this topic: http://en.sfml-dev.org/forums/index.php?topic=12504.0
And used SFML 2.2 *.so files from build to run it.

It's a bit complicated and it seems that SFML 2.2 binary package didn't works, it requires specific version of libc.so. I tried to place it from package, but it didn't help.

So, now my C# app can run in win32, win64, linux32, linux64 from the same executable with no need to rebuild it or reconfigure something!  :)

Here is instruction on how to use SFML.NET on linux:
1) Download and extract SFML.NET binaries from this link: http://www.sfml-dev.org/download/sfml.net/
Actually you need content of the following subfolders inside archive:
SFML.Net-2.2-32-bit.zip\SFML.Net-2.2\
SFML.Net-2.2-32-bit.zip\SFML.Net-2.2\extlibs
 

Place all these folders into folder with platform name, for example "x32" and "x64"

2) Add config files for each sfmlnet-*.dll assembly with dllmap. You need to place in the same folder with sftmlnet-*.dll assemblies.
I'm using the same content for all sfmlnet libraries, for example:

sfmlnet-system-2.dll.config
&#65279;<?xml version="1.0"?>
<configuration>
    <dllmap os="windows" dll="csfml-system-2" target="csfml-system-2.dll"/>
    <dllmap os="windows" dll="csfml-graphics-2" target="csfml-graphics-2.dll"/>
    <dllmap os="windows" dll="csfml-window-2" target="csfml-window-2.dll"/>
    <dllmap os="windows" dll="csfml-audio-2" target="csfml-audio-2.dll"/>
    <dllmap os="linux" dll="csfml-system-2" target="libcsfml-system.so.2.2"/>
    <dllmap os="linux" dll="csfml-graphics-2" target="libcsfml-graphics.so.2.2"/>
    <dllmap os="linux" dll="csfml-window-2" target="libcsfml-window.so.2.2"/>
    <dllmap os="linux" dll="csfml-audio-2" target="libcsfml-audio.so.2.2"/>
</configuration>
 

3) Build SFML binaries, use download page for SFML 2.2: http://www.sfml-dev.org/download/sfml/2.2/
I'm used Debian, so it may be different if you are using different linux.
Install the following packages (I don't remember all, just writing down what I installed):
apt-get install libglew-dev
apt-get install freeglut3-dev
apt-get install libjpeg-dev
apt-get install libfreetype6-dev
apt-get install libxrandr-dev
apt-get install libglew-dev
apt-get install libsndfile1-dev
apt-get install libopenal-dev
apt-get install g++
apt-get install cmake
apt-get install cmake-gui
apt-get install make
apt-get install libudev-dev
 

Now, build SFML 2.2 by following instructions from Tirion Helkaraxe on the page http://en.sfml-dev.org/forums/index.php?topic=12504.0
(run CMake, then build with make build and then make install with su permission)

When build complete, you can get SFML 2.2 *.so files from the folder build/lib

place it into the same folder near csfml-*.so

4) Now it's ready to run :)

Make your app in Visual Studio, I'm using the following startup code with automatic platform specific assembly loader:
    class Program
    {
        static Program()
        {
            Logger.Start();
            AppDomain.CurrentDomain.UnhandledException += AppDomain_OnUnhandledException;
            AppDomain.CurrentDomain.AssemblyResolve += AppDomain_OnAssemblyResolve;
        }

        static void Main(string[] args)
        {
            try
            {
                RunSafe(args);
            }
            catch (Exception ex)
            {
                Logger.Fatal(ex);
            }
            finally
            {
                Logger.Finish();
            }
        }

        private static void RunSafe(string[] args)
        {
            using (var game = new Game())
            {
                game.Run(args);
            }
        }

        private static void AppDomain_OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            if (e.IsTerminating)
                Logger.Fatal(e.ExceptionObject as Exception);
            else
                Logger.Error(e.ExceptionObject as Exception);
        }

        private static Assembly AppDomain_OnAssemblyResolve(object sender, ResolveEventArgs e)
        {
            var asmName = Path.Combine(
                Environment.Is64BitProcess ? "x64" : "x32",
                new AssemblyName(e.Name).Name + ".dll");
            Logger.Trace("Loading {0}...", asmName);
            var folder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            var asmPath = Path.Combine(folder, asmName);
            if (!File.Exists(asmPath)) return null;
            return Assembly.LoadFrom(asmPath);
        }
}
 

As you can see I little improved assembly loader from my previous example on how to make platform independent executable. Now it more flexible, there is no need to hardcode assembly names, it just loads all platform dependent assemblies form ".\x32\" or ".\x64\" folders.

Here is log output from linux machine:
=== 2015-10-06T23:01:03 ===

[INFO ] OS:           Unix 3.2.0.4 (3.2.0.4)
[INFO ] CLR:          4.0.30319.1
[INFO ] System:       x32 (Unix)
[INFO ] Process:      x32
[INFO ] Cpu cores:    2
[INFO ] Command line: /home/qa/Documents/Proto/Proto.exe
[TRACE] Loading x32/sfmlnet-audio-2.dll...
[TRACE] Loading x32/sfmlnet-window-2.dll...
[TRACE] Loading x32/sfmlnet-graphics-2.dll...
<... game logs...>
 

As you can see Mono did not load sfmlnet-system-2.dll at all.
Just look on windows log output from the same exe:
=== 2015-10-06T22:26:13 ===

[INFO ] OS:           Microsoft Windows NT 6.1.7601 Service Pack 1 (6.1.7601.65536)
[INFO ] CLR:          4.0.30319.34209
[INFO ] System:       x64 (Win32NT)
[INFO ] Process:      x64
[INFO ] Cpu cores:    4
[INFO ] Command line: "G:\SRC\Game\Proto\bin\Release\Proto.vshost.exe"
[TRACE] Loading x64\sfmlnet-system-2.dll...
[TRACE] Loading x64\sfmlnet-audio-2.dll...
[TRACE] Loading x64\sfmlnet-window-2.dll...
[TRACE] Loading x64\sfmlnet-graphics-2.dll...
<...game logs...>
 


Also, you need to disable copy local flag for sfmlnet-*.dll references (on reference property page). It needs to avoid copy of sfmlnet assemblies near executable. Don't forgot to set Any CPU target option for the project.

Now you can run the same executable under win x86 and it will run as 32-bit process. If you run it under win x64 it will run as 64-bit process. And if you run it under linux with mono it will load SO files instead of DLL.

To run the app under linux, the path to SFML libraries should be specified in LD_LIBRARY_PATH.
You can run app without installing SFML libraries into lib folder with following command line:
LD_LIBRARY_PATH="/home/qa/Documents/MyApp/x32" mono MyApp.exe
 

where "/home/qa/Documents/MyApp/x32/" is the path to SFML libraries.

If something is going wrong, you can run the app with debug level logging, with following command line:
LD_LIBRARY_PATH="/home/qa/Documents/MyApp/x32" MONO_LOG_LEVEL=debug mono MyApp.exe
 

It will show all error details for app loading .

Also you can check if there is any unresolved dependency for SO library with ldd:
LD_LIBRARY_PATH="/home/qa/Documents/MyApp/x32" ldd libcsfml-graphics.so.2.2
 
« Last Edit: October 06, 2015, 10:24:27 pm by mkalex777 »

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: [SOLVED] How to use SFML.NET on linux/mono?
« Reply #12 on: October 06, 2015, 11:50:55 pm »
I knew you could do it  ;)
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

Kameko

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: [SOLVED] How to use SFML.NET on linux/mono?
« Reply #13 on: November 03, 2015, 12:14:48 am »
Sorry for bumping, but I didn't feel this deserved it's own thread.

Is there a good way to do this when you have your dlls in multiple directories? For instance, a "win" directory for the Windows SFML dlls, and a "linux" directory, etc. I tried making *.dll.config files by specifying "target="win\csfml-system-2.dll"" but that didn't seem to work.

Also, besides making *.dll.configs for all of the dlls, is there a way to just probe for a directory on a specific OS? Right now my probing is just set to "<probing privatePath="lib;lib\win" />" and all the DLLs, both the sfmlnet and the csfml are in the same directory, and of course that won't run outside of Windows.

Sorry for asking, but I've been trying tons of configurations and looking up stuff for hours and I can't figure this out.

mkalex777

  • Full Member
  • ***
  • Posts: 206
    • View Profile
Re: [SOLVED] How to use SFML.NET on linux/mono?
« Reply #14 on: November 03, 2015, 08:08:40 am »
Sorry for bumping, but I didn't feel this deserved it's own thread.

Is there a good way to do this when you have your dlls in multiple directories? For instance, a "win" directory for the Windows SFML dlls, and a "linux" directory, etc. I tried making *.dll.config files by specifying "target="win\csfml-system-2.dll"" but that didn't seem to work.

Also, besides making *.dll.configs for all of the dlls, is there a way to just probe for a directory on a specific OS? Right now my probing is just set to "<probing privatePath="lib;lib\win" />" and all the DLLs, both the sfmlnet and the csfml are in the same directory, and of course that won't run outside of Windows.

Sorry for asking, but I've been trying tons of configurations and looking up stuff for hours and I can't figure this out.

Unfortunately you cannot use config file for such purposes due to the issues with diffent behavior for .net and mono. Also there is a bug in mono implementation for config processing.
For example, probing doesn't support platform dependency and even worse it works incorrectly on mono.


According to Microsoft recommendations there are several ways to configure assembly path, but in such case the only one will works on .net and mono. It's AssemblyResolve event.

Here is a tested example which works very well on .net and mono:
    class Program
    {
        static Program()
        {
            Logger.Start();
            AppDomain.CurrentDomain.UnhandledException += AppDomain_OnUnhandledException;
            AppDomain.CurrentDomain.AssemblyResolve += AppDomain_OnAssemblyResolve;
        }

        static void Main(string[] args)
        {
            try
            {
                RunSafe(args);
            }
            catch (Exception ex)
            {
                Logger.Fatal(ex);
            }
            finally
            {
                Logger.Finish();
            }
        }

        private static void RunSafe(string[] args)
        {
            using (var game = new Game())
            {
                game.Run(args);
            }
        }

        private static void AppDomain_OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            if (e.IsTerminating)
                Logger.Fatal(e.ExceptionObject as Exception);
            else
                Logger.Error(e.ExceptionObject as Exception);
        }

        private static Assembly AppDomain_OnAssemblyResolve(object sender, ResolveEventArgs e)
        {
            var asmName = Path.Combine(
                Environment.Is64BitProcess ? "x64" : "x32",
                new AssemblyName(e.Name).Name + ".dll");
            Logger.Trace("Loading {0}...", asmName);
            var folder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            var asmPath = Path.Combine(folder, asmName);
            if (!File.Exists(asmPath))
            {
                Logger.Error("File not found: {0}", Path.GetFullPath(asmPath));
                return null;
            }
            return Assembly.LoadFrom(asmPath);
        }
   }
 

This code will try to load unresolved assemblies from subfolder x32 on 32-bit system and from x64 on 64-bit system.
So, all what you need is to add reference on sfmlnet libraries and set the flag Copy Local=false on property page for these references. It will prevent to copy sfmlnet assemblies into output folder. Next, you need to create x32 and x64 subfolder into output folder and place sfmlnet and csfml dll's into these folders.

For linux platform you also need to place config files for each sfmlnet assembly with the following content:

sfmlnet-audio-2.dll.config:
<?xml version="1.0"?>
<configuration>
    <dllmap os="windows" dll="csfml-system-2" target="csfml-system-2.dll"/>
    <dllmap os="windows" dll="csfml-graphics-2" target="csfml-graphics-2.dll"/>
    <dllmap os="windows" dll="csfml-window-2" target="csfml-window-2.dll"/>
    <dllmap os="windows" dll="csfml-audio-2" target="csfml-audio-2.dll"/>
    <dllmap os="linux" dll="csfml-system-2" target="libcsfml-system.so.2.2"/>
    <dllmap os="linux" dll="csfml-graphics-2" target="libcsfml-graphics.so.2.2"/>
    <dllmap os="linux" dll="csfml-window-2" target="libcsfml-window.so.2.2"/>
    <dllmap os="linux" dll="csfml-audio-2" target="libcsfml-audio.so.2.2"/>
</configuration>
 


I tested it on windows and linux and it works like charm :)

Also, as you can see it uses safe logging to make sure that all errors will be written into log file. The RunSafe method is used to move reference on Game class into separate method. In such way we can guarantee that the mehod Main will be executed safe even if there are some errors with loading reference assemly which is required to access Game class. So, such error will be logged into log file.
« Last Edit: November 03, 2015, 09:45:27 am by mkalex777 »

 

anything