On Mon, Apr 4, 2011 at 8:26 AM, Brad King <brad.k...@kitware.com> wrote: > On 04/01/2011 02:42 PM, Manuel Klimek wrote: >> sorry for the delay, but I was busy with other stuff - please find >> attached a proposal patch for the test - I don't know enough about the >> cmake testing infrastructure to say whether that was what you >> imagined, please let me know if I should change anything. > > That looks pretty good, thanks. Here are a few comments from review: > > - The cmSystemTools::ParseArguments method is not very solid. It fails for > double-quotes in the middle of an argument, like '-I"a b"'. Use the newer > ParseUnixCommandLine instead. Unfortunately for historical reasons we > need to convert from vector<std::string> to vector<cmStdString>. Try > the patch below.
Done. > - The Source directory should not be touched for this. Put the source code > in Tests/CMakeLib and move the code to build the executable to the > CMakeLists.txt file in that directory. Done. > - In the CompileCommandOutput test source files, please actually create a > symbol in each library and call them from the main. Otherwise some > toolchains will complain about empty object files. Done. > - The ADD_TEST_MACRO call will need to be conditioned to run only when the > exported compile lines will work. I will take care of that for you when > the rest of the patch is ready. I also have the previous patches ready (re-based with master). Let me know how we'll go on about submitting all that. Thanks, /Manuel > > Thanks, > -Brad > > > diff --git a/Source/run_compile_commands.cxx b/Source/run_compile_commands.cxx > index 0b248f7..82cedfb 100644 > --- a/Source/run_compile_commands.cxx > +++ b/Source/run_compile_commands.cxx > @@ -117,8 +117,9 @@ int main () > it = parser.GetTranslationUnits().begin(), > end = parser.GetTranslationUnits().end(); it != end; ++it) > { > - std::vector<cmStdString> command = > - cmSystemTools::ParseArguments(it->at("command").c_str()); > + std::vector<std::string> command1; > + cmSystemTools::ParseUnixCommandLine(it->at("command").c_str(), command1); > + std::vector<cmStdString> command(command1.begin(), command1.end()); > if (!cmSystemTools::RunSingleCommand( > command, 0, 0, it->at("directory").c_str())) > { > -- Manuel Klimek (http://go/klimek)
diff --git a/Tests/CMakeLib/CMakeLists.txt b/Tests/CMakeLib/CMakeLists.txt index bda2fa5..7815545 100644 --- a/Tests/CMakeLib/CMakeLists.txt +++ b/Tests/CMakeLib/CMakeLists.txt @@ -30,3 +30,6 @@ endif() foreach(test ${CMakeLib_TESTS}) add_test(CMakeLib.${test} CMakeLibTests ${test}) endforeach() + +ADD_EXECUTABLE(runcompilecommands run_compile_commands.cxx) +TARGET_LINK_LIBRARIES(runcompilecommands CMakeLib) diff --git a/Tests/CMakeLib/run_compile_commands.cxx b/Tests/CMakeLib/run_compile_commands.cxx new file mode 100644 index 0000000..c925167 --- /dev/null +++ b/Tests/CMakeLib/run_compile_commands.cxx @@ -0,0 +1,132 @@ +#include "cmSystemTools.h" + +class CompileCommandParser { +public: + typedef std::map<std::string, std::string> CommandType; + typedef std::vector<CommandType> TranslationUnitsType; + + CompileCommandParser(std::ifstream *input) + { + this->Input = input; + } + + void Parse() + { + NextNonWhitespace(); + ParseTranslationUnits(); + } + + const TranslationUnitsType& GetTranslationUnits() + { + return this->TranslationUnits; + } + +private: + void ParseTranslationUnits() + { + this->TranslationUnits = TranslationUnitsType(); + ExpectOrDie('[', "at start of compile command file"); + do + { + ParseTranslationUnit(); + this->TranslationUnits.push_back(this->Command); + } while(Expect(',')); + ExpectOrDie(']', "at end of array"); + } + + void ParseTranslationUnit() + { + this->Command = CommandType(); + if(!Expect('{')) return; + if(Expect('}')) return; + do + { + ParseString(); + std::string name = this->String; + ExpectOrDie(':', "between name and value"); + ParseString(); + std::string value = this->String; + this->Command[name] = value; + } while(Expect(',')); + ExpectOrDie('}', "at end of object"); + } + + void ParseString() + { + this->String.clear(); + if(!Expect('"')) return; + while (!Expect('"')) + { + Expect('\\'); + this->String.push_back(C); + Next(); + } + } + + bool Expect(char c) + { + if(this->C == c) + { + NextNonWhitespace(); + return true; + } + return false; + } + + void ExpectOrDie(char c, const std::string & message) + { + if (!Expect(c)) + ErrorExit(std::string("'") + c + "' expected " + message + "."); + } + + void NextNonWhitespace() + { + do { Next(); } while (IsWhitespace()); + } + + void Next() + { + this->C = Input->get(); + if (this->Input->bad()) ErrorExit("Unexpected end of file."); + } + + void ErrorExit(const std::string &message) { + std::cout << "ERROR: " << message; + exit(1); + } + + bool IsWhitespace() + { + return (this->C == ' ' || this->C == '\t' || + this->C == '\n' || this->C == '\r'); + } + + char C; + TranslationUnitsType TranslationUnits; + CommandType Command; + std::string String; + std::ifstream *Input; +}; + +int main () +{ + std::ifstream file("compile_commands.json"); + CompileCommandParser parser(&file); + parser.Parse(); + for(CompileCommandParser::TranslationUnitsType::const_iterator + it = parser.GetTranslationUnits().begin(), + end = parser.GetTranslationUnits().end(); it != end; ++it) + { + std::vector<std::string> std_command; + cmSystemTools::ParseUnixCommandLine(it->at("command").c_str(), std_command); + std::vector<cmStdString> command(std_command.begin(), std_command.end()); + if (!cmSystemTools::RunSingleCommand( + command, 0, 0, it->at("directory").c_str())) + { + std::cout << "ERROR: Failed to run command \"" + << command[0] << "\"" << std::endl; + exit(1); + } + } + return 0; +} diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 6265f81..01eb84a 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -2018,6 +2018,9 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ ENDIF() SET_TESTS_PROPERTIES(Contracts.${project} PROPERTIES TIMEOUT ${timeout}) ENDFOREACH() + + ADD_TEST_MACRO(CompileCommandOutput + "${CMake_BINARY_DIR}/Tests/CMakeLib/runcompilecommands") ENDIF(BUILD_TESTING) SUBDIRS(CMakeTests) diff --git a/Tests/CompileCommandOutput/CMakeLists.txt b/Tests/CompileCommandOutput/CMakeLists.txt new file mode 100644 index 0000000..ac39b8b --- /dev/null +++ b/Tests/CompileCommandOutput/CMakeLists.txt @@ -0,0 +1,11 @@ +# a simple C only test case +cmake_minimum_required (VERSION 2.6) +project (CompileCommandOutput CXX) + +SET(CMAKE_EXPORT_COMPILE_COMMANDS ON) +set(CMAKE_DEBUG_POSTFIX "_test_debug_postfix") +ADD_LIBRARY(test1 STATIC "file with spaces.cxx") +ADD_LIBRARY(test2 SHARED "../CompileCommandOutput/relative.cxx") +INCLUDE_DIRECTORIES(${CompileCommandOutput_SOURCE_DIR}/../../Source) +ADD_EXECUTABLE(CompileCommandOutput compile_command_output.cxx) +TARGET_LINK_LIBRARIES(CompileCommandOutput test1 test2) diff --git a/Tests/CompileCommandOutput/compile_command_output.cxx b/Tests/CompileCommandOutput/compile_command_output.cxx new file mode 100644 index 0000000..9487c89 --- /dev/null +++ b/Tests/CompileCommandOutput/compile_command_output.cxx @@ -0,0 +1,9 @@ +#include "file with spaces.h" +#include "relative.h" + +int main (int argc, char** argv) +{ + file_with_spaces(); + relative(); + return 0; +} diff --git a/Tests/CompileCommandOutput/file with spaces.cxx b/Tests/CompileCommandOutput/file with spaces.cxx new file mode 100644 index 0000000..5759319 --- /dev/null +++ b/Tests/CompileCommandOutput/file with spaces.cxx @@ -0,0 +1,3 @@ +#include "file with spaces.h" + +void file_with_spaces() {} diff --git a/Tests/CompileCommandOutput/file with spaces.h b/Tests/CompileCommandOutput/file with spaces.h new file mode 100644 index 0000000..49b686c --- /dev/null +++ b/Tests/CompileCommandOutput/file with spaces.h @@ -0,0 +1 @@ +void file_with_spaces(); diff --git a/Tests/CompileCommandOutput/relative.cxx b/Tests/CompileCommandOutput/relative.cxx new file mode 100644 index 0000000..eae11e2 --- /dev/null +++ b/Tests/CompileCommandOutput/relative.cxx @@ -0,0 +1,3 @@ +#include "relative.h" + +void relative() {} diff --git a/Tests/CompileCommandOutput/relative.h b/Tests/CompileCommandOutput/relative.h new file mode 100644 index 0000000..2168035 --- /dev/null +++ b/Tests/CompileCommandOutput/relative.h @@ -0,0 +1 @@ +void relative();
_______________________________________________ cmake-developers mailing list cmake-developers@cmake.org http://public.kitware.com/cgi-bin/mailman/listinfo/cmake-developers