© 2026 Hedgehog Software, LLC

TwitterGitHubDiscord
More
CommunitiesDocsAboutTermsPrivacy
Search
Star
Setup for Free
C#C
C#•3y ago•
10 replies
MiKom

Publishing application with native libraries

Hey.

I'm trying to create an application that depends on some native shared libraries (written in C++). I created a
NativeLibraries
NativeLibraries
project that contains the required shared libraries as
Content
Content
elements in
.csproj
.csproj
:
    <Content Condition="$(OS)=='Unix'" Include="../path/to/x64/library.so" LinkBase="runtimes/linux-x64/native">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Condition="$(OS)=='Unix'" Include="../path/to/arm/library.so" LinkBase="runtimes/linux-arm/native">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Condition="$(OS)=='Unix'" Include="../path/to/x64/library.so" LinkBase="runtimes/linux-x64/native">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
    <Content Condition="$(OS)=='Unix'" Include="../path/to/arm/library.so" LinkBase="runtimes/linux-arm/native">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>


Then my main application depends on this
NativeLibraries
NativeLibraries
project. When I build it, everything is fine, the native libraries are nicely placed in
runtimes/*
runtimes/*
folder in the build directory of the main application.

Problem is that the libraries are not copied to the output directory directly for rid-specific publishing (
dotnet publish -r linux-arm
dotnet publish -r linux-arm
) but are still present in
runtimes/linux-arm/native
runtimes/linux-arm/native
folder. Unlike for example SkiaSharp (that I also use). The native libraries of SkiaSharp are correctly copied directly to the publish output directory. SkiaSharp doesn't seem to be particularly clever here:
<ItemGroup>
    <!-- glibc -->
    <PackageFile Include="..\..\output\native\linux\x64\libHarfBuzzSharp*" PackagePath="runtimes\linux-x64\native\%(Filename)%(Extension)" />
    <PackageFile Include="..\..\output\native\linux\x86\libHarfBuzzSharp*" PackagePath="runtimes\linux-x86\native\%(Filename)%(Extension)" />
<ItemGroup>
    <!-- glibc -->
    <PackageFile Include="..\..\output\native\linux\x64\libHarfBuzzSharp*" PackagePath="runtimes\linux-x64\native\%(Filename)%(Extension)" />
    <PackageFile Include="..\..\output\native\linux\x86\libHarfBuzzSharp*" PackagePath="runtimes\linux-x86\native\%(Filename)%(Extension)" />


And the
PackageFile
PackageFile
is expanded as follows:
  <ItemGroup>
    <None Include="@(PackageFile)" Link="%(PackagePath)" Pack="True" />
  </ItemGroup>
  <ItemGroup>
    <None Include="@(PackageFile)" Link="%(PackagePath)" Pack="True" />
  </ItemGroup>


Which is similar to my
Content
Content
element. I tried adding this
Pack
Pack
as well but it didn't help.

Probably, SkiaSharp is doing something else that I don't see here. What may it be?
Microsoft docs mostly talk about packaging native libraries as Nuget packages which is not the case for me. Thanks
C# banner
C#Join
We are a programming server aimed at coders discussing everything related to C# (CSharp) and .NET.
61,871Members
Resources
Was this page helpful?

Similar Threads

Recent Announcements

Similar Threads

✅ Package native libraries with nuget
C#CC# / help
4y ago
❔ Publishing an winforms application
C#CC# / help
3y ago
❔ Need help with publishing
C#CC# / help
3y ago
Help with libraries
C#CC# / help
2y ago