2016-11-07 9 views
1

cc(1)を使用してプログラムをリンクすると、デフォルトのリンカーコマンドが呼び出されます。たとえば、あなたのバージョンのコンパイラは、UNIXのようなプラットフォームではデフォルトで/ usr/bin/ldを使うようにビルドされているかもしれません。'cc'とリンクするときに代替リンカーコマンドを指定する方法

cc(1)(またはc++(1))が(例えば、/usr/local/bin/ld代わり/usr/bin/ldの)使用することを異なるリンカーコマンドを指定する方法はありますか?私は主にgccとclangに興味があります。

私は、さまざまなコンパイルステップを別々に実行する方法(たとえば、前処理、コンパイル、アセンブル、リンク)を必要としない方法を探していません。

例えば、私はこの仕事をするかもしれないような何かを期待していた:

env LD=/usr/local/bin/ld cc foo.c -o foo 

をしかし、それはGCCや打ち鳴らすために動作しません。あなたが最初のオブジェクトファイルを構築し、メイクファイルを持っていた場合には、当然のことながら、働くだろう、そしてリンクに$ {LDを}呼び出された(例えば、env LD=/usr/local/bin/ld make

更新(一つの可能​​な動機で):簡単にテストするには既定のリンカーとは異なるリンカーです。例えば、これを行うことができるようにいいだろう:

cc --linker=/usr/local/bin/ld foo.c -o foo 

は代わりに、あなたは、オブジェクトファイルを生成しませんldに引数を把握するためにcc -vを実行して、手動のものとしたいldを実行する必要があります引数:

cc -c foo.c 
cc -v foo.c -o /dev/null 

リンカの呼び出しを見て、リンカと一時オブジェクトファイルを置き換えて手動でコピー/ペーストします。このような何か(フェドーラ23上のテストから取られた例)あなたは/usr/local/bin/ld/usr/libexec/gcc/x86_64-redhat-linux/5.3.1/collect2を交換する(それはまさにではありませんが、collect2と同じ):

/usr/local/bin/ld -plugin /usr/libexec/gcc/x86_64-redhat-linux/5.3.1/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/x86_64-redhat-linux/5.3.1/lto-wrapper -plugin-opt=-fresolution=/tmp/jhein/ccM2XKIg.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o c /usr/lib/gcc/x86_64-redhat-linux/5.3.1/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-redhat-linux/5.3.1/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/5.3.1/crtbegin.o -L/usr/lib/gcc/x86_64-redhat-linux/5.3.1 -L/usr/lib/gcc/x86_64-redhat-linux/5.3.1/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/5.3.1/../../.. c.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-redhat-linux/5.3.1/crtend.o /usr/lib/gcc/x86_64-redhat-linux/5.3.1/../../../../lib64/crtn.o 

あなたはそれが簡単ではない、見ることができるように。 collect2がリンカープログラムを探す方法については、gcc infoページのドキュメントを参照してください。しかし、これらのドキュメントによれば、最初に見えるのは、環境変数やコマンドラインで指定できるもの(例えば、--linker)ではありません。ドキュメントでは、 "ハードコーディングされたリンカファイル名"については、の最初の文字がとなっています。そのドキュメントが正しい場合、そのリンカーを使用しないように強制する(つまり、それを騙す)ためには、デフォルトのリンカーの名前を変更する必要があります(例:sudo mv /usr/bin/ld /usr/bin/ld.tmp-disable)。

更新2-Bを使用すると、私のニーズに十分に対応しているようです。私が答えを投稿したところを見てください。私は自分の答えを受け入れることはできませんが、できれば私はします。問題をうまく解決するようです。

+1

'cc'は' gcc'、 'clang'、またはあなたのシステムが使うデフォルトのCコンパイラのエイリアスです。 –

+0

はい、同意します。確かにそうだ。あなたはgccやclangの質問に対する答えを持っていますか? – Juan

+0

'gcc'の' -c'フラグを試すことができます。 –

答えて

1

コンパイラが使用します。これは、[1]のgccのいくつかのバージョンのために働くと打ち鳴らすため(現在は文書化されていない - 少なくとも打ち鳴らす3.7 & 3.8のmanページで):これはccは他のツールを検索するようになりますことを

cc -B/usr/local/bin foo.c -o foo 

注意(例えば、アセンブラ)を-Bで指定されたパスに挿入します。ですから、だけそのリンカー(。。というよりも/usr/local/bin/asら)を使用したい場合は、/ usr/local/binにインストールのbinutilsの異なるバージョンを持っていると仮定、あなたはこのような何かを行うことができます:

mkdir /tmp/usemyld 
ln -s /usr/local/bin/ld /tmp/usemyld 
cc -B/tmp/usemyld foo.c -o foo 

-Bには、gccコンパイラが使用しようとするさまざまなファイル(プログラム、ライブラリ、インクルードファイル、データファイル)をオーバーライドするための独自のルールセットがあります。これは、少なくともgcc 2.95以上にまで文書化されています - gcc man/infoページを読んでください。 -Bの動作がclangのためにどのように互換性があるのか​​わかりません。言及したように、現在clangのmanページには書かれていません。しかし、私は上記のように別のリンカーを選択するのに十分にうまくいきました。

gccは、-wrapperで指定されたスクリプト/プログラムの呼び出しもサポートしています。 clang(現在)はありません。また、それを使用して、コンパイラが呼び出すプログラムを変更するラッパースクリプトを指すこともできます。 collect2-wrapperオプション(そしてgccの場合、少なくともc/C++プログラムをコンパイルするときにリンカを呼び出すのはcollect2)であるかどうかわかりません。

[1] collect2ためgcc情報ページに記載さリンカ検索順序が)「GCCは 『--with-LD』オプションで設定された場合は、ハードコーディングされたリンカファイル名」、それがために最初に検索することを言います。したがって、gccが '--with-ld'で構成されていない場合は、-Bで指定されたパス(最終的にreal-ldが見つからない場合)で検索されます。あなたのgcc --with-ldで設定されただった場合、-Bオプションはあなたが選択した代替リンカーを指定するのに役立ちません。

