[Qt5-feedback] The #include directives for Qt Essentials and Qt Add-on modules

Charley Bay charleyb123 at gmail.com
Fri Jul 1 18:47:51 CEST 2011


Hi, All--

Thank you all for humoring me.

Summary:  I concede.  The following makes the most sense:

#include<QtAddOn/SomeWidget>

What follows is "thread housekeeping" regarding the context and (irrelevant)
limitations regarding my acquiescence.  ;-))

Specifically:

(1) There is precedent for "#include<QtAddOn/SomeWidget>"

(2) I don't have a reasonable alternative.

Original assertion:

> >>>// ARE YOU SURE YOU WANT TO DO THIS?
> >>>#include <some/path/SomeFile.hpp>
> >>>
> >>>...is really pretty dangerous.  It's a general nightmare for build
> systems
> >>>and configuration management, since the "INCLUDE_PATH" is no
> >>>longer "in-charge":
>

My concerns stemmed from <somedir/SomeFile> (in the source code) logically
polluting the *build configuration* namespace, undermining the idea that
*exactly* and *only* those paths in "INCLUDE_PATH" are considered (e.g.,
"bulletproof builds", no matter how much cruft existed in the workspace).

But, then, Ben raises something I neglected (Craig may have said it too):

(me sayeth):

> >But yes, in the case of "common dirname collisions", paths would be
> searched
> >that didn't even have source code in them (they should never have been
> conceived
> >to be part of the INCLUDE_PATH).
>

Ben respondeth:

> There is a far greater issue of collisions when you just do #include
> <QString>
> versus #include <Qt/QString.h>.
> One limits you to a specific file under a specified subdir in any of the
> directories in INCLUDE_PATH.
> The other matches any file in any of the directories in INCLUDE_PATH but
> not any
> of their subdirectories.
>

What I missed (and the primary reason for my concession) is that
<dirname/FileName> cuts *both* ways:  The "dirname" (as Ben points out) in
the *source files* represent *local disambiguation* of intended header,
similar to a namespace, *in addition to* possibly introducing a global
workspace collision with "dirname" (e.g., as a build-configuration
extension).  The "local disambiguation" (of course) is legitimate, because
source files *know* the namespaces with which they are working.  For
example, (of course), I concede it is legitimate for an individual source
file to say, "#include<CompanyA/Object>" separate from
"#include<CompanyB/Object>" when such a namespace collision occurs across
packages used in the same target executable.  (There is extensive
precedent.)

I was concerned because I wasn't thinking of it primarily as a namespace
(which it really is), but as a coupling-to-package internal-organization
that introduces a global dirname as a "build-system extension" (which it
kind-of is).

Of course, it doesn't solve the "version" problem for those namespaces you
are using (e.g., what is installed where at the time of the build).  That is
the purpose of the build, and you must (of course) have *some* discipline
with your build configuration, and ideally the contents of the build is
explicitly (well-) documented.

