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
環境変数はアプリケーションバンドルから.dylib
sをロードするために必要です。
ビルドするダイナミックライブラリに、ライブラリからエクスポートする必要があるものをリストしたエクスポートシンボルファイルがあることを確認する必要があります。エクスポートするのは、1行に1つずつのシンボルのフラットリストです。
また、ダイナミックライブラリがビルドされると、インストール名が埋め込まれます。これは、デフォルトでは、ビルドされたパスです。その後、それに対してリンクするものは、最初に指定されたパスでそれを探し、その後のみ dyld(1)
manページのDYLD_FALLBACK_LIBRARY_PATH
で説明されているデフォルトパスの(小さい)セットを検索します 。
このライブラリを実行可能ファイルの横に配置する場合は、それを参照するようにインストール名を調整する必要があります。 Googleで「インストール名」を検索するだけで、インストールに関する大量の情報が表示されます。
Mac OS Xでの動的リンク、小さな例
手順:
問題:他のモジュールが使用するライブラリを作成したいだけです。ただし、膨大な数のオプション、いくつかのよく腐った堆肥、MacOSXとLinuxの違いがある、gcc、ld、macosx libtool、dyldなどのプログラムの厄介な山があります。たくさんのmanページがありますが(10.4.11 ppcでは7679 + 1358 + 228 + 226行と数えます)、例や、「何をしているのか教えて」モードのプログラムはそれほど多くありません。
(理解する上で最も重要なことは、簡単な概要を自分で作成することです。いくつかの絵を描き、いくつかの小さな例を実行し、それを他の人に説明します)。
背景: Apple OverviewOfDynamicLibraries 、 Wikipedia 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 Libtool と SCons を参照してください。)
乾杯
-デニス
残念ながら、私の経験では、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
お役に立てれば。
Apple参照ページ 動的ライブラリプログラミングのトピック ?プログラムの起動と動的に読み込まれるライブラリ(バンドル、IIRC)はオンデマンドで読み込まれます。この2つは、MacOS XではLinuxまたはSolarisの同等のものと多少異なります。