I have problem running tool fix_includes.py that automatically fixes up source files based on the include-what-you-use recommendations.
I have configured IWYU tool accordingly to the documentation:
downloaded IWYU version matching my Clang version
located it following the issue 100 So IWYU is located in /usr/bin/iwyu/include-what-you-use
and clang in
/usr/lib/llvm-10/lib/clang/10.0.0
in /usr/bin/iwyu/
built it with following commands:
mkdir build && cd build
cmake -G "Unix Makefiles" -DCMAKE_PREFIX_PATH=/usr/lib/llvm 10/lib/clang/10.0.0
make
sudo make install
/home/kpolok/worksapce/projects/using_iwyu_proj
:cmake_minimum_required(VERSION 3.16.3)
set(CMAKE_CXX_STANDARD 17)
project(using_mocks_with_di_proj LANGUAGES CXX)
option(USE_IWYU "Enable include-what-you-use reports during build" ON)
if(USE_IWYU)
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()
message("Found IWYU ${IWYU_PATH}")
set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE ${IWYU_PATH})
set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE ${IWYU_PATH})
endif()
set(PROJ_DIR ${PROJECT_SOURCE_DIR})
add_subdirectory(app)
add_subdirectory(src)
And it produces report while building:
[ 20%] Building CXX object src/Car/CMakeFiles/Car.dir/src/Car.cpp.o
Warning: include-what-you-use reported diagnostics:
/home/kpolok/worksapce/projects/using_iwyu_proj/src/Car/inc/Car.h should add these lines:
class MotorIf;
/home/kpolok/worksapce/projects/using_iwyu_proj/src/Car/inc/Car.h should remove these lines:
- #include "MotorIf.h" // lines 2-2
The full include-list for /home/kpolok/worksapce/projects/using_iwyu_proj/src/Car/inc/Car.h:
class MotorIf;
---
/home/kpolok/worksapce/projects/using_iwyu_proj/src/Car/src/Car.cpp should add these lines:
#include "inc/MotorIf.h" // for MotorIf
/home/kpolok/worksapce/projects/using_iwyu_proj/src/Car/src/Car.cpp should remove these lines:
The full include-list for /home/kpolok/worksapce/projects/using_iwyu_proj/src/Car/src/Car.cpp:
#include "inc/Car.h"
#include <iostream> // for basic_ostream::operator<<, operator<<, endl
#include "inc/MotorIf.h" // for MotorIf
---
[ 40%] Building CXX object src/Car/CMakeFiles/Car.dir/src/CarMotor.cpp.o
[ 60%] Linking CXX static library libCar.a
make[3]: Leaving directory '/home/kpolok/worksapce/projects/using_iwyu_proj/build'
[ 60%] Built target Car
make[3]: Entering directory '/home/kpolok/worksapce/projects/using_iwyu_proj/build'
Scanning dependencies of target Executable
make[3]: Leaving directory '/home/kpolok/worksapce/projects/using_iwyu_proj/build'
make[3]: Entering directory '/home/kpolok/worksapce/projects/using_iwyu_proj/build'
[ 80%] Building CXX object app/CMakeFiles/Executable.dir/main.cpp.o
Warning: include-what-you-use reported diagnostics:
/home/kpolok/worksapce/projects/using_iwyu_proj/app/main.cpp should add these lines:
/home/kpolok/worksapce/projects/using_iwyu_proj/app/main.cpp should remove these lines:
- #include <vector> // lines 2-2
The full include-list for /home/kpolok/worksapce/projects/using_iwyu_proj/app/main.cpp:
#include <iostream> // for operator<<, endl, basic_ostream, cout, ost...
#include "inc/Car.h" // for Car
#include "inc/CarMotor.h" // for CarMotor
That part went pretty smooth, but now i want to use the script fix_includes.py. So I once more followed the documentation and invoked this commands in my project root /home/kpolok/worksapce/projects/using_iwyu_proj
:
make -k CXX=/usr/bin/iwyu/build/bin/include-what-you-use CXXFLAGS="-Xiwyu --error_always" 2> ./err.txt
python3 /usr/bin/iwyu/include-what-you-use/fix_includes.py < ./err.txt
But after first command I get:
rm -rf build
mkdir build
cmake -S . -B ./build/
-- The CXX compiler identification is unknown
-- Check for working CXX compiler: /usr/bin/iwyu/build/bin/include-what-you-use
-- Check for working CXX compiler: /usr/bin/iwyu/build/bin/include-what-you-use -- broken
CMake Error at /usr/share/cmake-3.16/Modules/CMakeTestCXXCompiler.cmake:53 (message):
The C++ compiler
"/usr/bin/iwyu/build/bin/include-what-you-use"
is not able to compile a simple test program.
It fails with the following output:
Change Dir: /home/kpolok/worksapce/projects/using_iwyu_proj/build/CMakeFiles/CMakeTmp
Run Build Command(s):/usr/bin/make cmTC_d324c/fast && make[1]: Entering directory '/home/kpolok/worksapce/projects/using_iwyu_proj/build/CMakeFiles/CMakeTmp'
/usr/bin/make -f CMakeFiles/cmTC_d324c.dir/build.make CMakeFiles/cmTC_d324c.dir/build
make[2]: Entering directory '/home/kpolok/worksapce/projects/using_iwyu_proj/build/CMakeFiles/CMakeTmp'
Building CXX object CMakeFiles/cmTC_d324c.dir/testCXXCompiler.cxx.o
...
CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
CMakeLists.txt:3 (project)
By the way, the Makefile in my project root looks like this:
all: prepare configure build_project
prepare:
rm -rf build
mkdir build
configure:
cmake -S . -B ./build/
build_project:
cmake --build ./build/
I'm quite new to cmake/clang stuff so I don't know what I'm doing wrong. I suppose that those commands should be invoked somewhere else?But exactly where? Maybe something else is off?
Btw IMO the instructions I found in IWYU documentations aren't really clear.
As @Friedrich mentioned, I was confusing make with cmake (in fact, I was blindly following the IWYU documentation, without trying to understand, what I was actually doing). The solution to the problem is easy. So, during the build process, CMake already generates the report required by the fix_includes.py script by utilizing the CMAKE_CXX_INCLUDE_WHAT_YOU_USE variable.
option(USE_IWYU "Enable include-what-you-use reports during build" ON)
if(USE_IWYU)
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()
message("Found IWYU ${IWYU_PATH}")
set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE ${IWYU_PATH})
endif()
I just needed to separate IWYU report from the build logs part:
if(USE_IWYU)
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()
message("Found IWYU ${IWYU_PATH}")
set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE ${IWYU_PATH} CXXFLAGS="-Xiwyu --error_always")
endif()
Thanks to --error_always, IWYU report parts are treated as errors. Now I need to collect this report e.g. by redirecting it to separate file:
build_project:
cmake --build ./build/ 2> report.txt
This is the part of my Makefile that triggers cmake build process. All that's left is to run the fix_includes.py:
using_iwyu_proj$ python3 /usr/bin/iwyu/include-what-you-use/fix_includes.py < report.txt
>>> Fixing #includes in '/home/kpolok/worksapce/projects/using_iwyu_proj/src/Car/inc/Car.h'
>>> Fixing #includes in '/home/kpolok/worksapce/projects/using_iwyu_proj/src/Car/src/Car.cpp'
>>> Fixing #includes in '/home/kpolok/worksapce/projects/using_iwyu_proj/app/main.cpp'
IWYU edited 3 files on your behalf.