cmake_minimum_required(VERSION 3.3 FATAL_ERROR)
add_executable(hello main.cc)
find_program(iwyu_path NAMES include-what-you-use iwyu REQUIRED)
# If using CGAL<3.18, you remove REQUIRED and use
# 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})
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$
# 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()
#.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 <wolters.fl@gmail.com>
#===============================================================================
# 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()
cmake -DBUILD_IWYU=ON <path-to-source>
cmake --build . --target all
输出应如下所示:
-- 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
4条答案
按热度按时间uxh89sit1#
CMake 3.3引入了新的目标属性CXX_INCLUDE_WHAT_YOU_USE,可以将其设置为程序
include-what-you-use
的路径。能够构建文件 * main.cc *
并且同时使
include-what-you-use
给予不需要所包括的报头 * 向量 * 的警告。如果您想将自定义选项传递给
include-what-you-use
,例如--mapping_file
,您可以通过cngwdvgl2#
如果你没有访问CMake 3.3的权限,
include-what-you-use
附带了一个名为iwyu_tool.py的Python工具,它可以做你想做的事情。它通过解析JSON编译数据库来工作,这很容易用CMake生成(见下文)。
手动运行工具
假设你已经为你的项目准备了一个CMake构建目录,你首先需要告诉CMake生成编译数据库:
这将生成一个文件
compile_commands.json
,其中包含项目中每个目标文件的编译器调用。您不需要重新构建项目。现在,您可以通过在构建目录中运行Python工具来在项目上运行
include-what-you-use
:为CMake项目添加自定义目标
下面的代码片段可用于向CMake项目添加
iwyu
目标。注解
include-what-you-use
二进制文件需要在您的路径中,以使上述任何文件正常工作。默认情况下,
iwyu_tool.py
是单线程的,这对于大型项目来说可能会很慢。您可以使用--jobs
参数来增加将并行处理的源文件的数量。zujrkrfu3#
您也可以通过设置CMake变量在CMake脚本外部全局启用它:
然后它将在每个CXX目标上调用它。
n3h0vuf24#
为了创建一个可重用的解决方案,我扩展了Alastair Harrison的源代码。我提出了以下应该适用于所有CMake 版本的解决方案:
文件
iwyu.cmake
:文件
CMakeLists.txt
:如下调用 CMake,在调用
all
目标时运行 include-what-you-use:输出应如下所示: