Skip to content

Commit

Permalink
[Build] Native libraries get copied to runtimes/RID/native folder
Browse files Browse the repository at this point in the history
- In user project nuget will take care of copying required native libs to final output folder depending on used RuntimeIdentifier
- Native libraries can be registered as dependencies for a later lookup (used by Stride.NuGetLoader to register native dependencies from global nuget package cache)
- Fixes library not found exceptions on platforms other than windows
  • Loading branch information
azeno committed May 12, 2022
1 parent 4886142 commit 0b98e05
Show file tree
Hide file tree
Showing 50 changed files with 175 additions and 70 deletions.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
8 changes: 4 additions & 4 deletions deps/VHACD/build.bat
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ if %ERRORLEVEL% neq 0 GOTO :error_popd
popd

REM Create folders
mkdir x86
mkdir x64
mkdir win-x86
mkdir win-x64

copy ..\..\externals\BulletSharpPInvoke\src\VHACD_Lib\VHACD\Release\*.dll x86
copy ..\..\externals\BulletSharpPInvoke\src\VHACD_Lib\VHACD\x64\Release\*.dll x64
copy ..\..\externals\BulletSharpPInvoke\src\VHACD_Lib\VHACD\Release\*.dll win-x86
copy ..\..\externals\BulletSharpPInvoke\src\VHACD_Lib\VHACD\x64\Release\*.dll win-x64

