Include what you use windows

Include what you use windows

Include What You Use

For more in-depth documentation, see docs.

Instructions for Users

«Include what you use» means this: for every symbol (type, function, variable, or macro) that you use in foo.cc (or foo.cpp ), either foo.cc or foo.h should include a .h file that exports the declaration of that symbol. (Similarly, for foo_test.cc , either foo_test.cc or foo.h should do the including.) Obviously symbols defined in foo.cc itself are excluded from this requirement.

This puts us in a state where every file includes the headers it needs to declare the symbols that it uses. When every file includes what it uses, then it is possible to edit any file and remove unused headers, without fear of accidentally breaking the upwards dependencies of that file. It also becomes easy to automatically track and update dependencies in the source code.

This is alpha quality software — at best (as of July 2018). It was originally written to work specifically in the Google source tree, and may make assumptions, or have gaps, that are immediately and embarrassingly evident in other types of code.

While we work to get IWYU quality up, we will be stinting new features, and will prioritize reported bugs along with the many existing, known bugs. The best chance of getting a problem fixed is to submit a patch that fixes it (along with a test case that verifies the fix)!

Include-what-you-use makes heavy use of Clang internals, and will occasionally break when Clang is updated. Usually such discrepancies are detected by build bot and fixed promptly.

The IWYU master branch follows Clang main branch.

We also have convenience tags and branches for released versions of Clang (called clang_ , e.g. clang_5.0 ). To build against a Clang release, check out the corresponding branch in IWYU before configuring the build. More details in the instructions below.

We assume you already have compiled LLVM and Clang libraries on your system, either via packages for your platform or built from source. You can use this mapping table to combine Clang and IWYU versions correctly:

Clang IWYU version IWYU branch
3.6 0.4 clang_3.6
3.7 0.5 clang_3.7
3.8 0.6 clang_3.8
3.9 0.7 clang_3.9
4.0 0.8 clang_4.0-r2
5.0 0.9 clang_5.0
6 0.10 clang_6.0
7 0.11 clang_7.0
8 0.12 clang_8.0
9 0.13 clang_9.0
10 0.14 clang_10
11 0.15 clang_11
. . .
main master

NOTE: If you use the Debian/Ubuntu packaging available from https://apt.llvm.org, you’ll need the following packages installed:

Packaging for other platforms will likely be subtly different.

To set up an environment for building:

Create a directory for IWYU development, e.g. iwyu

Clone the IWYU Git repo:

Presumably, you’ll be building IWYU with a released version of LLVM and Clang, so check out the corresponding branch. For example, if you have Clang 6.0 installed, use the clang_6.0 branch. IWYU master tracks LLVM & Clang main :

Create a build root and use CMake to generate a build system linked with LLVM/Clang prebuilts:

(substitute the llvm-6.0 or llvm-7 suffixes with the actual version compatible with your IWYU branch)

or, if you have a local LLVM and Clang build tree, you can specify that as CMAKE_PREFIX_PATH for IWYU 0.11 and later:

Once CMake has generated a build system, you can invoke it directly from build , e.g.

Instructions for building Clang are available at https://clang.llvm.org/get_started.html.

If you’re building IWYU out-of-tree or installing pre-built binaries, you need to make sure it can find Clang built-in headers ( stdarg.h and friends.)

Clang’s default policy is to look in path/to/clang-executable/../lib/clang/ /include . So if Clang 3.5.0 is installed in /usr/bin , it will search for built-ins in /usr/lib/clang/3.5.0/include .

Clang tools have the same policy by default, so in order for IWYU to analyze any non-trivial code, it needs to find Clang’s built-ins in path/to/iwyu/../lib/clang/3.5.0/include where 3.5.0 is a stand-in for the version of Clang your IWYU was built against.

Note that some distributions/packages may have different defaults, you can use clang -print-resource-dir to find the base path of the built-in headers on your system.

So for IWYU to function correctly, you need to copy the Clang include directory to the expected location before running (similarly, use include-what-you-use -print-resource-dir to learn exactly where IWYU wants the headers).

This weirdness is tracked in issue 100, hopefully we can make this more transparent over time.

The original design was built for Make, but a number of alternative run modes have come up over the years.

Plugging into Make

The easiest way to run IWYU over your codebase is to run

(include-what-you-use always exits with an error code, so the build system knows it didn’t build a .o file. Hence the need for -k .)

Include-what-you-use only analyzes .cc (or .cpp) files built by make , along with their corresponding .h files. If your project has a .h file with no corresponding .cc file, IWYU will ignore it unless you use the —check_also switch to add it for analysis together with a .cc file.

Using with CMake

CMake has grown native support for IWYU as of version 3.3. See their documentation for CMake-side details.

