Linker error building a release project with a binding project on XM3.4

JohnConnersJohnConners GBMember ✭✭

Got an error building a release version of an app where I have a binding project against Sparkle that's just started failing as soon as I updated from Xamarin.Mac 3.0 to 3.4 (and the rest of the 15.2 release).

Attached is an example project that exhibits the problem - just do a release build and it'll fail. The relevant bit of the build log (I suspect) is this:

Undefined symbols for architecture x86_64:
  "_OBJC_CLASS_$_SUUpdater", referenced from:
      objc-class-ref in registrar-4205f1.o
ld: symbol(s) not found for architecture x86_64
clang : error : linker command failed with exit code 1 (use -v to see invocation)

Any idea what's changed and that I'm doing wrong? As I say, built and worked previously, now won't build.

https://www.dropbox.com/s/1qv7tmp5fwi7oc4/TestSparkle.zip?dl=1

Best Answer

Answers

  • JohnConnersJohnConners GBMember ✭✭

    As always @ChrisHamons it works perfectly - thanks! Let me know if there's anything I can do to help figure out what's happening.

  • ChrisHamonsChrisHamons USXamarin Team Xamurai

    Likely what's going on is you have code referencing SUUpdater but you aren't linking in things in a way that makes the static registrar happy.

    The static registrar is just an optimization that improves launch performance.

    Posting a sample here would be helpful obvious, but if your application is launching "fast enough" then you can just keep using the dynamic registrar. It's what < 3.4 defaulted to.

  • JohnConnersJohnConners GBMember ✭✭

    Ok here's a fully working version of the example project above:

    https://www.dropbox.com/s/m6myn4lvrn355cu/TestSparkle2.zip?dl=1

    If you build the release version and run it it'll prompt you to update the app (I'm just pointing it at SourceTree's appcast). Removing the mmp switch prevents the release build from building but I'd be interested to know how I can get the static registrar to "see" SUUpdater. I don't have any launch performance problems so I don't mind either way but I'd obviously prefer to be doing things the "default" way if I can.

  • AlexanderMaasAlexanderMaas USMember ✭✭

    I was actually seeing a similar error in my app, but also managed to reproduce this error in a very simple binding example, where I bind the following class containing only one single simple method:

    @implementation NativLibTestObject
    
    -(void)LogValue:(NSInteger)val
    {
        NSLog(@"%ld",val);
    }
    @end
    

    In my binding project, I include the .dylib file under native references and the ApiDefinition.cs file looks like this:

    using System;
    using AppKit;
    using Foundation;
    using ObjCRuntime;
    using CoreGraphics;
    
    namespace NativLibTestBinding
    {
        //...
        // @interface NativLibTest : NSObject
        [BaseType(typeof(NSObject))]
        interface NativLibTestObject
        {
            // -(void)LogValue:(NSInteger)val;
            [Export("LogValue:")]
            void LogValue(nint input);
        }
    }
    
    

    Then in my Mac application project in AppDelegate.cs, I include the following code.

        public override void DidFinishLaunching(NSNotification notification)
            {
                // Insert code here to initialize your application
                NativLibTestObject testObject = new NativLibTestObject();
                testObject.LogValue(10);
            }
    

    When I run the mac project in Debug mode, I see the output I expect: 10.
    When I run the mac project in Release mode, I find the following error:

    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    

    The solution mentioned above works for me as well, but I am not really sure why this binding example is incorrect. Any hints?

  • ChrisHamonsChrisHamons USXamarin Team Xamurai

    I'm able to reproduce (both) your issues.

    I'm looking into what's going on. FWICT it should be working:

    $ nm PATH/libNativLibTestBinding.dylib | grep OBJC_CLASS$NativLibTestObject
    U _OBJC_CLASS
    $NSObject
    0000000000001120 S _OBJC_CLASS
    $_NativLibTestBinding

    Let me get back to you.

  • ChrisHamonsChrisHamons USXamarin Team Xamurai

    Well I thought I could reproduce the second issue. I had a typo where the native name did not match the managed name.

    @AlexanderMaas @JohnConners - I am having trouble reproducing both issues in 3.4.

    Can you try with 3.4 (https://dl.xamarin.com/XamarinforMac/Mac/xamarin.mac-3.4.0.33.pkg) and report back.

  • JohnConnersJohnConners GBMember ✭✭

    So I can definitely reproduce the issue. I re-downloaded the second project I linked to, Release build - success. Remove the mmp arguments, rebuild all, error.

    Visual Studio: Version 7.0 (build 3146)
    Xcode: 8.3.2 (12175)
    Xamarin.iOS: 10.10.0.33 (Visual Studio Community)
    Xaamrin.Mac: 3.4.0.33 (Visual Studio Community)
    Mac OS X 10.12.4

  • ChrisHamonsChrisHamons USXamarin Team Xamurai

    Ah, I downloaded a second copy, and that copy still had "--registrar:dynamic".

    It appears Xamarin.Sparkle does not have any native references.

    Adding Sparkle.framework fixed the issue on my end.

  • JohnConnersJohnConners GBMember ✭✭

    Right, I see! Only snag is that will always bundle Sparkle.framework in my package which I don't want for Mac App Store builds - easy enough to delete in an after build command. Thanks for the help!

  • ChrisHamonsChrisHamons USXamarin Team Xamurai

    Or you can just use --registrar:dynamic.

    The static registrar requires that all of the bits be available at compile time, linked in, so we can codegen sane code.

  • JohnConnersJohnConners GBMember ✭✭
    True. However I've just discovered conditional project references so I'm all good! Thanks for the help!
  • AlexanderMaasAlexanderMaas USMember ✭✭

    @ChrisHamons: I also still see the same error:
    Xamarin Studio: Version 6.3 (build 864)
    Xcode: Version 8.3.2 (8E2002)
    Xamarin.iOS: Version 10.10.0.33 (Xamarin Studio Community)
    Xaamrin.Mac: Version 3.4.0.33 (Xamarin Studio Community)
    Mac OS X 10.12.4

  • ChrisHamonsChrisHamons USXamarin Team Xamurai

    @AlexanderMaas - Can you attach a cleaned example project somewhere. I reproduced your example the best I could and it works for me.

  • AlexanderMaasAlexanderMaas USMember ✭✭

    I've posted my project and code here:
    https://teamo.blob.core.windows.net/esc-ape/DebugExample.zip

  • ChrisHamonsChrisHamons USXamarin Team Xamurai
    edited May 2017

    Your clang invocation to create your dylib is wrong:

    clang -dynamiclib -ObjC++ -L. -lc++ ./NativLibTest.m -current_version 1.0 -compatibility_version 1.0 -fvisibility=hidden -framework Cocoa -framework AppKit -framework AVFoundation -o bin/NativLibTest.dylib

    Do not use -fvisibility=hidden

    It makes your symbols not visible without hinting attributes (visibility).

    Once you fix that, things work fine.

  • AlexanderMaasAlexanderMaas USMember ✭✭

    Thanks!

  • HariK.5376HariK.5376 USMember

    After upgrading to 3.0, I started getting this "linker command failed with exit code 1" for solution with PCL project referenced to native projects. Any clues?

    Thanks,

  • ChrisHamonsChrisHamons USXamarin Team Xamurai

    "linker command failed with exit code 1" unfortunately says nothing about the problem at hand. There is some trouble with the native link of your application. You'll have to read the build log for more details.

  • HariK.5376HariK.5376 USMember

    Below is the complete error. Though I did't modify anything, after updating framework this started sowing.

    /MTOUCH: Error MT5212: Native linking failed, duplicate symbol: 'OBJC_CLASS$XuniEaseAction'. (MT5212)
    Mobile.iOS/MTOUCH: Error MT5213: Duplicate symbol in: obj/iPhone/Ad-Hoc/mtouch-cache/libXuniCore.a(Easing.o) (Location related to previous error) (MT5213)
    Mobile.iOS/MTOUCH: Error MT5213: Duplicate symbol in: /obj/iPhone/Ad-Hoc/mtouch-cache/arm64/registrar.o (Location related to previous error) (MT5213)
    Mobile.iOS/MTOUCH: Error MT5212: Native linking failed, duplicate symbol: '_OBJC_METACLASS
    $_XuniEaseAction'. (MT5212)

    Thanks,

  • ChrisHamonsChrisHamons USXamarin Team Xamurai

    The fact that you have "mtouch-cache" means to begin with this is a Xamarin.iOS project, not Xamarin.Mac.

    It looks like you have a static library libXuniCore.a and your managed code both defining the same type? XuniEaseAction

    I would see what's specifically going on with that type.

Sign In or Register to comment.