Reputation: 1256
edit Totally rewritten example, the issue is the same.
I have SConsctruct
file:
env = Environment()
def write_main( out ):
out.write("""
#include <iostream>
int main(int argc, char **argv)
{{
std::cout << "[{0}]" << std::endl;
return 0;
}}
\n""".format(ARGUMENTS.get('print', 'nothing'))
)
def generate_main(env, target, source):
with open( env.GetBuildPath( target[0] ), 'w') as out:
write_main( out )
main_builder = env.Builder( action = generate_main )
main_cpp = main_builder( env, env.GetBuildPath('main.cpp'), [] )
prog = env.Program( target='main', source=main_cpp )
Now if I run:
$ scons print=one && ./main
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
generate_main(["main.cpp"], [])
g++ -o main.o -c main.cpp
g++ -o main main.o
scons: done building targets.
[one]
$ scons print=two && ./main
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
scons: `.' is up to date.
scons: done building targets.
[one]
$ rm main.cpp
$ scons print=two && ./main
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
generate_main(["main.cpp"], [])
g++ -o main.o -c main.cpp
g++ -o main main.o
scons: done building targets.
[two]
So you can clearly see that the middle build was incorrect. How can this be solved?
note: If I move body of write_main
to generate_main
(so I have only one function) it rebuilds correctly.
note:
One solution I can think of is providing all functions with target
object so they can call Depends
explicitly. In that example that would mean calling something like:
Depends( target, env.Variable( ARGUMENTS.get('print', 'nothing') ) )
Is there any other approach which would allow me to maintain current signature of write_main
without requiring any knowledge about it in generate_main
?
And how do I enforce particular syntax highlighting for a piece of code? (in above shell output gets weird/incorrect colors)
Upvotes: 3
Views: 1036
Reputation: 1835
It seems like you have already figured out that the basic issue is that SCons does not know the content of your generated main.cpp
file at analysis time. Therefore it simply does not rebuild on your second run because no dependencies has changed. What you need is to make the env.Builder( action = generate_main )
builder depend on the input argument. In that way, if the input argument change it will rebuild the main.cpp
.
There are several ways to obtain this. One way I can think of, is to add your argument to the env, as the builders take the env into account when building. It could look something like:
env.inputArguments = ARGUMENTS.get('print', 'nothing')
placed right above your main_builder = env.Builder( action = generate_main )
Hope it helps Regards
Upvotes: 3