web-dev-qa-db-ja.com

OS Xで静的リンクする方法

OS Xで静的ライブラリにリンクしようとしています。-staticフラグはgccコマンドに含まれていますが、次のエラーメッセージが表示されます。

 ld_classic:次のファイルが見つかりません:-lcrt0.o 
 collect2:ldが1の終了ステータスを返しました

私はmanページを見て、それは次のようなものを読みます:

このオプションは、すべてのライブラリ(libgcc.aを含む)も-staticでコンパイルされていない限り、Mac OS Xでは機能しません。 libSystem.dylibの静的バージョンもcrt0.oも提供されていないため、このオプションはほとんどの人にとって役に立ちません。

この静的ライブラリにリンクする別の方法はありますか?

48
Frank

アーカイブライブラリ(静的ライブラリとも呼ばれます)にリンクするには、リンク行に追加します。

gcc main.o ... -lfoo ...

リンカはlibfoo.dylibを検索し、次にlibfoo.aを検索します。

bothライブラリのバージョンがあり、動的バージョンよりもアーカイブバージョンにリンクする場合は、リンク行にアーカイブへの完全パスを指定するだけです。

gcc main.o ... /path/to/libfoo.a ...
53

残念ながら、 サポートされていません 。 crt0を手動でコンパイルすることが可能であると報告した人もいますが、 誰も確認していない です。

15
alecco

一般的なケースはシステムフレームワークに対して動的にリンクしながら、3番目のユーザーライブラリに対する静的リンクとライブラリです。そのため、ユーザーはプログラムを使用する前にサードパーティのライブラリをインストールする必要はありません。ライブラリがフレームワークに対して動的にリンクされている場合(よくあることです)、それでも静的な.aで出荷される可能性がありますが、-l<libname>/path/to/libname.aで置き換えるだけでは不十分です。依存関係はありません。また、ライブラリが使用していたフレームワークに対して動的にリンクする必要があります。

たとえば、ユーザーがlibusbをダウンロードしてインストールすることなく、オープンソースのlibusbを使用するプログラムを作成するとします。これを使用してビルドした動的にリンクされたバイナリがあるとします。

clang -lusb-1.0 main.c -o myprogram

OS Xで静的にリンクするには、コマンドは次のようになります(-framework引数に注意してください)。

clang -framework CoreFoundation -framework IOKit main.c /path/to/libusb-1.0.a -o myprogram

追加する必要があるシステムフレームワークとライブラリを見つけるには、otoolを使用してサードパーティのdylibを確認します。

otool -L /usr/local/opt/libusb/lib/libusb-1.0.0.dylib

示す:

/usr/local/opt/libusb/lib/libusb-1.0.0.dylib:
    /usr/local/opt/libusb/lib/libusb-1.0.0.dylib (compatibility version 2.0.0, current version 2.0.0)
    /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
    /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0)
    /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1348.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.0.0)  

最初にフレームワークを追加し、その後にライブラリを1つずつ追加すると、未定義の参照エラーのリストが縮小されます。一部のライブラリは明示的に追加したライブラリの依存関係としてロードされる可能性があるため、おそらくすべてのライブラリを追加する必要はありません。

Dylibの場所がわからない場合は、プログラムを(-lusb-1.0を使用して)元の動的な方法でビルドし、otoolを実行します。

clang -lusb-1.0 main.c -o myprogram
otool -L myprogram

それは与える:

myprogram:
    /usr/local/opt/libusb/lib/libusb-1.0.0.dylib (compatibility version 2.0.0, current version 2.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.0.0)

また、リンク先のライブラリのライセンスもお読みください。

10
Michael Chinen

-BstaticはOS-X Lionでは何もしないようです-使用済みgcc -vこれを確認します。

7
atrens

同じ問題に遭遇しました。回避策の例を次に示します。

STEP1:ファイルを作成する

myfunc1.c:

#include <stdio.h>

void myfunc1() {
    printf( "This is my func1!\n" );
}

myfunc2.c:

#include <stdio.h>

void myfunc2() {
    printf( "This is my func2!\n" );
}

およびmyfunc.c:

#include <stdio.h>

void myfunc1( void );
void myfunc2( void );

int main() {
    myfunc1();
    myfunc2();
    return 0;
}

STEP2:ライブラリを作成する

gcc -c myfunc1.c myfunc2.c

ar -r libmyfuncs.a myfunc1.o myfunc2.o

STEP3:リンク

gcc -o myfunc -L. myfunc.c -lmyfuncs 

「-L。」と入力することを忘れないでください。ドットは現在のパスを示します。

お役に立てば幸いです。

0
Zhi Q.