c++ - microsoft - visual studio installer
¿Cómo usar la herramienta include-what-you-use junto con CMake para detectar encabezados no utilizados? (4)
La herramienta include-what-you-use
se puede usar para detectar encabezados innecesarios. Estoy usando CMake para mi proyecto de software C ++. ¿Cómo puedo instruir a CMake para que ejecute include-what-you-use automáticamente en los archivos fuente de mi proyecto de software?
Amplié el código fuente de Alastair Harrison para crear una solución reutilizable. He encontrado lo siguiente que debería funcionar con todas las versiones de CMake :
Archivo iwyu.cmake
:
#.rst:
# include-what-you-use (iwyu)
# ----------------------------
#
# Allows to run the static code analyzer `include-what-you-use (iwyu)
# <http://include-what-you-use.org>`_ as a custom target with the build system
# `CMake <http://cmake.org>`_.
#
# .. topic:: Dependencies
#
# This module requires the following *CMake* modules:
#
# * ``FindPythonInterp``
#
# .. topic:: Contributors
#
# * Florian Wolters <[email protected]>
#===============================================================================
# Copyright 2015 Florian Wolters
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#===============================================================================
# ------------------------------------------------------------------------------
# Include guard for this file.
# ------------------------------------------------------------------------------
if(iwyu_included)
return()
endif()
set(iwyu_included TRUE)
option(BUILD_IWYU
"Run the include-what-you-use static analyzer on the source code of the project."
OFF)
function(iwyu_enable)
set(iwyu_EXECUTABLE_NAME include-what-you-use)
find_program(iwyu_EXECUTABLE ${iwyu_EXECUTABLE_NAME})
if(iwyu_EXECUTABLE)
# This is not exactly the same behavior as with CMake v3.3, since here all
# compiled targets are analyzed.
set(iwyu_tool_EXECUTABLE_NAME iwyu_tool.py)
find_package(PythonInterp)
find_program(iwyu_tool_EXECUTABLE ${iwyu_tool_EXECUTABLE_NAME})
if(PYTHONINTERP_FOUND AND iwyu_tool_EXECUTABLE)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON PARENT_SCOPE)
add_custom_target(iwyu
ALL
COMMAND "${PYTHON_EXECUTABLE}" "${iwyu_tool_EXECUTABLE}" -p "${CMAKE_BINARY_DIR}"
COMMENT "Running the ${iwyu_tool_EXECUTABLE_NAME} compilation database driver"
VERBATIM)
else()
message(STATUS
"Unable to find the Python interpreter and/or the ${iwyu_tool_EXECUTABLE_NAME} script")
endif()
else()
message(STATUS "Unable to find the ${iwyu_EXECUTABLE_NAME} executable")
endif()
endfunction()
Archivo CMakeLists.txt
:
cmake_minimum_required(VERSION 3.0)
include(iwyu.cmake)
project(hello_world)
add_executable(${PROJECT_NAME} main.cc)
if(BUILD_IWYU)
iwyu_enable()
endif()
Invoque CMake de la siguiente manera para ejecutar include-what-you-use cuando se invoque all
destino:
cmake -DBUILD_IWYU=ON <path-to-source>
cmake --build . --target all
El resultado debería ser el siguiente:
-- Configuring done
-- Generating done
-- Build files have been written to: /home/wolters/workspace/include-what-you-use_example/build
[ 66%] Built target hello_world
[100%] Running the iwyu_tool.py compilation database driver
/home/wolters/workspace/include-what-you-use_example/develop/main.cc should add these lines:
/home/wolters/workspace/include-what-you-use_example/develop/main.cc should remove these lines:
- #include <vector> // lines 1-1
The full include-list for /home/wolters/workspace/include-what-you-use_example/develop/main.cc:
#include <iostream> // for operator<<, basic_ostream, cout, endl, ostream
---
[100%] Built target iwyu
Editar 2015-08-19: El enfoque con la propiedad CMake <LANG>_INCLUDE_WHAT_YOU_USE
no funcionó para mí con CMake versión 3.3.1. Por lo tanto, actualicé la solución.
Editar 30-09-2015: La salida fue incorrecta, ya que mi instalación de inclusión-lo-que-uso estaba rota. Los archivos include-what-you-use
y iwyu_tool.py
deben estar en el mismo directorio que clang
, clang++
, etc.
Si no tiene acceso a CMake 3.3, include-what-you-use
viene con una herramienta python llamada iwyu_tool.py que puede hacer lo que quiera.
Funciona mediante el análisis de una base de datos de compilación de clang, que se produce fácilmente con CMake.
Ejecutando la herramienta manualmente
Suponiendo que ya tiene un directorio de compilación de CMake para su proyecto, primero necesita decirle a CMake que produzca la base de datos de compilación:
$ cd build
$ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .
Esto genera un archivo, compile_commands.json
contiene invocaciones de compilador para cada archivo de objeto en su proyecto. No necesita reconstruir el proyecto.
Ahora puede ejecutar include-what-you-use
en su proyecto ejecutando la herramienta python en su directorio de compilación:
$ python /path/to/iwyu_tool.py -p .
Agregar un destino personalizado a su proyecto cmake
El siguiente fragmento se puede usar para agregar un objetivo iwyu
a un proyecto de cmake.
# Generate clang compilation database
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
find_package(PythonInterp)
find_program(iwyu_tool_path NAMES iwyu_tool.py)
if (iwyu_tool_path AND PYTHONINTERP_FOUND)
add_custom_target(iwyu
ALL # Remove ALL if you don''t iwyu to be run by default.
COMMAND "${PYTHON_EXECUTABLE}" "${iwyu_tool_path}" -p "${CMAKE_BINARY_DIR}"
COMMENT "Running include-what-you-use tool"
VERBATIM
)
endif()
Notas
El binario include-what-you-use
debe estar en su camino para que cualquiera de los anteriores funcione correctamente.
También puede habilitarlo globalmente fuera del script cmake configurando la variable cmake:
cmake -DCMAKE_CXX_INCLUDE_WHAT_YOU_USE="iwyu" <builddir>
Luego lo llamará a cada objetivo CXX.
CMake 3.3 introdujo la nueva propiedad de destino CXX_INCLUDE_WHAT_YOU_USE que se puede establecer en la ruta del programa include-what-you-use
. Por ejemplo, este 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})
es capaz de construir el archivo main.cc
#include <iostream>
#include <vector>
int main() {
std::cout << "Hello World!" << std::endl;
return 0;
}
y al mismo tiempo, include-what-you-use
da una advertencia de que el vector de cabecera incluido no es necesario.
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$
Si desea pasar opciones personalizadas para include-what-you-use
, como por ejemplo --mapping_file
, puede hacerlo a través de
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})