Still, it means a "messy/crufty workspace" would yield side-effect.  That's
sort-of always true, but we've worked hard to minimize that, and all our
builds are pretty darned close to "bullet-proof" and highly documented for
what is *actually* in the build.  Ultimately, though, I concede the
trade-offs with what we've done in our system are probably not reasonable
based on precedent for packaged distributions, and I'm not even convinced
our approach is reasonable for the foundation of we're talking about for Qt5
and add-ons (so I'm still conceding.)

>(3) Your build is no longer documented.  "INCLUDE_PATH" no longer
> >>reflects the directories from which files are included.  Accidental
> >>location of files can violate the build target, and you would NEVER
> >>KNOW (e.g., you can't reproduce it on different machines, or on the
> >>same machine on different days, unless you *always* started
> >>with a "virgin build".)
> >>
> >>I'd argue the opposite. The source files document exactly where you
> expect the
> >>files to be. If you are using this arrangement, you are typically saying
> that
> >>you expect to use a relatively limited number of INCLUDE_PATH search
> locations.
> >>These INCLUDE_PATH locations would define the base points of the search
> and the
> >>paths you use in your source files specify the directory structure.
>

This was a documentation-and-manual-reconciliation convenience regarding
file-system-search for "SomeFile", and cross-referencing it with the
"INCLUDE_PATH".  A collision means a (possible) problem.  In contrast, if
<somedir/SomeFile> is in source code, then we *must know* the dirname in the
*source code* in order to detect a problem (to locations in addition to
those found in our INCLUDE_PATH).  That's the general "namespace corruption"
question, especially when we install someone else's source, or during
development when the developer "sometimes" remembered <somedir/SomeFile> and
sometimes forgets and does just <SomeFile> (we hope the latter will *fail*
to find something).  I can live with that -- it just means as widgets are
used, we must remember their namespace/module, and you should keep your
build workspace reasonably clean.


> The specified sub-dir can be easily regulated by controlling your
> INCLUDE_PATH
> and the INCLUDE_PATH environment variable, which you seem to be missing
> concern
> for.  INCLUDE_PATH environment variable specifies the primary headers
> required for the
> system you are building on, this is in addition to whatever is specified on
> the
> command-line to the compiler, and to truly control the build you have to
> control both.
>

We don't use the INCLUDE_PATH environment variable, nor any environment
variables (all our builds are well-documented in files that are checked-in).

For example, Scons doesn't consider the INCLUDE_PATH environment variable
either, and Scons' general policy is to not consider any environment
variables (although some early Scons-plug-ins may have violated that).

It doesn't simply help users. It helps compilers and IDEs too.
>
> One code-base I occassionally work on does exactly what you do - everything
> does
> simple #include <somefile.xxx>, and then a ton of specific directories are
> added
> to the INCLUDE_PATH.
> Visual Studios often cannot find the files when going through the source
> code
> and trying to open the various headers.
> However, another code-base I work on does the #include <dir/file.xxx>, and
> Visual Studios never has a problem finding the files - and there only has
> to be
> a couple directories added to INCLUDE_PATH.
>

We probably agree that today's IDEs are insufficiently smart (I concede it
is a hard problem).  You assert many paths in INCLUDE_PATH creates a problem
for MSVS (and I've seen that too), and that fewer paths with
<dirname/SomeFile> works better (which I don't dispute).

In our case we use VisualAssist (from WholeTomato) with our MSVS and it
solves these problems (and other stuff like syntax highlighting and
code-completion).  But, I agree that your point is a real one (I find it
pretty easy to break MSVS).


> >same project in accidental locations).  However, it is *possible* for a
> >developer to unpack something locally someplace (like another version of
> the
> >add-on that should *not* be part of the build, and which is *not* in the
> >INCLUDE_PATH, and it may be used (depending on where it was unpacked).
>  That's
> >the "undocumented" thing I worry about.
>
> If they are doing that, then they need to manage the issue itself.
>

True.  However, "real world" workspaces can increase the chance of collision
or problems:

*- very large workspaces

*- old workspaces

*- mis-understood workspaces from developers no longer here

*- rich workspaces, such as for branched/merging development that may
require multiple versions of the same libraries (when one or both versions
are in development)

*- workspaces managed by idiots that still expect you to fix it when they
can no longer build, and the manager doesn't understand and doesn't care
about "who's right"  ;-))

