Reputation: 31
I have a builder which look like this:
sFooBuilder = Builder( action = os.path.join(rBuildPath, 'foo_binary') + ' $SOURCE',
suffix = '.c',
src_suffix = '.foo'
)
As the binary I rely on doesn't take a $TARGET argument and would produce an execution error otherwise I only specify a $SOURCE argument. What happens is that the output file of the binary is placed in the src dir instead of the variant dir. However SCons expects the output file in the variant dir.
Every time you are calling scons, the build target above is executed due to the following:
scons: building `variant_dir/foo.c' because it doesn't exist
And just to copy the file to the variant dir via a Command Builder doesn't work either
scons: warning: Two different environments were specified for target foo.c,
but they appear to have the same action: foo_binary $SOURCE
File "sconscript",
scons: *** Multiple ways to build the same target were specified for: foo.c foo.foo'] and from ['foo.c'])
File "/sconscript",
My questions is if this is the expected behaviour?
Are there any suggestions (beside fixing the used binary) how to solve such a case? Unfortunately I couldn't find any documentation which touches the case described above.
Thanks in advance!
Upvotes: 3
Views: 2756
Reputation: 56488
The foo_binary takes input.foo and produces output.c in the same directory as the input? How are you calling the builder? Like this? env.FooBuilder('foo.c', 'foo.foo').
When using variant dir, scons expects the output of the builder to go to variant_dir/foo.c. When that fails, it thinks you have deleted the file and recreates it next build. I bet the first build also fails, but the second works because scons finds the "foo.c" that is in your source tree.
Sounds like the easiest way is to have the foo_binary generate the output in the source directory, then move it afterwards. You said you tried this, but you maybe did it as a separate step, not in the same builder. In that case it would have got all muddled up about paths. This should do the trick:
sFooBuilder = Builder(action=[
os.path.join(rBuildPath, 'foo_binary') + ' $SOURCE',
Move('$TARGET.dir', '$TARGET.srcpath')],
suffix = '.c', src_suffix = '.foo' )
This runs 2 steps in the same builder action:
foo_binary foo.foo
mv foo.c variant_dir
Now that the builder does what you say it does (create foo.c in the variant dir) it should all work as expected.
The other solution would be to copy the input file to the build directory, but that is not possible with the same file name in the source and build directories. SCons gets a bit confused and pulls in the source directory file first.
If you used different names it would be doable (foo.foo.in copied to foo.foo in the variant dir, then transform that to foo.c), but seems a bit messy.
Upvotes: 2