21

再構築する必要がないことを確認するだけで約 10 秒かかる SCons スクリプトがあります。これは、本質的にかなり小さなプロジェクトであるために非常に長く感じます。SConscript 自体の読み取りには 1 ~ 2 秒しかかかりません。ほとんどの時間は次の場所で費やされます。

scons: Building targets ...

ステップ。

sconsこの時点で正確に何が行われているのかを知るにはどうすればよいですか? また、高速な SCons スクリプトを作成する上で、他に一般的なアドバイスはありますか?

4

7 に答える 7

25

(直接盗んだhttp://www.scons.org/wiki/GoFastButton )

コマンド「scons --max-drift=1 --implicit-deps-unchanged」は、ビルドを可能な限り高速に実行します。

また:

  • env.Decider('MD5-timestamp'): SCons 0.98 以降、環境に Decider 関数を設定できます。MD5-timestamp は、タイムスタンプが一致する場合は、ファイルを再 MD5 する必要はありません。これにより、大幅な高速化が可能になります。詳細については、man ページを参照してください。
  • --max-drift: デフォルトでは、SCons は実行されるたびにビルド内のすべてのソース ファイルの MD5 チェックサムを計算し、ファイルが 2 日経過した後にのみチェックサムをキャッシュします。このデフォルトの 2 日間は、NFS またはリビジョン管理システムからのクロック スキューから保護するためのものです。--max-drift=SECONDS を使用してこの遅延を微調整できます。SECONDS は秒数です。SECONDS を減らすと、余分な MD5 チェックサム計算が不要になり、ビルド速度が向上します。実行のたびにコマンド ラインでこれを指定する代わりに、"SetOption('max_drift', SECONDS)" を使用して SConstruct または SConscript ファイル内でこのオプションを設定できます。
  • --implicit-deps-unchanged: デフォルトでは、SCons はすべてのソース ファイルを再スキャンして暗黙的な依存関係 (C/C++ ヘッダーの #include など) を探します。これはコストのかかるプロセスになる可能性があります。--implicit-deps-unchanged を使用して、呼び出し間の暗黙的な依存関係をキャッシュするよう SCons に指示できます。このオプションを使用することで、最後に実行してから暗黙の依存関係を変更していないことを SCons に約束することになります。暗黙の依存関係を変更した場合、 --implicit-deps-changed を使用すると、それらが再スキャンされてキャッシュされます。(SConstruct または SConscript ファイル内からこのオプションを設定することはできません。)
  • --implicit-cache: このオプションは、SCons に暗黙的な依存関係をインテリジェントにキャッシュするように指示します。前回のビルド以降に暗黙の依存関係が変更されているかどうかを判断しようとし、変更されている場合は再計算します。通常、これは --implicit-deps-unchanged を使用するよりも遅くなりますが、より正確です。実行のたびにコマンド ラインでこれを指定する代わりに、"SetOption('implicit_cache', 1)" を使用して SConstruct または SConscript ファイル内でこのオプションを設定できます。
  • CPPPATH: 通常、CPPPATH 構成変数を設定することで、Scons にインクルード ディレクトリについて通知します。これにより、暗黙的な依存関係スキャンを実行するときに SCons がそれらのディレクトリを検索し、コンパイル コマンド ラインにそれらのディレクトリも含めます。まったくまたはめったに変更されないヘッダー ファイル (システム ヘッダーや C ランタイム ヘッダーなど) がある場合は、それらを CPPPATH から除外し、代わりに CCFLAGS 構成変数に含めることができます。これにより、SCons はスキャン時にそれらのインクルード ディレクトリを無視します。暗黙の依存関係用。このようにインクルード ディレクトリを慎重に調整すると、通常、正確さをほとんど損なうことなく速度を大幅に向上させることができます。
  • env.SourceCode(".", None) を使用して RCS および SCCS スキャンを回避します。これは、プログラムで多数の c または c++ ヘッダーを使用していて、ファイル システムがリモート (nfs、samba) である場合に特に重要です。
  • "BuildDir" を使用する場合は、"duplicate" を 0 に設定して使用してください: "BuildDir( dir1, dir2, duplicate=0".ただし、ビルド中にソース ファイルが生成された場合、または呼び出されたツールが派生ファイルをソース ファイルと同じディレクトリに配置するようにハードコードされている場合は、ビルドの問題が発生する可能性があります。
  • マルチプロセッサ マシンでは、一度に複数のジョブを実行すると便利な場合があります。SConstruct 内で --jobs N (N はマシン上のプロセッサの数) または "SetOption('num_jobs', N)" を使用します。またはSConscript。Windows マシンでは、プロセッサの数は環境変数 'NUMBER_OF_PROCESSORS' で取得できます。
  • 数十を超えるプリプロセッサ定義 (「-DFOO1 -DFOO2」) がある場合、 --profile を使用すると、SCons が subst() 関数で多くの時間を費やしていることがわかります。通常は定義に -D 文字列を追加するだけです。何度も何度も。これにより、何も変更されていないビルドの速度が大幅に低下する可能性があります。このページの「CPPDEFINES のキャッシング」で説明されているアイデアを使用すると、100 以上の定義で何もしないビルド時間が 35 秒から 20 秒に短縮されることがわかりました。

作業を高速化するもう 1 つの秘訣は、共有ライブラリが変更されたが再構築されていない場合に、プログラムを再リンクしないようにすることです。SharedLibrarySignatureOverrideを参照してください

于 2009-09-22T18:14:32.450 に答える
9

scons md5-sums ファイルを使用して、それらが変更されたことを把握するため、ほぼすべてのファイルを md5sums します。

タイムスタンプのみを使用して再構築するものを決定し、「make」のように毎回すべてのファイルを MD5sum する必要がないように指示できます。これにより、処理が高速化されます。もっと壊れやすいかもしれません。たとえば、ファイルが最後にビルドされてから 1 秒以内に変更された場合、scons はそれに気づきません。使用する

env.Decider('timestamp-newer')

MD5-timestamp もあります。これは最初にタイムスタンプをチェックし、タイムスタンプが新しい場合に実際に変更されている場合は Md5 を使用してコンテンツを比較します。

env.Decider('MD5-timestamp')

高速化するもう 1 つの簡単なオプションは、-j パラメーターを使用して並列ビルドを実行することです。

scons -j 2

私の 2 コア ボックスでは、通常、-j 3 で最大のスピードアップが得られます。

scons が行っていることに関する出力の一部は、scons の呼び出しに --debug 引数を使用して実行できます。さまざまなオプションについては、マンページを参照してください。

于 2009-08-23T16:13:04.693 に答える
8

SCons が遅い理由を理解するために少し試行錯誤を行いましたが、これまでのところいくつかの結果が得られています (正確な結果はもちろん、SCons スクリプトの構造と複雑さによって異なります)。

  • CacheDir()目立った悪影響はありません。
  • Decider()影響は非常に小さく、気にする価値はありません。
  • variant_dir/を使用VariantDir()すると、ビルド時間が約 10% 増加します。
  • ファイル自体の読み取りにSConstructは、完全な scons 呼び出しの約 10% がかかります。
  • これまでで最大の影響はライブラリの依存関係のようで、プロジェクトに Gtkmm があるとビルド時間が 2 倍になりました。

可能な解決策:

  • 完全な再構築を行うのではなく、作業中のディレクトリ/モジュールのみを再構築します (scons -uの代わりにscons -D)。
  • オプションの部分を作成してSConscript、手動で呼び出されたときにのみ再構築します。
  • -isystemの代わりにライブラリ インクルードのコンパイラ フラグを使用します-I。この変更だけで、ビルド時間が 10.5 秒から 6 秒に短縮されました。少しの sed 呼び出しで簡単に達成できます。

    env.ParseConfig('pkg-config --cflags --libs gtkmm-2.4 | sed "s/-I/-isystem/g"')

    gccなぜこれが機能するのか正確にはわかりませんが、出力される依存関係が削減され、scons追跡される依存関係が削減されると思います。

CacheDir()andを使用するscons -j Nことももちろん強くお勧めしますが、SCons スクリプト自体の評価ではなく、実際のビルドを高速化するだけです。

于 2009-08-24T16:11:35.967 に答える
7

サードパーティのインクルードを CPPPATH から CCFLAGS に移動すると、大きな違いが生じました。12 個の外部インクルード ディレクトリ (boost と python を含む) を持つ私たちのプロジェクトでは、何もしないコンパイルは 30 秒から 3 秒に短縮され、10 倍のスピードアップになりました。

于 2014-09-30T11:50:43.487 に答える
5

SCons が最初Environmentに作成するとき、一連の検索を行って、利用可能なツールを確認します。最初DefaultEnvironmentenv.

DefaultEnvironment(tools=[])
于 2014-05-02T12:10:06.557 に答える