From ff96c5f42087d00ef0cdebf0c0a88231c9207b4a Mon Sep 17 00:00:00 2001
From: Ben Parsons <--global>
Date: Fri, 8 May 2020 02:20:20 +1000
Subject: [PATCH] Added Platform.cs - to copy (correct) native library at
 runtime (for netfx) Targets file now copies runtimes folder to output
 directory minor bug fix in sln file.

---
 Raylib-cs.sln               |   4 +-
 Raylib-cs/Platform.cs       |  96 ++++++++++++++++++++++++++
 Raylib-cs/Raylib-cs.csproj  | 133 +++++++++++++++++++-----------------
 Raylib-cs/Raylib-cs.targets |  27 ++++----
 4 files changed, 182 insertions(+), 78 deletions(-)
 create mode 100644 Raylib-cs/Platform.cs

diff --git a/Raylib-cs.sln b/Raylib-cs.sln
index f5ddf0c..823188f 100644
--- a/Raylib-cs.sln
+++ b/Raylib-cs.sln
@@ -19,8 +19,8 @@ Global
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
 		{B02C431E-271A-432E-BA5C-EE3B68DBF585}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{B02C431E-271A-432E-BA5C-EE3B68DBF585}.Release|Any CPU.Build.0 = Release|Any CPU