The CMAKE_CXX_INCLUDE_WHAT_YOU_USE option enables a mode where CMake first compiles a source file, and then runs IWYU on it.

Use it like this:

or, on Windows systems:

The option appears to be separately supported for both C and C++, so use CMAKE_C_INCLUDE_WHAT_YOU_USE for C code.

Note that with Microsoft’s Visual C++ compiler, IWYU needs the —driver-mode=cl argument to understand the MSVC options from CMake.

Using with a compilation database

The iwyu_tool.py script predates the native CMake support, and works off the compilation database format. For example, CMake generates such a database named compile_commands.json with the CMAKE_EXPORT_COMPILE_COMMANDS option enabled.

The script’s command-line syntax is designed to mimic Clang’s LibTooling, but they are otherwise unrelated. It can be used like this:

or, on Windows systems:

Unless a source filename is provided, all files in the project will be analyzed.

See iwyu_tool.py —help for more options.

We also include a tool that automatically fixes up your source files based on the IWYU recommendations. This is also alpha-quality software! Here’s how to use it (requires python):

If you don’t like the way fix_includes.py munges your #include lines, you can control its behavior via flags. fix_includes.py —help will give a full list, but these are some common ones:

  • -b : Put blank lines between system and Google includes
  • —nocomments : Don’t add the ‘why’ comments next to includes

How to Correct IWYU Mistakes

  • If fix_includes.py has removed an #include you actually need, add it back in with the comment ‘ // IWYU pragma: keep ‘ at the end of the #include line. Note that the comment is case-sensitive.
  • If fix_includes.py has added an #include you don’t need, just take it out. We hope to come up with a more permanent way of fixing later.
  • If fix_includes.py has wrongly added or removed a forward-declare, just fix it up manually.
  • If fix_includes.py has suggested a private header file (such as ) instead of the proper public header file ( ), you can fix this by inserting a specially crafted comment near top of the private file (assuming you can write to it): ‘ // IWYU pragma: private, include «the/public/file.h» ‘.

Current IWYU pragmas are described in IWYUPragmas.

Include what you use windows

Why Include What You Use Is Difficult

This section is informational, for folks who are wondering why include-what-you-use requires so much code and yet still has so many errors.

Include-what-you-use has the most problems with templates and macros. If your code doesn’t use either, IWYU will probably do great. And, you’re probably not actually programming in C++.

Use Versus Forward Declare

Include-what-you-use has to be able to tell when a symbol is being used in a way that you can forward-declare it. Otherwise, if you wrote

IWYU would tell you to #include «myclass.h» , when perhaps the whole reason you’re using a pointer here is to avoid the need for that #include .

In the above case, it’s pretty easy for IWYU to tell that we can safely forward-declare MyClass . But now consider

To distinguish these, clang has to instantiate the vector and scoped_ptr template classes, including analyzing all member variables and the bodies of the constructor and destructor (and recursively for superclasses).

But that’s not enough: when instantiating the templates, we need to keep track of which symbols come from template arguments and which don’t. For instance, suppose you call MyFunc () , where MyFunc looks like this:

In this case, the caller of MyFunc is not using the full type of MyClass , because the template parameter is only used as a pointer. On the other hand, the file that defines MyFunc is using the full type information for MyClass . The end result is that the caller can forward-declare MyClass , but the file defining MyFunc has to #include «myclass.h» .

Handling Template Arguments

Even figuring out what types are ‘used’ with a template can be difficult. Consider the following two declarations:

These both have default template arguments, so are parsed like

What symbols should we say are used? If we say alloc is used when you declare a vector, then every file that #includes will also need to #include .

So it’s tempting to just ignore default template arguments. But that’s not right either. What if hash is defined in some local myhash.h file (as hash often is)? Then we want to make sure IWYU says to #include «myhash.h» when you create the hash_set (otherwise the code won’t compile). That requires paying attention to the default template argument. Figuring out how to handle default template arguments can get very complex.

Even normal template arguments can be confusing. Consider this templated function:

and you call MyFunc(FunctionReturningAFunctionPointer()) . What types are being used where, in this case?

Who is Responsible for Dependent Template Types?

If you say vector v; , it’s clear that you, and not vector.h are responsible for the use of MyClass , even though all the functions that use MyClass are defined in vector.h . (OK, technically, these functions are not «defined» in a particular location, they’re instantiated from template methods written in vector.h , but for us it works out the same.)

When you say hash_map h; , you are likewise responsible for MyClass (and int ), but are you responsible for pair ? That is the type that hash_map uses to store your entries internally, and it depends on one of your template arguments, but even so it shouldn’t be your responsibility — it’s an implementation detail of hash_map. Of course, if you say hash_map

