私はC++開発者ではありませんが、常にコンパイラーに興味があり、GCCのもの(特にLLVM)のいくつかをいじくり回すことに興味があります。
Windowsでは、GCCを正しく実行するにはPOSIXエミュレーションレイヤー(cygwinまたはMinGW)が必要です。
何故ですか?
私はC++で書かれ、さまざまなプラットフォーム(Subversion、Firefox、Apache、MySQL)用にクロスコンパイルされた他の多くのソフトウェアを使用していますが、どれもcygwinやMinGWを必要としません。
C++のベストプラクティスプログラミングについての私の理解は、適度にプラットフォームに依存しないコードを記述し、コンパイルプロセス中にすべての違いに対処できるということです。
では、GCCとの取引は何ですか? Windowsでネイティブに実行できないのはなぜですか?
編集:
さて、これまでの2つの回答では、基本的に「GCCはposixヘッダーを使用しているため、posixレイヤーを使用しています」と述べています。
しかし、それは実際には質問に答えません。
お気に入りの標準ライブラリ用のヘッダーのセットがすでにあるとしましょう。なぜまだposixヘッダーが必要なのですか?
GCCは実際に[〜#〜] run [〜#〜]するためにcygwin/mingwを必要としますか?
それとも、ヘッダーとライブラリのエミュレーションレイヤーのみが必要ですか?もしそうなら、なぜ私はそれに必要なリソースを備えた「lib」ディレクトリを与えることができないのですか?
もう一度編集:
さて、質問を明確にするためにもう一度やり直します...
また、 Dプログラミング言語 でコードを記述します。公式コンパイラの名前は「dmd」で、WindowsとLinuxの両方に公式のコンパイラバイナリがあります。
Windowsバージョンでは、POSIXエミュレーションは必要ありません。また、LinuxバージョンではWin32エミュレーションは必要ありません。コンパイラーがその環境についての仮定を持っている場合、コンパイラーはそれらの仮定をかなりうまく隠します。
もちろん、標準ライブラリの場所と、静的または動的にリンクするライブラリの場所をコンパイラに指示する必要があります。
対照的に、GCCは、posix環境内で動作しているふりをすることを主張し、エミュレーションレイヤーを設定することによってそれらの仮定をユーモアを交えて要求します。
しかし、正確には、GCC内でそのレイヤーに依存しているのは何ですか? stdlibヘッダーを探しているだけで、「/ usr/lib」内にそれらのヘッダーが見つかると想定していますか?
その場合は、「C:/ gcc/lib」を調べてそれらのヘッダーファイルを見つけるように指示するだけでよいのではないでしょうか。
または、GCC自体がファイルシステムにアクセスする(および他の低レベルの処理を行う)ためにPOSIXライブラリに依存していますか?そうだとすれば、なぜ彼らはお気に入りのWindowsPOSIXライブラリと静的にリンクしないのだろうか。依存関係をアプリケーションに直接組み込むことができるのに、なぜユーザーに依存関係の設定を要求するのですか?
実際、質問の前提は間違っています: MinGW GCCは[〜#〜] not [〜#〜]はCygwinを必要としません。
Cygwinはまったく必要ないことがわかります。 Windows上でネイティブに実行されます(少なくとも32ビット)。ツールチェーンと生成されたバイナリはどちらもCygwinから独立しています。
Cygwinで利用可能なMinGWコンパイラは異なります。Cygwinプラットフォーム上に構築されており、Cygwinランタイムに依存しないコードを生成します。その場合、コンパイラ自体はCygwinに依存します。しかし、それはCygwinからインストールしたためです。
CygwinバージョンのGCCにはCygwinコンパイルするプログラムの場合、インストールします。
MinGWバージョンは、Windowsの作業コピーを除いて、コンパイル後に何も必要としません。
Cygwinはプリコンパイルされたライブラリのパスを変更するため、Cygwin環境とMinGWコンパイラを実際に混在させることはできません。
Bashスタイルのシェルが必要であるがCygwinを使用したくない場合は、 [〜#〜] msys [〜#〜] をお勧めします。
からコピー MinGW Wiki
Cygwinアプリケーションは、Posix関数のCygwin®POSIXエミュレーションDLLまたは_cygwin1.dll
_に依存し、win32関数を直接使用しないため、原則として「ネイティブWin32アプリケーション」とは見なされません。MinGW一方、Win32 APIによって提供される関数を提供します。MinGWでアプリケーションを移植する場合、fork()
、mmap()
、ioctl()
などのWin32にネイティブでない関数はアプリケーションが正しく機能するには、Win32に相当するものに再実装する必要があります。
POSIX(Portable Operating System Interface)は、「IEEEによって作成され、ANSIおよびISOによって標準化されている、進化し成長しているドキュメントです。POSIXの目標は、アプリケーションのソースコードの移植性です」[1]。
実際には、目標は、1つのソース実装を記述し、再コンパイルのみで異なる(POSIX準拠の)システムで実行できるようにすることとして定義されます。
GCCは、その約束を果たすことができるコンパイラであるため、マシンをPOSIX標準に「合わせる」コードの層が必要です。
それがあなたの質問に対する答えの核心です。
私が何を意味するのかを理解するために、この演習を提供します。
UNIXまたはLINUXシステムでコンパイルされるネイティブのWIN32APIのみを使用するコードを作成することは非常に難しいことがわかると思います。
POSIX APIを使用するコードを記述して(他のLINUXボックスでできるように)、Windowsでコンパイルすることはわずかに難しくなります(DevStudio2005には驚くほど多くのPOSIX準拠のヘッダーがあります...閉じる)。
上からLINUXプログラムを取得し、CygwinまたはMinGWで実行されているGCCでコンパイルします。私はそれがコンパイルされて実行されるに違いない。
GCCはどのようにそのちょっとした魔法を実行しましたか? CygwinまたはMinGWによって提供されるPOSIXヘッダーとその基礎となる実装。
WindowsでのCygwin/MinGWへのGCCの依存は、今ではもっと意味がありますか?
私は、WindowsでのプログラムをWindowsの市民のように振る舞わせ、LinuxでのプログラムをLinuxの市民のように振る舞わせるようにしています。
Windowsは標準のPOSIXライブラリを提供していないため、cygwinは標準のPOSIXライブラリ(cygwin1.dll)を提供します。 cygwinに付属のgccパッケージはそれを使用します。
一方、mingwは、必ずしもPOSIXレイヤーを提供するわけではありません。たとえば、私が使用しているmingwインストールには、pthreadライブラリすらありません。
必要な場合はインストールする必要があります。 Mingw-gccはWin32ネイティブコードを生成します(実際にはMSVCRT.DLLに依存しています)。
編集:編集内容を読むgcc自体にmingw/cygwinライブラリが必要な理由を尋ねているのか、Winでgccを使用してコンパイルされたプログラムにこれらのライブラリが必要なのかがわかりません。
どうして? [〜#〜] gcc [〜#〜] が作成されたとき、Windows32ビットも終了していなかったため...
もっと正確に言うと、UNIX/PosixOS用に開発されました。その後、Windowsに移植されました。
WindowsはPOSIX対応システムではありません。それは非常に基本的な機能さえ提供しません。 Windowsコンパイラでreaddir
またはstat
を見つけてみませんか?そして、これは非常に基本的な機能なので、コンパイラを作成する必要があります。
明確にするために、GCCでコンパイルされたプログラムは通常、実行できるように不足している機能を追加するために1つのmingw32.dllのみを必要としました。
それで... GCCがPOSIXレイヤーを必要とする理由を尋ねますか? WindowsOSはPOSIXオペレーティングシステムではないためです。
私はC++開発者ではありませんが、常にコンパイラーに興味があり、GCCのもの(特にLLVM)のいくつかをいじくり回すことに興味があります。
LLVMとGCCは関連していないことに注意してください。 LLVMは主に、Chris Lattner( http://llvm.org/developers.cgi )が最新の最適化について行った調査の結果です。彼の論文は http://llvm.org で入手できます。今日では、それはアップルによって大いに後援されています。 GCCのC/C++/Obj-Cフロントエンドはllvm-gccに使用され、LLVMマシンコードを出力します(そしてllvmで大量の最適化を行った後、最終的な実行可能ファイルが出力されます)。 llvm-gccは、いくつかの準備ができているC/C++/Obj-C-frontendをLLVMに結合するための一種のハックです。
とにかく、LLVMクルーは、clangと呼ばれる独自の完全なC/C++/Obj-Cコンパイラも構築していることに注意してください。 Cの実装はほぼ完了しており、C++のサポートはどんどん良くなっていますが、Obj-Cについてはわかりません。
したがって、誰かが「コンパイラllvm」と言った場合、彼は実際にはllvm-gccまたはclangのいずれかを意味します。 LLVM自体は単なる低レベルの仮想マシンであり、静的単一代入形式の命令はほんの一握りです(約32命令、公平)が、メガトンの最適化が構文ツリーに渡されます。
さまざまなプラットフォーム用にコンパイルされたソフトウェアの多くは、MinGWでコンパイルされています。 gccとの唯一の違いは、コンパイラーであるということですitselfこれは、通常はプログラムでコンパイルされるすべてのヘッダーが必要であり、通常は結果のプログラムを実行する必要がないことを意味します。
PthreadまたはOpenMPをサポートしたくない場合は、gccをビルドするときに、posix以外のenable-threadsオプションを指定するオプションがあります。言うまでもなく、それらは十分にテストされていません。 WindowsスレッドでのOpenMPのサードパーティのクローズドソースサポートがいくつかありますが、gccでの使用はライセンスに違反しているようです。 Windows pthreadsライブラリはWindowsスレッド機能への高レベルのインターフェイスであるため、パフォーマンスが低下したり、Microsoftによるアフィニティサポートの拒否に遭遇したりしても、おそらく驚くことではありません。つい最近、MicrosoftはWindowsでgccを許容し始めました。マイクロソフトのツールだけで再現できたとしても、gccユーザーから報告されたバグには対処しないと実際に言っていた時期がありました。