Load i386 libraries instead of x86_64 libraries on path /usr/lib

HumbleArchitectHumbleArchitect USMember ✭✭
edited August 2017 in Xamarin.iOS

I have a third party library that is i386 only. It has versions of libcrypto.dylib and libssl.dylib with the appropriate i386 architecture. However, every time I try and run my application, it says that it found those libraries on the path at /usr/lib and attempted to load them. It then fails because the libraries in /usr/lib are built for x86_64.

Any idea on how to fix this?

A little more information, we have a Mac Binding project which contains the native references to the third party library and libssl.dylib and libcrypto.dylib with the appropriate architecture. We then reference that binding project from our application. I checked my {MyAppName}.app/Contents/ and see that the libraries libssl.dylib and libcrypto.dylib are placed in the MonoBundle folder.

Thanks,
Rich

Answers

  • ChrisHamonsChrisHamons USForum Administrator, Xamarin Team Xamurai

    So the way to load i386 libraries is to be a i386 application yourself. If you are a Xamarin.Mac application, you can set the architecture in Project Options -> Build -> Mac Build -> Supported Architectures

    I will note that Apple states the release after macOS 10.13 will not run 32-bit applications "without compromises" and there are a number of macOS frameworks that are 64-bit only already, so I would work with your vendor to fix this as soon as reasonably possible.

  • HumbleArchitectHumbleArchitect USMember ✭✭

    Thanks, but we have already done this and that does not work.

  • ChrisHamonsChrisHamons USForum Administrator, Xamarin Team Xamurai

    Well, then you may need to teach the xamarin.mac created launcher (via install_name_tool) to look for your libraries in the expected location.

    You can use the hook shown here:

    https://github.com/xamarin/mac-samples/tree/master/UseMSBuildToCopyFilesToBundleExample

    to run it after bundle creation before signing.

  • HumbleArchitectHumbleArchitect USMember ✭✭

    Thanks Chris. Unfortunately this did not work either. Here is what I have tried.

    1) Check that the libssl and libcrypto dylibs are in the application bundle. They are in fact located in the bundle under MyAppName.app/Contents/MonoBundle/ (see image).

    2) I copied the files manually into a variety of locations in the MyAppName.app/Contents including

    MyAppName.app/Contents/Framework/
    MyAppName.app/Contents/Resources/lib
    MyAppName.app/Contents/Resources/
    

    NOTE: The application is not signed [yet].

    I have attached what we see on startup as well as the text of the error. You will be able to see, the files are in the MonoBundle folder inside our application.

  • ChrisHamonsChrisHamons USForum Administrator, Xamarin Team Xamurai

    So, as I said, you may need to direct the native loader (via install_name_tool) to search for those libraries before the standard system path.

    man install_name_tool

    https://stackoverflow.com/a/7332980/36782

  • HumbleArchitectHumbleArchitect USMember ✭✭

    I think you are correct on that. Will let you know.

  • HumbleArchitectHumbleArchitect USMember ✭✭

    Okay, I was able to figure out some things. According to otool, it turns out that the libraries I have used the @rpath/{library name}.dylib as part of their search path. So, I do not need to modify the libraries using install_name_tool at all. What I need to do is be able to set the @rpath as a part of the executable (i.e. application).

    I confirmed this by going to the Xcode sample application that works without the need to recompile the libraries or modify them in any way. The project settings modify the Run Search Path to @loader_path/../Frameworks which are where the libraries are located in the Xcode-built application.

    Now I need to figure out how to modify the @rpath from Visual Studio for Mac. It seems that this can be set through the "Additional mmp arguments" of the Mac Build settings. Unfortunately, there is very little or no documentation on this.

    Any pointers to some docs would be great. Thanks again for pointing me in the right direction.

  • ChrisHamonsChrisHamons USForum Administrator, Xamarin Team Xamurai

    You will need to run the install_name_tool command after complication on the final output binary.

    You can see how to customize your build with the sample I linked before (https://github.com/xamarin/mac-samples/tree/master/UseMSBuildToCopyFilesToBundleExample)

    I'd expect something like /usr/bin/install_name_tool bin/Debug/Foo.App/Contents/MacOS/Foo -add_rpath SOMETHING

  • HumbleArchitectHumbleArchitect USMember ✭✭

    Thank you! That last bit was really helpful and got me to where you were pointing me too. I ran the 'otool -L' on the binary and I was able to run the install_name_tool to add the rpath.

    Unfortunately, I ran smack into the next error which states that Xamarin.Mac does not support 32-bit. ?????

  • ChrisHamonsChrisHamons USForum Administrator, Xamarin Team Xamurai

    Hmm, that shouldn't be happening. Does it still show up with a clean build?

    Can you post the build log?

  • HumbleArchitectHumbleArchitect USMember ✭✭

    Sure, been up most of the night and a little tired. Just give me a little bit.

  • HumbleArchitectHumbleArchitect USMember ✭✭

    Here is the build log.

  • ChrisHamonsChrisHamons USForum Administrator, Xamarin Team Xamurai

    Try adding "-v -v -v -v -v" to the additional mmp arguments, and rebuild. I'm not seeing the mismatch here.

  • HumbleArchitectHumbleArchitect USMember ✭✭
    edited August 2017

    Thanks for all the help. I found the issue and I am attaching a project to demonstrate it. The issue is not with Xamarin.Mac or Visual Studio for Mac, but with the pre-release of Xamarin Forms for Mac.

    We have been in the midst of an effort to demonstrate abstracting a 3rd party library that is available on Android, iOS, and Mac using dependency injection while showing Xamarin working cross platform for iOS, Android, and Mac. Along with that, we included the pre-release of Xamarin Forms for Mac. There have been a number of challenges including interop to a 3rd party library, the 3rd party library is 32-bit, and showing Xamarin Forms on three platforms. The primary platform that we are interested in is Mac.

    I have included a simple "Hello Forms" project which is a simple Xamarin Forms based application. I then follow the guidance to add the Mac version to the solution.

    https://blog.xamarin.com/preview-bringing-macos-to-xamarin-forms/

    I compile and that works amazingly well. Unfortunately, when I change the architecture of the Mac project from x86_64 to i386, things fail miserably.

    Thanks for your help so far! We have been able to call into the third party API using the install_name_tool. Unfortunately, that led right into the crash because we were using Xamarin Forms for Mac.

    Our goals for this project are high, but so are the long term benefits. Our hope is that we can get Xamarin Forms + Mac + 32-bit [for interop to 3rd party sdk] all playing nicely.

Sign In or Register to comment.