Finally, the concept of "bullet-proof" is the concept of *absolute
certainty* regarding what comprised a build (including traceable
configuring-and-resulting documentation).  We think we pretty-much have
that, but it is more difficult with <somedir/SomeFile>, but I don't have a
practical alternative (I'm still conceding).

>True.  However, the INCLUDE_PATH is discrete and un-ambiguous, and checked
> into
> >version control.
>


> As noted above you forget about the INCLUDE_PATH environment variable,
> which
> unless you project explicitly clears it cannot be checked into version
> control
> so easily.
>

True, which is why we don't use INCLUDE_PATH.  Even if it is set, it is not
considered in the build.


> >And, the INCLUDE_PATH doesn't have the other problem:  If
> "MyCollision.hpp"
> >exists in two directories in the INCLUDE_PATH, the earlier one wins (maybe
> in
> >error), but at least the list is discrete.  Yet, if I must manually-search
> for
> >"MyCollision.hpp" in subdirectories that are *implied* based on "dirnames"
> in
> >*source code* that is *not even my source code* relative to paths in my
> >INCLUDE_PATH to resolve "bad-build-errors", then I'll have to blow my
> brains
> >out.
>
> As noted above, I can show you problems in IDEs with finding the file _at
> all_
> (forget about whether it is the right one or not) using the #include
> "mycollissionl.hpp" method.
> But it has no problem finding _the right_ file with #include
> <dir/somefile.hpp>.
>

Your point is legitimate (IDEs may be insufficiently smart), our work-around
was VisualAssist with MSVS.


> As to which file is used in the case of a collision - yes, the file that is
> in
> the earliest specified path in INCLUDE_PATH is utilized.
> That doesn't change when doing #include <dir/somefile.hpp>, and as noted
> above,
> it doesn't add 'dir' to the search for everything.
>

True, I just don't know if *every* developer used <dir/SomeFile> in *every
instance*, or if some accidentally just did <SomeFile>.  In this case, my
only concern would be for which "SomeFile" was used (ideally it was only
that one found in the INCLUDE_PATH).

Actually, in our case, we "check" for collisions for the same file in the
INCLUDE_PATH on any given build (it is a warning, because the earlier
"hides" the later).  However, we do not check for every occurrence of
"SomeFile" recursively through the workspace (that would be prohibitive,
unrealistic, and erroneous, because file name duplications are common and
allowed, such as the many occurrences of "StdAfx.h" or "Resource.h".

>Since this has happened to me before, I have very few brains left.
> >
> >In short, when INCLUDE_PATH dominates, the messiest-workspace-on-Earth
> will
> >still build the correct target, efficiently.
>
> Yes, it may build. But does the IDE work? The one code-base I mentioned
> above
> builds just fine - but the IDEs cannot find anything.
>

Fair point.


> >It took me a bit to decide I liked "#include<QWidget>",
> >but I've decided that it was a good deployment decision (to solve the
> >cross-platform file extension-convention-and-case problem).
>
> It doesn't really solve the cross-platform file-extensions-convertion-case
> problem.
> It just does what C++ does - e.g. #include <string> - it still has to match
> a
> header file.
> In the case of Qt, they've added a header file QWidget that then goes on to
> #include "qtgui/qwidget.h". (or is it ../qtgui/qwidget.h? - something like
> that.)
> Check out the files. It's not like Qt isn't already doing what they are
> suggesting - just making it more explicity.
> Of course, you can already do that too - I typically use the #include
> <module/header> convention already.
>

Yes, I know that's "under the hood", and that's fine with me because I
*know* no developer ever tries to reference those files directly.  And, I
accept that precedent for deployed packages that do such conventions (I
agree they are necessary to get aggregation/deployment benefits at the
expense of trade-offs).

So, in conclusion, I apologize for kicking up dust.  I appreciate the strong
(and well-reasoned) responses, and I concede my position.

Of course, if you ever put relative paths in the system, like:

// IF THIS HAPPENS SOMEONE MUST DIE:
#include<../../somedir/SomeFile>  // MOMMY, MAKE IT STOP!!!

...then we shall see if a well-adjusted person exercises aggression upon
himself or upon those innocent persons around him.  ;-))

>I merely voted.  I didn't expect to win the vote.  ;-))
>

Hearing concerns is always a good thing, if for no other reason than to
> provide
> the information to alleviate them at worst and at best address the issue
> should
> there really be one.
>
> $0.02
>

Is that a polite way to say, "It's all in your head?"  ;-))

Seriously, thanks for the feedback.

--charley
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.qt.nokia.com/pipermail/qt5-feedback/attachments/20110701/96bc4a9c/attachment-0001.html 


More information about the Qt5-feedback mailing list