2011-09-21 15 views
5

ビルドの一部であるファイルの内容を更新するための適切なSCONSメソッドは何ですか?SCONSをビルドで使用されるファイルの内容を更新する方法

私はSCONSを使ってかなり大きなプロジェクトを構築しています。しかし、単純な質問のために、それはこのようになりますと仮定します。

env.Program("foo", ["foo.c", "version.c"]) 

特定のビルド条件の下では、それは新しい情報でのビルドでCPPファイルのいずれかの内容を更新する必要があります - 実際にバージョン情報。上の例では、 "version.c"の内容を変更する必要があります。私は、次の例ではなく、うまくこれを行うことが考えた:

env.Command(target="version.c", source=[], action=PythonFunctionToUpdateContents) 
env.Program("foo", ["foo.c", "version.c"]) 

PythonFunctionToUpdateContentsは、ファイルの名前として[0]ターゲットを使用し、それを開いて、いくつかの特定のテキストを探し、それを変更し、変更内容を記述します同じファイルに戻ります。残念ながら、上記のサンプルは動作しません。 SCONSはビルド前に自動的にターゲットファイルを削除するので、私の "version.c"ファイルは更新される前に削除されています。

env.Command()呼び出しでターゲットとソースを同じファイルに設定しようとしましたが、依存関係のサイクルが作成されました。

SCONSに全version.cファイルを生成させることでこれを解決できますが、version.cには通常の開発の一部として変更できる他の多くのコードが含まれているため、適切ではありません。

答えて

5

これを行う通常の方法は、「version.c.in」または「version-in.c」などを呼び出すことです。これを修正し、version.cに出力します。バージョン管理システムに "in"ファイルを追加しますが、version.cファイルはそこにはありません。だから、のようになります。このすべての結果は次のとおりです。

env.Command(target="version.c", source="version-in.c", 
      action=PythonFunctionToUpdateContents) 
env.Program("foo", ["foo.c", "version.c"]) 

これは、あまりにも、他のビルドシステムに適用されます - 一般的に、出力ファイルで入力ファイルを持っていることは悪い考えです。仕事を終わらせるために中間ファイルを使用するほうがずっと良いです。

+0

例があまりにも単純すぎます。私の "env.Program()"呼び出しは、実際にSCONSベースではないサードパーティのビルドプロセスへの外部呼び出しです。だから私は彼らのプロセスを蹴る前にファイルを修正しようとしています。私は同意する - 場所でファイルを変更することは良い考えではない。しかし、私はビルドプロセスのその部分を支配していません。 –

+1

同じ原則が適用されます。外部ビルドプロセスへの入力のテンプレートである、あなたが管理するファイルがあります。外部プロセスを開始する前に、関連するディレクトリにテンプレートの修正コピーを作成します。それに失敗した場合は、サードパーティビルドの完全なコピーを作成し(実用的ではないかもしれない)、そのコピーのファイルを変更することができます。 – richq

5

この回答は遅くパーティーにちょっとですが、ここでは、とにかくです:

あなたはenv.Precious("version.c")を使用する必要があります。これにより、ファイルが作成される前に削除されることを防ぎます。

env.NoClean("version.c")を使用して、クリーニング中に削除されないようにすることもできます。

あなたはおそらく env.SideEffectを使用することができますが、それについては奇妙なことがいくつかあります。私はメーリングリストで、一般的にそれを使用しないように言われました。

+0

この回答を読んだ人のための更新: 'env。SideEffect'は、複数のビルダーが同じファイルに出力する場合(ログ、カウンタを含むバイナリファイルなど)に使用する必要があります。私はそれがこの状況で助けになるとは思わない。 「Precious」と「NoClean」のペアリングは「正しい」解決策になります。 –

関連する問題