elmo
elmo

Reputation: 1256

SCons and dependencies for python function generating source

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

Answers (2)

KlausCPH
KlausCPH

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

Brady
Brady

Reputation: 10357

You can create explicit dependencies in SCons using the Depends() function.

Upvotes: 3

Related Questions