My External Storage

Aug 4, 2017 - 3 minute read - Comments - Xamarin.Mac c-sharp VisualStudio

Xmarin.Macアプリでネイティブメソッドの動的ロードを含むビルドを行う

ネイティブライブラリの動的ロードを含むXamarin.Macアプリを作ろうとしたら、ビルドエラーに遭遇しました。

TL;DR

  • MMP : error MM5109: Native linking failed with error code 1というビルドエラーを解決したい。
  • プロジェクトオプション-「Mac Build」タブ-「追加のmmp引数」に「--link_flags="-Wl,-undefined,dynamic_lookup"」と設定する。
  • Xamarin.Macアプリのプロジェクトに、動的ロードで解決するメソッドが含まれていてもビルド出来るようになる。

MMP : error MM5109: Native linking failed with error code 1

Xamarin.Macプロジェクトをビルドするとき、C#のアプリをネイティブアプリに変換する処理が走ります。このとき、C#の中でネイティブライブラリを動的にロードしているようなプロジェクトは以下のようなエラーでビルドが止まることがあります。_C_FooFunction_C_BarFunctionは動的にロードするライブラリの中で宣言されているメソッドです。

Target _CompileToNative:

...

    xcrun -sdk macosx clang -g -mmacosx-version-min=10.12 -arch x86_64 -fobjc-runtime=macosx -ObjC -u _C_FooFuncion -u _C_BarFunction  ....
    Undefined symbols for architecture x86_64:
      "_C_FooFunction", referenced from:
         -u command line option
      "_C_BarFunction", referenced from:
         -u command line option

...

    ld: symbol(s) not found for architecture x86_64
    clang : error : linker command failed with exit code 1 (use -v to see invocation)
    
    MMP : error MM5109: Native linking failed with error code 1.  Check build log for details.
Done building target "_CompileToNative" in project "CocoaApp.csproj" -- FAILED.

mmp--link_flags経由でリンカーにオプションを渡す

ネイティブアプリにするビルドの過程でclangが呼ばれ、そのなかでリンカー(ld)がシンボルを解決出来ないようでした。ビルド過程のldコマンドにオプションを渡して、シンボルが未解決でもビルドを完了させるようにします。

  • VSforMacでプロジェクトの「オプション」ウインドウを開く
  • 「Mac Build」タブを選択する。
  • 「追加のmmp引数」という入力欄に、「--link_flags="-Wl,-undefined,dynamic_lookup"」を追記する。

プロジェクトオプション

これで未定義のメソッドが合っても、ビルドエラーが発生しなくなります。 当然実行時エラーが発生する恐れがあるので、ビルドしたアプリが正しく動くかは別途確認が必要です。mmpに渡せるオプションは他にもいくつかあるのですが、Web上にあまり情報がありません。オプションの調べ方は別記事にまとめました。

Xamarin.Macプロジェクトのオプションにある「追加のmmp引数」に指定できる値

ちなみに、「追加のmmp引数」近くに「リンカーの動作」というオプションもあるのですが、これでは解決しませんでした。

参考

Error when making dynamic lib from .o

Xamarin.Macプロジェクトのオプションにある「追加のmmp引数」に指定できる値

関連記事