web-dev-qa-db-ja.com

クロスプラットフォームコードでのstdafx.hの処理

プリコンパイル済みヘッダー(_stdafx.h_)を使用するVisual Studio C++ベースのプログラムがあります。現在、gcc 4.xを使用してアプリケーションをLinuxに移植しています。

問題は、両方の環境でプリコンパイル済みヘッダーを処理する方法です。私はグーグルで調べましたが、結論に達することができません。

コードベースはかなり大きく、プリコンパイル済みヘッダーはコンパイル時間を短縮するので、明らかに_stdafx.h_をVisual Studioに残したいです。

しかし、問題はLinuxで何をすべきかです。これは私が見つけたものです:

  1. _stdafx.h_はそのままにします。 gccはVC++よりもかなり高速にコードをコンパイルします(または単にLinuxマシンの方が強力です... :))。したがって、このオプションに満足するかもしれません。
  2. here からのアプローチを使用して、_stdafx.h_を次のようにします(VSのみ_USE_PRECOMPILED_HEADER_を設定します):

    _#ifdef USE_PRECOMPILED_HEADER
    ... my stuff
    #endif 
    _
  3. here からのアプローチを使用します。VC++を_/FI_でコンパイルし、implicitlyinclude _stdafx.h_ in各cppファイル。したがって、VSでは、プリコンパイル済みヘッダーなしでコードを簡単に切り替えてコンパイルでき、コードを変更する必要はありません。
    私は個人的に依存関係を嫌い、混乱_stdafx.h_は大きなコードベースを推進しています。したがって、このオプションは私にとって魅力的です-Linuxでは_stdafx.h_がなく、VSでプリコンパイル済みヘッダーを_/FI_のみで有効にすることができます。

  4. Linuxでは、プリコンパイル済みヘッダーとしてのみ_stdafx.h_をコンパイルします(Visual Studioを模倣)

あなたの意見?問題を処理する他のアプローチはありますか?

53
dimba

コンパイルを高速化するために、プリコンパイル済みヘッダーを使用することをお勧めします。

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を削除しても、コンパイルは機能します。

46
Brian R. Bondy

前回 option を使用して、これと同じことをする必要がありました。私のプロジェクトはかなり小さいものでしたが、これは見事に機能しました。

3
Kredns

非常にシンプルなソリューション。 Linux環境で「stdafx.h」のダミーファイルエントリを追加します。

2
Bikramjit singh

オプション4またはオプション2を選択します。さまざまなVSバージョンとLinux上のGCCの両方でプリコンパイル済みヘッダーを試しました(これについてのブログ投稿 here および here )。私の経験では、VSはインクルードパスの長さ、インクルードパス内のディレクトリの数、およびインクルードファイルの数に対してG ++よりもはるかに敏感です。ビルド時間を適切に配置したプリコンパイル済みヘッダーを測定すると、VSでのコンパイル時間に大きな違いが生じますが、G ++はこれにほとんど感銘を受けませんでした。

実際、上記に基づいて、コンパイル時間を抑えるためにこれが必要だったプロジェクトで前回作業したときに、Windowsでstdafx.hに相当するものをプリコンパイルし、それを通常のファイルとして単純に使用しましたLinuxで。

2
Timo Geusch

オプション1は、大規模な開発者チームでのみ使用します。オプション2、3、および4はチームの他のメンバーの生産性を停止させることが多いため、yoはコンパイル時間を1日数分節約できます。

その理由は次のとおりです。

開発者の半分がVSを使用し、半分がgccを使用していると仮定しましょう。時々、一部のVS開発者は.cppファイルにヘッダーを含めることを忘れます。 stdafx.hに暗黙的に含まれているため、彼は気づきません。そのため、彼はバージョン管理の変更をプッシュし、gccチームの他のメンバーがコンパイラエラーを取得します。そのため、プリコンパイル済みヘッダーを使用して1日5分ごとに、失われたヘッダーを修正することで5人が無駄になります。

すべてのコンパイラで同じコードを共有しないと、毎日そのような問題に遭遇します。 VS開発者に変更をプッシュする前にgccでコンパイルをチェックするように強制すると、プリコンパイル済みヘッダーを使用することによる生産性の向上がすべて失われます。

オプション4は魅力的ですが、ある時点で別のコンパイラを使用したい場合はどうでしょうか?オプション4は、VSとgccのみを使用する場合にのみ機能します。

オプション1を使用すると、gccのコンパイルに数秒かかることがあります。目立たないかもしれませんが。

2
Grim Fandango

本当に簡単です:

プロジェクト->プロジェクト設定(Alt + F7)

プロジェクト設定ダイアログ:
C++->カテゴリ:プリコンパイル済みヘッダー->プリコンパイル済みヘッダーラジオボタン->無効化

1
Stefan Steiger

プロジェクトでCMakeを使用している場合、それを自動化するモジュールがあり、非常に便利です。たとえば、cmake-precompiled-headerを参照してください- ここ 。それを使用するには、モジュールをインクルードして呼び出します:

include( cmake-precompiled-header/PrecompiledHeader.cmake )
add_precompiled_header( ${target} ${header} FORCEINCLUDE SOURCE_CXX ${source} )

Cotireと呼ばれる別のモジュールは、プリコンパイルするヘッダーファイルを作成し(StdAfx.hを手動で記述する必要はありません)、他の方法でビルドを高速化します- ここ

1
Roman Kruglov

stdafx.hはデフォルトですべてのWindows固有のものです。空のstdafx.h私の他のプラットフォーム。そうすれば、ソースコードは同じままであると同時に、Linuxでstdafxをすべて無効にすることなく#include "stdafx.h"コードの行。

1
Jeff

クロスプラットフォームコードのオプション2(#ifdef)とオプション4(gccのPCH)の両方を問題なく実行しました。

GccはVSよりもはるかに高速にコンパイルされるため、巨大なヘッダーファイルを参照しない限り、プリコンパイル済みヘッダーは一般的にそれほど重要ではありません。

0
Soo Wei Tan

特に#2が機能しなかった状況があります(#ifdefの周りの#include "stdafx.h"が機能しないVSビルド構成が多数あります)。他のソリューションは、ファイル自体がクロスプロジェクトであり、クロスプラットフォームであるため、次善策でした。私はプリプロセッサマクロを強制的に設定したり、LinuxやWindowsビルドでpchを使用する(または使用しない)ことを強制したくないので...

たとえば、notificationEngine.cppという名前のファイルを指定すると、#include stdafx.h行が完全に削除され、pchNotificationEngine.cppという同じディレクトリに次の内容の新しいファイルが作成されました。

#include "stdafx.h"
#include "notificationEngine.cpp"

任意のプロジェクトに、正しいバージョンのファイルを含めることができます。確かに、これはおそらく、単一のプロジェクトでのみ使用されるcppファイルには最適なオプションではありません。

0
zzxyz