(参考リンク:https://zhuanlan.zhihu.com/p/69393545)
Linuxの
私たちは、このようなリンカーエラーが発生する可能性があり、Linuxでベアメタルプログラムを準備してみてください。
エラー:終了コード:: `cc`が失敗したとのリンク1 | =注: "CC" [...] =注:/usr/lib/gcc/../x86_64-linux-gnu/Scrt1.o:関数`_start 'において: (の.text + 0x12を):__libc_csu_fini`への未定義参照' /usr/lib/gcc/../x86_64-linux-gnu/Scrt1.o:関数で`_start': (の.text + 0x19):` __libc_csu_init」への未定義参照 /usr/lib/gcc/../ x86_64の-LinuxベースのGNU / Scrt1.o:関数`_startで': (の.text + 0x25):` __libc_start_mainに未定義の参照' collect2は:エラー:ldは1つの終了ステータスが返さ
ここでの問題は、リンカーは、C言語のランタイムを参照するプロセスを開始するには、デフォルト、またはとしても説明することである_start
機能。私たちは、使用するno_std
実装はC言語の標準ライブラリの下で除外されていること、ライブラリをlibc
リンカは、関連する参照を解決することはできませんので、「未定義の参照」の問題を取得し、。この問題を解決するために、我々はそれがプロセスはC言語の使用を参照していない開始することをリンカに指示する必要があります-私たちが追加することができ-nostartfiles
、これを行うためのタグを。
貨物によってリンカにパラメータを追加するために、我々は使用cargo rustc
コマンドを。コマンドの役割とcargo build
同じですが、下錆コンパイラに現像剤を可能にするrustc
パス・パラメーター。さらに、ラベルは、リンカに必要なパラメータを渡すことが可能です。要約すると、我々は、次のコマンドを書くことができます。rustc
-C link-arg
貨物rustc - -Cリンク-argを= -nostartfiles
この後、我々は成功したLinuxシステムの下で、スタンドアロンの実行可能プログラムとして、パッケージをコンパイルすることができるはずです。リンカはデフォルトの関数名を使用しますので、ここでは明示的に、エントリポイント関数の名前を指定しないでください_start
。
ウィンドウズ
Windowsシステムでは、異なるリンカーエラーを持っていることがあります。
エラー:終了コード:失敗した`link.exe`とリンク1561 | =注: "C:\\プログラムファイル(x86の)\\ ... \\ link.exeを" [...] =注:LINK:致命的なエラーLNK1561:エントリポイントが定義する必要があります
リンカエラーは、エントリポイントが見つからないことを意味する「エントリポイントを定義する必要があります」。Windowsシステムでは、デフォルトのエントリポイントは、サブシステムの関数名によって決まる[1] 。CONSOLE
サブシステム、リンカという名前を探しますmainCRTStartup
機能;一方、WINDOWS
サブシステム、それが見えますWinMainCRTStartup
。当社の_start
機能は二つの名前ではありません-それを使用するために、我々は、リンカに渡すことができる/ENTRY
パラメータ:
貨物rustc - -Cリンク-argに= / ENTRY:_start
ここから我々はまた、パラメータの形式の使用上のWindowsシステムでは次のリンクを参照してください、とLinuxの下ではかなり異なっています。
コマンドを実行して、我々は他のリンカエラーを得ました:
エラー:終了コード:失敗した`link.exe`とリンク1221 | =注: "C:\\プログラムファイル(x86の)\\ ... \\ link.exeを" [...] =注:LINK:致命的なエラーLNK1221:サブシステムが推測できないとしなければならない 定義されました
このエラーは、異なるサブシステム(使用可能なWindows実行プログラムが原因であるサブシステム)。一般的なWindowsプログラム、から推測されるエントリポイントによって使用されるサブ関数名:エントリポイントがある場合にmain
使用する機能CONSOLE
サブシステムを、それがある場合WinMain
の関数は、使用WINDOWS
サブシステム。当社以来_start
関数名と両者の違いは、我々は明示的にサブシステムの使用を指定する必要があります。
貨物rustc - -Cリンク-argsを= "/ ENTRY:_start / SUBSYSTEM:コンソール"
ここでは、使用してCONSOLE
サブシステムを、しかし、WINDOWS
サブシステムが実現可能です。ここでは、複雑な引数を使用link-args
代わりに、複数のを-C link-arg
、後者は、すべてのパラメータが順番にリストされている多くのスペースを必要とするため、。
このコマンドを使用した後、実行可能プログラムは、我々は、Windows上で実行することができます。
マックOS
あなたはMacOSのシステム開発を使用している場合、我々は、リンカエラーが発生する場合があります。
エラー:終了コード:: `cc`が失敗したとのリンク1 | =注: "CC" [...] =注:LD:エントリポイント(_main)不定。アーキテクチャはx86_64のため 打ち鳴らす:エラー:リンカコマンドが終了コードで失敗しました1 [...]
エラーメッセージは、リンカがデフォルトエントリポイント関数を見つけることができないことを教えてくれる、それが命名されたmain
-いくつかの理由で、すべての関数名のMacOSのは、下線付きであることをされている_
接頭辞。関数へのエントリポイントを設定するために_start
、我々は、リンクパラメータを送信します-e
:
貨物rustc - -Cリンク引数= " - E __start"
-e
パラメータは、エントリ・ポイントの名前を指定します。各MacOSの下の関数は下線があるので_
プレフィックスを、私たちは、エントリポイント関数として指名されなければならない__start
かわりに_start
。
今、そのようなAリンク・エラーの出現を、このコマンドを実行します。
エラー:終了コード:: `cc`が失敗したとのリンク1 | =注:「CC」[...] =注:LD:動的主実行可能ファイルがlibSystem.dylibとリンクしなければならない アーキテクチャはx86_64のため 打ち鳴らす:エラー:リンカーコマンド終了コードで失敗しました1 [...]
その理由は、このエラーを取得することで、MacOSのは、正式に静的にリンクされたバイナリライブラリサポートされていない[2]を、デフォルトのプログラムはへのリンクが必要ですlibSystem
ライブラリを。静的バイナリライブラリにリンクする、我々は入れ-static
リンカーにタグ:
貨物rustc - -Cリンク引数= " - E __start -static"
修正されたコマンドを実行します。リンカが成立しているようだ、私たちは新しいエラーをスローしました:
エラー:終了コード:: `cc`が失敗したとのリンク1 | =注: "CC" [...] =注:LD:ライブラリ-lcrt0.oが見つかりません 打ち鳴らす:エラー:リンカコマンドは[...]終了コード1で失敗しました
このエラーの理由は、プログラムがMacOSでデフォルトにリンクされていることであるcrt0
(Cランタイムゼロ)ライブラリ。Linuxと同様のシステム上で発生したこの問題は、我々が追加できる-nostartfiles
リンクパラメータを:
貨物rustc - -Cリンク引数= " - 電子__start -static -nostartfiles"
今、私たちのプログラムが正常にMacOSの上でコンパイルすることができるはずです。