プリコンパイル済みヘッダー(_stdafx.h
_)を使用するVisual Studio C++ベースのプログラムがあります。現在、gcc 4.xを使用してアプリケーションをLinuxに移植しています。
問題は、両方の環境でプリコンパイル済みヘッダーを処理する方法です。私はグーグルで調べましたが、結論に達することができません。
コードベースはかなり大きく、プリコンパイル済みヘッダーはコンパイル時間を短縮するので、明らかに_stdafx.h
_をVisual Studioに残したいです。
しかし、問題はLinuxで何をすべきかです。これは私が見つけたものです:
stdafx.h
_はそのままにします。 gccはVC++よりもかなり高速にコードをコンパイルします(または単にLinuxマシンの方が強力です... :))。したがって、このオプションに満足するかもしれません。here からのアプローチを使用して、_stdafx.h
_を次のようにします(VSのみ_USE_PRECOMPILED_HEADER
_を設定します):
_#ifdef USE_PRECOMPILED_HEADER
... my stuff
#endif
_
here からのアプローチを使用します。VC++を_/FI
_でコンパイルし、implicitlyinclude _stdafx.h
_ in各cppファイル。したがって、VSでは、プリコンパイル済みヘッダーなしでコードを簡単に切り替えてコンパイルでき、コードを変更する必要はありません。
私は個人的に依存関係を嫌い、混乱_stdafx.h
_は大きなコードベースを推進しています。したがって、このオプションは私にとって魅力的です-Linuxでは_stdafx.h
_がなく、VSでプリコンパイル済みヘッダーを_/FI
_のみで有効にすることができます。
stdafx.h
_をコンパイルします(Visual Studioを模倣)あなたの意見?問題を処理する他のアプローチはありますか?
コンパイルを高速化するために、プリコンパイル済みヘッダーを使用することをお勧めします。
Gccでもプリコンパイル済みヘッダーを使用できます。 こちらを参照 。
コンパイル済みのプリコンパイル済みヘッダーには、.gch
の代わりに.pch
として拡張子が追加されます。
たとえば、stdafx.hをプリコンパイルすると、プリコンパイル済みヘッダーがあり、stdafx.h.gch
をインクルードするたびに、呼び出されたstdafx.h
を自動的に検索します。
例:
stdafx.h:
#include <string>
#include <stdio.h>
a.cpp:
#include "stdafx.h"
int main(int argc, char**argv)
{
std::string s = "Hi";
return 0;
}
次に、次のようにコンパイルします。
> g++ -c stdafx.h -o stdafx.h.gch
> g++ a.cpp
> ./a.out
手順1の後にstdafx.hを削除しても、コンパイルは機能します。
前回 option を使用して、これと同じことをする必要がありました。私のプロジェクトはかなり小さいものでしたが、これは見事に機能しました。
非常にシンプルなソリューション。 Linux環境で「stdafx.h」のダミーファイルエントリを追加します。
オプション4またはオプション2を選択します。さまざまなVSバージョンとLinux上のGCCの両方でプリコンパイル済みヘッダーを試しました(これについてのブログ投稿 here および here )。私の経験では、VSはインクルードパスの長さ、インクルードパス内のディレクトリの数、およびインクルードファイルの数に対してG ++よりもはるかに敏感です。ビルド時間を適切に配置したプリコンパイル済みヘッダーを測定すると、VSでのコンパイル時間に大きな違いが生じますが、G ++はこれにほとんど感銘を受けませんでした。
実際、上記に基づいて、コンパイル時間を抑えるためにこれが必要だったプロジェクトで前回作業したときに、Windowsでstdafx.hに相当するものをプリコンパイルし、それを通常のファイルとして単純に使用しましたLinuxで。
オプション1は、大規模な開発者チームでのみ使用します。オプション2、3、および4はチームの他のメンバーの生産性を停止させることが多いため、yoはコンパイル時間を1日数分節約できます。
その理由は次のとおりです。
開発者の半分がVSを使用し、半分がgccを使用していると仮定しましょう。時々、一部のVS開発者は.cppファイルにヘッダーを含めることを忘れます。 stdafx.hに暗黙的に含まれているため、彼は気づきません。そのため、彼はバージョン管理の変更をプッシュし、gccチームの他のメンバーがコンパイラエラーを取得します。そのため、プリコンパイル済みヘッダーを使用して1日5分ごとに、失われたヘッダーを修正することで5人が無駄になります。
すべてのコンパイラで同じコードを共有しないと、毎日そのような問題に遭遇します。 VS開発者に変更をプッシュする前にgccでコンパイルをチェックするように強制すると、プリコンパイル済みヘッダーを使用することによる生産性の向上がすべて失われます。
オプション4は魅力的ですが、ある時点で別のコンパイラを使用したい場合はどうでしょうか?オプション4は、VSとgccのみを使用する場合にのみ機能します。
オプション1を使用すると、gccのコンパイルに数秒かかることがあります。目立たないかもしれませんが。
本当に簡単です:
プロジェクト->プロジェクト設定(Alt + F7)
プロジェクト設定ダイアログ:
C++->カテゴリ:プリコンパイル済みヘッダー->プリコンパイル済みヘッダーラジオボタン->無効化
プロジェクトでCMakeを使用している場合、それを自動化するモジュールがあり、非常に便利です。たとえば、cmake-precompiled-headerを参照してください- ここ 。それを使用するには、モジュールをインクルードして呼び出します:
include( cmake-precompiled-header/PrecompiledHeader.cmake )
add_precompiled_header( ${target} ${header} FORCEINCLUDE SOURCE_CXX ${source} )
Cotireと呼ばれる別のモジュールは、プリコンパイルするヘッダーファイルを作成し(StdAfx.hを手動で記述する必要はありません)、他の方法でビルドを高速化します- ここ 。
stdafx.h
はデフォルトですべてのWindows固有のものです。空のstdafx.h
私の他のプラットフォーム。そうすれば、ソースコードは同じままであると同時に、Linuxでstdafx
をすべて無効にすることなく#include "stdafx.h"
コードの行。
クロスプラットフォームコードのオプション2(#ifdef)とオプション4(gccのPCH)の両方を問題なく実行しました。
GccはVSよりもはるかに高速にコンパイルされるため、巨大なヘッダーファイルを参照しない限り、プリコンパイル済みヘッダーは一般的にそれほど重要ではありません。
特に#2が機能しなかった状況があります(#ifdef
の周りの#include "stdafx.h"
が機能しないVSビルド構成が多数あります)。他のソリューションは、ファイル自体がクロスプロジェクトであり、クロスプラットフォームであるため、次善策でした。私はプリプロセッサマクロを強制的に設定したり、LinuxやWindowsビルドでpchを使用する(または使用しない)ことを強制したくないので...
たとえば、notificationEngine.cpp
という名前のファイルを指定すると、#include stdafx.h
行が完全に削除され、pchNotificationEngine.cpp
という同じディレクトリに次の内容の新しいファイルが作成されました。
#include "stdafx.h"
#include "notificationEngine.cpp"
任意のプロジェクトに、正しいバージョンのファイルを含めることができます。確かに、これはおそらく、単一のプロジェクトでのみ使用されるcppファイルには最適なオプションではありません。