Teaching cpplint About External Libraries h-Files

The Google C++ Style Guide defines a guideline for names and order of includes. Unfortunately, the cpplint tool that automates style-guide checking isn’t consistent with that guideline, as far as “other libraries h files” are concerned.

In this post, I demonstrate the claimed inconsistency, and suggest an enhancement to cpplint to fix the inconsistent behavior.

The enhancement is available on my GitHub cpplint fork (including addition unit tests).

Google C++ Style Guide take on order of includes

Quoting from the Google C++ Style Guide:

In “dir/foo.cc” or “dir/foo_test.cc”, whose main purpose is to implement or test the stuff in dir2/foo2.h, order your includes as follows:

1. dir2/foo2.h (preferred location — see details below).
2. C system files.
3. C++ system files.
4. Other libraries’ .h files.
5. Your project’s .h files.

That’s fine by me. I’m happy to follow it.

cpplint doesn’t agree with the style-guide on “other libraries”

Here’s a dummy C++ source file that I wrote according to the quoted style guide:

# Copyright 2014 The Ostrich

#include "foo/bar.h"  // own header - preferred location

#include <stdio.h>  // C system file

#include <vector>  // C++ system file

#include <glog/glog.h>  // "Other" library h-file, installed system-wide

#include "general/utils.h"  // Other project file

int foobar() {
  return 42;
}

Seems compliant, doesn’t it? Not if you ask cpplint!

itamar@legolas cpplint (google-upstream-svn) $ python cpplint.py foo/bar.cc
foo/bar.cc:9:  Found C system header after C++ system header. Should be: bar.h, c system, c++ system, other.  [build/include_order] [4]
Done processing foo/bar.cc
Total errors found: 1
The Google C++ Style Guide and cpplint don’t agree on “other libraries h files”…

My cpplint enhancement – introducing configurable external libs prefixes

I previously wrote about the value of automated style-guide checking. To enjoy the value without this false positive, I modified Google’s cpplint.py script to accommodate for external libraries.

The modified code is available on my GitHub cpplint fork (including addition unit tests).

My modification introduces new options that can be set in CPPLINT.cfg. Here it is in operation:

itamar@legolas cpplint (includes/ext-libs) $ cat cpplint.cfg
set noparent
system_wide_external_libs = True
external_lib_prefixes = gtest,gflags,glog
itamar@legolas cpplint (includes/ext-libs) $ python cpplint.py foo/bar.cc
Done processing foo/bar.cc
Total errors found: 0

Now cpplint understands the difference between an external library h-file and a project h-file!

My cpplint enhancement fixes the disagreement with the Style Guide!

New cpplint configuration options

As shown in the example above, I introduced two new configuration options.

system_wide_external_libs is a boolean option. By default, external libraries are assumed to be included with quotes (e.g. #include "glog/glog.h"). Setting system_wide_external_libs to True (or Yes or 1) changes the expected include pattern to system-includes, using brackets (like in my example).

external_lib_prefixes is a list of comma-separated string prefixes. It is used to match the first element of the include path. If it matches, the include is classified as an external library h-file.

Summary

My suggested cpplint enhancement solves an annoying inconsistency between the Google C++ style guide, and the cpplint tool.

With this enhancement, I can happily write conforming include-sections without having cpplint produce warnings. I believe this is important, because false positives are dreadful obstacles in the face of adopting “non-essentials” tools in the development cycle, whose sole function is to improve code quality.

Feel free to use my enhancement from my GitHub cpplint fork. You’re also welcome to fork it yourself, and do whatever you want with it. If you find issues with this enhancement, open me an issue on GitHub.

No Comments Yet.

Leave a Reply