# Steps to reproduce
Create a new Xamarin.Forms project, add Mobile Center Nuget Packages to the project and then call MobileCenter.Start function in AppDelegate.FinishedLaunching
Build for device (iPhone)
# Expected behavior
Successfully build the project for iOS platform
# Actual behavior
15 MT5211 build errors.
# Supplemental info (logs, images, videos)
One of the errors like this
MTOUCH: Error MT5211: Native linking failed, undefined Objective-C class: MSLogger. The symbol '_OBJC_CLASS_$_MSLogger' could not be found in any of the libraries or frameworks linked with your application. (MT5211) (Test5211.iOS)
# Test environment (full version information)
Cycle 9 Xamarin Studio Professional on macOS.
Created attachment 19357 [details]
I can reproduce this issue using
=== Xamarin Studio Enterprise ===
Version 6.2 (build 1718)
Installation UUID: 48af9690-0e4c-4b21-b82d-5c9cce64d17e
Mono 4.8.0 (mono-4.8.0-branch/9e8f0ee) (64-bit)
GTK+ 2.24.23 (Raleigh theme)
Package version: 408000429
=== Apple Developer Tools ===
Xcode 8.2 (11766)
=== Xamarin.iOS ===
Version: 10.4.0.73 (Visual Studio Enterprise)
Build date: 2017-01-08 14:16:01-0500
=== Build Information ===
Release ID: 602001718
Git revision: 0591bf7fba648f3ece7d03b790ff8c35f494e69d
Build date: 2017-01-09 14:51:42-05
Xamarin addins: cc3da0af6946082a463525b3db698a6b04ce2c2f
Build lane: monodevelop-lion-cycle9
=== Operating System ===
Mac OS X 10.12.2
Darwin iAlexRet.local 16.3.0 Darwin Kernel Version 16.3.0
Thu Nov 17 20:23:58 PST 2016
The class is definitely there
Alex$ lipo -info MobileCenter.a
Architectures in the fat file: MobileCenter.a are: armv7 armv7s i386 x86_64 arm64
iAlexRet:mobilecenter Alex$ strings MobileCenter.a | grep MSLogger
Build Log: https://gist.github.com/dalexsoto/57afa82637e42c905ee3f9be89f4f30f
> clang -framework Foundation -framework UIKit /Users/Alex/Projects/Bug51548/iOS/obj/iPhone/Debug/mtouch-cache/MobileCenter.a /Library/Frameworks/Xamarin.iOS.framework/Versions/10.4.0.73/SDKs/MonoTouch.iphoneos.sdk/usr/lib/libmonosgen-2.0.dylib /Library/Frameworks/Xamarin.iOS.framework/Versions/10.4.0.73/SDKs/MonoTouch.iphoneos.sdk/usr/lib/libxamarin-debug.dylib -lz -isysroot /Applications/Xcode82.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.2.sdk -Qunused-arguments -miphoneos-version-min=8.0 -arch arm64 -shared -read_only_relocs suppress -install_name @executable_path/libMicrosoft.Azure.Mobile.iOS.Bindings.dll.dylib -fapplication-extension -o /Users/Alex/Projects/Bug51548/iOS/obj/iPhone/Debug/mtouch-cache/Microsoft.Azure.Mobile.iOS.Bindings.dll.arm64.dylib -x assembler /Users/Alex/Projects/Bug51548/iOS/obj/iPhone/Debug/mtouch-cache/Microsoft.Azure.Mobile.iOS.Bindings.dll.arm64.s -DDEBUG
We are extracting and giving the static library to clang so must be something else.
@Alex, is the MSLogger class in the arm64 slice in the binary?
nm -arch arm64 /Users/Alex/Projects/Bug51548/iOS/obj/iPhone/Debug/mtouch-cache/MobileCenter.a | grep MSLogger
@Rolf, looks like it is, inside arm64 and armv7
iAlexRet:mobilecenter Alex$ nm -arch arm64 MobileCenter.a | grep MSLogger
0000000000000168 t +[MSLogger currentLogLevel]
000000000000013c t +[MSLogger initialize]
0000000000000238 t +[MSLogger isUserDefinedLogLevel]
00000000000001c0 t +[MSLogger logMessage:level:tag:file:function:line:]
0000000000000174 t +[MSLogger setCurrentLogLevel:]
0000000000000244 t +[MSLogger setIsUserDefinedLogLevel:]
000000000000018c t +[MSLogger setLogHandler:]
0000000000000658 S _OBJC_CLASS_$_MSLogger
0000000000000630 S _OBJC_METACLASS_$_MSLogger
00000000000004f0 s l_OBJC_$_CLASS_METHODS_MSLogger
00000000000005e8 s l_OBJC_CLASS_RO_$_MSLogger
00000000000005a0 s l_OBJC_METACLASS_RO_$_MSLogger
iAlexRet:mobilecenter Alex$ nm -arch armv7 MobileCenter.a | grep MSLogger
00000108 t +[MSLogger currentLogLevel]
000000de t +[MSLogger initialize]
000001aa t +[MSLogger isUserDefinedLogLevel]
00000162 t +[MSLogger logMessage:level:tag:file:function:line:]
00000116 t +[MSLogger setCurrentLogLevel:]
000001ba t +[MSLogger setIsUserDefinedLogLevel:]
00000132 t +[MSLogger setLogHandler:]
00000484 S _OBJC_CLASS_$_MSLogger
00000470 S _OBJC_METACLASS_$_MSLogger
000003c4 s l_OBJC_$_CLASS_METHODS_MSLogger
00000448 s l_OBJC_CLASS_RO_$_MSLogger
00000420 s l_OBJC_METACLASS_RO_$_MSLogger
@Rolf I was also thinking that could be a visibility issue but that also seems fine
> MobileCenter.a:MSLogger.o: 0000000000000658 (__DATA,__objc_data) external _OBJC_CLASS_$_MSLogger
> MobileCenter.a:MSLogger.o: 0000000000000630 (__DATA,__objc_data) external _OBJC_METACLASS_$_MSLogger
@Rolf: Tested the native library with a Xcode project and works fine, after some other filed attempts Sebastien came to the rescue and suggested to disable fastdev and it built fine without it.
@Zhen Liu uncheck "Enable incremental builds" in your Project Options > Build > iOS Build as a workaround
Downgrading severity as there's a workaround for the issue.
What happens is that we link the native library into Microsoft.Azure.Mobile.iOS.Bindings.dll.arm64.dylib, but the code that is actually using referencing these classes is compiled into libregistrar.o, which is only linked into the main app, so the native linker will just remove the native library from Microsoft.Azure.Mobile.iOS.Bindings.dll.arm64.dylib (since it's not used).
One possible solution is to add -force_load to third-party native libraries when linking them into dylibs, but that would be a functional difference between incremental builds and non-incremental builds, so I don't think it's a good idea.
Unfortunately I think this will probably hit most projects using binding projects and incremental builds (which suggests another (temporary) solution: automatically disable incremental builds if any binding projects are used).
A more permanent solution would be to ask the linker to keep any bound classes (I'm not sure if passing '-u _OBJC_CLASS_$_MSLogger' will work, but if not, we can generate an ObjC file that just does '[MSLogger class]' which will have the pretty much the same effect).
@Sebastien, I can try to implement the permanent solution in master, and if it turns out to be too complicated (or other problems show up that causes it to take too long/risky to fix), we can easily implement the temporary solution in C9.
BTW this works by accident in C8: the native library is linked into both Microsoft.Azure.Mobile.iOS.Bindings.dll.arm64.dylib and the executable, and since the native linker does not add anything from the native library in Microsoft.Azure.Mobile.iOS.Bindings.dll.arm64.dylib, everything works fine. Had there been any P/Invokes in the managed binding assembly to the native library (which would have prevented the native linker from removing the native library), then we'd end up with two copies of the native library in the process.
Let's do (and test) this* on master - with a potential backport to C9 or a service release later.
* We'll discuss options on the next meeting -> https://trello.com/c/SMvrUWAN/665-incremental-builds-fastdev
@Rolf in the mean time let's add this to the 10.4 release notes as a known issue.