[RFC]: Include file proposal

994 views
Skip to first unread message

Mandeep Singh Baines

unread,
Jun 11, 2010, 12:11:08 AM6/11/10
to chromiu...@chromium.org
Hi,

One thing I've noticed while refactoring the ebuilds is that we have
inconsistent strategies for header file includes of program-local
header files. This is causing some hackery to be needed in the ebuilds.

Some packages use (assume the current package is foo):

#include <foo/foo.h>

Other packages do the following:

#include "foo.h"

The former is legacy from when we used to treat the tree as one
project.

So I'd like to propose we adopt the latter convention:

#include "foo.h"

when including a file local to the package.

And use:

#include <chromeos/bar.h>

when including a file in another package.

I'm pasting the cpp reference below.
From http://gcc.gnu.org/onlinedocs/cpp/Include-Syntax.html:

<syntax>

2.1 Include Syntax

Both user and system header files are included using the preprocessing directive `#include'. It has two variants:

#include <file>
This variant is used for system header files. It searches for a file named file in a standard list of system directories. You can prepend directories to this list with the -I option (see Invocation).
#include "file"
This variant is used for header files of your own program. It searches for a file named file first in the directory containing the current file, then in the quote directories and then the same directories used for <file>. You can prepend directories to the list of quote directories with the -iquote option.

The argument of `#include', whether delimited with quote marks or angle brackets, behaves like a string constant in that comments are not recognized, and macro names are not expanded. Thus, #include <x/*y> specifies inclusion of a system header file named x/*y.

However, if backslashes occur within file, they are considered ordinary text characters, not escape characters. None of the character escape sequences appropriate to string constants in C are processed. Thus, #include "x\n\\y" specifies a filename containing three backslashes. (Some systems interpret `\' as a pathname separator. All of these also interpret `/' the same way. It is most portable to use only `/'.)

It is an error if there is anything (other than comments) on the line after the file name.

</syntax>

Thoughts?

We should agree on a convention and use it for new code. For the old code,
we can open tracker issue to cleanup when appropriate.

Regards,
Mandeep

Bill Richardson

unread,
Jun 11, 2010, 10:39:33 AM6/11/10
to Mandeep Singh Baines, chromiu...@chromium.org
We should never use <foo.h> for anything other than system files. That means

#include "chromeos/bar.h"

NOT

#include <chromeos/bar.h>






--
Chromium OS Developers mailing list: chromiu...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-os-dev?hl=en

Daniel Erat

unread,
Jun 11, 2010, 12:13:02 PM6/11/10
to Mandeep Singh Baines, chromiu...@chromium.org
On Thu, Jun 10, 2010 at 9:11 PM, Mandeep Singh Baines <m...@chromium.org> wrote:
> Hi,
>
> One thing I've noticed while refactoring the ebuilds is that we have
> inconsistent strategies for header file includes of program-local
> header files. This is causing some hackery to be needed in the ebuilds.
>
> Some packages use (assume the current package is foo):
>
> #include <foo/foo.h>

You mean

#include "foo/foo.h"

, right? I see some packages that use angled brackets to include
headers from other packages (e.g.
login_manager/session_manager_main.cc includes <base/basictypes.h>),
but none with the style that you describe. From the platform
directory:

