ビルド中に自動的に生成されるファイルの依存関係に従い、マルチスレッド ビルドで正しく動作するように SCons をセットアップしようとしています。
私が構築しているプロジェクトは CIM プロバイダーであり、データ構造を定義する MOF ファイル、MOF ファイルから生成された自動生成されたソース ファイルとヘッダー ファイル、自動生成されたファイルを参照する手書きのソース ファイルとヘッダー ファイルで構成されています。ビルドを成功させるには、手書きファイルをコンパイルする前に、自動生成ステップを最後まで実行する必要があります。そうしないと、手書きファイルが依存するヘッダーがまだ存在せず、失敗します。自動生成ステップで作成された .cpp ファイルもソース リストに追加し、最終ビルドでコンパイルする必要があります。
シングル スレッド ビルドを実行すると、自動生成ステップは常にコンパイル ステップの前に完了し、生成されたヘッダーが配置されるため、すべてが正常に機能します。ただし、ビルドをマルチスレッドで実行すると、自動生成ステップが完了する前に手書きファイルをコンパイルしようとするため、ビルドは失敗します。明示的な依存関係を指定しましたが、SCons はそれに従っていません。
これが私の SConscript ファイルの関連部分です。リストが非常に長いため、cim_targets[] から個々のファイル名を削除しましたが、要約すると、cim_targets[] は自動生成ステップのターゲット出力ファイルのリストであり、provider_sources[] は返されたファイルです。 autogen ステップが完了した後のソースのリスト、sources[] は手書きのソース ファイルのリスト、GenProvider() は自動生成ステップを実行する外部で定義された Command ビルダー、SharedLibrary() は外部で定義されたビルダーであり、そのように動作します。 、いくつかの拡張機能を備えた SCons ライブラリ ビルダーを使用します
# Define directory paths for the CIM schema
cim_dir = 'cim-schema-2.26.0'
var_smis_dir = Dir('.').abspath # src/lib/XXX in variant
cim_sources = [
Glob(os.path.join(cim_dir, '*qualifiers*.mof')),
Glob(os.path.join(cim_dir, 'Core') + '/CIM_*.mof'),
Glob(os.path.join(cim_dir, 'Device') + '/CIM_*.mof'),
Glob(os.path.join(cim_dir, 'Event') + '/CIM_*.mof'),
Glob(os.path.join(cim_dir, 'XXXXXX') + '/XXX_*.mof'),
Glob(os.path.join(cim_dir, 'Interop') + '/CIM_*.mof'),
Glob(os.path.join(cim_dir, 'Physical') + '/CIM_*.mof'),
Glob(os.path.join(cim_dir, 'System') + '/CIM_*.mof'),
]
cim_sources_flat = []
for cim in cim_sources:
for src in cim:
cim_sources_flat.append(src)
cim_targets = [
......
]
sources = [
'driver.cpp',
'device.cpp',
'cim_static_data.cpp',
'module.cpp',
'diag_log.cpp',
'profile_element.cpp',
]
staticlibs = [
......
]
dynamiclibs = [
.....
]
var_cim_sources = this_env.Install(var_smis_dir, cim_sources_flat)
cim_mof = 'cimv226.mof'
cim_linux_mof = os.path.join(cim_dir, 'cimv226-gen-flat.mof')
var_cim_sources.extend(this_env.Command(cim_mof, cim_linux_mof, Copy('$TARGET', '$SOURCE')))
# first generate the provider infrastructure using cimple
provider_sources = this_env.GenProvider(cim_targets, var_cim_sources, name, var_smis_dir)
# make sure these files don't build until AFTER the provider files have been created
this_env.Depends(sources, provider_sources)
sources_full = provider_sources + sources
# now we can compile the provider
this_env.SharedLibrary(libname, source=sources_full, staticlibs=staticlibs, dynamiclibs=dynamiclibs, installpath=install_dir)
明示的な依存関係を設定して、生成されたすべてのソースが作成されるまで手書きのソースがコンパイルされないようにしようとしましたが (this_env.Depends(sources, provider_sources))、マルチスレッドで実行すると、SCons はこの依存関係を無視し、自動生成ステップが完了しました。