5

GNU ld 2.21 で Debian/Linux x86_64 を実行しています。

簡単に言えば、リンクすると

ld -o main main.o /usr/lib/crti.o /usr/lib/crt1.o /usr/lib/crtn.o -lc -lm

動作しますが、リンクすると

ld -r -o main1.o main.o /usr/lib/crti.o /usr/lib/crt1.o /usr/lib/crtn.o -lc -lm

文句を言う

ld: cannot find -lc
ld: cannot find -lm

私は実際にこの方法でコードをコンパイルしようとしているわけではありませんが、ライブラリが存在するかどうかを確認する他の誰かのテストが機能しない理由を理解しようとしています。(したがって、何が起こっているのかよくわかりませんld...通常はGCCを使用してリンクします)

再配置可能な方法でリンクするように指示ldすると、突然ライブラリが見つからなくなるのはなぜですか? 存在することをテストしたいだけなら-lm、他に何をすべきですか

ld -r -lm

ライブラリを見つけるように?

私が扱っているソースを見たい場合は、https ://github.com/jeremysalwen/ESPS からダウンロードできます (最初のコミットは元のソース コードであり、その後のコミットは変更であることにご注意ください)。個人で作っています。)

4

2 に答える 2

3

macOS X

MacOS X では、 の man ページでオプションldについて明確に説明されています。-r

-rオブジェクト ファイルをマージして、ファイル タイプが MH_OBJECT の別のマッハ オブジェクト ファイルを生成します。

したがって、MacOS X を使用している場合の問題は、それ-lmが Mach-O オブジェクト ファイルではなく、-lc. ただし、理論的には、オブジェクト ファイルmain.oobj1.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

于 2011-07-07T00:53:08.220 に答える
0

何がecho $LD_PRELOADあなたを示していますか?

おそらく、リンクされたライブラリがld見つからないというエラー メッセージが表示されます。これらのファイルを指すように.so設定すると役立ちます。LD_PRELOAD.so

于 2011-07-07T00:56:31.293 に答える