# angled brackets
for i in *; do grep '#include <$i/' $i/*.cc; done 2>/dev/null | wc -l
0

# doublequotes
for i in *; do grep "#include \"$i/" $i/*.cc; done 2>/dev/null | wc -l
779

Project "foo" including one of its own headers as "foo/bar.h" is
consistent with what Chrome does, and it's also the way that things
work in google3. I think we should stick with this unless there's a
compelling reason to change it.

Using <other_package/blah.h> for headers from other packages seems
reasonable to me, since I believe that those headers are going to need
to be installed in /usr/include with the new build system.

Vince Laviano

unread,
Jun 11, 2010, 1:04:34 PM6/11/10
to Mandeep Singh Baines, chromiu...@chromium.org
Hi Mandeep,

On Thu, Jun 10, 2010 at 9:11 PM, Mandeep Singh Baines <m...@chromium.org> wrote:
Hi,

One thing I've noticed while refactoring the ebuilds is that we have
inconsistent strategies for header file includes of program-local
header files. This is causing some hackery to be needed in the ebuilds.

Some packages use (assume the current package is foo):

#include <foo/foo.h>

Other packages do the following:

#include "foo.h"

The former is legacy from when we used to treat the tree as one
project.

So I'd like to propose we adopt the latter convention:

#include "foo.h"

when including a file local to the package.

cpplint.py complains about #include "foo.h" with the message "Include the directory when naming .h files".  #include "foo/foo.h" avoids this warning.


So, if we want to stick with Google convention, I think that we should do foo/foo.h.

Vince
 

And use:

#include <chromeos/bar.h>

when including a file in another package.

I'm pasting the cpp reference below.
From http://gcc.gnu.org/onlinedocs/cpp/Include-Syntax.html:

<syntax>

2.1 Include Syntax

Both user and system header files are included using the preprocessing directive `#include'. It has two variants:

#include <file>
   This variant is used for system header files. It searches for a file named file in a standard list of system directories. You can prepend directories to this list with the -I option (see Invocation).
#include "file"
   This variant is used for header files of your own program. It searches for a file named file first in the directory containing the current file, then in the quote directories and then the same directories used for <file>. You can prepend directories to the list of quote directories with the -iquote option.

The argument of `#include', whether delimited with quote marks or angle brackets, behaves like a string constant in that comments are not recognized, and macro names are not expanded. Thus, #include <x/*y> specifies inclusion of a system header file named x/*y.

However, if backslashes occur within file, they are considered ordinary text characters, not escape characters. None of the character escape sequences appropriate to string constants in C are processed. Thus, #include "x\n\\y" specifies a filename containing three backslashes. (Some systems interpret `\' as a pathname separator. All of these also interpret `/' the same way. It is most portable to use only `/'.)

It is an error if there is anything (other than comments) on the line after the file name.

</syntax>

Thoughts?

We should agree on a convention and use it for new code. For the old code,
we can open tracker issue to cleanup when appropriate.

Regards,
Mandeep

Mandeep Singh Baines

unread,
Jun 11, 2010, 2:19:39 PM6/11/10
to Daniel Erat, Mandeep Singh Baines, chromiu...@chromium.org
Daniel Erat (de...@chromium.org) wrote:
> On Thu, Jun 10, 2010 at 9:11 PM, Mandeep Singh Baines <m...@chromium.org> wrote:
> > Hi,
> >
> > One thing I've noticed while refactoring the ebuilds is that we have
> > inconsistent strategies for header file includes of program-local
> > header files. This is causing some hackery to be needed in the ebuilds.
> >
> > Some packages use (assume the current package is foo):
> >
> > #include <foo/foo.h>
>
> You mean
>
> #include "foo/foo.h"
>

D'oh. You're right.

Mandeep Singh Baines

unread,
Jun 11, 2010, 2:31:51 PM6/11/10
to Vince Laviano, Mandeep Singh Baines, chromiu...@chromium.org
Vince Laviano (vlav...@chromium.org) wrote:
> Hi Mandeep,
>
> On Thu, Jun 10, 2010 at 9:11 PM, Mandeep Singh Baines <m...@chromium.org>wrote:
>
> > Hi,
> >
> > One thing I've noticed while refactoring the ebuilds is that we have
> > inconsistent strategies for header file includes of program-local
> > header files. This is causing some hackery to be needed in the ebuilds.
> >
> > Some packages use (assume the current package is foo):
> >
> > #include <foo/foo.h>
> >

As pointed out by derat, we don't have this. We have:

#include "foo/foo.h"

I've been looking at so many different packages as part of the refactoring
that I just got confused. I might have been in bar but thought I was info.
My bad.

> > Other packages do the following:
> >
> > #include "foo.h"
> >
> > The former is legacy from when we used to treat the tree as one
> > project.
> >
> > So I'd like to propose we adopt the latter convention:
> >
> > #include "foo.h"
> >
> > when including a file local to the package.
> >
>
> cpplint.py complains about #include "foo.h" with the message "Include the
> directory when naming .h files". #include "foo/foo.h" avoids this warning.
>
> The example given in
> http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Names_and_Order_of_Includes
> also
> shows the foo/foo.h form.
>
> So, if we want to stick with Google convention, I think that we should do
> foo/foo.h.
>

Yep.

So here's the issue:

A typical unix package, doesn't really have control over its top-level
directory. If you are the foo maintainer, you'll release the foo-1.4.tar.bz
src tarball to checkout at foo-1.4 which breaks:

#include "foo/foo.h"

So portage assumes that it control the top-level directory. When you src_unpack
the foo-1.4.ebuild which is checking out from git it gets checked out at:

${WORKDIR}/${P}

/blah/blah/foo-1.4

I can workaround by creating symlinks:

ln -s /blah/blah/foo-1.4 /blah/blah/foo

This solves the problems for us I guess but I'm worried about creating hassles
for someone that tries to use foo.git in another context and runs into this
problem. To be portable, you'll want to avoid relying on the top-level dir.

A lot of packages avoid that by having an src directory and a Makefile in the
top-level dir.

Thinking about this, I'm just going to create the symlinks. But I want
to bring this to folks attention if they want their packages to be
portable to other systems.

Justin Neddo

unread,
Jun 11, 2010, 3:01:47 PM6/11/10
to chromiu...@chromium.org
Is there some way to configure a test image to automatically login. I want to be able to create a test image and run some remote UI tests without having to interact with the login screen.
-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information. Any unauthorized review, use, disclosure or distribution
is prohibited. If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------

Vince Laviano

unread,
Jun 11, 2010, 3:04:46 PM6/11/10
to Mandeep Singh Baines, chromiu...@chromium.org
I think that this is the way to go.  Refining my earlier statement, the standard 
isn't necessarily foo/foo.h, but something/foo.h.  If we have all include files 
sitting in <toplevel>/include/foo.h (for public headers to be installed) or 
<toplevel>/src/foo.h (for private headers), we can #include "include/foo.h" or 
#include "src/foo.h" and shut up cpplint without relying on knowing the toplevel 
dir.  In that scenario,  the only thing likely to be at the toplevel is config.h, and 
the best practice there is to #include <config.h>, which sidesteps the issue.

Will Drewry

unread,
Jun 11, 2010, 3:12:54 PM6/11/10
to Justin Neddo, chromiu...@chromium.org
That's normally done by implementing those tests in the autotest
framework. There is support there for logging in and then performing
the test (and then logging out). Not sure if it is exactly what
you're hoping for, but it might be a good start:

Here's a recent change that ported a test over to use autologin:

http://git.chromium.org/cgi-bin/gitweb.cgi?p=autotest.git;a=commit;h=71775f079bab2aad8e9807503969460e8abf316b

The diff shows the manual way to auto-login in a test and the newer
way to write a ui test as a subclass.

hth,
will

Justin Neddo

unread,
Jun 11, 2010, 3:14:23 PM6/11/10
to Will Drewry, chromiu...@chromium.org
Thanks Will

Sean Parent

unread,
Jun 14, 2010, 5:25:17 PM6/14/10
to Bill Richardson, Mandeep Singh Baines, chromiu...@chromium.org
From correct account...

On Mon, Jun 14, 2010 at 2:22 PM, Sean Parent <seanp...@google.com> wrote:
There are several different conventions for include paths. -

(1) <> should only be used to name standard (not system) headers only. In fact, in the C++ standard, the token inside <> isn't necessarily a file name (that is why C++ standard headers don't have an extension - they aren't necessarily files).
(2) <> should just be for files installed in the system search path.
(3) <> be used for any file which is not local to the project or included by headers that could be included externally.

Despite being supported by the standard, (1) doesn't have a large following because compilers tend to only have two search paths, system and usr. Both (2) and (3) have large followings (I see (2) more from C programmers and (3) more from C++ programmers more on why in a moment). I prefer (3) because as the author of a package I don't really want to know if an external package is installed in the system search path or not.

In a C++ project, you get much more code in headers because of templates and inline functions. If you start having "foo/bar.h" in a header which is included with <foo/bar.h> then you require that both system and usr search paths include the same roots. This is why you see projects like Boost that, for the most part use <> for everything and you see things like:

#include <boost/range/functions.hpp>

Inside of a boost header file.

However, the end result of this is that if you are writing libraries (and I'm someone who thinks all code should be written as a library) then you end up using <> for everything - but you could just as easily use "" for everything (except standard includes). The other reason why I like option 3 is because it eliminates what is really a false dichotomy between types of external files.

I wrote a doc on this awhile ago but never got much feedback on it one way or the other:


Sean

Justin Neddo

unread,
Jun 15, 2010, 6:53:41 PM6/15/10
to Justin Neddo, Will Drewry, chromiu...@chromium.org
If I'm using an autotest enabled image, am I supposed to be able to login via the browser?

What happens to me is that the browser keeps resetting and clearing the username / password out of the dialog boxes as I'm typing.

Richard Barnette

unread,
Jun 15, 2010, 7:00:21 PM6/15/10
to Justin Neddo, Will Drewry, chromiu...@chromium.org
On Jun 15, 2010, at 3:53 PM, Justin Neddo wrote:

> If I'm using an autotest enabled image, am I supposed to be able to
> login via the browser?
>

Yes, you're supposed to be able to log in.

> What happens to me is that the browser keeps resetting and clearing
> the username / password out of the dialog boxes as I'm typing.

When did you build your image? There's at least one known problem
with recent
images. However, your description doesn't match the known failure.

When you say the username/password get reset, does the screen get
cleared
and redrawn, too? If so, it sounds like chrome is dying and restarting
early in start up. Otherwise, there's something more mysterious going
on...

Thanks!

-- jrb

Justin Neddo

unread,
Jun 15, 2010, 7:05:09 PM6/15/10
to Richard Barnette, Will Drewry, chromiu...@chromium.org
I built it today. Yes, the screen gets cleared and redrawn.

I can log into the machine over ssh and poke around but I can't interact with the logon screen without it refreshing. If I build a normal (non-test) image everything comes up fine.

ko...@codeaurora.org

unread,
Jun 15, 2010, 7:15:44 PM6/15/10
to Justin Neddo, Richard Barnette, Will Drewry, chromiu...@chromium.org
> I built it today. Yes, the screen gets cleared and redrawn.
>
> I can log into the machine over ssh and poke around but I can't interact
> with the logon screen without it refreshing. If I build a normal
> (non-test) image everything comes up fine.
>

You might be hitting that issue:
http://code.google.com/p/chromium-os/issues/detail?id=3310

It has a temp workaround.

Kobi

Justin Neddo

unread,
Jun 15, 2010, 7:24:28 PM6/15/10
to ko...@codeaurora.org, Richard Barnette, Will Drewry, chromiu...@chromium.org
Yep, that's what I'm hitting.

With no Ethernet I'm not going to be able to run autotest

> >> >>>> Chromium OS Developers mailing list: chromium-os-
> d...@chromium.org


> >> >>>> View archives, change email options, or unsubscribe:
> >> >>>> http://groups.google.com/a/chromium.org/group/chromium-os-
> >> dev?hl=en
> >> >>>>
> >> >>
> >> >> --
> >> >> Chromium OS Developers mailing list: chromiu...@chromium.org
> >> >> View archives, change email options, or unsubscribe:
> >> >> http://groups.google.com/a/chromium.org/group/chromium-os-
> dev?hl=en
> >> >
> >> > --
> >> > Chromium OS Developers mailing list: chromiu...@chromium.org
> >> > View archives, change email options, or unsubscribe:
> >> > http://groups.google.com/a/chromium.org/group/chromium-os-
> dev?hl=en
> >>

Reply all
Reply to author
Forward
This conversation is locked
You cannot reply and perform actions on locked conversations.
0 new messages