Bug 39757 - [Regression] [assembly: LinkWith("libToolBox.a", ...)] in ios libraries not working anymore
Summary: [Regression] [assembly: LinkWith("libToolBox.a", ...)] in ios libraries not w...
Status: RESOLVED ANSWERED
Alias: None
Product: iOS
Classification: Xamarin
Component: General ()
Version: unspecified
Hardware: PC Windows
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2016-03-18 09:15 UTC by softlion
Modified: 2016-03-18 15:37 UTC (History)
3 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED ANSWERED

Description softlion 2016-03-18 09:15:30 UTC
Hi,
i'm rebuilding an ios library DLL (not binding) containing a native C/C++ ios library (.a file) that i've created in february 2016.
At this time i followed this guide: https://developer.xamarin.com/guides/ios/advanced_topics/native_interop/, but instead of adding the following line to the final ios app build configuration:

-cxx -gcc_flags "-L${ProjectDir} -lMylibrary -lSystemLibrary -framework CFNetwork -force_load ${ProjectDir}/libMyLibrary.a"

i added these lines in one of the code file of the ios library project:

[assembly: LinkWith("libClient.a", LinkTarget.ArmV7 | LinkTarget.ArmV7s | LinkTarget.Simulator | LinkTarget.Arm64 | LinkTarget.Simulator64,
    Frameworks = "Security SystemConfiguration MobileCoreServices", ForceLoad = true, SmartLink = true,
    IsCxx = true)]

It instructs the ios app project referencing this library to add the -cxx -gcc_flags ... to the build configuration. And it was working correctly. In february 2016.

With the current ios version 9.4.2.24 (visual studio), or XS Mac alpha channel (9.8.0.58), the build systems fails with these errors:

The build error is:

5>C:\Program Files (x86)\MSBuild\Xamarin\iOS\Xamarin.iOS.Common.targets(673,3): 
warning : Could not extract the native library 'libPatchClient.a' from '....../mtbs/builds/TestClientIos/9004a9a5907844abf344a7145137545f/obj/iPhoneSimulator/Debug/mtouch-cache/libClient.a'. Please ensure the native library was properly embedded in the managed assembly (if the assembly was built using a binding project, the native library must be included in the project, and its Build Action must be 'ObjcBindingNativeLibrary').
...
ld: file not found: (same file path)
clang: error: linker command failed with exit code 1 (use -v to see invocation)
...
error : Native linking error: file not found: (same file path)
error : Native linking failed. Please review the build log.


On native ios library projects, there is no such Build Action 'ObjcBindingNativeLibrary'. Btw it was working OK back in february.
Comment 1 Rolf Bjarne Kvinge [MSFT] 2016-03-18 10:00:58 UTC
Does it build correctly if you use Xamarin Studio on the mac instead?
Comment 2 softlion 2016-03-18 10:25:51 UTC
Xamarin Mac: no it does not compile with the same error.

Using the old method (adding additional mtouch arguments) seems to work:

-cxx -gcc_flags "-L${ProjectDir} -lClient -lPatchClient -framework Security -framework SystemConfiguration -framework MobileCoreServices -force_load ${ProjectDir}/libClient.a -force_load ${ProjectDir}/libPatchClient.a"
Comment 3 Rolf Bjarne Kvinge [MSFT] 2016-03-18 10:30:27 UTC
I'm wondering how this worked in February; if the build action was set to 'None' for the native library, I would assume it would not be copied to the Mac, in which case the build should fail the same way.

In any case I'm reassigning to the VS team, since this only happens when using VS according to comment #2.
Comment 4 softlion 2016-03-18 10:46:01 UTC
Comment #2 says it does NOT work on XS Mac too !

> if the build action was set to 'None' for the native library, I would assume it would not be copied to the Mac, in which case the build should fail the same way.

From your Xamarin documentation (link in Description):

"To bring the library into your project, Select the project from the solution explorer and press Command+Option+a. Navigate to the libMyLibrary.a and add it to the project. When prompted, tell Xamarin Studio or Visual Studio to copy it into the project. After adding it, find the libFoo.a in the project, right click on it, and set the Build Action to none."

It has always worked like this.
Comment 5 Rolf Bjarne Kvinge [MSFT] 2016-03-18 11:55:56 UTC
(In reply to softlion from comment #4)
> Comment #2 says it does NOT work on XS Mac too !

Oh, sorry, I misunderstood then.

I still don't understand how this worked though, because Xamarin.iOS will try to extract any native libraries the LinkWith attribute refers to from the resources in that assembly, and in your case that won't be found. We'll also try to link with the resulting file (which doesn't exist because it wasn't found in the resources). If this ever worked, it was by accident, not design.

My suggestion would be to create an iOS binding project instead of a class library project, and set the proper BuildAction for the native library there. You'll also need some managed code in the library project (but you don't have to write any bindings), and reference that managed code from your main project (otherwise the executable assembly won't reference binding project's assembly).

Alternatively you can set the additional mtouch arguments, like you've already found out.
Comment 6 softlion 2016-03-18 14:21:42 UTC
Sorry,
but i can not find a way to succesfully compile an ios binding lib.

So, using Xamarin, there is no way to include a ".a" C++ static library in a C# library. It must be included in the final app.

Nice tool!
Comment 7 Rolf Bjarne Kvinge [MSFT] 2016-03-18 14:30:16 UTC
Why doesn't your ios binding library compile?
Comment 8 softlion 2016-03-18 14:55:57 UTC
The binding project and the app are both compiling, the .a library is in the final .app package, but the DllImport does not find the library. In fact, there is no DllImport probing at all, as i used to see when it was working.

So, it compiles, but i think xamarin tried to get only objective-c contracts. And there are no such contracts in this .a file, as it is a pure ios C++ library, not an objectiveC library.

And now when i put the .a files in the app project and add the mtouch arguments, it won't work anymore with duplicate C symbols errors.

This tools makes me crazy !!!
Comment 9 Rolf Bjarne Kvinge [MSFT] 2016-03-18 15:37:08 UTC
How are your DllImports defined? For static libraries (*.a) the library in a DllImport must be "__Internal":

    [DllImport ("__Internal")]
    static extern void my_function ();

otherwise you will end up with EntryPointNotFoundExceptions.

If you have build errors, please provide the complete build log, that makes it much easier for me to help you.

There are certain cases when linking a native library may not pull in every native function into the binary, but it does not depend on the language, but instead linker flags (with a build log I would be able to determine if this was the case).