0

GCCは(gccプログラムがどのように動作するか、特にどのようにリンクしているのか、どのリンカを使用するのかを決定するために)内部でspec filesを使用します。そのwith -specs=を設定または変更して、独自の仕様ファイルを作成して使用することができます。または、-T optiongcc)のldに明示的に渡します)を使用してリンカースクリプトを作成します。

デフォルトの仕様は、またgcc -dumpspecs

で得られるstrace(1)は、いくつかのgccコマンドを-ingことで、あなたはそれが例えばアクセスしようとしていることがわかります/usr/lib/gcc/x86_64-linux-gnu/specs;そこに独自のspecファイルを置いてください。

これらのスペックファイルはテキストファイルなので、独自のファイルを作成することができます。

しかし、私はそれが良い考えであるかどうかはわかりません。

ところで、/usr/bin/ccは、Linuxディストリビューション(Debianの上:/usr/bin/cc -> /etc/alternatives/cc -> /usr/bin/gcc)シンボリックリンクの上にあるいくつかのgccまたは一部clangのいずれか、。私の知る限り、cc(およびc99)はPOSIXで指定されている(もちろん、何もldとの関係について語られていない)ファイルに&データファイルを含め、-Bオプションは、実行ファイル、ライブラリの代替検索パスを指定することができます

+1

'-T'オプションは' ld(1) 'のためのもので、' cc(1) 'のものではありません。 '-specs'を見ていきます。 gcc固有のように見えます。そして、私はそれが正しい解決策のようには感じないと同意します。 – Juan

+0

'-T'オプションは' gcc'用です –

+0

'-T'は' ld(1) '用です。リンカに '--startgroup'などのように他のオプションを渡すのと同様に、' gcc'(または 'clang')を使って' -T 'をリンカに渡す場合は、 '-Wl、 - T -Wl、your_link_script_file.ld'。それはショートカット( '-L'に似ています)として、' gcc'や 'clang'に-Tを渡すことができますが、それはどこにも書かれていません(マニュアルページ、情報ページ、--help) 。そう、はい、あなたは正しいです。申し訳ありません - 私は間違ってドキュメントを探していました。しかし、リンカスクリプトは、ccではなくldによって読み込まれます。指定する方法があったとしても、別のコマンドを指すのが遅すぎます。 – Juan

関連する問題