LLVM 4.0はLLDを有効にして出荷されますが、AFAIKはまだすべてのプラットフォームで本番環境に対応しているわけではありません。 とにかくAVR / emscriptenの問題を解決するためにLLVMのアップグレードが間もなく計画されていると思います。それをサポートするために何をする必要があるか、コンパイラのパフォーマンス/バイナリサイズ/ランタイムのパフォーマンスにどのように影響するかを判断するときが来ました。通常のリンカー、およびデフォルトでそれを有効にする可能性のあるプラットフォーム。
https://github.com/rust-lang/rust/issues/39915#issuecomment -618726211に要約されている現在のステータス(2020-04-24)
#36120のPoCも参照してください。
LLDはMinGWターゲットの非常に良い候補である可能性があります。これは、現在リンカーをバンドルしており、MinGWのリンカーにはASLRの欠如からbigobjサポートの欠如までさまざまな問題があるためです。 ネイティブターゲティング(rustupのmingwパッケージが現在制限されている)だけでなく、クロスコンパイル時に必要なmingwライブラリも何とか持っていくことができれば、Linuxからのrustクロスコンパイルがすぐに可能になります。これは大きな改善になります。ディストリビューションはほとんどの場合互換性のないMinGWを使用するため、人々がディストリビューションからMinGWを取得し、問題が発生するという既存の状況を超えています。
LLDは、いくつかの理由により、MSVCターゲットをネイティブにターゲットにするのに適した候補ではありません。主な理由は、debuginfoのサポートがないことです。 MSVCターゲットへのクロスコンパイルには、再配布できないライブラリが必要であるため、そのままではサポートできません。
LLVM 4.0にアップグレードする際の追跡の問題は、 https://github.com/rust-lang/rust/issues/37609です。
記録のために、lldはSolarisターゲットに対して確実に準備ができていません。 しかし、Solarisでは、ネイティブのldの代わりにlldを使用することに気付いている理由はありません。 リンクにgccを使用する代わりに、SolarisでSolarisldを錆びさせるには何が必要かをすでに検討しました。
Solaris用ではなく、Solaris上で構築する際に使用LLDに@binarycrusader一つの理由です。
PR rust-lang / rust#40018は、 -Z linker-flavor
フラグをrustcに追加して、LLDをリンカーとして使用できるようにします。 そのPRは、LLDをrustcに埋め込んでいませんが、ツリー外での実験を可能にします。
@binarycrusader ^これは、gccの代わりにSolarisのldを直接使用する実験に役立つ可能性があります。
これで、LLVM4.0で実行されているように見えます。 @japaric 、これは、リンカーフレーバーフラグを使用して、LLDをシステムリンカーと比較および対比できるようになったことを意味しますか?
@ bstrie #40018は数週間前に着陸しました。 その着陸以来、 -Z linker-flavor=ld -C linker=ld.lld
を使用して外部LLDバイナリをリンカーとして使用できるようになりました。 gccとは異なり、LLDはシステムライブラリがどこにあるかを認識しないため、システムライブラリにリンクする場合は、 -C link-args='-L ...'
を使用してライブラリ検索パスをリンカーに渡す必要があることに注意してください。
LLVM 4.0が役立つのは、LLDをrustcにマージすることです。 この変更により、MUSLバイナリやベアメタルプログラムのリンクなど、一部のシナリオでは外部リンカーが不要になります。 ほとんどのターゲットは、前述のライブラリ検索パスの問題に遭遇するシステムライブラリへのリンクを必要とするため、いくつかのシナリオを言います。 これらのターゲットの場合、LLDはそのままでは機能しません。 その問題をどこでどのように解決するかは明確ではなく、その解決策がなければ、最も重要な(ティア1)ターゲットをLLDに切り替えることはできません。これにより、そもそもLLDをrustcに埋め込む魅力が低下します。
@japaric (sysroot-relativeライブラリ)検索パスや-lc -lpthread crt0.o
などを直接rustcに埋め込むことに反対する議論は何ですか? 結局のところ、ツールチェーンの一部のコンポーネントは、従うべきプラットフォームの標準がないため、それらを埋め込む必要があり、binutilsはこの知識の優れた黄金の情報源ではありません。
私が考えることができる唯一の欠点は、同じトリプルが異なるフレーバーのシステムで異なる検索パスを持つという状況です(これは、Linux / glibcトリプル専用であり、multilibを備えたプラットフォームでは特に悪いでしょう)。 その場合、clangはOS名をスヌープし、OS固有の規則をハードコードすると思います。これは悪いように見えますが、Linuxで実行される(システムリンカーを必要としない)単一のバイナリを配布する場合はおそらく避けられません。
@ retep998数ヶ月前にlldを簡単に調べました。 Linuxから.exeをクロスコンパイル(クロスリンク?)できませんでした。 lldはプラットフォームのネイティブフォーマットのみをサポートしているようです。
うまくいけば、私は間違っています。
これをパフォーマンスバグとしてタグ付けします。LLDのベンチマークによると、GNU ldよりも10倍優れているようであり、リンクパフォーマンスは現在コンパイラ速度の大きな要素です。
えー、ベンチマークをリンクするのを忘れました: https :
(LLVM 5.0がリリースされたばかりなので、今日関連しています。)
LLDとのリンクは、bfdやgoldよりもはるかに高速ですが、LLDを使用すると全体的なパフォーマンスが大幅に向上するとは思えません。 それでも、この問題は重要であり、優先すべきだと思います。
@tpimh I-slowタグが実行時のパフォーマンスのバグを表すのか、コンパイル時のパフォーマンスのバグを表すのか、実際には完全には
@bstrie I-slowは実行時のパフォーマンスが悪いため、I-compiletimeは前回チェックしたときのコンパイラパフォーマンス用です
LinuxからWindowsへのクロスリンクというあいまいなトピックに関心のある人には朗報です。 lldでは不可能だと前に言いましたが、それはlldのldフレーバーにのみ当てはまります。 lldのlink.exeフレーバー(lld-link)が可能です。
特にRustの場合、コードをいくつか変更するだけで、今日これを行うことができます。
mingw-w64のCRTの非常に小さなサブセットを.oオブジェクトファイルにコンパイルする必要があります。 つまり、いくつかのスレッドローカルストレージの初期化。 chkstkも必要です。
lldはMinGWの通常のインポートライブラリが好きではありません。 代わりに、lld-linkまたはllvm-dlltoolを使用して、.defファイルを自分で.libファイルにビルドする必要があります。
lldを変更して、IMPORT_NAME_NOPREFIXを次のように扱います。
IMPORT_NAME_UNDECORATE、ステップ2でも.libsは完全ではないため
Rustのseh.rsを変更して、TYPE_INFO_VTABLEをptr :: null()に置き換えます。 シンボル??_7type_info@@6B@
がMinGWで定義されていないため、必須です。 次に、Rustをビルドしてインストールします。
.cargo / configを使用して、リンカーとしてカスタムラッパースクリプトを指定します。
ラッパーリンカスクリプトは、主に渡されたパラメータを使用してlld-linkを呼び出す必要があります。 ただし、いくつかの調整を行う必要があります。
a)ファイル名の大文字と小文字を修正します。たとえばAdvAPI32.Libをadvapi32.libに変更します。
b)Rustが生成する.defファイルを変更して、シンボルの前に追加のアンダースコアを付けます
c)エントリポイント(/ entry)をオーバーライドします。 名前マングリングの問題が原因である可能性があります。
d)ステップ1でコンパイルしたmingw-crtオブジェクトファイルを追加します
xargo --target = i686-pc-windows-msvcを使用してRustプロジェクトをビルドします
上記の手順を実行すると、Rustコードをクロスコンパイルできます。 RustのSEHベースの巻き戻しを使用して、パニックを起こしたり、パニックをキャッチしたりすることもできます。
@iainnicol msvcターゲットをMinGWビットと混合しているため、これらの奇妙な変更をすべて行う必要があります。 既存のVC ++インストールからライブラリをコピーするだけの場合は、これらすべての変更やMinGWビットを使用せずに、通常はlld-linkを使用できます。
しかし、既存のVC ++インストールを使用したくありませ
スタンドアロンのビルドツールは、それがすでに言及しているものでない限り、はるかに軽量です。その場合、MinGWが実際にMSVCと互換性があるように、改善または再作成するためにいくつかの作業を行う必要があります。
スタンドアロンのビルドツールははるかに軽量です
マイクロソフトがそれらを配布していることに気づいていません。 それらにリンクしてもらえますか? 実際に実行せずにインストールアーカイブを抽出する合理的な方法はありますか?つまり、msiまたは同様のものですか?
本当にWindowsでこれを正しく実行したい場合は、まずhttps://github.com/rust-lang/rust/issues/30027を使用して、WindowsSDKまたはMinGWのインポートライブラリの必要性を排除する必要があります。 次に、CRTビットを独自の純粋なRustバージョン(数学/メモリ関数、エントリポイント、Rustが必要とする他のいくつかのランタイムビット)に置き換えるだけで、完全に自己完結型のRustツールチェーンを使用できます。 Windowsバイナリを作成してください! これの欠点は、MinGWまたはVC ++からの適切なCRTでのリンクに非常に大きく依存しているため、C / C ++コードを静的にリンクできないことです。 もちろん、Rustの要点は、Rustのすべてを書き直すことなので、これはそれほど問題にはなりません。
LinuxからWindowsへのクロスリンクというあいまいなトピックに関心のある人には朗報です。 lldでは不可能だと前に言いましたが、それはlldのldフレーバーにのみ当てはまります。 lldのlink.exeフレーバー(lld-link)が可能です。
ldフレーバーでも可能になるはずです: https :
新しいlldのMinGW互換ドライバーは、lld-linkリンカーのラッパーです。 Unix風のオプションをWindows風のオプションに内部的に変換してから、lld-linkのエントリポイントを呼び出します。 MinGW用のMakefileがない限り、(ラッパードライバーが不完全で、使用する準備ができていないことを除いて)それを使用したいかどうかはわかりません。
クロスコンパイルについて、(おそらくばかげた)質問があります。 Windowsでは、すべてのdllimportされたシンボルには、インポート元のDLL名があります。 MSVCライブラリファイルがない場合、dllimportされたシンボルがどのファイルからインポートされたかをどのようにして知ることができますか?
クロスコンパイルについて、(おそらくばかげた)質問があります。 Windowsでは、すべてのdllimportされたシンボルには、インポート元のDLL名があります。 MSVCライブラリファイルがない場合、dllimportされたシンボルがどのファイルからインポートされたかをどのようにして知ることができますか?
インポートライブラリがない場合は、インポートライブラリを作成するか、 https://github.com/rust-lang/rust/issues/30027を実装して、 winapi
がすべてのハードを実行できるようにする必要があります。各シンボルがどのDLLからのものであるかを指定する作業と、通常のようなざわめき。 何かが、それはあなたのコード内でインポートライブラリや注釈あるかどうか、のDLL内のシンボル/序へのリンク時のシンボルのマッピングを指定する必要があります。
https://reviews.llvm.org/rL311734をプルした後、macOSでlldを使用してrustcをブートストラップすることがほぼ可能になりました。 dylibメタデータに問題があるようですが、まだ調査する必要があります。
https://github.com/rust-lang/rust/pull/36120を復活させるブランチがありhttps://github.com/rust-lang/rust/issues/43370でブロックされてい
@tamird :#43370は終了しました。
LLDはhttps://github.com/rust-lang/rust/pull/48125に追加され、現在、ティア1プラットフォーム(mac、linux、windows)で出荷されてい-Z linker-flavor
を使用してテストできますが、デフォルトではほとんどのプラットフォームで機能する可能性はほとんどありません。 ただし、MSVCではデフォルトで機能します。 例えば:
$ RUSTFLAGS='-Z linker-flavor=lld-link' cargo build
Cargo自身のリンク時間を2.5秒から1.5秒に短縮しました。これは素晴らしい改善です。
@alexcrichton 、次のステップは何ですか? 理想的には、すべてのプラットフォームでデフォルトでLLDが機能するようにし(これにかかる作業量についてはわかりません)、コンパイル時/実行時ベンチマークを実行して、LLDをデフォルトにすることが理にかなっているかどうかを確認します。任意のプラットフォーム。 特にインクリメンタルコンパイルでは、リンクのパフォーマンスがこれまで以上に重要になります。
特にインクリメンタルコンパイルでは、リンクのパフォーマンスがこれまで以上に重要になります。
残念なことに、リンクのパフォーマンスは、それをサポートするプラットフォームでインクリメンタルリンクを有効にするなどのことを行うにはまだ十分に重要ではありません。 https://github.com/rust-lang/rust/issues/37543
@bstrieこれらが次のステップであり、他のプラットフォームで機能するようになると思います:)
それが何を伴うのかはわかりませんが、すでにMSVCで動作しているので、MinGW / Linuxで動作することにはほど遠いと思います。また、OSXにもかなり近づいています。 クロスアーキテクチャのサポートについても、よくわかりません。 近い将来、wasmプラットフォーム以外で「安定化」することはないと思います。
@alexcrichton 「安定化」をどのように指定しますか? 錆がサポートする他の主要なプラットフォームのlldとのリンクを「安定化」できないのはなぜですか? (例:Linux for macOSから実行可能ファイルをクロスコンパイルする)。
現時点では、クロスコンパイルするのは非常に面倒です。たとえば、LinuxからmacOS(x86_64-apple-darwin)の実行可能ファイルをクロスコンパイルするために必要な作業には、xcodeSDKの取得やツールチェーン全体の構築などの簡単な手順が必要です。
@cynecx良い質問です! あまり考えていないもの。 ただし、LLDを別のプラットフォームに追加したからといって、事実上安定化させたくないと思います。LLDを正しく公開するには、時間と労力が必要です。
たとえば、LinuxからmacOS(x86_64-apple-darwin)の実行可能ファイルをクロスコンパイルするために必要な作業には、xcodeSDKの取得やツールチェーン全体の構築などの重要な手順が必要です。
LLDはここではあまり役に立ちません。再配布できないヘッダーがあるため、Xcode SDKが必要です(構築するものによっては、他のSDKツールも必要になります)。
LLDが毎晩組み込まれていることの本当に素晴らしい点は、純粋なRustプロジェクトをWindowsからLinuxにRUSTFLAGS='-Z linker-flavor=ld.lld' cargo build --target x86_64-unknown-linux-musl
簡単にクロスコンパイルできることです。 Rustを単純にインストールできないLinuxマシン用の小さなツールを作成するのに最適です。
近い将来、wasmプラットフォーム以外で「安定化」することはないと思います。
@rkarpが言ったように、非常に一般的なユースケースは、コンテナ化されたLinuxワークロードをサポートするためにx86_64-unknown-linux-musl(そして最終的にはsteed)をターゲットにすることです。 これは、Goが非常にうまく機能していることの1つであり、Rustが同様に実行できることに非常に近いように思われます。 実際の使用法に関しては、x86_64-unknown-linux-muslのLLDは、実際にはwasmよりもはるかに広く使用されると思います。
より一般的には、クロスビルディングに関しては、「すべてのホストおよび/またはすべてのターゲットで機能する必要がある」というアプローチは意味がないと思います。 ターゲットが機能し始めたら、ターゲットごとにこれを安定させることは理にかなっていると思います。
特に、x86_64-unknown-linux-muslターゲットのLLDをできるだけ早く安定させるための取り組みを支援したいと思います。
私のプロジェクトには37個のクレートがあり、ビルドは約70個のバイナリ(多くのテスト)にリンクしています。 非科学的に( top
)、ビルド時間の少なくとも半分はldのみを実行しています。 lldを使用すると、ビルドが大幅に高速化されると思います。 私たちは安定したRustを使用しており、lld6.0をまだ動作させることができていません。
@briansmithは、muslとユースケースについてLLDをテストしましたか? 理論的には、テストするために必要なのは-Z linker-flavor=ld.lld
に合格することだけです。それがうまくいくと思われる場合は、デフォルトを切り替えることができます。
@rocallahan確認のために、現在、すべての人がゴールドリンカーを使用していますよね? (afaikとして、標準のbinutilsリンカーよりも高速です)。 -Z linker-flavor=ld.lld
機能する(そしてより高速である)場合、おそらくそれを安定させることができます! それはどのプラットフォームにありましたか?
非科学的に(目を見張るようなトップ)、ビルド時間の少なくとも半分はldのみを実行しています。
ところで、これはデバッグビルド用です。
現在、全員がゴールドリンカーを使用していますよね? (afaikとして、標準のbinutilsリンカーよりも高速です)
いいえ、それは標準のGNUリンカーであるFedoraシステムリンカーです。
それはどのプラットフォームにありましたか?
Fedora 27、SSDを搭載したクアッドコアSkylakeラップトップ。 いくつかのパフォーマンス数値を取得します。
知ってよかった! デバッグビルドは、リンカーの改善ではなく、スプリットドワーフ(https://github.com/rust-lang/rust/issues/34651)からリンク時間で最大の利益を得る可能性があります。
ただし、タイミング情報については、 ld.gold
とld.lld
使用してテストする機会があれば、 @ rocallahan ?
もちろん。 また、問題#48762は、Linuxのデバッグリンク時間を高速化するための非常に簡単な方法であることを忘れないでください。 (実行可能ファイルから.debug_pubnames
/ .debug_pubtypes
を削除するハッキングされたリンカースクリプトをすでに使用しています。)
分割DWARFは良いかもしれませんが、ユーザーに問題を引き起こす可能性もあります。 その号でコメントします。
@briansmithは、muslとユースケースについてLLDをテストしましたか? 理論的には、テストするために必要なのは-Zリンカー-flavor = ld.lldを渡すことだけです。それがうまくいくと思われる場合は、デフォルトを切り替えることができます。
OK、テストします。 おそらく最初は、「デフォルト」と「毎晩のみ」の中間にあるはずです。 -Z
でできるように、LLDを使用することを選択する方法がありますが、 -Z
使用しないで機能します。安定したビルドで。
ただし、-Zを使用しないため、安定したビルドで機能します。
RUSTC_BOOTSTRAP=1 RUSTFLAGS="-Z linker-flavor=foo" cargo build
試すことができます
ブートストラップフラグをお勧めしませんか? 十分な数のプロジェクトがそれに依存している場合、物事は事実上安定し、安定メカニズム全体のポイントを打ち負かすのではないかと心配しています。
申し訳ありません= /
データポイントとして、Rustリポジトリ内のrustc_trans
クレートをリンクすること自体が、ローカルマシンの78秒のリンク時間から1秒のリンク時間に急落しました。
私のパフォーマンスは、クレート階層の最下部近くにあるクレートに空白を変更した結果です。 クアッドコアSkylakeラップトップ、16GB RAM、rustc 1.24.0、LLD 7.0.0、GNU ld2.29-13。 .debug_pubnames
と.debug_pubtypes
を破棄するカスタムリンカースクリプトを使用します。 リンカスクリプトが存在する場合、LLDはまったく異なるコードパスを使用するため、状況に影響を与える可能性があります。
GNU ld:
real 2m39.138s
user 8m18.992s
sys 1m37.513s
LLD:
real 2m19.164s
user 6m4.477s
sys 0m56.858s
ゴールドは機能しませんでした。リンカースクリプトでバーフされました。 結果はかなり安定しています。 LLDはエンドツーエンドの時間にはそれほど影響しませんが、CPU使用率を大幅に削減します。 これは、ビルドがldの終了を待つのに多くの時間を費やさないことを意味していると思いますが、実行には多くのCPU時間が費やされます。
GNU ldからlldに切り替えると、一般的な「マイナーな変更と再構築」ワークロードの実行が2.5倍以上速くなる実際の例については、#50584を参照してください。
Er https://github.com/rust-lang/rust/issues/50584#issuecomment -400918647は、ここでより適切です。
LLDを安定させるための次のステップは、すべてのターゲット(Windows + Mac + Linux)で機能する-Zリンカー-flavor = lldのようなフラグを取得することです。 さまざまなプラットフォーム間で機能するために必要なことは何でもします。
それが完了したら、フィードバックを求めて、コミュニティに宣伝することができます。 ここでは、タイミング情報とバグレポートの両方を取得してLLDに送信できます。 すべてがスムーズに進む場合(まったく新しいリンカーでは疑わしいですが、わかりません!)、デフォルトでオンにすることができます。それ以外の場合は、LLDの選択を安定させてから、Cargoにオプションを追加できます。 tomlなので、プロジェクトは少なくともオプトインできます。
一部のターゲットではlldに切り替えました: https :
私もwasmを信じますか?
この問題は、外部lldバイナリとのリンクとrustc自体に組み込まれている内部lldサポートとのリンクの両方をカバーしていますか? それとも前者だけ?
この問題は、外部lldバイナリとのリンクとrustc自体に組み込まれている内部lldサポートとのリンクの両方をカバーしていますか? それとも前者だけ?
外部のlldバイナリIIUCだけです。
@nnethercote内部リンカーの使用を追跡するための別の問題がありますか、それとも別の問題を提出する必要がありますか?
内部リンカーのアイデアについては、これまで聞いたことがありません。 私はそれのPRを知りません。
https://github.com/rust-lang/rust/pull/57514LLDを使用してLLVMをリンクするための準備されたグラウンド。
おそらく最初は、「デフォルト」と「夜間のみ」の中間にあるはずです。-Zを使用する場合と同様に、安定したビルドで機能するように-Zを使用せずに、LLDの使用を選択する方法があります。
https://github.com/rust-lang/rust/pull/56351が-C linker-flavor
追加しました。
この問題が何を追跡することを意図しているのかは明確ではありません。 「Microsoftのツールチェーンが利用できない場合は、-msvcターゲットのLLDとリンクする」などの特定の問題を抱えるために、これを閉じる方がよいようです。
私にとって、この問題は、すべてのターゲットのデフォルトリンカーとしてLLDを有効にすることに関するものです。 LLDは非常に高速であり、リンク時間はコンパイル時間の重要な要素であることが多く、コンパイル速度は永続的な問題であるため、私はそれを望んでいます。
FWIWBMOのmacOSでLLDをサポートするための
@briansmithに同意し、さまざまなターゲットのステータスを追跡するための専用の問題を勧めしますが、これを閉じるのではなく、メタバグに変えることができます。 問題を開く価値のあるターゲットについて詳しく知っている人がいる場合は、LLDサポートステータスのループから外れているので、遠慮なくお問い合わせください。
LLDとのリンクはどこかに文書化されていますか? 私は(Linuxでは) rustc -C linker-flavor=ld.lld hello.rs
を持っていますが、運がありません。 LLDはLLVMのコピーと一緒に配布されていると思いましたが、間違っていますか? apt経由でLLDをインストールしようとしましたが、rustcはまだ謎に包まれています。 今日RustコードでLLDを試すために取らなければならないステップは何ですか?
@bstrieさらに-C linker=rust-lld
引数を渡す必要があります。
貨物で動作するはずですか? さびと貨物の最新のナイトリービルドで空白のプロジェクトをビルドしようとすると、現在次のエラーが発生します。
$ RUSTFLAGS='-C linker=rust-lld' cargo build
Compiling rust3 v0.1.0 (/home/carado/tmp/rust3)
error: linking with `rust-lld` failed: exit code: 1
|
= note: "rust-lld" "-flavor" "gnu" "-L" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55.2ualxzb8lqn4ho3y.rcgu.o" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55.32vfyq64cfbzv618.rcgu.o" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55.4rbt3m5y8o8cl09t.rcgu.o" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55.ben0932xzwyt64v.rcgu.o" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55.fzsdnygvstiwzxo.rcgu.o" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55.x0rq6ifodcf11zi.rcgu.o" "-o" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55.1m259ox4uzrzk583.rcgu.o" "--gc-sections" "-pie" "-zrelro" "-znow" "-L" "/home/carado/tmp/rust3/target/debug/deps" "-L" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "--start-group" "-Bstatic" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-44988553032616b2.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-607feef6be9150b2.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libbacktrace-a8dbf6d92401e34a.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libbacktrace_sys-9a4716f5e8a3e722.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_demangle-988a64d96b043c6d.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcfg_if-cadd6177b8c6d586.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libhashbrown-8f1d8efc92b45369.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_alloc-1e76014677816767.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunwind-cc28bce38cb195d9.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-4123e9e89add689a.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-4d259c17788c1fb5.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_core-9495dbda85bb8f16.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-793d0026c575805f.rlib" "--end-group" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-33c3162edae6574e.rlib" "-Bdynamic" "-ldl" "-lrt" "-lpthread" "-lgcc_s" "-lc" "-lm" "-lrt" "-lpthread" "-lutil" "-lutil"
= note: rust-lld: error: unable to find library -ldl
rust-lld: error: unable to find library -lrt
rust-lld: error: unable to find library -lpthread
rust-lld: error: unable to find library -lgcc_s
rust-lld: error: unable to find library -lc
rust-lld: error: unable to find library -lm
rust-lld: error: unable to find library -lrt
rust-lld: error: unable to find library -lpthread
rust-lld: error: unable to find library -lutil
rust-lld: error: unable to find library -lutil
error: aborting due to previous error
error: Could not compile `rust3`.
To learn more, run the command again with --verbose.
カラドと同じエラーが発生します。 -L / usr / libをリンカー呼び出しに「靴べら」することができましたが、これにより、欠落したライブラリのリストが-lgcc
短縮され、システムのどこにもlibgcc
として存在しません( libgcc_s.a
)これはいくつかのgnu-ismの結果だと思いますが、修正方法がわかりません。
@almindorはRUSTFLAGS='-C linker=rust-lld -L /usr/lib -L /usr/lib/gcc/x86_64-pc-linux-gnu/9.1.0'
または同様のものを試してください。 パスは、ディストリビューションとコンパイラのバージョンによって異なります。
私のコメントはLLDを使用する正しい方法の上にありますか? すべてのプログラムがSIGSEGV
クラッシュするため、動作させることができません。
Reading symbols from target/debug/hello...
(gdb) show directories
Source directories searched: ~/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/etc:$cdir:$cwd
(gdb) r
Starting program: target/debug/hello
Program received signal SIGSEGV, Segmentation fault.
core::ops::function::FnOnce::call_once{{vtable-shim}} () at /rustc/a7f28678bbf4e16893bb6a718e427504167a9494/src/libcore/ops/function.rs:231
(gdb) l
226 #[stable(feature = "fn_once_output", since = "1.12.0")]
227 type Output;
228
229 /// Performs the call operation.
230 #[unstable(feature = "fn_traits", issue = "29625")]
231 extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
232 }
233
234 mod impls {
235 #[stable(feature = "rust1", since = "1.0.0")]
(gdb) info reg
rax 0x0 0
rbx 0x0 0
rcx 0x0 0
rdx 0x0 0
rsi 0x0 0
rdi 0x0 0
rbp 0x0 0x0
rsp 0x7fffffffddb0 0x7fffffffddb0
r8 0x0 0
r9 0x0 0
r10 0x0 0
r11 0x0 0
r12 0x0 0
r13 0x0 0
r14 0x0 0
r15 0x0 0
rip 0x7ffff7ffc000 0x7ffff7ffc000 <core::ops::function::FnOnce::call_once{{vtable-shim}}>
eflags 0x10202 [ IF RF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
(gdb) disassemble
Dump of assembler code for function core::ops::function::FnOnce::call_once{{vtable-shim}}:
=> 0x00007ffff7ffc000 <+0>: mov (%rdi),%rax
0x00007ffff7ffc003 <+3>: mov (%rax),%rdi
0x00007ffff7ffc006 <+6>: jmpq *0x11d4(%rip) # 0x7ffff7ffd1e0
End of assembler dump.
GCC 9またはClangをコンパイラーとして使用している場合、ここで終わる人にとって、魔法の呪文はRUSTFLAGS="-C link-arg=-fuse-ld=lld" cargo build
です。 あるいは、 -C linker=clang
はGCCのバージョンに関係なく機能するはずなので、それが好まれるかもしれません。
これを永続的にするには、特定のプロジェクトの~/.cargo/config
または.cargo/config
に追加します。
[build]
rustflags = ["-C", "linker=clang"]
# rustflags = ["-C", "link-arg=-fuse-ld=lld"]
@lnicolaは、GCC9またはClangをCCとして使用する場合にのみ
@bstrieこれの現在の状況を知っていますか? それを前進させるための阻害要因は何ですか?
@ mati865古いGCCを持つ人々のための代替呼び出しをたまたま知っていますか?
@lnicolaすべてのプラットフォームにClang + GCC 9があり、互換性のないコンパイラーでの使用方法については調査していません。
@jonhoo私はこの分野の仕事に遅れをとっていません。コンパイラチームに聞いてみたいと思います。
チームにタグを付けることはできないと思いますし、チームに過度のノイズを発生させたくもありません。 そこから誰かにあなたの考えをざっと見てもらうための最良の方法は何ですか?
トリアージ; @ rust-lang / compiler誰かがこの問題の現在の状況を知っていますか?
LLDをRustで動作させることに成功した人のために、プラットフォームと使用されているすべてのコンパイラの特定のバージョンに関する詳細を追加で含めることができますか? ここにリストされているアドバイスがあっても、野生の人々がそれを機能させるのに苦労しているのを見ています。
上記で投稿したコマンドは、GCC9.2.0およびLLD9.0.0を使用するLinuxで機能します。 Windowsでも動作することがあると思いますが、-fuse = lldをサポートしていないWindows用のGCC9を使用している人を見かけました。 ここに投稿されたいくつかのリンクによると、MacOSでは試す価値はありません。
LLDをRustで動作させることに成功した人のために、プラットフォームと使用されているすべてのコンパイラの特定のバージョンに関する詳細を追加で含めることができますか? ここにリストされているアドバイスがあっても、野生の人々がそれを機能させるのに苦労しているのを見ています。
cat / etc / system-release
Fedoraリリース30(30)
cc --version
cc(GCC)9.2.1 20190827(Red Hat 9.2.1-1)
ld.lld --version
LLD 8.0.0(GNUリンカーと互換性があります)
うまくいけば、これが役立つ
しかし、-fuse = lldをサポートしていないGCC9 forWindowsを使用している人を見たことがあります。
@lnicola
Windows GCC 9ビルドは-fuse-ld=lld
をサポートします(サポートしないようにパッチが適用されている場合を除きますが、なぜ誰かがそれを行うのでしょうか?)。
rust-mingw
コンポーネントがインストールされ、リンカーが.cargo/config
オーバーライドされなかったと思います。 そのようにして、rustcはシステム1の代わりに出荷するGCC6を選択しました。
Windowsのもう1つの問題は、LLD 9以前ではサポートされていないハードコードされたリンカーフラグ--enable-long-section-names
です(将来的にサポートする予定です)。 これを回避するには、次のことができます。
Windowsのもう1つの問題は、LLD 9以前ではサポートされていないハードコードされたリンカーフラグ--enable-long-section-namesです(将来的にサポートする予定です)。
この部分は次の方法で修正されています: https :
ただし、Windows-gnuユーザーは、 -fuse-ld=lld
をサポートするCコンパイラを使用するために手作業を行う必要があります。
@bstrie :これはWindows-MSVCのStable and Nightlyで動作します。詳細は、このgamedev-wg問題の最初の投稿にあります: //github.com/rust-gamedev/wg/issues/50
別のデータポイント: rustc
自体を構築するときにRUSTFLAGS="-C link-arg=-fuse-ld=lld"
を使用すると、高速の14コアLinuxボックスでリンク時間が93秒から41秒に短縮されます。
@nnethercote :それは(たとえば) config.toml
の[target.x86_64-unknown-linux-gnu]
セクションでlinker=lld
を設定することとは異なりますか?
@ Aaron1011 :2つのアプローチは同じ効果があると思いますが、私はこれを自分でチェックしていません。
@ Aaron1011それはclangである必要があります。https: //github.com/rust-lang/rust/issues/39915#issuecomment-538049306を参照して
@ mati865
LLDをリンカーとしてx86_64-pc-windows-gnu
rustc
を構築しようとしましたか?
今日試してみましたが、LLDがビルドの途中でハングして作業を停止するか、 unknown argument: --version-script=...
について文句を言います。
ハングは、LLDがLLVMのリンクにのみ使用されている場合にも発生します。
[llvm]
use-linker = "lld"
ツールバージョン:
$ ld.lld --version
LLD 9.0.1 (https://github.com/msys2/MINGW-packages.git 5e3b8820ed9f04221affee4197e458aca2612e87) (compatible with GNU linkers)
$ gcc --version
gcc.exe (Rev2, Built by MSYS2 project) 9.2.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
@petrochenkovはい私はいくつかのハックでそれを構築することができました:
.def
ファイルで問題ありません。 簡単に解決できますlib
始まることを期待しています(これはUNIXの世界では標準です)が、どういうわけかRustはすべてのwindows-*
ターゲットに対してそれを行わないことになりました: https : 私はここにいくつかの将来の可能性を書き留めています。 いくつかの実装作業が必要ですが、これらはRust開発における長年の問題点の解決に役立つと思います。
リンカコマンドとして多くのパス名をlldに渡す代わりに、仮想ファイルシステムを使用し、十分なメモリスペースがある場合は常に、ディスクIOを使用する代わりに、それらのデータをメモリからメモリに渡します。 大規模なプロジェクトの場合、これにより数百または数千メガバイトのディスクIOが節約され、コンパイル時間が改善される可能性があります。
IO帯域幅の問題だけではありません。 Windowsのようなプラットフォームでは、特にWindows Defenderが有効になっている場合、操作するファイルごとにかなりの時間ペナルティが追加されます。Rustのcodegenユニットモデルは、クレートが数百の小さなオブジェクトファイルに分割され、大量のコンパイルをすばやく処理できることを意味します。時間。
このバグは少し混乱しているので、これを前進させたい人々のために、現在の状況の簡単な要約で私のベストショットを示します。
llvmプロジェクトの一部であるリンカー。これは、次の2つの理由で望ましいものです。
また、一般的に、lldは新しいものであり、ほとんどのOSのデフォルトではありません。これをより多くの場所で使用し始めると、ランダムな互換性のあるバグがほぼ確実に発生します。
2つのプラットフォームでデフォルトで(rust-)lldを使用することに焦点を当てた取り組みのために、2つのメタバグを提出しました。
windows-msvcは明らかに良好な状態であり、バックエンドでrust-lldを使用するためのサポートが制限されているようですが、ここで何をする必要があるのかわかりません。
LLD + windows-msvc
はかなり良好な状態です。現在、このセットアップをrustc
開発に使用しています。
lld-link
必要なすべてのサポートは、 rustc
バックエンドで実施されていますが、 https://github.com/rust-lang/rust/issues/68647のようなバグがあり
- これは重要かもしれません、どうやらlldはそれが「ld」または「ld.lld」として実行されているかどうかのclangスタイルのバイナリ名検出を行います(調査が必要です)
ありますが、ldとld.lldは同じモードです: https :
- 残念ながら、-fuse-ld = lldはGCC9の一部にすぎないため、使用するには機能/バージョンの検出が必要になる場合があります(clangには長い間使用されてきました)
ld.lldはldと同じであり、 https: //patches-gcc.linaro.org/patch/11148/によると、-fuse-ld = lldでの唯一の変更は、ldの代わりにld.lldを実行することです。 PATHインジェクションを使用します。問題ないはずです。 しかし、これをgcc 9+にロックアウトするのは良くないと思います。debianstableは8.3しかなく、ブルズアイはおそらく2021年までリリースされないでしょう。
- windows-mingwはlinux / unixとほぼ同じ場所にあるようですが、古いGCCを入手する傾向があり、pseudo-windows-linuxは十分にテストされた構成ではないため、状況は少し不安定ですか?
2018-09-16にリリースされたmingw-w646.0.0にはgcc8.3.0があり、-fuse-ld = lldはありませんが、それでもかなり新しいものです。 2019-11-11にリリースされたmingw-w647.0.0にはgcc9.3.0があり、-fuse-ld = lldがあります。 Debianバスター(安定版)は6.0.0、ブルズアイ(テスト)は7.0.0です。 Debianストレッチ(oldstable)には5.0.1とgcc 6.3.0しかありませんが、gcc 6.3に重大な問題がある場合は、lldサポート用に最新のdebian安定版を要求するのが妥当だと思います。
2つのプラットフォームでデフォルトで(rust-)lldを使用することに焦点を当てた取り組みのために、2つのメタバグを提出しました。
lldのmacOS(Mach-O)ポートについて: https: //github.com/rust-lang/rust/issues/39915#issuecomment -618726211以降、動作するか、少なくとも大幅に改善されているようです。書かれた!
このLLVMコミットを使用しlld
をビルドし、 nightly-x86_64-apple-darwin
に対してトレースを作成し、すべてのテストを正常に実行しました。 私は(デバッグ)ビルド時間について特に満足しています:
ld
場合、クリーンなcargo build
は35秒かかりました。lld
場合、クリーンなcargo build
は20秒かかりました。ご了承ください:
@davidbarskyかっこいい! 好奇心から、そのパフォーマンスはzld
とどのように比較されますか? (https://github.com/michaeleisel/zld)
また、サーマルについて説明しましたか? MBPは、特にデフォルトのファン速度プロファイルを使用すると、非常に迅速に熱スロットリングに入ります。 実行を実行する前に、ヒンジの近くのマシンの下部が触ると冷えるまで待つだけで、一貫性が保たれます。
私はUbuntu16i686でちょうどそのようなバグです
最も参考になるコメント
このバグは少し混乱しているので、これを前進させたい人々のために、現在の状況の簡単な要約で私のベストショットを示します。
lldとは
llvmプロジェクトの一部であるリンカー。これは、次の2つの理由で望ましいものです。
Rustが今日lldで行うこと
より多くの場所(つまり、デスクトップlinux / mac / windows)でrust-lldを使用する際の問題
また、一般的に、lldは新しいものであり、ほとんどのOSのデフォルトではありません。これをより多くの場所で使用し始めると、ランダムな互換性のあるバグがほぼ確実に発生します。
2つのプラットフォームでデフォルトで(rust-)lldを使用することに焦点を当てた取り組みのために、2つのメタバグを提出しました。