web-dev-qa-db-ja.com

Xcodeでダイナミックライブラリ(dylib)を作成するにはどうすればよいですか?

Xcodeでいくつかのコマンドラインユーティリティを構築しています(プレーンC、Cocoaなし)。すべての実行可能ファイルで使用するlibpngをカスタマイズし、すべての実行可能ファイル間でライブラリの1つのコピーを共有することでスペースを節約したい(.dylibを再配布してもかまいません)。

Libpngエクスポートシンボルを取得するために魔法をかける必要がありますか?

"Link Binary With Libraries"フェーズリンクを静的に構築しますか?

Appleのドキュメントには、実行時にdlopenを使用してライブラリをロードすることが記載されていますが、シンボルの欠落について文句を言わずにXcodeを実行可能にする方法を教えてください。


私はそれを理解したと思います:

  • libpngは正しくリンクされていませんでした。32/ 64ビットの実行可能ファイルと32ビットのライブラリをビルドしたためです。ライブラリと実行可能ファイルのビルド設定は一致している必要があります。

  • libpngのconfig.hには、#define FEATURE_XXX_SUPPORTEDのような多数の定義が必要です。

  • "Link Binary With Libraries"ビルドフェーズは動的ライブラリを適切に処理し、DYLD_FALLBACK_LIBRARY_PATH環境変数はアプリケーションバンドルから.dylibsをロードするために必要です。

28
Kornel

ビルドするダイナミックライブラリに、ライブラリからエクスポートする必要があるものをリストしたエクスポートシンボルファイルがあることを確認する必要があります。エクスポートするのは、1行に1つずつのシンボルのフラットリストです。

また、ダイナミックライブラリがビルドされると、インストール名が埋め込まれます。これは、デフォルトでは、ビルドされたパスです。その後、それに対してリンクするものは、最初に指定されたパスでそれを探し、その後のみ dyld(1) manページのDYLD_FALLBACK_LIBRARY_PATHで説明されているデフォルトパスの(小さい)セットを検索します

このライブラリを実行可能ファイルの横に配置する場合は、それを参照するようにインストール名を調整する必要があります。 Googleで「インストール名」を検索するだけで、インストールに関する大量の情報が表示されます。

7
Chris Hanson

Mac OS Xでの動的リンク、小さな例

手順:

  1. mymod.oを含むライブラリーlibmylib.dylibを作成します。
  2. それを呼び出す「callmymod」をコンパイルしてリンクする
  3. dYLD_LIBRARY_PATHおよびDYLD_PRINT_LIBRARIESを使用して、callmymodからmymodを呼び出す

問題:他のモジュールが使用するライブラリを作成したいだけです。ただし、膨大な数のオプション、いくつかのよく腐った堆肥、MacOSXとLinuxの違いがある、gcc、ld、macosx libtool、dyldなどのプログラムの厄介な山があります。たくさんのmanページがありますが(10.4.11 ppcでは7679 + 1358 + 228 + 226行と数えます)、例や、「何をしているのか教えて」モードのプログラムはそれほど多くありません。

(理解する上で最も重要なことは、簡単な概要を自分で作成することです。いくつかの絵を描き、いくつかの小さな例を実行し、それを他の人に説明します)。

背景: Apple OverviewOfDynamicLibrariesWikipedia Dynamic_library


ステップ1、libmylib.dylibを作成します-

mymod.c:
    #include <stdio.h>
    void mymod( int x )
    {
        printf( "mymod: %d\n", x );
    }
gcc -c mymod.c  # -> mymod.o
gcc -dynamiclib -current_version 1.0  mymod.o  -o libmylib.dylib
    # calls libtool with many options -- see man libtool
    # -compatibility_version is used by dyld, see also cmpdylib

file libmylib.dylib  # Mach-O dynamically linked shared library ppc
otool -L libmylib.dylib  # versions, refs /usr/lib/libgcc_s.1.dylib

ステップ2、callmymodをコンパイルしてリンクします-

callmymod.c:
    extern void mymod( int x );
    int main( int argc, char** argv )
    {
        mymod( 42 );
    }
gcc -c callmymod.c
gcc -v callmymod.o ./libmylib.dylib -o callmymod
    # == gcc callmymod.o -dynamic -L. -lmylib
otool -L callmymod  # refs libmylib.dylib
nm -gpv callmymod  # U undef _mymod: just a reference, not mymod itself

ステップ3、libmylib.dylibにリンクするcallmymodを実行する-

export DYLD_PRINT_LIBRARIES=1  # see what dyld does, for ALL programs
./callmymod
    dyld: loaded: libmylib.dylib ...
    mymod: 42

mv libmylib.dylib /tmp
export DYLD_LIBRARY_PATH=/tmp  # dir:dir:...
./callmymod
    dyld: loaded: /tmp/libmylib.dylib ...
    mymod: 42

unset DYLD_PRINT_LIBRARIES
unset DYLD_LIBRARY_PATH

これで小さな例が1つ終わります。手順の理解に役立つことを願っています。
(これを頻繁に行う場合、macsのglibtoolである GNU LibtoolSCons を参照してください。)
乾杯
-デニス

50
denis

残念ながら、私の経験では、Appleのドキュメントは古く、冗長であり、通常は必要となる多くの一般的な情報が不足しています。

私はこれについてたくさんのことを私のWebサイトに書きました。そこでは、私たちがuniで開発したクロスプラットフォームゲームで動作するようにFMOD(サウンドAPI)を取得する必要がありました。その奇妙なプロセスですが、Appleが開発者ドキュメントに関する情報を追加しないことに驚いています。

残念ながら、Microsoftのように「悪」であるように、彼らは実際に開発者のドキュメントを手伝うというはるかに優れた仕事をしています(これはApple evangelistからのものです)。

基本的には、.app Bundleをコンパイルした後ではないと思います。次に、実行可能ファイルがライブラリファイルを探す場所を変更するために、実行可能バイナリ/MyApp.app/contents/MacOS/MyAppでコマンドを実行する必要があります。スクリプトを実行できる新しいビルドフェーズを作成する必要があります。このプロセスについては再度説明しませんが、ここではすでに詳しく説明しています。

http://brockwoolf.com/blog/how-to-use-dynamic-libraries-in-xcode-31-using-fmod

お役に立てれば。

6
Brock Woolf

Apple参照ページ 動的ライブラリプログラミングのトピック ?プログラムの起動と動的に読み込まれるライブラリ(バンドル、IIRC)はオンデマンドで読み込まれます。この2つは、MacOS XではLinuxまたはSolarisの同等のものと多少異なります。

5