web-dev-qa-db-ja.com

コンパイラは通常、インストールされているプラ​​ットフォームの実行可能ファイルのみを生成するのはなぜですか?

私はC++開発者であり、クロスプラットフォーム開発をよりよく理解するために、コンパイラーの実装の詳細と、それらがOS固有のバイナリーをどのように作成するかをよりよく理解しようとしています。私の調査の最中に、少なくともしばらくの間、特定のプラットフォーム用にダウンロードしたほとんどのコンパイラーは、そのプラットフォーム用のバイナリーしかコンパイルしていないことに気付きました。したがって、Windows用のコンパイラexeに付属するIDEをダウンロードした場合、そのコンパイラは、x86-x64 Windowsアプリケーション用のプログラムのみをコンパイルでき、LinuxまたはMacアプリケーション用ではありません。

今ではプラットフォームごとに異なるバイナリ形式が必要であることを理解していますが、WindowsのビジュアルC++コンパイラーがLinuxバイナリ実行可能ファイルを生成するのが難しいのはなぜですか?実行中のCPUのアセンブリ命令とOS固有のライブラリがある限り、任意のマシンの任意のプラットフォーム用の実行可能ファイルをコンパイルできませんか?

10
Jason

windowsのビジュアルC++コンパイラーがLinuxバイナリ実行可能ファイルを生成するのが難しいのはなぜですか?

Microsoft側でそれを実行したくないという以外は、まったく何もありません。障害は技術的なものではありません。

開発ツールチェーンは、入力を受け取り、出力を生成する単なるプログラムです。 Visual C++はx86アセンブリを生成し、アセンブラを使用してそれをCOFFオブジェクトファイルに変換します。マイクロソフトがELFを生成するようにしたい場合、それは単なるコードです。アセンブリが入って、ELFが出ます。オブジェクトファイルやライブラリに魔法はありません。それらは、よく理解された形式の単なるデータの塊です。

石器時代に戻ると、クロスコンパイルははるかに困難でした。それは、たいていの場合、ターゲットプラットフォームのツールチェーンを、それが実行されるプラットフォームのアセンブリでAssemblyに記述していたためです。つまり、VAX、M68K、Alphaアーキテクチャが世界中にあったとしても、クロスコンパイラーの完全なスイートでは、そのうちの9つをほとんどゼロから作成する必要がありました。 (VAX-to-VAX、VAX-to-M68K、VAX-to-Alpha、M68K-to-VAX、M68K-to-M68Kなど)VAXコンパイラの一部は再利用でき、各ターゲットのコードジェネレーター(VAX、M68K、Alphaなど、VAX用に作成されたもの)に接続されています。

この問題は、Cなどの特定のプロセッサに関連付けられていない言語でコンパイラを作成し始めたときに解消されました。このルートに進むと、Cでツールチェーン全体を1回記述し、ローカルプラットフォーム向けの記述を使用することになりますそれをビルドするCコンパイラ。 (ローカルプラットフォームのコンパイラーでブートストラップされた後、コンパイラーを使用して再コンパイルすることがよくありますが、これは別の議論です。)クロスコンパイラーの構築は、ネイティブコンパイラーの構築と本質的に同じ努力になったということです。ローカルプラットフォーム。唯一の大きな違いは、ビルドプロセスのどこかで、ローカルプラットフォーム用のコードジェネレーターではなく、ターゲットプラットフォーム用のコードジェネレーターでコンパイルするように指示したことです。 GCCは、ローカル/ターゲットプラットフォームのペアごとに1つのバイナリを構築することで、これを実行しました(現在も実行しています)。

コンパイラーのアーキテクチャーが進化するにつれて、製品にすべてのコードジェネレーターを含めてビルドし、実行時に使用するコードジェネレーターを選択するのが便利になりました。 Clang/LLVMがこれを行いますが、他にもあると思います。

機能するツールチェーン(コンパイラー、アセンブラー、リンカー)を取得すると、ライブラリーはソースから構築され、最終的には他のプラットフォーム用の実行可能ファイルを作成するために必要なすべてのものになります。

18
Blrfl

はい。ターゲットプラットフォームに関するすべての情報を入手している場合は、実際に実行しているプラ​​ットフォームは問題ではありません。

発生する傾向のある2つの問題があります。

  1. あまり一般的でないシナリオなので、人々はそれに焦点を合わせません。多くの場合、クロスコンパイルするのはコンパイラだけなので、クロスコンパイルを停止できます。焦点を絞らないとサポートが悪化します。
  2. 重要なプログラムには、単なるコード以上のものが必要です。ライブラリのインクルード/リンケージの処理は、実行しているプラ​​ットフォーム用のライブラリがあると、少し簡単になります。それらは、よく知られている場所に、よく知られているエンコーディングで配置されます。

もちろん、それらを克服することはできません。ほとんどの場合、それが実行されるプラットフォームをターゲットとするコンパイラーを入手します。

8
Telastyn

私はあなたの前提に同意しません。数百万のAndroidおよびiOS開発者。そしてallは、WindowsまたはMacで実行されるコンパイラを使用して、まったく異なるコンピュータ用のコードを生成します。

市場での需要がない場合は、クロスコンパイラを入手できません。たとえば、Linuxデスクトップ用のコードを開発している人は、ほとんどの場合Linuxデスクトップを利用でき、Linuxベースのコンパイラを使用します。ネットワーク経由で転送せずにコンパイルされたマシンでアプリケーションを直接実行できる場合は、はるかに速く、はるかに簡単かつ高速です。同じマシンでデバッガーを実行する場合など。

では、コンパイラがLinux用にもビルドされるとしたら、Microsoftはどれだけ多くのお金を稼ぐでしょうか?約$ 0。 Windows用のソフトウェアはどれくらい作成されますか?なし。どのくらいのLinuxソフトウェアが作成されますか?わかりませんが、Microsoftが気にすることではありません。費用はいくらですか?かなりかなり。コンパイラーにはバグがない必要があります。テストする必要があります。

別の問題:Windowsでコンパイラーを作成する場合、Windowsソフトウェアの作成方法を知っている人が必要です。 Linux用のコンパイラーを作成する場合は、Linuxソフトウェアの作成方法を知っている人が必要です。 Windows上で動作するLinux用のコンパイラを作成する場合、突然、WindowsとLinuxの両方を知っている、よりまれな開発者のパンが必要になります。

2
gnasher729