, int> , then you are responsible for the use of pair . Distinguishing these two cases from each other, and from the vector case, can be difficult.

Now suppose there’s a template function like this:

If you call MyFunc(some_char_star) , which of these symbols are you responsible for, and which is the author of MyFunc responsible for: strcat , strchr , operator ?

strcat is a normal function, and the author of MyFunc is responsible for its use. This is an easy case.

In C++, strchr is a templatized function (different impls for char* and const char* ). Which version is called depends on the template argument. So, naively, we’d conclude that the caller is responsible for the use of strchr . However, that’s ridiculous; we don’t want caller of MyFunc to have to #include just to call MyFunc . We have special code that (usually) handles this kind of case.

operator is also a templated function, but it’s one that may be defined in lots of different files. It would be ridiculous in its own way if MyFunc was responsible for including every file that defines operator for all T . So, unlike the two cases above, the caller is the one responsible for the use of operator , and will have to #include the file that defines it. It’s counter-intuitive, perhaps, but the alternatives are all worse.

As you can imagine, distinguishing all these cases is extremely difficult. To get it exactly right would require re-implementing C++’s (byzantine) lookup rules, which we have not yet tackled.

Template Template Types

Let’s say you have a function

And you call MyFunc . Who is responsible for the ‘use’ of hash , and thus needs to #include «myhash.h» ? I think it has to be the caller, even if the caller never uses the string type in its file at all. This is rather counter-intuitive. Luckily, it’s also rather rare.

Suppose you #include a file «foo.h» that has typedef hash_map MyMap; . And you have this code:

Who, if anyone, is using the symbol hash_map ::iterator ? If we say you, as the author of the for-loop, are the user, then you must #include , which undoubtedly goes against the goal of the typedef (you shouldn’t even have to know you’re using a hash_map). So we want to say the author of the typedef is responsible for the use. But how could the author of the typedef know that you were going to use MyMap::iterator ? It can’t predict that. That means it has to be responsible for every possible use of the typedef type. This can be complicated to figure out. It requires instantiating all methods of the underlying type, some of which might not even be legal C++ (if, say, the class uses SFINAE).

Worse, when the language auto-derives template types, it loses typedef information. Suppose you wrote this:

The compiler sees this as syntactic sugar for find , equal_to , alloc >(m.begin(), m.end(), some_foo);

Not only is the template argument hash_map instead of MyMap , it includes all the default template arguments, with no indication they’re default arguments. All the tricks we used above to intelligently ignore default template arguments are worthless here. We have to jump through lots of hoops so this code doesn’t require you to #include not only , but and as well.

It’s no surprise macros cause a huge problem for include-what-you-use. Basically, all the problems of templates also apply to macros, but worse: with templates you can analyze the uninstantiated template, but with macros, you can’t analyze the uninstantiated macro — it likely doesn’t even parse cleanly in isolation. As a result, we have very few tools to distinguish when the author of a macro is responsible for a symbol used in a macro, and when the caller of the macro is responsible.

Includes with Side Effects

While not a major problem, this indicates the myriad «gotchas» that exist around include-what-you-use: removing an #include and replacing it with a forward-declare may be dangerous even if no symbols are fully used from the #include . Consider the following code:

If IWYU just blindly replaces the #include with a forward declare such as namespace ns < class Foo; >, the code will break because of the lost using declaration. Include-what-you-use has to watch out for this case.

Another case is a header file like this:

We might think we can remove an #include of foo.h and replace it by #include «module_writer.h» , but that is likely to break the build if module_writer.h requires MODULE_NAME be defined. Since my file doesn’t participate in this dependency at all, it won’t even notice it. IWYU needs to keep track of dependencies between files it’s not even trying to analyze!

Suppose you write vector v; . You are using vector, and thus have to #include . Even this seemingly easy case is difficult, because vector isn’t actually defined in ; it’s defined in . The C++ standard library has hundreds of private files that users are not supposed to #include directly. Third party libraries have hundreds more. There’s no general way to distinguish private from public headers; we have to manually construct the proper mapping.

In the future, we hope to provide a way for users to annotate if a file is public or private, either a comment or a #pragma . For now, we hard-code it in the IWYU tool.

The mappings themselves can be ambiguous. For instance, NULL is provided by many files, including stddef.h , stdlib.h , and more. If you use NULL , what header file should IWYU suggest? We have rules to try to minimize the number of #includes you have to add; it can get rather involved.

Conditional #includes are a problem for IWYU when the condition is false:

If you’re running IWYU without that preprocessor definition set, it has no way of telling if verbose_logger.h is a necessary #include or not.

Placing New Includes and Forward-Declares

Читайте также:  Если украли ноутбук windows
Оцените статью