[Scons-users] Listing all dependent headers?

Andrew C. Morrow andrew.c.morrow at gmail.com
Tue Oct 22 08:40:02 EDT 2013


On Tue, Oct 22, 2013 at 3:23 AM, Bill Deegan <bill at baddogconsulting.com>wrote:


> Andrew,

>

> As a CM guy I'd say the best thing to do is to arrange your "public" and

> "private" header files into different directories and then the problem

> becomes easy to solve and Glob() is a viable solution.

>


I agree with you 100% on this approach, but such a restructuring is out of
scope for the current release cycle.



> (I'm guessing via Google that the project in question is MongoDB)

>


Correct.



>

> Also I would hope that there are some CI test running post build which

> would identify when a needed header file is not copied into the proper

> packaging tree.

>


There is such a CI system, but I'll always prefer a system where it is
impossible to do the wrong thing (list of headers is generated) to one that
tells you that you did the wrong thing (list of headers managed manually
and later verified).



>

> To answer your specific question.. The DAG won't be complete until all the

> SConscript(s) are processed.

> You can get the 10k ft level view here:

> http://www.scons.org/wiki/SconsProcessOverview

>

>

Now you can write logic to walk the DAG after it's built, and extract the

> information you want, but I think a much cleaner solution would be what

> I've suggested above.

>


Agreed, and I hope to do exactly what you are suggesting in the near future.




> Hope that helps,

> Bill

>

>

>

>

>

> On Mon, Oct 21, 2013 at 3:13 PM, Andrew C. Morrow <

> andrew.c.morrow at gmail.com> wrote:

>

>>

>> One of my co-workers just raised an objection to this approach, stating

>> that he doesn't think it is legitimate to run the scanner at SConscript

>> interpretation time, as the above code is doing, and that it must be run

>> later in the build, at least after emitters have run.

>>

>> So I think I should step back and explain what I would like to do.

>> Perhaps there is a better way.

>>

>> I have a SharedLibrary target that I am going to install to

>> $INSTALL_DIR/lib.

>> The public facing interface to that library is encapsulated in one facade

>> header, lets call it client.h, which will be installed to

>> $INSTALL_DIR/include. This is the only header that users of the library are

>> intended to directly include.

>>

>> However, client.h in turn depends on many other headers. Unfortunately,

>> these headers are intermixed in the source tree with a large number of

>> other headers which should not be installed.

>>

>> Until now, we have kept an explicit list of headers to be installed along

>> with 'client.h'. However, it is easy to forget to update this list as the

>> set of indirect dependencies of client.h changes, in which case the set of

>> installed headers is incomplete and client.h will not be compilable from

>> its installed location. We cannot resort to Glob, since as mentioned there

>> are many other headers that would be picked up by Glob that are not

>> appropriate to install to $INSTALL_DIR/include.

>>

>> What I would like to do is arrange things so that a side effect of

>> installing client.h to $INSTALL_DIR/include is that all of the headers from

>> the source directory that client.h depends on are also installed to

>> $INSTALL_DIR/include. This would ensure that no matter what changes are

>> made to the header graph that the complete set of indirect headers required

>> by client.h are always installed along with client.h.

>>

>> What is the right way to accomplish this? Or is doing the scan at

>> SConscript interpretation time legitimate?

>>

>>

>>

>>

>> On Mon, Oct 21, 2013 at 3:54 PM, Andrew C. Morrow <

>> andrew.c.morrow at gmail.com> wrote:

>>

>>>

>>> Thanks. I was able to get it mostly working, doing something like:

>>>

>>> hdrSrcDir = env.Dir("#/src")

>>> hdrVarDir = env.Dir(".")

>>>

>>> clientHeaders = [

>>> hdrSrcDir.File("some/where/thing.h"),

>>> hdrSrcDir.File("some/where/else/another_thing.h")]

>>>

>>> clientHeaderDeps = set()

>>> for node in clientHeaders:

>>> clientHeaderDeps.add(node)

>>> scanner = node.select_scanner(SourceFileScanner)

>>> if scanner:

>>> for dep in node.get_implicit_deps(env, scanner, path=(hdrSrcDir,

>>> hdrVarDir)):

>>> clientHeaderDeps.add(dep)

>>> clientHeaders = clientHeaderDeps

>>>

>>>

>>> One complication is that I actually don't wan't to get all of the

>>> dependent headers, only the ones that originate within our 'src' directory

>>> (the project has some bundled libraries for which I don't want headers),

>>> and some of the headers I want to search are generated into the variant

>>> dir, hence the path restriction to get_implciti_deps.

>>>

>>> Overall though, this looks like it is working pretty well. The hardest

>>> part was getting out of the mud trying to use the scanner directly, rather

>>> than letting get_implicit_deps do it for me.

>>>

>>>

>>>

>>> On Sun, Oct 20, 2013 at 2:23 PM, Dirk Bächle <tshortik at gmx.de> wrote:

>>>

>>>> Hi Andrew,

>>>>

>>>>

>>>> On 20.10.2013 19:34, Andrew C. Morrow wrote:

>>>>

>>>>>

>>>>> I have a C++ header file that is intended for end user consumption,

>>>>> which in turn depends on many other headers. Part of our build process is

>>>>> to install this header and its dependencies to an install directory. But

>>>>> sometimes the hand-rolled list of dependent headers becomes out of date.

>>>>> I'd prefer that this list be auto-generated so it can no longer become

>>>>> stale.

>>>>>

>>>>>

>>>> note that there is also the FindSourceFiles() method, which you could

>>>> use to search all source files automatically. If required,

>>>> filter out the header files only, and then add the remaining Nodes to

>>>> your Install alias. Just as an idea, untested though.

>>>>

>>>>

>>>> I'd hoped that I could easily get the first level of required headers

>>>>> by saying:

>>>>>

>>>>> requiredHeaders = SourceFileScanner(env.File("**user/facing/thing.h"),

>>>>> env)

>>>>>

>>>>>

>>>> The call itself should work like this. Maybe something is wrong in the

>>>> way you setup CPPPATH?

>>>> Please, try a less contrived example first, where all header are on the

>>>> same subfolder level for example. Does it work then?

>>>> Otherwise, a simple example project would help to track this down...

>>>>

>>>> Best regards,

>>>>

>>>> Dirk

>>>>

>>>> ______________________________**_________________

>>>> Scons-users mailing list

>>>> Scons-users at scons.org

>>>> http://four.pairlist.net/**mailman/listinfo/scons-users<http://four.pairlist.net/mailman/listinfo/scons-users>

>>>>

>>>

>>>

>>

>> _______________________________________________

>> Scons-users mailing list

>> Scons-users at scons.org

>> http://four.pairlist.net/mailman/listinfo/scons-users

>>

>>

>

> _______________________________________________

> Scons-users mailing list

> Scons-users at scons.org

> http://four.pairlist.net/mailman/listinfo/scons-users

>

>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://four.pairlist.net/pipermail/scons-users/attachments/20131022/33a2c626/attachment.htm


More information about the Scons-users mailing list