-		{B02C431E-271A-432E-BA5C-EE3B68DBF585}.Debug|Any CPU.ActiveCfg = Debug|linux-x64
-		{B02C431E-271A-432E-BA5C-EE3B68DBF585}.Debug|Any CPU.Build.0 = Debug|linux-x64
+		{B02C431E-271A-432E-BA5C-EE3B68DBF585}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{B02C431E-271A-432E-BA5C-EE3B68DBF585}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{523DEE6A-20CD-47AB-94A6-8D3C3CF9ADAD}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{523DEE6A-20CD-47AB-94A6-8D3C3CF9ADAD}.Release|Any CPU.Build.0 = Release|Any CPU
 		{523DEE6A-20CD-47AB-94A6-8D3C3CF9ADAD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
diff --git a/Raylib-cs/Platform.cs b/Raylib-cs/Platform.cs
new file mode 100644
index 0000000..f1ba866
--- /dev/null
+++ b/Raylib-cs/Platform.cs
@@ -0,0 +1,96 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+
+namespace Raylib_cs
+{
+    public static class Platform
+    {
+        public static readonly IReadOnlyDictionary<string, ( PlatformID, bool)> SupportedPlatforms =
+            new Dictionary<string, (PlatformID PlatformID, bool x64)>()
+            {
+                {"osx-x64", (PlatformID.MacOSX, true)},
+                {"win-x64", (PlatformID.Win32NT, true)},
+                {"win-x86", (PlatformID.Win32NT, false)},
+                {"linux-x64", (PlatformID.Unix, true)},
+                {"linux-x86", (PlatformID.Unix, false)},
+            };
+
+        public static readonly List<(PlatformID, bool)> HasSupportedPlatformNativeLibrary =
+            new List<(PlatformID, bool)>();
+
+        public static string NativeLibrarySubfolder { get; set; } = "native";
+        public static string RuntimeLibraryFolder { get; set; } = "runtimes";
+
+        private static void DiscoverNativeLibraries()
+        {
+            var localFolders = Directory.GetDirectories(Directory.GetCurrentDirectory());
+            if (!localFolders.Any(d =>
+                string.Equals(d, RuntimeLibraryFolder, StringComparison.InvariantCultureIgnoreCase))) return;
+
+            // for each supported platform, see if the native library exists in the RuntimeLibraryFolder (for now this is any file that doesnt start with ".")
+            foreach (var platform in SupportedPlatforms)
+            {
+                var localPlatformFolder = localFolders.FirstOrDefault(f =>
+                    string.Equals(f, platform.Key, StringComparison.InvariantCultureIgnoreCase));
+
+                if (localPlatformFolder == default) continue;
+
+                var localNativeLibraryFolder = Path.Combine(localPlatformFolder, NativeLibrarySubfolder);
+
+                if (!Directory.Exists(localNativeLibraryFolder))
+                    continue;
+
+                // if all the files in the NativeLibrarySubfolder start with "." then we have not found any native libraries
+                if (Directory.GetFiles(localNativeLibraryFolder).All(f => f[0] == '.')) continue;
+
+                if (!HasSupportedPlatformNativeLibrary.Contains(platform.Value))
+                    HasSupportedPlatformNativeLibrary.Add(platform.Value);
+            }
+        }
+
+        private static string DetectSystem()
+        {
+            Debug.WriteLine(
+                $"System info: {Environment.NewLine}" +
+                $"OS:{Environment.OSVersion.Platform:G}{Environment.NewLine}" +
+                $"ServicePack:{Environment.OSVersion.ServicePack}{Environment.NewLine}" +
+                $"Version:{Environment.OSVersion.Version}{Environment.NewLine}" +
+                $"64OS?:{Environment.Is64BitOperatingSystem}{Environment.NewLine}" +
+                $"64Proc?:{Environment.Is64BitProcess}");
+
+            var x = Environment.Is64BitProcess && Environment.Is64BitOperatingSystem ? "-x64" : "-x86";
+
+            switch (Environment.OSVersion.Platform)
+            {
+                case PlatformID.Unix:
+                    return "linux" + x;
+                case PlatformID.Win32NT:
+                    return "win" + x;
+                case PlatformID.MacOSX:
+                    return "osx" + x;
+            }
+
+            return null;
+        }
+
+        public static void ResolveNativeLibraries()
+        {
+            DiscoverNativeLibraries();
+            CopyNativeLibraryFilesToRoot(DetectSystem());
+        }
+
+        private static void CopyNativeLibraryFilesToRoot(string platformString)
+        {
+            // native
+            foreach (var file in Directory.GetFiles(Path.Combine(Directory.GetCurrentDirectory(), RuntimeLibraryFolder,
+                platformString, NativeLibrarySubfolder)))
+            {
+                File.Copy(file, AppDomain.CurrentDomain.BaseDirectory + $"{Path.GetFileName(file)}", true);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/Raylib-cs/Raylib-cs.csproj b/Raylib-cs/Raylib-cs.csproj
index 066aa0c..56c414d 100644
--- a/Raylib-cs/Raylib-cs.csproj
+++ b/Raylib-cs/Raylib-cs.csproj
@@ -1,70 +1,79 @@
 <Project Sdk="Microsoft.NET.Sdk">
-  <PropertyGroup>
-    <Platforms>AnyCPU;osx-x64;linux-x64;win-x64;win-x86;linux-x86</Platforms>
-    <Configurations>Debug;Release</Configurations>
-    <TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
-  </PropertyGroup>
+    <PropertyGroup>
+        <Platforms>osx-x64;linux-x64;win-x64;win-x86;linux-x86</Platforms>
+        <Configurations>Debug;Release</Configurations>
+        <TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
+    </PropertyGroup>
 
-  <PropertyGroup>
-    <EnableDefaultItems>false</EnableDefaultItems>
-    <AssemblyName>Raylib-cs</AssemblyName>
-    <RootNamespace>Raylib_cs</RootNamespace>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
-  </PropertyGroup>
+    <PropertyGroup>
+        <EnableDefaultItems>false</EnableDefaultItems>
+        <AssemblyName>Raylib-cs</AssemblyName>
+        <RootNamespace>Raylib_cs</RootNamespace>
+        <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+        <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
+    </PropertyGroup>
+
+    <PropertyGroup>
+        <Version>3.1.0</Version>
+        <PackageVersion>3.1.7</PackageVersion>
+        <Authors>Chris Dill, Raysan5 &amp; Others</Authors>
+        <PackProject>true</PackProject>
+        <TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);GetNativeLibraryFiles</TargetsForTfmSpecificBuildOutput>
+        <PackageLicenseExpression>Zlib</PackageLicenseExpression>
+        <Title>Raylib-cs - C# Bindings for Raylib</Title>
+        <Description>C# bindings for raylib - A simple and easy-to-use library to learn videogames programming http://www.raylib.com/
+        </Description>
+        <PackageIcon>raylib-cs_64x64.png</PackageIcon>
+        <PackageTags>Raylib;Raysan;Games;Game-Engine;Engine;Game</PackageTags>
+        <RepositoryType>git</RepositoryType>
+        <RepositoryUrl>https://github.com/ChrisDill/Raylib-cs/</RepositoryUrl>
+        <PackageProjectUrl>https://www.raylib.com/</PackageProjectUrl>
+    </PropertyGroup>
 
-<PropertyGroup>
-  <Version>3.1.0</Version>
-  <PackageVersion>3.1.3</PackageVersion>
-  <Authors>Chris Dill, Raysan5 &amp; Others</Authors>
-  <PackProject>true</PackProject>
-  <TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);GetNativeLibraryFiles</TargetsForTfmSpecificBuildOutput>
-  <PackageLicenseExpression>Zlib</PackageLicenseExpression>
-  <Title>Raylib-cs - C# Bindings for Raylib</Title>
-  <Description>C# bindings for raylib - A simple and easy-to-use library to learn videogames programming http://www.raylib.com/
-  </Description>
-  <PackageIcon>raylib-cs_64x64.png</PackageIcon>
-  <PackageTags>Raylib;Raysan;Games;Game-Engine;Engine;Game</PackageTags>
-  <RepositoryType>git</RepositoryType>
-  <RepositoryUrl>https://github.com/ChrisDill/Raylib-cs/</RepositoryUrl>
-  <PackageProjectUrl>https://www.raylib.com/</PackageProjectUrl>
-</PropertyGroup>
-  
-  <ItemGroup>
-    <Compile Include="Easings.cs" />
-    <Compile Include="Raylib.cs" />
-    <Compile Include="Raymath.cs" />
-    <Compile Include="Rlgl.cs" />
-    <None Include="../Logo/raylib-cs_64x64.png" Pack="true" PackagePath="" />
-  </ItemGroup>
-  
-  <ItemGroup>
-    <Content Include="Raylib-cs.targets" />
-  </ItemGroup>
-  
-  <ItemGroup>
-    <PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
-  </ItemGroup>
-  
-  <Target Name="GetNativeLibraryFiles">
     <ItemGroup>
-      <TfmSpecificPackageFile Include="$(BaseOutputPath)\..\runtimes\linux-x64\native\libraylib.so">
-        <PackagePath>runtimes/linux-x64/native</PackagePath>
-      </TfmSpecificPackageFile>
-      <TfmSpecificPackageFile Include="$(BaseOutputPath)\..\runtimes\linux-x86\native\libraylib.so">
-        <PackagePath>runtimes/linux-x86/native</PackagePath>
-      </TfmSpecificPackageFile>
-      <TfmSpecificPackageFile Include="$(BaseOutputPath)\..\runtimes\win-x64\native\raylib.dll">
-        <PackagePath>runtimes/win-x64/native</PackagePath>
-      </TfmSpecificPackageFile>
-      <TfmSpecificPackageFile Include="$(BaseOutputPath)\..\runtimes\win-x86\native\raylib.dll">
-        <PackagePath>runtimes/win-x86/native</PackagePath>
-      </TfmSpecificPackageFile>
-      <TfmSpecificPackageFile Include="$(BaseOutputPath)\..\runtimes\osx-x64\native\libraylib.a">
-        <PackagePath>runtimes/osx-x64/native</PackagePath>
-      </TfmSpecificPackageFile>
+        <Compile Include="Easings.cs"/>
+        <Compile Include="Platform.cs"/>
+        <Compile Include="Raylib.cs"/>
+        <Compile Include="Raymath.cs"/>
+        <Compile Include="Rlgl.cs"/>
+        <None Include="../Logo/raylib-cs_64x64.png" Pack="true" PackagePath=""/>
     </ItemGroup>
-  </Target>
+
+    <ItemGroup>
+        <Content Include="Raylib-cs.targets"/>
+    </ItemGroup>
+
+    <ItemGroup>
+        <Content Include="runtimes\**" CopyToOutputDirectory="PreserveNewest" Link="runtimes\%(RecursiveDir)\%(Filename)%(Extension)"/>
+    </ItemGroup>
+
+    <Target Name="AfterBuild">
+        <Copy SourceFiles="@(MySourceFiles)" DestinationFiles="@(MySourceFiles->'$(OutputPath)\%(RecursiveDir)%(Filename)%(Extension)')"/>
+    </Target>
+
+    <ItemGroup>
+        <PackageReference Include="System.Numerics.Vectors" Version="4.5.0"/>
+    </ItemGroup>
+
+    <Target Name="GetNativeLibraryFiles">
+        <ItemGroup>
+            <TfmSpecificPackageFile Include="$(BaseOutputPath)\..\runtimes\linux-x64\native\libraylib.so">
+                <PackagePath>runtimes/linux-x64/native</PackagePath>
+            </TfmSpecificPackageFile>
+            <TfmSpecificPackageFile Include="$(BaseOutputPath)\..\runtimes\linux-x86\native\libraylib.so">
+                <PackagePath>runtimes/linux-x86/native</PackagePath>
+            </TfmSpecificPackageFile>
+            <TfmSpecificPackageFile Include="$(BaseOutputPath)\..\runtimes\win-x64\native\raylib.dll">
+                <PackagePath>runtimes/win-x64/native</PackagePath>
+            </TfmSpecificPackageFile>
+            <TfmSpecificPackageFile Include="$(BaseOutputPath)\..\runtimes\win-x86\native\raylib.dll">
+                <PackagePath>runtimes/win-x86/native</PackagePath>
+            </TfmSpecificPackageFile>
+            <TfmSpecificPackageFile Include="$(BaseOutputPath)\..\runtimes\osx-x64\native\libraylib.dylib">
+                <PackagePath>runtimes/osx-x64/native</PackagePath>
+            </TfmSpecificPackageFile>
+        </ItemGroup>
+    </Target>
 
 </Project>
 
diff --git a/Raylib-cs/Raylib-cs.targets b/Raylib-cs/Raylib-cs.targets
index b894bb6..63b6651 100644
--- a/Raylib-cs/Raylib-cs.targets
+++ b/Raylib-cs/Raylib-cs.targets
@@ -1,33 +1,32 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 
-    <ItemGroup Condition=" '$(Platform)' == 'osx-x64' Or '$(Platform)' == 'AnyCPU' Or '$(Platform)' == 'x64'">
+    <ItemGroup>
+        <None Update="runtimes\**\*.*">
+            <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+            <Visible>false</Visible>
+        </None>
+    </ItemGroup>
+    
+    <ItemGroup Condition=" '$(Platform)' == 'osx-x64' Or '$(Platform)' == 'x64'">
         <Content Include="raylib">
-            <PackagePath>runtimes\osx-x64\libraylib.dylib</PackagePath>
+            <PackagePath>runtimes\osx-x64\native\libraylib.dylib</PackagePath>
             <Pack>true</Pack>
             <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
         </Content>
     </ItemGroup>
 
-    <ItemGroup Condition=" '$(Platform)' == 'win-x86' Or '$(Platform)' == 'AnyCPU' Or '$(Platform)' == 'x86'">
+    <ItemGroup Condition="'$(Platform)' == 'x64' Or '$(Platform)' == 'win-x64'">
         <Content Include="raylib">
-            <PackagePath>runtimes\win-x86\raylib.dll</PackagePath>
+            <PackagePath>runtimes\win-x64\native\raylib.dll</PackagePath>
             <Pack>true</Pack>
             <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
         </Content>
     </ItemGroup>
 
-    <ItemGroup Condition=" '$(Platform)' == 'win-x64' Or '$(Platform)' == 'x64'">
+    <ItemGroup Condition=" '$(Platform)' == 'linux-x64' Or '$(Platform)' == 'x64'">
         <Content Include="raylib">
-            <PackagePath>runtimes\win-x64\raylib.dll</PackagePath>
-            <Pack>true</Pack>
-            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-        </Content>
-    </ItemGroup>
-
-    <ItemGroup Condition=" '$(Platform)' == 'linux-x64' Or '$(Platform)' == 'AnyCPU' Or '$(Platform)' == 'x64'">
-        <Content Include="raylib">
-            <PackagePath>runtimes\linux-x64\raylib.dll</PackagePath>
+            <PackagePath>runtimes\linux-x64\native\raylib.so</PackagePath>
             <Pack>true</Pack>
             <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
         </Content>