Is it possible to include native libraries automatically from a NuGet package?

JVattJVatt USMember

I need to create a NuGet package that includes some PCL code and some Android code with native libraries (.so).

Is it possible to include the .so files automatically in the project that is using the package? Right now I need to manually add them to the project from the packages directory, otherwise they are ignored, which kind of defeats the purpose of the package.

I hope to do the same with iOS also.

Posts

  • mattwardmattward GBMember Xamurai

    I am not an expert on how the native libraries need to be referenced in the project but it looks like they are extra MSBuild items.

    <AndroidNativeLibrary Include="path/to/libfoo.so">
        <Abi>armeabi</Abi>
    </AndroidNativeLibrary>
    

    So you may be able to do this using an MSBuild .targets file in the NuGet package. You could define the extra MSBuild elements in this .targets file and the project would have them imported. That is going to be the only way I can think of to get them into the project without resorting to using PowerShell which is not supported on Mac.

  • JVattJVatt USMember

    Thanks @mattward. Though it seems like NuGet just ignores my .target file. I put it under the 'build' directory where my .csproj file is. The naming should be correct: '{packageid}.targets'

    My MSBuild file is built like this:

    <?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <ItemGroup> <AndroidNativeLibrary Include="libs\armeabi-v7a\lib.so"> <Abi>armeabi</Abi> </AndroidNativeLibrary> <AndroidNativeLibrary Include="libs\armeabi-v7a\lib2.so"> <Abi>armeabi</Abi> </AndroidNativeLibrary> </ItemGroup> </Project>

    Also, the libraries are already included like that in the .csproj file, so I'm not quite sure if this will do me any good anyway?

  • mattwardmattward GBMember Xamurai

    Not sure what the problem is with the build.targets file. Is it in the created .nupkg?

    I may be misunderstanding what you are doing. I did not think the libraries would be in the project unless you added them manually.

  • JVattJVatt USMember

    When adding a NuGet package to a project, I wanted to have the native libraries inside the NuGet to be automatically added to the project. It seems that you're right and I'll have to manually add them after adding the package.

  • mattwardmattward GBMember Xamurai

    Without using PowerShell in the NuGet package there is no way to get the AndroidNativeLibrary elements added to the main project's .csproj file.

    The only possible way that may work without PowerShell scripts would be to use an MSBuild .targets file in the NuGet package. It would not add the AndroidNativeLibrary elements into your main .csproj but it would import them. So if you had a NuGet package called Foo, inside of this there is a build\Foo.targets file (or build\MonoAndroid\Foo.targets if you need to support multiple platforms), then installing this into the project would add an Import element to the main project:

      <Import Project="packages\Foo.1.0\build\MonoAndroid\Foo.targets" Condition="Exists('packages\Foo.1.0\build\MonoAndroid\Foo.targets')" />
    

    The Foo.targets would contain something like:

    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
        <ItemGroup>
            <AndroidNativeLibrary Include="libs\armeabi-v7a\lib.so">
                <Abi>armeabi</Abi>
            </AndroidNativeLibrary>
            <AndroidNativeLibrary Include="libs\armeabi-v7a\lib2.so">
                <Abi>armeabi</Abi>
            </AndroidNativeLibrary>
        </ItemGroup>
    </Project>
    

    The native libs would be in the directory:

    packages\Foo.1.0\build\MonoAndroid\libs\armeabi-v7a
    
  • JVattJVatt USMember

    Finally got this to work! Thank you.

    Had to add the <link> tag for the libs to be included in the .apk properly.

    Here's an example of the targets file for anyone that's interested:

    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup> <AndroidNativeLibrary Include="libs\armeabi-v7a\lib.so"> <Link>libs\armeabi-v7a\lib.so</Link> </AndroidNativeLibrary> <AndroidNativeLibrary Include="libs\armeabi-v7a\lib2.so"> <Link>libs\armeabi-v7a\lib2.so</Link> </AndroidNativeLibrary> </ItemGroup> </Project>

    The <Abi> tag is not needed as long as the library in the link is under the 'armeabi-v7a' directory.

    Also the targets file needs to be included in the .nuspec file as a <file> item:

    <files> <file src="build\MonoAndroid\*.targets" target="build\MonoAndroid"/> </files>

  • kristiandupontkristiandupont DKMember ✭✭

    I am trying to follow this but my .targets file is ignored completely. Is NuGet supposed to automatically pick up any .targets file that resides in the build/ folder?

  • mattwardmattward GBMember Xamurai

    Xamarin Studio will pick up the .targets file. If the .targets file is added to the project when the NuGet package is installed then Xamarin Studio should kill its MSBuild host so the project file and the new import is ready for the next compile.

    Does it work if you close and re-open the solution? Is the .targets file imported into the .csproj file?

  • The big tip is to be careful about naming your targets file - it is found by convention because the file is named ProjectID.targets.

    We had an issue because the project name, and name of our nuspec, didn't match the ID.

    See the NuGet page on targets for the precise rules on names and locations.

Sign In or Register to comment.