GOTO :end
:error_popd
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -355,15 +355,15 @@ public static void UpdateDependencies(SolutionProject project, bool directDepend
// Build list of assemblies
foreach (var a in targetLibrary.RuntimeAssemblies)
{
if (!a.Path.EndsWith("_._"))
if (!a.Path.EndsWith("_._") && !a.Path.Contains("/native/"))
{
var assemblyFile = Path.Combine(libraryPath, a.Path.Replace('/', Path.DirectorySeparatorChar));
projectDependency.Assemblies.Add(assemblyFile);
}
}
foreach (var a in targetLibrary.RuntimeTargets)
{
if (!a.Path.EndsWith("_._"))
if (!a.Path.EndsWith("_._") && !a.Path.Contains("/native/"))
{
var assemblyFile = Path.Combine(libraryPath, a.Path.Replace('/', Path.DirectorySeparatorChar));
projectDependency.Assemblies.Add(assemblyFile);
Expand Down
37 changes: 36 additions & 1 deletion sources/core/Stride.Core/Native/NativeLibraryHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public static class NativeLibraryHelper
{
private const string UNIX_LIB_PREFIX = "lib";
private static readonly Dictionary<string, IntPtr> LoadedLibraries = new Dictionary<string, IntPtr>(StringComparer.OrdinalIgnoreCase);
private static readonly Dictionary<string, string> NativeDependencies = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

/// <summary>
/// Try to preload the library.
Expand All @@ -33,6 +34,24 @@ public static void PreloadLibrary(string libraryName, Type owner)
return;
}

// Was the dependency registered beforehand?
{
if (NativeDependencies.TryGetValue(libraryName, out var path) && NativeLibrary.TryLoad(path, out var result))
{
LoadedLibraries.Add(libraryName, result);
return;
}
}

// Try default loading mechanism (https://docs.microsoft.com/en-us/dotnet/core/dependency-loading/loading-unmanaged)
{
if (NativeLibrary.TryLoad(libraryName, owner.Assembly, searchPath: null, out var result))
{
LoadedLibraries.Add(libraryName, result);
return;
}
}

string cpu;
string platform;
string extension;
Expand Down Expand Up @@ -103,7 +122,7 @@ public static void PreloadLibrary(string libraryName, Type owner)

// We are trying to load the dll from a shadow path if it is already registered, otherwise we use it directly from the folder
{
var platformNativeLibsFolder = $"{platform}-{cpu}";
var platformNativeLibsFolder = Path.Combine("runtimes", $"{platform}-{cpu}", "native");
foreach (var libraryPath in new[]
{
Path.Combine(Path.GetDirectoryName(owner.GetTypeInfo().Assembly.Location) ?? string.Empty, platformNativeLibsFolder),
Expand Down Expand Up @@ -174,5 +193,21 @@ public static void UnLoadAll()
}
#endif
}

/// <summary>
/// Registers a native dependency.
/// </summary>
/// <param name="libraryPath">The full path to the native library.</param>
/// <exception cref="ArgumentNullException"></exception>
public static void RegisterDependency(string libraryPath)
{
if (libraryPath == null) throw new ArgumentNullException(nameof(libraryPath));

lock (LoadedLibraries)
{
var libraryName = Path.GetFileNameWithoutExtension(libraryPath);
NativeDependencies[libraryName] = libraryPath;
}
}
}
}
17 changes: 8 additions & 9 deletions sources/core/Stride.Core/build/Stride.Core.targets
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,15 @@
<Type>$([System.Text.RegularExpressions.Regex]::Match('%(Identity)', `(.*);(.*);(.*)`).get_Groups().get_Item(1).ToString())</Type>
<SourcePath>$([System.Text.RegularExpressions.Regex]::Match('%(Identity)', `(.*);(.*);(.*)`).get_Groups().get_Item(2).ToString())</SourcePath>
<Link>$([System.Text.RegularExpressions.Regex]::Match('%(Identity)', `(.*);(.*);(.*)`).get_Groups().get_Item(3).ToString())</Link>
<HandledByPackage>false</HandledByPackage>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</_StrideDependencyLocal>
<_StrideDependencyContent Include="@(_StrideDependencyLocal->'$(_StrideSourceDir)%(SourcePath)')" Condition="'%(_StrideDependencyLocal.Type)' == 'Content'"/>
<_StrideDependencyNativeLib Include="@(_StrideDependencyLocal->'$(_StrideSourceDir)%(SourcePath)')" Condition="'%(_StrideDependencyLocal.Type)' == 'NativeLib'"/>
<!-- Mark runtimes/ as handled (NuGet will take care of copying it to output folder) -->
<!-- We can get rid of this once all native dependencies are handled through runtimes/ feature (mobile targets haven't been updated yet) -->
<_StrideDependencyNativeLib Update="@(_StrideDependencyNativeLib)" Condition="$([System.String]::new('%(_StrideDependencyNativeLib.Link)').StartsWith('runtimes\'))" >
<HandledByPackage>true</HandledByPackage>
</_StrideDependencyNativeLib>
</ItemGroup>

<!-- Message -->
Expand All @@ -176,24 +181,18 @@
</ItemGroup>
</Target>

<Target Name="_StrideCopyContent" DependsOnTargets="_StrideBuildDependencies" AfterTargets="ResolveAssemblyReferences">
<ItemGroup>
<Content Include="@(_StrideDependencyContent)"/>
</ItemGroup>
</Target>

<!-- Copy native libraries to output -->
<Target Name="_StrideSetupNativeLibrariesWindows" DependsOnTargets="_StrideBuildDependencies" AfterTargets="ResolveAssemblyReferences" Condition="('$(StridePlatform)' == 'Windows' Or '$(StridePlatform)' == 'macOS' Or '$(StridePlatform)' == 'Linux') And '$(CopyLocalLockFileAssemblies)' != 'false'">
<ItemGroup>
<None Include="@(_StrideDependencyNativeLib)">
<None Include="@(_StrideDependencyNativeLib)" Condition=" '%(_StrideDependencyNativeLib.HandledByPackage)' == 'false' ">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Target>
<!-- When publishing, copy native libraries (only needed if CopyLocalLockFileAssemblies is set to false since _StrideSetupNativeLibrariesWindows won't run) -->
<Target Name="_StrideSetupNativeLibrariesDotNetPublish" DependsOnTargets="_StrideBuildDependencies" AfterTargets="ComputeFilesToPublish" Condition="'$(UsingMicrosoftNETSdk)' == 'true' And '$(CopyLocalLockFileAssemblies)' == 'false'">
<ItemGroup>
<ResolvedFileToPublish Include="@(_StrideDependencyNativeLib)">
<ResolvedFileToPublish Include="@(_StrideDependencyNativeLib)" Condition=" '%(_StrideDependencyNativeLib.HandledByPackage)' == 'false' ">
<RelativePath>%(_StrideDependencyNativeLib.Link)</RelativePath>
</ResolvedFileToPublish>
</ItemGroup>
Expand Down
12 changes: 9 additions & 3 deletions sources/engine/Stride.Assets.Models/Stride.Assets.Models.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@

<PropertyGroup>
<TargetsForTfmSpecificBuildOutput>_StrideIncludeExtraAssemblies;$(TargetsForTfmSpecificBuildOutput)</TargetsForTfmSpecificBuildOutput>

<TargetsForTfmSpecificContentInPackage>_StrideIncludeNativeLibs;$(TargetsForTfmSpecificContentInPackage)</TargetsForTfmSpecificContentInPackage>
</PropertyGroup>

<Target Name="_StrideIncludeExtraAssemblies">
<ItemGroup>
<!-- Needed by .NET Core runtime to be able to load C++/CLI assemblies -->
Expand All @@ -40,8 +41,13 @@
<BuildOutputInPackage Include="$(OutputPath)Stride.Importer.FBX.dll" />
<BuildOutputInPackage Include="$(OutputPath)Stride.Importer.FBX.ssdeps" />
<BuildOutputInPackage Include="$(OutputPath)Stride.Importer.Common.dll" />
<BuildOutputInPackage Include="$(OutputPath)x64\assimp-vc140-mt.dll" TargetPath="x64\assimp-vc140-mt.dll" />
<BuildOutputInPackage Include="$(OutputPath)x64\libfbxsdk.dll" TargetPath="x64\libfbxsdk.dll" />
</ItemGroup>
</Target>

<Target Name="_StrideIncludeNativeLibs">
<ItemGroup>
<TfmSpecificPackageFile Include="$(OutputPath)runtimes\win-x64\native\assimp-vc140-mt.dll" PackagePath="runtimes\win-x64\native\assimp-vc140-mt.dll" />
<TfmSpecificPackageFile Include="$(OutputPath)runtimes\win-x64\native\libfbxsdk.dll" PackagePath="runtimes\win-x64\native\libfbxsdk.dll" />
</ItemGroup>
</Target>
</Project>
2 changes: 1 addition & 1 deletion sources/engine/Stride.Assets/Stride.Assets.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@
</ItemGroup-->
<ItemGroup>
<StrideNativeLib Include="..\..\..\deps\VHACD\**\VHACD.dll">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
<Link>runtimes\%(RecursiveDir)native\%(Filename)%(Extension)</Link>
</StrideNativeLib>
<Content Include="..\..\..\deps\FFmpeg\ffmpeg.exe">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
Expand Down
10 changes: 5 additions & 5 deletions sources/engine/Stride.Graphics/Stride.Graphics.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project>
<Project>
<PropertyGroup>
<StrideRuntime>true</StrideRuntime>
<StrideGraphicsApiDependent>true</StrideGraphicsApiDependent>
Expand All @@ -15,15 +15,15 @@
</PropertyGroup>
<ItemGroup Condition=" '$(StrideGraphicsApi)' == 'Vulkan' ">
<StrideNativeLib Include="..\..\..\deps\MoltenVK\$(StridePlatformDeps)\**\*.*">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
<RelativePath>%(RecursiveDir)%(Filename)%(Extension)</RelativePath>
<Link>runtimes\%(RecursiveDir)native\%(Filename)%(Extension)</Link>
<RelativePath>runtimes\%(RecursiveDir)native\%(Filename)%(Extension)</RelativePath>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</StrideNativeLib>
</ItemGroup>
<ItemGroup>
<StrideNativeLib Include="..\..\..\deps\freetype\$(StridePlatformDeps)\**\*.*">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
<RelativePath>%(RecursiveDir)%(Filename)%(Extension)</RelativePath>
<Link>runtimes\%(RecursiveDir)native\%(Filename)%(Extension)</Link>
<RelativePath>runtimes\%(RecursiveDir)native\%(Filename)%(Extension)</RelativePath>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</StrideNativeLib>
</ItemGroup>
Expand Down
4 changes: 2 additions & 2 deletions sources/engine/Stride.Physics/Stride.Physics.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project>
<PropertyGroup>
<StrideRuntime>true</StrideRuntime>
Expand All @@ -17,7 +17,7 @@
</PropertyGroup>
<ItemGroup>
<StrideNativeLib Include="..\..\..\deps\BulletPhysics\$(StridePlatformDeps)\**\libbulletc.*">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
<Link>runtimes\%(RecursiveDir)native\%(Filename)%(Extension)</Link>
</StrideNativeLib>
<Reference Include="BulletSharp">
<HintPath>..\..\..\deps\BulletPhysics\$(StrideBulletPlatform)\BulletSharp.NetStandard.dll</HintPath>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project>
<Project>
<PropertyGroup>
<StrideRuntime>true</StrideRuntime>
</PropertyGroup>
Expand All @@ -23,8 +23,8 @@
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == '$(StrideFramework)'">
<StrideNativeLib Include="$(WindowsSdkDir_10)\Redist\D3D\**\d3dcompiler_47.dll">
<Link>win-%(RecursiveDir)%(Filename)%(Extension)</Link>
<RelativePath>win-%(RecursiveDir)%(Filename)%(Extension)</RelativePath>
<Link>runtimes\win-%(RecursiveDir)native\%(Filename)%(Extension)</Link>
<RelativePath>runtimes\win-%(RecursiveDir)native\%(Filename)%(Extension)</RelativePath>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</StrideNativeLib>
<StrideContent Include="..\..\..\deps\glslang\**\glslangValidator*.*">
Expand Down
6 changes: 3 additions & 3 deletions sources/engine/Stride.Video/Stride.Video.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project>
<Project>
<PropertyGroup>
<StrideRuntime>true</StrideRuntime>
<StrideGraphicsApiDependent>true</StrideGraphicsApiDependent>
Expand Down Expand Up @@ -32,8 +32,8 @@
<When Condition="$(DefineConstants.Contains(STRIDE_VIDEO_FFMPEG))">
<ItemGroup>
<StrideNativeLib Include="$(MSBuildThisFileDirectory)..\..\..\deps\FFmpeg\$(StridePlatformDeps)\**\*.*" Exclude="$(MSBuildThisFileDirectory)..\..\..\deps\FFmpeg\$(StridePlatformDeps)\*.*">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
<RelativePath>%(RecursiveDir)%(Filename)%(Extension)</RelativePath>
<Link>runtimes\%(RecursiveDir)native\%(Filename)%(Extension)</Link>
<RelativePath>runtimes\%(RecursiveDir)native\%(Filename)%(Extension)</RelativePath>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</StrideNativeLib>
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project>
<Project>
<PropertyGroup>
<StrideRuntime>true</StrideRuntime>
<StrideGraphicsApiDependent>true</StrideGraphicsApiDependent>
Expand Down Expand Up @@ -27,8 +27,8 @@
<When Condition=" '$(StrideGraphicsApi)' == 'Direct3D11' Or '$(StrideGraphicsApi)' == 'Direct3D12' ">
<ItemGroup>
<StrideNativeLib Include="..\..\..\deps\OpenVR\$(StridePlatformDeps)\**\openvr_api.*">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
<RelativePath>%(RecursiveDir)%(Filename)%(Extension)</RelativePath>
<Link>runtimes\%(RecursiveDir)native\%(Filename)%(Extension)</Link>
<RelativePath>runtimes\%(RecursiveDir)native\%(Filename)%(Extension)</RelativePath>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</StrideNativeLib>
</ItemGroup>
Expand Down
Loading

0 comments on commit 0b98e05

Please sign in to comment.