0
votes

I want my target to depend on another target which I do not know the name or path of at the time I specify my depending target. I cannot use Depends at a later time when the second target is known for some reasons.

Is it possible to make some kind of placeholder which I can later set? I imagine something like

target1 = <placeholder_of_some_sort>
target2 = Program(files + [target1])

# Set target1 later
target1 = Object(...)

This does not work, however, because scons looks for the placeholder dependency.

EDIT:

The example shows the essence of problem I'm trying to solve. In reality I have a large and complex build system with dozens of SConscript files calling other SConscript files in a hierarchical fashion. I generate one or more targets depending on some user input:

for x in user_input:
    targets.append(env.SConscript(daughter_sconscript))

The targets generated are independent of each other ... except for an ugly edge case, where, depending on some user input, one of the calls to one of the daughter SConscript files generates an extra object file, which later is used in another call to the same daughter SConscript file.

The order in which the targets are generated depends on user input (user types scons 1 2 3 vs scons 3 2 1), so it is not guaranteed that the extra object is described to SCons, while the call to the SConscript which needs that object is executed. So I want to tell Scons "Hey, I know this target is going to need an object file, but it has not been described yet".

I could hardcode a name for the extra object file in the SConstruct file:

extra_object = File("path")

for x in user_input:
    targets.append(env.SConscript(daughter_sconscript, exports = {"extras": extra_object}))

But this clutters my SConstruct with details. I want to keep it as focused as possible, and let the daughter sconscript take care of the naming and path.

Thanks!

1
If you don't know which file(name) target1 will have, how can you guarantee a reproducible build? Can you expand your question and give an example of the steps you'd execute in a terminal for your (simplified) build process? Using Object in your example above is a little misguiding, because the obvious solution would be to set target2 after target1. But this is not what you're after, I guess? - dirkbaechle
Your Program statement is odd.. You specify no target, just sources. Please fix in your example. Should be Program('programname',<sources here>). - bdbaddog
@dirkbaechle I've elaborated a bit more, thanks! - Andak
@bdbaddog It is fine to only specify sources. From the scons manual: "When the target shares the same base name as the source and only the suffix varies, and if the builder method has a suffix defined for the target file type, then the target argument may be omitted completely, and scons will deduce the target file name from the source file name." source - Andak
You're iterating over for x in user_input, but don't use the x...this is confusing. Further, you seem to use the SConscript to compile a list of targets by aggregating the SConscript's return values. You don't have to do that to get the dependencies right, SCons can figure out the correct order for you. So I'd really like to see a MWE for this problem, because at this point I think that your general build setup may be overly complicated. It might turn out that there is no actual problem after all... - dirkbaechle

1 Answers

0
votes

First I wouldn't use the DefaultEnvironment (What you get when you use Program and not for example env.Program())

env=Environment()
env.Program('program_name',files + env['SOME_TARGET_NAME'])

.... later assuming shared env

env['SOME_TARGETNAME'] = env.SharedObject('fun_source.c')

Does this solve it for you? Or did you have a different use model.

A more common workflow would be to create a library (assuming this would be in a different directory) and then link that (by name) with the program

Top Level SConstruct:

env=Environment()
env.SConscript('program/SConscript', exports='env')
env.SConscript('other_dir/SConscript', exports='env')

program/SConscript:

Import('env')
env.Program('program_name',files+env['SOME_TARGET_NAME'])
or
env.Program('program_name',files,LIBPATH='#/other_dir',LIBS=['otherlib'])

other_dir/SConscript

Import('env')
env['SOME_TARGETNAME'] = env.SharedObject('fun_source.c')
or
env.StaticLibrary('otherlib',['fun_source.c'])