[Scons-users] Source paths across external projects

Bill Deegan bill at baddogconsulting.com
Thu Sep 8 21:27:05 EDT 2016


Bobby,

How about:
In the example above, `top_project/SConscript' would look like this:
    src = SConscript('sources.scons')
    foo =SConscript('extern/foo/sources.scons')
    src.extend(foo)
    prog = Program('test', src)

and `extern/foo/sources.scons' would look like this:
    src = [File('src/foo.c')]
    Return('src')

Or:
    src = [SharedObject('src/foo.c')]
    Return('src')



On Thu, Sep 8, 2016 at 11:15 AM, Bobby Casey <beecee808 at gmail.com> wrote:

> Hello,
>
> I'm going to start by apologizing for the length of this email.  I started
> off trying to explain what I'm looking for and what I have done and ended
> up trying other ideas as I went along.
>
> So here's what I'm trying to do - I have a project that depends on several
> external source repositories. The structure looks something like this:
>
> top_project/
> ---> SConstruct
> ---> SConscript
> ---> sources.scons
> ---> extern/foo
> ------> SConstruct
> ------> SConscript
> ------> sources.scons
> ------> src/
> ---------> foo.c
> ---> extern/bar
> ......
>
> Where each of the "extern" projects (there are several) is a separate
> repository that is capable of building itself (generally for testing
> purposes) and contains a sources.scons file that top_project's SConscript
> file pulls in to grab the list of source files that the sub-project
> provides. The problem, however, is that when `top_project/SConscript' calls
> `SConscript("extern/foo/sources.scons")', all the paths are relative to
> top_project (rather than extern/foo).
>
> This is a bit hard to explain, let me give a visual.
>
> In the example above, `top_project/SConscript' would look like this:
>     src = SConscript('sources.scons')
>     foo =SConscript('extern/foo/sources.scons')
>     src.extend(foo)
>     prog = Program('test', src)
>
> and `extern/foo/sources.scons' would look like this:
>     src = ['src/foo.c']
>     Return('src')
>
> This will fail with the following error:
>     scons: *** [build/src/foo.o] Source `build/src/foo.c' not found,
> needed by target `build/src/foo.o'.
>
> That is, of course, the correct behavior - just not the behavior what I
> wanted!  I could prepend os.path.abspath before each file, but that leaves
> the object files next to the sources, ignoring any variant_dir that was
> specified in top_project/SConstruct.
>
> I worked around this by modifying top_project/SConscript to look like this
> instead:
>     def add_scons_source(proj_dir):
>         src = SConscript('%s/sources.scons' % proj_dir)
>         src = ['%s/%s' % (proj_dir, s) for s in src]
>         return src
>
>     src = SConscript('sources.scons')
>     src.extend( add_scons_source('extern/foo') )
>     prog = Program('test', src)
>
> This prepends the appropriate path to each source file and works just fine
> but feels decidedly "unsconsy".  I then considered having each
> sources.scons be responsible for building it's own object files and that
> works great.  It's exactly what I wanted for building the application.  I
> suspect this is also the canonically correct way to do it.  The problem is
> that, in our real application, we also have a lint target that needs to be
> run against all source files so that it can detect issues across
> compilation units.  I'd like to avoid having the external projects know
> anything about lint, or whatever other targets are available in the
> top_project, so I came up with this as a possible solution.
>
> top_project/SConscript would look something like this:
>     env = Environment()
>     source_list = []
>     def do_lint(target, source, env):
>         print 'running lint on %s' % (str(s) for s in source)
>
>     def aggregate_sources(target, source, env):
>         global source_list
>         source_list.extend( [str(s) for s in source] )
>
>     env.Append(BUILDERS={'AggregateSources': Builder(action=aggregate_
> sources)})
>     env.Append(BUILDERS={'LintBuilder': Builder(action=do_lint)})
>
>     SrcBuilder = env.Object
>     src = SConscript('sources.scons', exports=['SrcBuilder'])
>     src.extend( SConscript('extern/foo/sources.scons',
> exports=['SrcBuilder']) )
>
>     prog = env.Program('test', src)
>     Default(prog)
>
>     SrcBuilder = env.AggregateSources
>     lint_src = SConscript('sources.scons', exports=['SrcBuilder'])
>     lint_src.extend( SConscript('extern/foo/sources.scons',
> exports=['SrcBuilder']) )
>     lint = env.LintBuilder('lint.out', lint_src)
>
>     Alias('lint', lint)
>
> and the sources.scons files would all look something like this:
>
>     Import('SrcBuilder')
>     src = ['src/foo.c']
>     built = [SrcBuilder(s) for s in src]
>     Return('built')
>
> This looks a bit silly in this contrived example because the SrcBuilder
> would really be part of two separate environments (one for Program and one
> for Lint targets), but I think you get the point.  The advantage to this
> method is that the builder is provided to sources.scons so it need not know
> how we're using the sources but can still handle them appropriately.  The
> disadvantage is that SrcBuilder needs to either be some common name for two
> wildly different things that are either part of the environment or passed
> as an extern.  It would be nicer if I could say something like `export(
> env.Object as "SrcBuilder")' and `export( env.AggregateSources as
> "SrcBuilder")'.  Is there some way to do this?
>
> I would appreciate any comments/feedback/suggestions/criticism.  Are any
> of these methods even remotely sound?  Is there some canonical way of doing
> this that I have just totally missed somehow?  Am I proposing a flawed
> architecture that could be easier/better done in some other way?
>
> Thanks in advance,
>   Bobby
>
>
> _______________________________________________
> Scons-users mailing list
> Scons-users at scons.org
> https://pairlist4.pair.net/mailman/listinfo/scons-users
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://pairlist4.pair.net/pipermail/scons-users/attachments/20160908/7afbe82b/attachment-0001.html>


More information about the Scons-users mailing list