Yes! I did it!
I build SFML 2.2 from sources with help of guides from this topic:
http://en.sfml-dev.org/forums/index.php?topic=12504.0And 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
<?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