macOS X
MacOS X では、 の man ページでオプションld
について明確に説明されています。-r
-r
オブジェクト ファイルをマージして、ファイル タイプが MH_OBJECT の別のマッハ オブジェクト ファイルを生成します。
したがって、MacOS X を使用している場合の問題は、それ-lm
が Mach-O オブジェクト ファイルではなく、-lc
. ただし、理論的には、オブジェクト ファイルmain.o
がobj1.o
ありobj2.o
、その場合:
cp obj1.o ./-lm
cp obj2.o ./-lc
ld -r -o main1.o main.o -lm -lc
それならうまくいくかもしれません。実際には、そうではなく、発生するエラーの中に次のようなものがあります。
ld: warning: unexpected dylib (/usr/lib/libm.dylib) on link line
ld: warning: unexpected dylib (/usr/lib/libc.dylib) on link line
ただし、実行中:
ld -r -o main1.o -arch x86_64 main.o obj1.o obj2.o
ローダーからの騒音なしで動作しました。
Linux
Linux の man ページld
はあまり明示的ではありませんが、次のように述べています。
-i
インクリメンタル リンクを実行します (オプション -r と同じ)。
-r
--relocatable
再配置可能な出力を生成します。つまり、 への入力として使用できる出力ファイルを生成しますld
。これはしばしば部分リンクと呼ばれます。副作用として、標準の Unix マジック ナンバーをサポートする環境では、このオプションは出力ファイルのマジック ナンバーも "OMAGIC" に設定します。このオプションが指定されていない場合、絶対ファイルが生成されます。C++ プログラムをリンクする場合、このオプションはコンストラクターへの参照を解決しません。そのためには、 を使用します-Ur
。
入力ファイルが出力ファイルと同じ形式でない場合、部分リンクは、その入力ファイルに再配置が含まれていない場合にのみサポートされます。異なる出力形式にはさらに制限があります。たとえば、一部の「a.out」ベースの形式は、他の形式の入力ファイルとの部分的なリンクをまったくサポートしていません。
このオプションは と同じことを行い-i
ます。
行間を読むと、これもオブジェクトファイルを取り、それらをオブジェクトファイルに変換します。ライブラリをミックスに追加しません。考えてみれば、ライブラリへの参照を含むオブジェクト ファイルは作成されません。
-r
そのため、オプションを使用する際にリンカー (ローダー) にライブラリを指定できるプラットフォームもあれば、そうでないプラットフォームもあります。
回避策
元の問題は、ライブラリが存在するかどうかを確認することです。何ができるかを模倣して、優先的に、ライブラリで定義されたシンボルへの参照を含むが、単に以下を含むことができる をautoconf
作成してみませんか?main.c
int main(void){return 0;}
それをコンパイルして C コンパイラとリンクします。
cc -o main main.c -lm -lc
機能しない場合は、ライブラリの 1 つが不足しています。が存在することをすでに確認している場合は、それが欠落していると-lc
推測できます。-lm