mirror of
https://github.com/reactos/CMake.git
synced 2024-12-14 07:09:22 +00:00
cmcmd: Restore support for running multiple lint tools
Refactoring in commit v3.10.0-rc1~115^2 (Clean up iwyu code to not be one big if statement, 2017-08-28) incorrectly changed the logic to run only one lint tool at a time. Restore support for running all tools specified on the command-line.
This commit is contained in:
parent
a5197eeac7
commit
992962c76d
120
Source/cmcmd.cxx
120
Source/cmcmd.cxx
@ -33,15 +33,13 @@
|
||||
#include "cmsys/Process.h"
|
||||
#include "cmsys/Terminal.h"
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <memory> // IWYU pragma: keep
|
||||
#include <sstream>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <utility>
|
||||
|
||||
class cmConnection;
|
||||
|
||||
@ -328,35 +326,41 @@ static int HandleCppCheck(const std::string& runCmd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef int (*CoCompileHandler)(const std::string&, const std::string&,
|
||||
const std::vector<std::string>&);
|
||||
|
||||
struct CoCompiler
|
||||
{
|
||||
const char* Option;
|
||||
CoCompileHandler Handler;
|
||||
bool NoOriginalCommand;
|
||||
};
|
||||
|
||||
static CoCompiler CoCompilers[] = { // Table of options and handlers.
|
||||
{ "--cppcheck=", HandleCppCheck, false },
|
||||
{ "--cpplint=", HandleCppLint, false },
|
||||
{ "--iwyu=", HandleIWYU, false },
|
||||
{ "--lwyu=", HandleLWYU, true },
|
||||
{ "--tidy=", HandleTidy, false }
|
||||
};
|
||||
|
||||
struct CoCompileJob
|
||||
{
|
||||
std::string Command;
|
||||
CoCompileHandler Handler;
|
||||
};
|
||||
|
||||
// called when args[0] == "__run_co_compile"
|
||||
int cmcmd::HandleCoCompileCommands(std::vector<std::string>& args)
|
||||
{
|
||||
// initialize a map from command option to handler function
|
||||
std::map<std::string,
|
||||
std::function<int(const std::string&, const std::string&,
|
||||
const std::vector<std::string>&)>>
|
||||
coCompileTypes;
|
||||
auto a1 = std::placeholders::_1;
|
||||
auto a2 = std::placeholders::_2;
|
||||
auto a3 = std::placeholders::_3;
|
||||
// create a map from option to handler function for option
|
||||
// if the option does not call the original command then it will need
|
||||
// to set runOriginalCmd to false later in this function
|
||||
coCompileTypes["--iwyu="] = std::bind(&HandleIWYU, a1, a2, a3);
|
||||
coCompileTypes["--tidy="] = std::bind(&HandleTidy, a1, a2, a3);
|
||||
coCompileTypes["--lwyu="] = std::bind(&HandleLWYU, a1, a2, a3);
|
||||
coCompileTypes["--cpplint="] = std::bind(&HandleCppLint, a1, a2, a3);
|
||||
coCompileTypes["--cppcheck="] = std::bind(&HandleCppCheck, a1, a2, a3);
|
||||
// copy the command options to a vector of strings
|
||||
std::vector<std::string> commandOptions;
|
||||
commandOptions.reserve(coCompileTypes.size());
|
||||
for (const auto& i : coCompileTypes) {
|
||||
commandOptions.push_back(i.first);
|
||||
}
|
||||
std::vector<CoCompileJob> jobs;
|
||||
std::string sourceFile; // store --source=
|
||||
|
||||
// Default is to run the original command found after -- if the option
|
||||
// does not need to do that, it should be specified here, currently only
|
||||
// lwyu does that.
|
||||
bool runOriginalCmd = true;
|
||||
|
||||
std::string runCmd; // command to be run from --thing=command
|
||||
std::string sourceFile; // store --source=
|
||||
std::string commandFound; // the command that was in the args list
|
||||
std::vector<std::string> orig_cmd;
|
||||
bool doing_options = true;
|
||||
for (std::string::size_type i = 2; i < args.size(); ++i) {
|
||||
@ -367,20 +371,25 @@ int cmcmd::HandleCoCompileCommands(std::vector<std::string>& args)
|
||||
doing_options = false;
|
||||
} else if (doing_options) {
|
||||
bool optionFound = false;
|
||||
// check arg against all the commandOptions
|
||||
for (auto const& command : commandOptions) {
|
||||
if (arg.compare(0, command.size(), command) == 0) {
|
||||
for (CoCompiler const* cc = cmArrayBegin(CoCompilers);
|
||||
cc != cmArrayEnd(CoCompilers); ++cc) {
|
||||
size_t optionLen = strlen(cc->Option);
|
||||
if (arg.compare(0, optionLen, cc->Option) == 0) {
|
||||
optionFound = true;
|
||||
runCmd = arg.substr(command.size());
|
||||
commandFound = command;
|
||||
CoCompileJob job;
|
||||
job.Command = arg.substr(optionLen);
|
||||
job.Handler = cc->Handler;
|
||||
jobs.push_back(std::move(job));
|
||||
if (cc->NoOriginalCommand) {
|
||||
runOriginalCmd = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// check arg with --source=
|
||||
if (cmHasLiteralPrefix(arg, "--source=")) {
|
||||
sourceFile = arg.substr(9);
|
||||
optionFound = true;
|
||||
}
|
||||
// if it was not a commandOptions or --source then error
|
||||
// if it was not a co-compiler or --source then error
|
||||
if (!optionFound) {
|
||||
std::cerr << "__run_co_compile given unknown argument: " << arg
|
||||
<< "\n";
|
||||
@ -390,39 +399,40 @@ int cmcmd::HandleCoCompileCommands(std::vector<std::string>& args)
|
||||
orig_cmd.push_back(arg);
|
||||
}
|
||||
}
|
||||
if (commandFound.empty()) {
|
||||
std::cerr << "__run_co_compile missing command to run. Looking for one of "
|
||||
"the following:\n";
|
||||
for (const auto& i : commandOptions) {
|
||||
std::cerr << i << "\n";
|
||||
if (jobs.empty()) {
|
||||
std::cerr << "__run_co_compile missing command to run. "
|
||||
"Looking for one or more of the following:\n";
|
||||
for (CoCompiler const* cc = cmArrayBegin(CoCompilers);
|
||||
cc != cmArrayEnd(CoCompilers); ++cc) {
|
||||
std::cerr << cc->Option << "\n";
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
// Default is to run the original command found after -- if the option
|
||||
// does not need to do that, it should be specified here, currently only
|
||||
// lwyu does that.
|
||||
bool runOriginalCmd = true;
|
||||
if (commandFound == "--lwyu=") {
|
||||
runOriginalCmd = false;
|
||||
}
|
||||
|
||||
if (runOriginalCmd && orig_cmd.empty()) {
|
||||
std::cerr << "__run_co_compile missing compile command after --\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// call the command handler here
|
||||
int ret = coCompileTypes[commandFound](runCmd, sourceFile, orig_cmd);
|
||||
// if the command returns non-zero then return and fail.
|
||||
// for commands that do not want to break the build, they should return
|
||||
// 0 no matter what.
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
for (CoCompileJob const& job : jobs) {
|
||||
// call the command handler here
|
||||
int ret = job.Handler(job.Command, sourceFile, orig_cmd);
|
||||
|
||||
// if the command returns non-zero then return and fail.
|
||||
// for commands that do not want to break the build, they should return
|
||||
// 0 no matter what.
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
// if there is no original command to run return now
|
||||
if (!runOriginalCmd) {
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Now run the real compiler command and return its result value
|
||||
int ret;
|
||||
if (!cmSystemTools::RunSingleCommand(orig_cmd, nullptr, nullptr, &ret,
|
||||
nullptr,
|
||||
cmSystemTools::OUTPUT_PASSTHROUGH)) {
|
||||
|
@ -370,6 +370,12 @@ if("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
|
||||
add_RunCMake_test(IncludeWhatYouUse -DPSEUDO_IWYU=$<TARGET_FILE:pseudo_iwyu>)
|
||||
add_RunCMake_test(Cpplint -DPSEUDO_CPPLINT=$<TARGET_FILE:pseudo_cpplint>)
|
||||
add_RunCMake_test(Cppcheck -DPSEUDO_CPPCHECK=$<TARGET_FILE:pseudo_cppcheck>)
|
||||
add_RunCMake_test(MultiLint
|
||||
-DPSEUDO_TIDY=$<TARGET_FILE:pseudo_tidy>
|
||||
-DPSEUDO_IWYU=$<TARGET_FILE:pseudo_iwyu>
|
||||
-DPSEUDO_CPPLINT=$<TARGET_FILE:pseudo_cpplint>
|
||||
-DPSEUDO_CPPCHECK=$<TARGET_FILE:pseudo_cppcheck>
|
||||
)
|
||||
if(DEFINED CMake_TEST_CUDA)
|
||||
list(APPEND CompilerLauncher_ARGS -DCMake_TEST_CUDA=${CMake_TEST_CUDA})
|
||||
endif()
|
||||
|
@ -1,5 +1,6 @@
|
||||
^__run_co_compile missing command to run. Looking for one of the following:
|
||||
.*--cppcheck=
|
||||
.*--cpplint=
|
||||
.*--iwyu=
|
||||
.*--tidy=
|
||||
^__run_co_compile missing command to run. Looking for one or more of the following:
|
||||
--cppcheck=
|
||||
--cpplint=
|
||||
--iwyu=
|
||||
--lwyu=
|
||||
--tidy=
|
||||
|
8
Tests/RunCMake/MultiLint/C-Build-stdout.txt
Normal file
8
Tests/RunCMake/MultiLint/C-Build-stdout.txt
Normal file
@ -0,0 +1,8 @@
|
||||
Warning: include-what-you-use reported diagnostics:
|
||||
should add these lines:
|
||||
*
|
||||
#include <\.\.\.>
|
||||
+
|
||||
.*Tests[/\]RunCMake[/\]MultiLint[/\]main\.c:0:0: warning: message \[checker\].*
|
||||
Total errors found: 0
|
||||
.*Warning: cppcheck reported diagnostics.*error.*warning.*style.*performance.*information.*
|
8
Tests/RunCMake/MultiLint/C-launch-Build-stdout.txt
Normal file
8
Tests/RunCMake/MultiLint/C-launch-Build-stdout.txt
Normal file
@ -0,0 +1,8 @@
|
||||
Warning: include-what-you-use reported diagnostics:
|
||||
should add these lines:
|
||||
*
|
||||
#include <\.\.\.>
|
||||
+
|
||||
.*Tests[/\]RunCMake[/\]MultiLint[/\]main\.c:0:0: warning: message \[checker\].*
|
||||
Total errors found: 0
|
||||
.*Warning: cppcheck reported diagnostics.*error.*warning.*style.*performance.*information.*
|
3
Tests/RunCMake/MultiLint/C-launch.cmake
Normal file
3
Tests/RunCMake/MultiLint/C-launch.cmake
Normal file
@ -0,0 +1,3 @@
|
||||
set(CTEST_USE_LAUNCHERS 1)
|
||||
include(CTestUseLaunchers)
|
||||
include(C.cmake)
|
6
Tests/RunCMake/MultiLint/C.cmake
Normal file
6
Tests/RunCMake/MultiLint/C.cmake
Normal file
@ -0,0 +1,6 @@
|
||||
enable_language(C)
|
||||
set(CMAKE_C_INCLUDE_WHAT_YOU_USE "${PSEUDO_IWYU}" -some -args)
|
||||
set(CMAKE_C_CLANG_TIDY "${PSEUDO_TIDY}" -some -args)
|
||||
set(CMAKE_C_CPPLINT "${PSEUDO_CPPLINT}" --verbose=0 --linelength=80)
|
||||
set(CMAKE_C_CPPCHECK "${PSEUDO_CPPCHECK}")
|
||||
add_executable(main main.c)
|
3
Tests/RunCMake/MultiLint/CMakeLists.txt
Normal file
3
Tests/RunCMake/MultiLint/CMakeLists.txt
Normal file
@ -0,0 +1,3 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(${RunCMake_TEST} NONE)
|
||||
include(${RunCMake_TEST}.cmake)
|
8
Tests/RunCMake/MultiLint/CXX-Build-stdout.txt
Normal file
8
Tests/RunCMake/MultiLint/CXX-Build-stdout.txt
Normal file
@ -0,0 +1,8 @@
|
||||
Warning: include-what-you-use reported diagnostics:
|
||||
should add these lines:
|
||||
*
|
||||
#include <\.\.\.>
|
||||
+
|
||||
.*Tests[/\]RunCMake[/\]MultiLint[/\]main\.cxx:0:0: warning: message \[checker\].*
|
||||
Total errors found: 0
|
||||
.*Warning: cppcheck reported diagnostics.*error.*warning.*style.*performance.*information.*
|
8
Tests/RunCMake/MultiLint/CXX-launch-Build-stdout.txt
Normal file
8
Tests/RunCMake/MultiLint/CXX-launch-Build-stdout.txt
Normal file
@ -0,0 +1,8 @@
|
||||
Warning: include-what-you-use reported diagnostics:
|
||||
should add these lines:
|
||||
*
|
||||
#include <\.\.\.>
|
||||
+
|
||||
.*Tests[/\]RunCMake[/\]MultiLint[/\]main\.cxx:0:0: warning: message \[checker\].*
|
||||
Total errors found: 0
|
||||
.*Warning: cppcheck reported diagnostics.*error.*warning.*style.*performance.*information.*
|
3
Tests/RunCMake/MultiLint/CXX-launch.cmake
Normal file
3
Tests/RunCMake/MultiLint/CXX-launch.cmake
Normal file
@ -0,0 +1,3 @@
|
||||
set(CTEST_USE_LAUNCHERS 1)
|
||||
include(CTestUseLaunchers)
|
||||
include(CXX.cmake)
|
6
Tests/RunCMake/MultiLint/CXX.cmake
Normal file
6
Tests/RunCMake/MultiLint/CXX.cmake
Normal file
@ -0,0 +1,6 @@
|
||||
enable_language(CXX)
|
||||
set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "${PSEUDO_IWYU}" -some -args)
|
||||
set(CMAKE_CXX_CLANG_TIDY "${PSEUDO_TIDY}" -some -args)
|
||||
set(CMAKE_CXX_CPPLINT "${PSEUDO_CPPLINT}" --verbose=0 --linelength=80)
|
||||
set(CMAKE_CXX_CPPCHECK "${PSEUDO_CPPCHECK}")
|
||||
add_executable(main main.cxx)
|
27
Tests/RunCMake/MultiLint/RunCMakeTest.cmake
Normal file
27
Tests/RunCMake/MultiLint/RunCMakeTest.cmake
Normal file
@ -0,0 +1,27 @@
|
||||
include(RunCMake)
|
||||
|
||||
set(RunCMake_TEST_OPTIONS
|
||||
"-DPSEUDO_CPPCHECK=${PSEUDO_CPPCHECK}"
|
||||
"-DPSEUDO_CPPLINT=${PSEUDO_CPPLINT}"
|
||||
"-DPSEUDO_IWYU=${PSEUDO_IWYU}"
|
||||
"-DPSEUDO_TIDY=${PSEUDO_TIDY}"
|
||||
)
|
||||
|
||||
function(run_multilint lang)
|
||||
# Use a single build tree for tests without cleaning.
|
||||
set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/${lang}-build")
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
|
||||
file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
|
||||
run_cmake(${lang})
|
||||
set(RunCMake_TEST_OUTPUT_MERGE 1)
|
||||
run_cmake_command(${lang}-Build ${CMAKE_COMMAND} --build .)
|
||||
endfunction()
|
||||
|
||||
run_multilint(C)
|
||||
run_multilint(CXX)
|
||||
|
||||
if(NOT RunCMake_GENERATOR STREQUAL "Watcom WMake")
|
||||
run_multilint(C-launch)
|
||||
run_multilint(CXX-launch)
|
||||
endif()
|
4
Tests/RunCMake/MultiLint/main.c
Normal file
4
Tests/RunCMake/MultiLint/main.c
Normal file
@ -0,0 +1,4 @@
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
4
Tests/RunCMake/MultiLint/main.cxx
Normal file
4
Tests/RunCMake/MultiLint/main.cxx
Normal file
@ -0,0 +1,4 @@
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user