6

sconsに基づくビルドシステムのリファクタリングで少し問題が発生しています。いくつかの異なる出力オブジェクト(dll、実行可能ファイル、テスト実行可能ファイル)を含むC / C ++ソースツリーがあり、ソースファイルのレイアウトはやや異質です(ただし、そのほとんどはとディレクトリの「モジュール」ディレクトリにsrc/ありますinc/)。

現在のセットアップに関する私の最大の問題の1つは、これらすべてのビルド製品をデフォルトで一貫したコンパイラオプションを使用してビルドすることを本当に望んでいることです。現在のレイアウトには、サブディレクトリ内の多くのサブSConscriptファイルを呼び出すマスターSConstructファイルがあり、これらのファイルは、より大きなビルド製品(.aたとえば、)の一部をビルドします。デフォルトでは、sconsのSConscript()関数は、呼び出されたSConstructファイルに現在の構築環境オブジェクトを渡したり継承したりしません。つまり、現在、これらのサブSConstriptファイルはすべて、独自の異なる構築環境を使用しています。

私がまとめようとしている新しいレイアウトでは、マスター構築環境がソースツリールートにまとめられ、必要なすべてのCFLAGSとビルドが必要な定義を備えています。この構築環境をサブSConscriptファイルに渡して.c.cppビルドツリー内のすべてのファイルが同じコマンドラインでビルドされていることを確認したいと思います。

ただし、これをsconsで行う方法はわかりません。Import()および関数がありExport()ますが、これらは基本的に醜いグローバル変数です。呼び出し元のSConstructファイルは、サブSConstructファイルが編集されたグローバル変数で何を行うかをあまり制御できませんExport()。サブSConscriptファイルを、必ずしも変更させずに、現在の構築環境をパラメーターとして本質的に渡すクリーンな方法はありますか?多分次のようなもの:

master_env = Environment()
master_env.Append( CXXFLAGS=['-Wall', '-Werror', '-g', '-fPIC', ... ] )

### add other stuff that we want everything to use

SConscript( 'somelibrary/SConstruct', inherited_environment=master_env.Clone() )

### master_env has now been used to build a 
### .dll in somelibrary/, but any variations
### made to somelibrary/SConstruct's inherited 
### env haven't contaminated master_env

私は次のような不器用で粗雑なことをすることができることを知っています:

clobber_env = Environment()
master_env = Environment()
master_env.Append( CXXFLAGS=['-Wall', '-Werror', '-g', '-fPIC', ... ] )

call_somelibrary_sconstruct( master_env )

def call_somelibrary_sconstruct(env):
    param_env = env.Clone()
    Export( 'param_env' )
    SConstript( 'somelibrary/SConstruct' )

    # because we don't want any contamination of our global variable 
    # between SConscript calls. I'm not even sure if this is necessary
    # or does what I think it does because I'm not sure how this ugly
    # Export()'d global variable environment works with locals like 
    # param_env here.
    param_env = clobber_env
    Export( 'param_env' ) 

これを行うためのエレガントな方法はありますか?

アップデート:

だから私はこれをもう少し試してみました、そして私がマスターSConstructファイルでこれをしている限りそれは次のように見えます:

def build_somelib( env ):
    Export( env=env.Clone() )
    somelib = SConscript( 'somelib/SConscript' )
    return somelib

master_env = Environment()
master_env.Append( CXXFLAGS=['-Wall', '-Werror', '-g', '-fPIC', ... ] )

build_somelib( master_env )

そしてsomelib/SConscript

Import( 'env' )
env.Append( CXXFLAGS=['-weirdoption1', ... ] )
lib = env.StaticLibrary( 'somelib', source=['source1.cpp', 'source2.cpp', ...] )
Return( "lib" )

その後、master_envメインのSConstruct内は汚染されないままになります。すべてのサブSConscriptsExport( env=env.Clone() )に依存して安全性(Clone()'ing)を実行する必要がなかったため、このポリシーは親SConscript/SConstructファイルである必要があります。

それでも、envポリシーによってパラメーター名として持つ必要があるのは少し醜いです。

4

3 に答える 3

8

私が知っている最善の方法は、マスターSConstructから次のようにすることです。

env = Environment()

env.SConscript('src/SConscript', 'env')

次に、src/SConscriptファイルで次のようにします。

Import('env')

次に、SConstructファイルの場合と同じようにenv変数を参照できます。src / SConscriptでSConstructのenvを変更したくない場合は、インポートの直後にこれを配置します。

env = env.Clone()

それがすべてだと確信しています。

于 2012-07-18T15:15:06.980 に答える
1

ソース(Ubuntu12.04のScons2.1.0)をgrepして、そのキーワードで辞書をExport更新していることを確認します。global_exports

したがって、このコードはおそらく実行されます。

Export( param_env=env.Clone() )
SConscript( 'somelibrary/SConstruct' )
Export( param_env=clobber_env ) 

ドキュメントには何も書かれていないので、それは機能です。

そしてExportSConstriptフレームマジックを使用して名前で変数を取得します。これは、Pythonをまだ知らないユーザーにとっては良いことかもしれませんが、悪です。

于 2012-07-17T23:13:14.467 に答える
1

アップデートでOPによって提示されたソリューションには、重大な問題があります(scons-2.3.3およびscons-2.3.4でテスト済み)。

def build_somelib( env ):
    Export( env=env.Clone() )
    somelib = SConscript( 'somelib/SConscript' )
    return somelib

master_env = Environment()
master_env.Append( CXXFLAGS=['-Wall', '-Werror', '-g', '-fPIC', ... ] )

build_somelib( master_env )

上記を使用してオンにしますCacheDir(some_dir)(違いが生じる場合は、VariantDirも使用しました)。でdir1、を使用してフルビルドを実行しscons --cache-debug=logます。ビルドが完了したら、dir2同じコードで、を使用してフルビルドも実行しscons --cache-debug=logます。すべてのファイルをビルドキャッシュからコピーする必要がありますが、大部分がコピーされていないことがわかりました。すべてではありませんが、ほとんどのファイルで、2つのディレクトリ間でMD5署名の不一致がありました。この問題は、「dir1」のファイルを変更して再構築し、変更を「dir2」に対処して再構築することによっても発生する可能性があります。同じMD5の不一致が表示されます。

この時点で、を実行してscons -cから、両方のディレクトリにある.sconsign.dbliteファイルを削除します(適切な方法でビルドキャッシュを削除します)。最初にで再構築しdir1、それが終了したら、「dir2」で再構築します。正しい動作が得られます。MD5署名が一致し、ファイルがビルドキャッシュからコピーされます。

トムのソリューションに従って、OPのソリューションを放棄し、親環境を維持する責任をすべてのサブディレクトリに移すことになりました。正確には私がやりたかったことではありませんが、少なくともビルドキャッシュは期待どおりに機能するようになりました。

于 2014-10-02T19:39:26.587 に答える