The tool include-what-you-use
can be used to detect unneeded headers. I am using CMake for my C++ software project. How can I instruct CMake to run include-what-you-use automatically on the source files of my software project?
CMake 3.3 introduced the new target property CXX_INCLUDE_WHAT_YOU_USE that can be set to the path of the program include-what-you-use
. For instance this CMakeLists.txt
cmake_minimum_required(VERSION 3.3 FATAL_ERROR)
add_executable(hello main.cc)
find_program(iwyu_path NAMES include-what-you-use iwyu)
if(NOT iwyu_path)
message(FATAL_ERROR "Could not find the program include-what-you-use")
endif()
set_property(TARGET hello PROPERTY CXX_INCLUDE_WHAT_YOU_USE ${iwyu_path})
is able to build the file main.cc
#include <iostream>
#include <vector>
int main() {
std::cout << "Hello World!" << std::endl;
return 0;
}
and at the same time have include-what-you-use
give out a warning that
the included header vector is not needed.
user@ubuntu:/tmp$ ls ~/hello
CMakeLists.txt main.cc
user@ubuntu:/tmp$ mkdir /tmp/build
user@ubuntu:/tmp$ cd /tmp/build
user@ubuntu:/tmp/build$ ~/cmake-3.3.0-rc2-Linux-x86_64/bin/cmake ~/hello
-- The C compiler identification is GNU 4.9.2
-- The CXX compiler identification is GNU 4.9.2
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/build
user@ubuntu:/tmp/build$ make
Scanning dependencies of target hello
[ 50%] Building CXX object CMakeFiles/hello.dir/main.cc.o
Warning: include-what-you-use reported diagnostics:
/home/user/hello/main.cc should add these lines:
/home/user/hello/main.cc should remove these lines:
- #include <vector> // lines 2-2
The full include-list for /home/user/hello/main.cc:
#include <iostream> // for operator<<, basic_ostream, cout, endl, ostream
---
[100%] Linking CXX executable hello
[100%] Built target hello
user@ubuntu:/tmp/build$ ./hello
Hello World!
user@ubuntu:/tmp/build$
If you want to pass custom options to include-what-you-use
, like for instance --mapping_file
you can do it via
set(iwyu_path_and_options
${iwyu_path}
-Xiwyu
--mapping_file=${my_mapping})
set_property(TARGET hello
PROPERTY CXX_INCLUDE_WHAT_YOU_USE ${iwyu_path_and_options})
CMake 3.18 introduced the new option REQUIRED
to the
find_program()
, so it should be possible to remove the if statement if(NOT iwyu_path)
above.