summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBill Hoffman <bill.hoffman@kitware.com>2015-05-14 17:31:32 (GMT)
committerBrad King <brad.king@kitware.com>2015-05-19 17:16:29 (GMT)
commit67fa3da9e84888029d128280f35a8e7b3d208377 (patch)
treeaddcaa89ea96957b1c298568b758fb47aa74317b
parenta390de65e09e3ebc496fc14d40848ea4940cc9b0 (diff)
downloadCMake-67fa3da9e84888029d128280f35a8e7b3d208377.zip
CMake-67fa3da9e84888029d128280f35a8e7b3d208377.tar.gz
CMake-67fa3da9e84888029d128280f35a8e7b3d208377.tar.bz2
cmake: Add internal -E mode to run include-what-you-use with the compiler
Add an internal "cmake -E __run_iwyu" mode to wrap the compiler call. Run a given include-what-you-use command line with the compiler options and report a warning if it finds anything. Then run the real compiler. Co-Author: Brad King <brad.king@kitware.com>
-rw-r--r--Source/cmcmd.cxx82
-rw-r--r--Tests/RunCMake/CommandLine/E___run_iwyu-bad-iwyu-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E___run_iwyu-bad-iwyu-stderr.txt2
-rw-r--r--Tests/RunCMake/CommandLine/E___run_iwyu-no----result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E___run_iwyu-no----stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E___run_iwyu-no-cc-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E___run_iwyu-no-cc-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E___run_iwyu-no-iwyu-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E___run_iwyu-no-iwyu-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/RunCMakeTest.cmake5
10 files changed, 96 insertions, 0 deletions
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 12bb8ee..50254ff 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -211,6 +211,88 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
return 0;
}
+ // run include what you use command and then run the compile
+ // command. This is an internal undocumented option and should
+ // only be used by CMake itself when running iwyu.
+ else if (args[1] == "__run_iwyu")
+ {
+ if (args.size() < 3)
+ {
+ std::cerr << "__run_iwyu Usage: -E __run_iwyu [--iwyu=/path/iwyu]"
+ " -- compile command\n";
+ return 1;
+ }
+ bool doing_options = true;
+ std::vector<std::string> orig_cmd;
+ std::string iwyu;
+ for (std::string::size_type cc = 2; cc < args.size(); cc ++)
+ {
+ std::string const& arg = args[cc];
+ if (arg == "--")
+ {
+ doing_options = false;
+ }
+ else if (doing_options && cmHasLiteralPrefix(arg, "--iwyu="))
+ {
+ iwyu = arg.substr(7);
+ }
+ else if (doing_options)
+ {
+ std::cerr << "__run_iwyu given unknown argument: " << arg << "\n";
+ return 1;
+ }
+ else
+ {
+ orig_cmd.push_back(arg);
+ }
+ }
+ if (iwyu.empty())
+ {
+ std::cerr << "__run_iwyu missing --iwyu=\n";
+ return 1;
+ }
+ if (orig_cmd.empty())
+ {
+ std::cerr << "__run_iwyu missing compile command after --\n";
+ return 1;
+ }
+
+ // Construct the iwyu command line by taking what was given
+ // and adding all the arguments we give to the compiler.
+ std::vector<std::string> iwyu_cmd;
+ cmSystemTools::ExpandListArgument(iwyu, iwyu_cmd, true);
+ iwyu_cmd.insert(iwyu_cmd.end(), orig_cmd.begin()+1, orig_cmd.end());
+
+ // Run the iwyu command line. Capture its stderr and hide its stdout.
+ int ret = 0;
+ std::string stdErr;
+ if(!cmSystemTools::RunSingleCommand(iwyu_cmd, 0, &stdErr, &ret,
+ 0, cmSystemTools::OUTPUT_NONE))
+ {
+ std::cerr << "Error running '" << iwyu_cmd[0] << "': "
+ << stdErr << "\n";
+ return 1;
+ }
+
+ // Warn if iwyu reported anything.
+ if(stdErr.find("should remove these lines:") != stdErr.npos
+ || stdErr.find("should add these lines:") != stdErr.npos)
+ {
+ std::cerr << "Warning: include-what-you-use reported diagnostics:\n"
+ << stdErr << "\n";
+ }
+
+ // Now run the real compiler command and return its result value.
+ if(!cmSystemTools::RunSingleCommand(orig_cmd, 0, &stdErr, &ret, 0,
+ cmSystemTools::OUTPUT_PASSTHROUGH))
+ {
+ std::cerr << "Error running '" << orig_cmd[0] << "': "
+ << stdErr << "\n";
+ return 1;
+ }
+ return ret;
+ }
+
// Echo string
else if (args[1] == "echo" )
{
diff --git a/Tests/RunCMake/CommandLine/E___run_iwyu-bad-iwyu-result.txt b/Tests/RunCMake/CommandLine/E___run_iwyu-bad-iwyu-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E___run_iwyu-bad-iwyu-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E___run_iwyu-bad-iwyu-stderr.txt b/Tests/RunCMake/CommandLine/E___run_iwyu-bad-iwyu-stderr.txt
new file mode 100644
index 0000000..338f7c4
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E___run_iwyu-bad-iwyu-stderr.txt
@@ -0,0 +1,2 @@
+^Error running 'iwyu-does-not-exist': [^
+]+$
diff --git a/Tests/RunCMake/CommandLine/E___run_iwyu-no----result.txt b/Tests/RunCMake/CommandLine/E___run_iwyu-no----result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E___run_iwyu-no----result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E___run_iwyu-no----stderr.txt b/Tests/RunCMake/CommandLine/E___run_iwyu-no----stderr.txt
new file mode 100644
index 0000000..c251adf
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E___run_iwyu-no----stderr.txt
@@ -0,0 +1 @@
+^__run_iwyu given unknown argument: command-does-not-exist$
diff --git a/Tests/RunCMake/CommandLine/E___run_iwyu-no-cc-result.txt b/Tests/RunCMake/CommandLine/E___run_iwyu-no-cc-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E___run_iwyu-no-cc-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E___run_iwyu-no-cc-stderr.txt b/Tests/RunCMake/CommandLine/E___run_iwyu-no-cc-stderr.txt
new file mode 100644
index 0000000..1998abb
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E___run_iwyu-no-cc-stderr.txt
@@ -0,0 +1 @@
+^__run_iwyu missing compile command after --$
diff --git a/Tests/RunCMake/CommandLine/E___run_iwyu-no-iwyu-result.txt b/Tests/RunCMake/CommandLine/E___run_iwyu-no-iwyu-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E___run_iwyu-no-iwyu-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E___run_iwyu-no-iwyu-stderr.txt b/Tests/RunCMake/CommandLine/E___run_iwyu-no-iwyu-stderr.txt
new file mode 100644
index 0000000..0024097
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E___run_iwyu-no-iwyu-stderr.txt
@@ -0,0 +1 @@
+^__run_iwyu missing --iwyu=$
diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
index 644e5ae..69beed9 100644
--- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -12,6 +12,11 @@ run_cmake_command(E_echo_append ${CMAKE_COMMAND} -E echo_append)
run_cmake_command(E_rename-no-arg ${CMAKE_COMMAND} -E rename)
run_cmake_command(E_touch_nocreate-no-arg ${CMAKE_COMMAND} -E touch_nocreate)
+run_cmake_command(E___run_iwyu-no-iwyu ${CMAKE_COMMAND} -E __run_iwyu -- command-does-not-exist)
+run_cmake_command(E___run_iwyu-bad-iwyu ${CMAKE_COMMAND} -E __run_iwyu --iwyu=iwyu-does-not-exist -- command-does-not-exist)
+run_cmake_command(E___run_iwyu-no--- ${CMAKE_COMMAND} -E __run_iwyu --iwyu=iwyu-does-not-exist command-does-not-exist)
+run_cmake_command(E___run_iwyu-no-cc ${CMAKE_COMMAND} -E __run_iwyu --iwyu=iwyu-does-not-exist --)
+
run_cmake_command(G_no-arg ${CMAKE_COMMAND} -G)
run_cmake_command(G_bad-arg ${CMAKE_COMMAND} -G NoSuchGenerator)
run_cmake_command(P_no-arg ${CMAKE_COMMAND} -P)