From 3f064efe40cdf9d2eac955581b171e0c723e92a2 Mon Sep 17 00:00:00 2001 From: Manuel Klimek Date: Wed, 12 Jan 2011 20:06:25 -0800 Subject: [PATCH 01/15] refactor flags and defines --- Source/cmMakefileTargetGenerator.cxx | 120 +++++++++++++++------------ Source/cmMakefileTargetGenerator.h | 3 + 2 files changed, 68 insertions(+), 55 deletions(-) diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 69320dac4..01545fc50 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -249,6 +249,66 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules() } //---------------------------------------------------------------------------- +std::string cmMakefileTargetGenerator::GetFlags(const std::string &l) { + std::string flags; + const char *lang = l.c_str(); + + bool shared = ((this->Target->GetType() == cmTarget::SHARED_LIBRARY) || + (this->Target->GetType() == cmTarget::MODULE_LIBRARY)); + + // Add language feature flags. + this->AddFeatureFlags(flags, lang); + + this->LocalGenerator->AddArchitectureFlags(flags, this->Target, + lang, this->ConfigName); + + // Fortran-specific flags computed for this target. + if(l == "Fortran") + { + this->AddFortranFlags(flags); + } + + // Add shared-library flags if needed. + this->LocalGenerator->AddSharedFlags(flags, lang, shared); + + // Add include directory flags. + this->AddIncludeFlags(flags, lang); + + // Append old-style preprocessor definition flags. + this->LocalGenerator-> + AppendFlags(flags, this->Makefile->GetDefineFlags()); + + // Add include directory flags. + this->LocalGenerator-> + AppendFlags(flags,this->GetFrameworkFlags().c_str()); + + return flags; +} + +std::string cmMakefileTargetGenerator::GetDefines(const std::string &l) { + std::string defines; + const char *lang = l.c_str(); + // Add the export symbol definition for shared library objects. + if(const char* exportMacro = this->Target->GetExportMacro()) + { + this->LocalGenerator->AppendDefines(defines, exportMacro, lang); + } + + // Add preprocessor definitions for this target and configuration. + this->LocalGenerator->AppendDefines + (defines, this->Makefile->GetProperty("COMPILE_DEFINITIONS"), lang); + this->LocalGenerator->AppendDefines + (defines, this->Target->GetProperty("COMPILE_DEFINITIONS"), lang); + std::string defPropName = "COMPILE_DEFINITIONS_"; + defPropName += + cmSystemTools::UpperCase(this->LocalGenerator->ConfigurationName); + this->LocalGenerator->AppendDefines + (defines, this->Makefile->GetProperty(defPropName.c_str()), lang); + this->LocalGenerator->AppendDefines + (defines, this->Target->GetProperty(defPropName.c_str()), lang); + return defines; +} + void cmMakefileTargetGenerator::WriteTargetLanguageFlags() { // write language flags for target @@ -262,72 +322,22 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags() cmStdString compiler = "CMAKE_"; compiler += *l; compiler += "_COMPILER"; - *this->FlagFileStream << "# compile " << l->c_str() << " with " << + *this->FlagFileStream << "# compile " << l->c_str() << " with " << this->Makefile->GetSafeDefinition(compiler.c_str()) << "\n"; } for(std::set::const_iterator l = languages.begin(); l != languages.end(); ++l) { - const char *lang = l->c_str(); - std::string flags; - std::string defines; - bool shared = ((this->Target->GetType() == cmTarget::SHARED_LIBRARY) || - (this->Target->GetType() == cmTarget::MODULE_LIBRARY)); - - // Add the export symbol definition for shared library objects. - if(const char* exportMacro = this->Target->GetExportMacro()) - { - this->LocalGenerator->AppendDefines(defines, exportMacro, lang); - } - - // Add preprocessor definitions for this target and configuration. - this->LocalGenerator->AppendDefines - (defines, this->Makefile->GetProperty("COMPILE_DEFINITIONS"), lang); - this->LocalGenerator->AppendDefines - (defines, this->Target->GetProperty("COMPILE_DEFINITIONS"), lang); - std::string defPropName = "COMPILE_DEFINITIONS_"; - defPropName += - cmSystemTools::UpperCase(this->LocalGenerator->ConfigurationName); - this->LocalGenerator->AppendDefines - (defines, this->Makefile->GetProperty(defPropName.c_str()), lang); - this->LocalGenerator->AppendDefines - (defines, this->Target->GetProperty(defPropName.c_str()), lang); - - // Add language feature flags. - this->AddFeatureFlags(flags, lang); - - this->LocalGenerator->AddArchitectureFlags(flags, this->Target, - lang, this->ConfigName); - - // Fortran-specific flags computed for this target. - if(*l == "Fortran") - { - this->AddFortranFlags(flags); - } - - // Add shared-library flags if needed. - this->LocalGenerator->AddSharedFlags(flags, lang, shared); - - // Add include directory flags. - this->AddIncludeFlags(flags, lang); - - // Append old-style preprocessor definition flags. - this->LocalGenerator-> - AppendFlags(flags, this->Makefile->GetDefineFlags()); - - // Add include directory flags. - this->LocalGenerator-> - AppendFlags(flags,this->GetFrameworkFlags().c_str()); - - *this->FlagFileStream << lang << "_FLAGS = " << flags << "\n\n"; - *this->FlagFileStream << lang << "_DEFINES = " << defines << "\n\n"; + *this->FlagFileStream << *l << "_FLAGS = " << this->GetFlags(*l) << "\n\n"; + *this->FlagFileStream << *l << "_DEFINES = " << this->GetDefines(*l) << + "\n\n"; } // Add target-specific flags. if(this->Target->GetProperty("COMPILE_FLAGS")) { - std::string flags; + std::string flags; this->LocalGenerator->AppendFlags (flags, this->Target->GetProperty("COMPILE_FLAGS")); *this->FlagFileStream << "# TARGET_FLAGS = " << flags << "\n\n"; diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index bd26795d3..0005b48b0 100644 --- a/Source/cmMakefileTargetGenerator.h +++ b/Source/cmMakefileTargetGenerator.h @@ -216,6 +216,9 @@ protected: std::string MacContentDirectory; std::set MacContentFolders; + std::string GetFlags(const std::string &l); + std::string GetDefines(const std::string &l); + // Target-wide Fortran module output directory. bool FortranModuleDirectoryComputed; std::string FortranModuleDirectory; From 65c0c24a296c12c8037361cc5c53d884c4cde5f0 Mon Sep 17 00:00:00 2001 From: Manuel Klimek Date: Fri, 14 Jan 2011 14:28:38 -0800 Subject: [PATCH 02/15] cache flags and defines --- Source/cmMakefileTargetGenerator.cxx | 97 +++++++++++++++------------- Source/cmMakefileTargetGenerator.h | 2 + 2 files changed, 54 insertions(+), 45 deletions(-) diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 01545fc50..1c45f18a1 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -250,63 +250,70 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules() //---------------------------------------------------------------------------- std::string cmMakefileTargetGenerator::GetFlags(const std::string &l) { - std::string flags; - const char *lang = l.c_str(); + std::pair::iterator, bool> + insert_result = this->FlagsByLanguage.insert(std::make_pair(l, "")); + if (insert_result.second) { + std::string& flags = insert_result.first->second; + const char *lang = l.c_str(); - bool shared = ((this->Target->GetType() == cmTarget::SHARED_LIBRARY) || - (this->Target->GetType() == cmTarget::MODULE_LIBRARY)); + bool shared = ((this->Target->GetType() == cmTarget::SHARED_LIBRARY) || + (this->Target->GetType() == cmTarget::MODULE_LIBRARY)); - // Add language feature flags. - this->AddFeatureFlags(flags, lang); + // Add language feature flags. + this->AddFeatureFlags(flags, lang); - this->LocalGenerator->AddArchitectureFlags(flags, this->Target, - lang, this->ConfigName); + this->LocalGenerator->AddArchitectureFlags(flags, this->Target, + lang, this->ConfigName); - // Fortran-specific flags computed for this target. - if(l == "Fortran") - { - this->AddFortranFlags(flags); - } + // Fortran-specific flags computed for this target. + if(l == "Fortran") + { + this->AddFortranFlags(flags); + } - // Add shared-library flags if needed. - this->LocalGenerator->AddSharedFlags(flags, lang, shared); + // Add shared-library flags if needed. + this->LocalGenerator->AddSharedFlags(flags, lang, shared); - // Add include directory flags. - this->AddIncludeFlags(flags, lang); + // Add include directory flags. + this->AddIncludeFlags(flags, lang); - // Append old-style preprocessor definition flags. - this->LocalGenerator-> - AppendFlags(flags, this->Makefile->GetDefineFlags()); + // Append old-style preprocessor definition flags. + this->LocalGenerator-> + AppendFlags(flags, this->Makefile->GetDefineFlags()); - // Add include directory flags. - this->LocalGenerator-> - AppendFlags(flags,this->GetFrameworkFlags().c_str()); - - return flags; + // Add include directory flags. + this->LocalGenerator-> + AppendFlags(flags,this->GetFrameworkFlags().c_str()); + } + return insert_result.first->second; } std::string cmMakefileTargetGenerator::GetDefines(const std::string &l) { - std::string defines; - const char *lang = l.c_str(); - // Add the export symbol definition for shared library objects. - if(const char* exportMacro = this->Target->GetExportMacro()) - { - this->LocalGenerator->AppendDefines(defines, exportMacro, lang); - } + std::pair::iterator, bool> + insert_result = this->DefinesByLanguage.insert(std::make_pair(l, "")); + if (insert_result.second) { + std::string &defines = insert_result.first->second; + const char *lang = l.c_str(); + // Add the export symbol definition for shared library objects. + if(const char* exportMacro = this->Target->GetExportMacro()) + { + this->LocalGenerator->AppendDefines(defines, exportMacro, lang); + } - // Add preprocessor definitions for this target and configuration. - this->LocalGenerator->AppendDefines - (defines, this->Makefile->GetProperty("COMPILE_DEFINITIONS"), lang); - this->LocalGenerator->AppendDefines - (defines, this->Target->GetProperty("COMPILE_DEFINITIONS"), lang); - std::string defPropName = "COMPILE_DEFINITIONS_"; - defPropName += - cmSystemTools::UpperCase(this->LocalGenerator->ConfigurationName); - this->LocalGenerator->AppendDefines - (defines, this->Makefile->GetProperty(defPropName.c_str()), lang); - this->LocalGenerator->AppendDefines - (defines, this->Target->GetProperty(defPropName.c_str()), lang); - return defines; + // Add preprocessor definitions for this target and configuration. + this->LocalGenerator->AppendDefines + (defines, this->Makefile->GetProperty("COMPILE_DEFINITIONS"), lang); + this->LocalGenerator->AppendDefines + (defines, this->Target->GetProperty("COMPILE_DEFINITIONS"), lang); + std::string defPropName = "COMPILE_DEFINITIONS_"; + defPropName += + cmSystemTools::UpperCase(this->LocalGenerator->ConfigurationName); + this->LocalGenerator->AppendDefines + (defines, this->Makefile->GetProperty(defPropName.c_str()), lang); + this->LocalGenerator->AppendDefines + (defines, this->Target->GetProperty(defPropName.c_str()), lang); + } + return insert_result.first->second; } void cmMakefileTargetGenerator::WriteTargetLanguageFlags() diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index 0005b48b0..db87ebce6 100644 --- a/Source/cmMakefileTargetGenerator.h +++ b/Source/cmMakefileTargetGenerator.h @@ -217,7 +217,9 @@ protected: std::set MacContentFolders; std::string GetFlags(const std::string &l); + std::map FlagsByLanguage; std::string GetDefines(const std::string &l); + std::map DefinesByLanguage; // Target-wide Fortran module output directory. bool FortranModuleDirectoryComputed; From fe07b0557b0b6cc47c29547d9c1d30a2b440fcd8 Mon Sep 17 00:00:00 2001 From: Manuel Klimek Date: Wed, 12 Jan 2011 20:39:13 -0800 Subject: [PATCH 03/15] implement cxx command output --- Source/cmGlobalUnixMakefileGenerator3.cxx | 41 +++++++++++++++++++++++ Source/cmGlobalUnixMakefileGenerator3.h | 6 ++++ Source/cmMakefileTargetGenerator.cxx | 21 ++++++++++-- 3 files changed, 66 insertions(+), 2 deletions(-) diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index d9a341c38..92f87c9c4 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -31,6 +31,7 @@ cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3() #else this->UseLinkScript = true; #endif + this->CommandDatabase = NULL; } void cmGlobalUnixMakefileGenerator3 @@ -139,6 +140,17 @@ void cmGlobalUnixMakefileGenerator3 } //---------------------------------------------------------------------------- +std::string EscapeJSON(const std::string& s) { + std::string result; + for (int i = 0; i < s.size(); ++i) { + if (s[i] == '"' || s[i] == '\\') { + result += '\\'; + } + result += s[i]; + } + return result; +} + void cmGlobalUnixMakefileGenerator3::Generate() { // first do superclass method @@ -189,6 +201,35 @@ void cmGlobalUnixMakefileGenerator3::Generate() // write the main makefile this->WriteMainMakefile2(); this->WriteMainCMakefile(); + + if (this->CommandDatabase != NULL) { + *this->CommandDatabase << std::endl << "]"; + delete this->CommandDatabase; + this->CommandDatabase = NULL; + } +} + +void cmGlobalUnixMakefileGenerator3::AddCXXCompileCommand( + const std::string &sourceFile, const std::string &workingDirectory, + const std::string &compileCommand) { + if (this->CommandDatabase == NULL) + { + std::string commandDatabaseName = + std::string(this->GetCMakeInstance()->GetHomeOutputDirectory()) + + "/cxx_commands.json"; + this->CommandDatabase = + new cmGeneratedFileStream(commandDatabaseName.c_str()); + *this->CommandDatabase << "[" << std::endl; + } else { + *this->CommandDatabase << "," << std::endl; + } + *this->CommandDatabase << "{" << std::endl + << " \"directory\": \"" << EscapeJSON(workingDirectory) << "\"," + << std::endl + << " \"command\": \"" << EscapeJSON(compileCommand) << "\"," + << std::endl + << " \"file\": \"" << EscapeJSON(sourceFile) << "\"" + << std::endl << "}"; } void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2() diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h index cdc946084..a152e01f8 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.h +++ b/Source/cmGlobalUnixMakefileGenerator3.h @@ -112,6 +112,10 @@ public: /** Record per-target progress information. */ void RecordTargetProgress(cmMakefileTargetGenerator* tg); + void AddCXXCompileCommand(const std::string &sourceFile, + const std::string &workingDirectory, + const std::string &compileCommand); + protected: void WriteMainMakefile2(); void WriteMainCMakefile(); @@ -178,6 +182,8 @@ protected: size_t CountProgressMarksInTarget(cmTarget* target, std::set& emitted); size_t CountProgressMarksInAll(cmLocalUnixMakefileGenerator3* lg); + + cmGeneratedFileStream *CommandDatabase; }; #endif diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 1c45f18a1..e5df2f428 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -658,6 +658,9 @@ cmMakefileTargetGenerator vars.Flags = flags.c_str(); vars.Defines = defines.c_str(); + bool lang_is_c_or_cxx = ((strcmp(lang, "C") == 0) || + (strcmp(lang, "CXX") == 0)); + // Construct the compile rules. { std::string compileRuleVar = "CMAKE_"; @@ -668,6 +671,22 @@ cmMakefileTargetGenerator std::vector compileCommands; cmSystemTools::ExpandListArgument(compileRule, compileCommands); + if (lang_is_c_or_cxx && compileCommands.size() == 1) + { + std::string compileCommand = compileCommands[0]; + this->LocalGenerator->ExpandRuleVariables(compileCommand, vars); + std::string workingDirectory = + this->LocalGenerator->Convert( + this->Makefile->GetStartOutputDirectory(), cmLocalGenerator::FULL); + compileCommand.replace(compileCommand.find(langFlags), + langFlags.size(), this->GetFlags(lang)); + std::string langDefines = std::string("$(") + lang + "_DEFINES)"; + compileCommand.replace(compileCommand.find(langDefines), + langDefines.size(), this->GetDefines(lang)); + this->GlobalGenerator->AddCXXCompileCommand( + source.GetFullPath(), workingDirectory, compileCommand); + } + // Expand placeholders in the commands. for(std::vector::iterator i = compileCommands.begin(); i != compileCommands.end(); ++i) @@ -708,8 +727,6 @@ cmMakefileTargetGenerator } } - bool lang_is_c_or_cxx = ((strcmp(lang, "C") == 0) || - (strcmp(lang, "CXX") == 0)); bool do_preprocess_rules = lang_is_c_or_cxx && this->LocalGenerator->GetCreatePreprocessedSourceRules(); bool do_assembly_rules = lang_is_c_or_cxx && From 5674844de4b74d0b66cfc6b8237e631702c43637 Mon Sep 17 00:00:00 2001 From: Manuel Klimek Date: Fri, 14 Jan 2011 15:16:11 -0800 Subject: [PATCH 04/15] make compile command output optional --- Modules/CMakeGenericSystem.cmake | 3 +++ Source/cmGlobalUnixMakefileGenerator3.cxx | 2 +- Source/cmMakefileTargetGenerator.cxx | 3 ++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Modules/CMakeGenericSystem.cmake b/Modules/CMakeGenericSystem.cmake index b5d30724a..e64d0baa3 100644 --- a/Modules/CMakeGenericSystem.cmake +++ b/Modules/CMakeGenericSystem.cmake @@ -50,6 +50,9 @@ IF(CMAKE_GENERATOR MATCHES "Makefiles") IF(DEFINED CMAKE_RULE_MESSAGES) SET_PROPERTY(GLOBAL PROPERTY RULE_MESSAGES ${CMAKE_RULE_MESSAGES}) ENDIF(DEFINED CMAKE_RULE_MESSAGES) + SET(CMAKE_EXPORT_COMPILE_COMMANDS OFF CACHE BOOL + "Enable/Disable output of compile commands during generation." + ) ENDIF(CMAKE_GENERATOR MATCHES "Makefiles") diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index 92f87c9c4..54f2b0331 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -216,7 +216,7 @@ void cmGlobalUnixMakefileGenerator3::AddCXXCompileCommand( { std::string commandDatabaseName = std::string(this->GetCMakeInstance()->GetHomeOutputDirectory()) - + "/cxx_commands.json"; + + "/compile_commands.json"; this->CommandDatabase = new cmGeneratedFileStream(commandDatabaseName.c_str()); *this->CommandDatabase << "[" << std::endl; diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index e5df2f428..6d3fbe0c9 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -671,7 +671,8 @@ cmMakefileTargetGenerator std::vector compileCommands; cmSystemTools::ExpandListArgument(compileRule, compileCommands); - if (lang_is_c_or_cxx && compileCommands.size() == 1) + if (this->Makefile->IsOn("CMAKE_EXPORT_COMPILE_COMMANDS") && + lang_is_c_or_cxx && compileCommands.size() == 1) { std::string compileCommand = compileCommands[0]; this->LocalGenerator->ExpandRuleVariables(compileCommand, vars); From 0e6b05fcba61a1b113b841dd2b3e1e5060866d0e Mon Sep 17 00:00:00 2001 From: Manuel Klimek Date: Thu, 31 Mar 2011 16:55:00 -0700 Subject: [PATCH 05/15] Adds a test for the compile command line output. --- Tests/CMakeLib/CMakeLists.txt | 3 + Tests/CMakeLib/run_compile_commands.cxx | 132 ++++++++++++++++++ Tests/CMakeLists.txt | 3 + Tests/CompileCommandOutput/CMakeLists.txt | 11 ++ .../compile_command_output.cxx | 9 ++ .../CompileCommandOutput/file with spaces.cxx | 3 + Tests/CompileCommandOutput/file with spaces.h | 1 + Tests/CompileCommandOutput/relative.cxx | 3 + Tests/CompileCommandOutput/relative.h | 1 + 9 files changed, 166 insertions(+) create mode 100644 Tests/CMakeLib/run_compile_commands.cxx create mode 100644 Tests/CompileCommandOutput/CMakeLists.txt create mode 100644 Tests/CompileCommandOutput/compile_command_output.cxx create mode 100644 Tests/CompileCommandOutput/file with spaces.cxx create mode 100644 Tests/CompileCommandOutput/file with spaces.h create mode 100644 Tests/CompileCommandOutput/relative.cxx create mode 100644 Tests/CompileCommandOutput/relative.h diff --git a/Tests/CMakeLib/CMakeLists.txt b/Tests/CMakeLib/CMakeLists.txt index bda2fa5f8..78155457f 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 000000000..c9251678a --- /dev/null +++ b/Tests/CMakeLib/run_compile_commands.cxx @@ -0,0 +1,132 @@ +#include "cmSystemTools.h" + +class CompileCommandParser { +public: + typedef std::map CommandType; + typedef std::vector 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_command; + cmSystemTools::ParseUnixCommandLine(it->at("command").c_str(), std_command); + std::vector 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 157814e05..126eaddd2 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -2031,6 +2031,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 000000000..ac39b8bb3 --- /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 000000000..9487c896c --- /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 000000000..5759319df --- /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 000000000..49b686c00 --- /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 000000000..eae11e226 --- /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 000000000..2168035cc --- /dev/null +++ b/Tests/CompileCommandOutput/relative.h @@ -0,0 +1 @@ +void relative(); From 8346a28a0a6587382a30d06a998ae83caa574f4b Mon Sep 17 00:00:00 2001 From: Manuel Klimek Date: Mon, 25 Apr 2011 10:16:01 -0700 Subject: [PATCH 06/15] Only offer the compile command output feature on unix systems --- Modules/CMakeGenericSystem.cmake | 9 ++++++--- Tests/CMakeLib/CMakeLists.txt | 6 ++++-- Tests/CMakeLists.txt | 10 ++++++++-- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/Modules/CMakeGenericSystem.cmake b/Modules/CMakeGenericSystem.cmake index e64d0baa3..6615849b2 100644 --- a/Modules/CMakeGenericSystem.cmake +++ b/Modules/CMakeGenericSystem.cmake @@ -50,9 +50,12 @@ IF(CMAKE_GENERATOR MATCHES "Makefiles") IF(DEFINED CMAKE_RULE_MESSAGES) SET_PROPERTY(GLOBAL PROPERTY RULE_MESSAGES ${CMAKE_RULE_MESSAGES}) ENDIF(DEFINED CMAKE_RULE_MESSAGES) - SET(CMAKE_EXPORT_COMPILE_COMMANDS OFF CACHE BOOL - "Enable/Disable output of compile commands during generation." - ) + IF(CMAKE_GENERATOR MATCHES "Unix Makefiles") + SET(CMAKE_EXPORT_COMPILE_COMMANDS OFF CACHE BOOL + "Enable/Disable output of compile commands during generation." + ) + MARK_AS_ADVANCED(CMAKE_EXPORT_COMPILE_COMMANDS) + ENDIF(CMAKE_GENERATOR MATCHES "Unix Makefiles") ENDIF(CMAKE_GENERATOR MATCHES "Makefiles") diff --git a/Tests/CMakeLib/CMakeLists.txt b/Tests/CMakeLib/CMakeLists.txt index 78155457f..41bf03437 100644 --- a/Tests/CMakeLib/CMakeLists.txt +++ b/Tests/CMakeLib/CMakeLists.txt @@ -31,5 +31,7 @@ foreach(test ${CMakeLib_TESTS}) add_test(CMakeLib.${test} CMakeLibTests ${test}) endforeach() -ADD_EXECUTABLE(runcompilecommands run_compile_commands.cxx) -TARGET_LINK_LIBRARIES(runcompilecommands CMakeLib) +if(TEST_CompileCommandOutput) + add_executable(runcompilecommands run_compile_commands.cxx) + target_link_libraries(runcompilecommands CMakeLib) +endif() diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 126eaddd2..2344af78c 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -39,6 +39,10 @@ CONFIGURE_FILE(${CMake_SOURCE_DIR}/Tests/EnforceConfig.cmake.in # Testing IF(BUILD_TESTING) + IF("${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles") + SET(TEST_CompileCommandOutput 1) + ENDIF() + ADD_SUBDIRECTORY(CMakeLib) # Collect a list of all test build directories. @@ -2032,8 +2036,10 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ SET_TESTS_PROPERTIES(Contracts.${project} PROPERTIES TIMEOUT ${timeout}) ENDFOREACH() - ADD_TEST_MACRO(CompileCommandOutput - "${CMake_BINARY_DIR}/Tests/CMakeLib/runcompilecommands") + IF(TEST_CompileCommandOutput) + ADD_TEST_MACRO(CompileCommandOutput + "${CMake_BINARY_DIR}/Tests/CMakeLib/runcompilecommands") + ENDIF() ENDIF(BUILD_TESTING) SUBDIRS(CMakeTests) From c9174c0e4b3605895ff15a2c4102dfdfec011c8c Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 16 May 2011 11:55:56 -0400 Subject: [PATCH 07/15] Fix signed/unsigned comparison in EscapeJSON --- Source/cmGlobalUnixMakefileGenerator3.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index 54f2b0331..c6dbdb1ea 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -142,7 +142,7 @@ void cmGlobalUnixMakefileGenerator3 //---------------------------------------------------------------------------- std::string EscapeJSON(const std::string& s) { std::string result; - for (int i = 0; i < s.size(); ++i) { + for (std::string::size_type i = 0; i < s.size(); ++i) { if (s[i] == '"' || s[i] == '\\') { result += '\\'; } From a7e7a04aafdcb91e13180f421df550418041d9bf Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 16 May 2011 12:05:49 -0400 Subject: [PATCH 08/15] Fix run_compile_commands build on Apple GCC 3.3 This compiler does not provide the "at" method of std::map. Approximate it well enough for our needs. --- Tests/CMakeLib/run_compile_commands.cxx | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Tests/CMakeLib/run_compile_commands.cxx b/Tests/CMakeLib/run_compile_commands.cxx index c9251678a..31049d392 100644 --- a/Tests/CMakeLib/run_compile_commands.cxx +++ b/Tests/CMakeLib/run_compile_commands.cxx @@ -2,7 +2,19 @@ class CompileCommandParser { public: - typedef std::map CommandType; + class CommandType: public std::map + { + public: +#if defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ < 4 + cmStdString const& at(cmStdString const& k) const + { + const_iterator i = this->find(k); + if(i != this->end()) { return i->second; } + static cmStdString empty; + return empty; + } +#endif + }; typedef std::vector TranslationUnitsType; CompileCommandParser(std::ifstream *input) From 4e2185cbd0d37dd642eefdc3365e8985d8f688c0 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 17 May 2011 08:50:55 -0400 Subject: [PATCH 09/15] Make std::map usage more portable in language=>flags/defines maps Older versions of GCC, the HP compiler, and the SGI MIPSpro compiler do not like the use of make_pair in this case and the conversions it requires: a value of type "const char *" cannot be used to initialize an entity of type "char [1]" /usr/include/g++-3/stl_pair.h:68: assignment of read-only location Instead use a map lookup pattern already used throughout the rest of our source tree. --- Source/cmMakefileTargetGenerator.cxx | 36 +++++++++++++++++----------- Source/cmMakefileTargetGenerator.h | 5 ++-- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 6d3fbe0c9..d0df8f076 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -249,11 +249,12 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules() } //---------------------------------------------------------------------------- -std::string cmMakefileTargetGenerator::GetFlags(const std::string &l) { - std::pair::iterator, bool> - insert_result = this->FlagsByLanguage.insert(std::make_pair(l, "")); - if (insert_result.second) { - std::string& flags = insert_result.first->second; +std::string cmMakefileTargetGenerator::GetFlags(const std::string &l) +{ + ByLanguageMap::iterator i = this->FlagsByLanguage.find(l); + if (i == this->FlagsByLanguage.end()) + { + std::string flags; const char *lang = l.c_str(); bool shared = ((this->Target->GetType() == cmTarget::SHARED_LIBRARY) || @@ -284,15 +285,19 @@ std::string cmMakefileTargetGenerator::GetFlags(const std::string &l) { // Add include directory flags. this->LocalGenerator-> AppendFlags(flags,this->GetFrameworkFlags().c_str()); - } - return insert_result.first->second; + + ByLanguageMap::value_type entry(l, flags); + i = this->FlagsByLanguage.insert(entry).first; + } + return i->second; } -std::string cmMakefileTargetGenerator::GetDefines(const std::string &l) { - std::pair::iterator, bool> - insert_result = this->DefinesByLanguage.insert(std::make_pair(l, "")); - if (insert_result.second) { - std::string &defines = insert_result.first->second; +std::string cmMakefileTargetGenerator::GetDefines(const std::string &l) +{ + ByLanguageMap::iterator i = this->DefinesByLanguage.find(l); + if (i == this->DefinesByLanguage.end()) + { + std::string defines; const char *lang = l.c_str(); // Add the export symbol definition for shared library objects. if(const char* exportMacro = this->Target->GetExportMacro()) @@ -312,8 +317,11 @@ std::string cmMakefileTargetGenerator::GetDefines(const std::string &l) { (defines, this->Makefile->GetProperty(defPropName.c_str()), lang); this->LocalGenerator->AppendDefines (defines, this->Target->GetProperty(defPropName.c_str()), lang); - } - return insert_result.first->second; + + ByLanguageMap::value_type entry(l, defines); + i = this->DefinesByLanguage.insert(entry).first; + } + return i->second; } void cmMakefileTargetGenerator::WriteTargetLanguageFlags() diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index db87ebce6..b68f8bf3b 100644 --- a/Source/cmMakefileTargetGenerator.h +++ b/Source/cmMakefileTargetGenerator.h @@ -216,10 +216,11 @@ protected: std::string MacContentDirectory; std::set MacContentFolders; + typedef std::map ByLanguageMap; std::string GetFlags(const std::string &l); - std::map FlagsByLanguage; + ByLanguageMap FlagsByLanguage; std::string GetDefines(const std::string &l); - std::map DefinesByLanguage; + ByLanguageMap DefinesByLanguage; // Target-wide Fortran module output directory. bool FortranModuleDirectoryComputed; From 169bb05f90258447a0b93379364374eb03e45bf7 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 17 May 2011 08:56:08 -0400 Subject: [PATCH 10/15] Provide std::map<>::at for use in run_compile_commands Many compilers we support do not provide the at() member of std::map. Use the workaround added by commit a7e7a04a (Fix run_compile_commands build on Apple GCC 3.3, 2011-05-16) for all compilers. --- Tests/CMakeLib/run_compile_commands.cxx | 2 -- 1 file changed, 2 deletions(-) diff --git a/Tests/CMakeLib/run_compile_commands.cxx b/Tests/CMakeLib/run_compile_commands.cxx index 31049d392..d7422a893 100644 --- a/Tests/CMakeLib/run_compile_commands.cxx +++ b/Tests/CMakeLib/run_compile_commands.cxx @@ -5,7 +5,6 @@ public: class CommandType: public std::map { public: -#if defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ < 4 cmStdString const& at(cmStdString const& k) const { const_iterator i = this->find(k); @@ -13,7 +12,6 @@ public: static cmStdString empty; return empty; } -#endif }; typedef std::vector TranslationUnitsType; From 7c5be5114c1c1adb26cfe7e8556187bf9bd8bd0a Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 17 May 2011 09:25:44 -0400 Subject: [PATCH 11/15] run_compile_commands: Avoid shadow in std::map<>::at workaround The map has a member called "empty" so use a different name for the local variable in our approximate at() method. --- Tests/CMakeLib/run_compile_commands.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/CMakeLib/run_compile_commands.cxx b/Tests/CMakeLib/run_compile_commands.cxx index d7422a893..cfb7ecec4 100644 --- a/Tests/CMakeLib/run_compile_commands.cxx +++ b/Tests/CMakeLib/run_compile_commands.cxx @@ -9,8 +9,8 @@ public: { const_iterator i = this->find(k); if(i != this->end()) { return i->second; } - static cmStdString empty; - return empty; + static cmStdString emptyString; + return emptyString; } }; typedef std::vector TranslationUnitsType; From c45c60b24ff52d9435ceab0de027fbadac130a1f Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 18 May 2011 09:44:28 -0400 Subject: [PATCH 12/15] run_compile_commands: Avoid extra stl vector conversion The Sun compiler does not provide the proper vector constructor to initialize it from an iterator pair of a non-matching type. Extend the ParseUnixCommandLine API to provide a vector of the proper type so no conversion is needed. --- Source/cmSystemTools.cxx | 16 ++++++++++++++++ Source/cmSystemTools.h | 2 ++ Tests/CMakeLib/run_compile_commands.cxx | 5 ++--- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 7bc89a4c4..df6469f5b 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -440,6 +440,13 @@ public: args.push_back(*arg); } } + void Store(std::vector& args) const + { + for(char** arg = this->ArgV; arg && *arg; ++arg) + { + args.push_back(*arg); + } + } }; //---------------------------------------------------------------------------- @@ -451,6 +458,15 @@ void cmSystemTools::ParseUnixCommandLine(const char* command, argv.Store(args); } +//---------------------------------------------------------------------------- +void cmSystemTools::ParseUnixCommandLine(const char* command, + std::vector& args) +{ + // Invoke the underlying parser. + cmSystemToolsArgV argv = cmsysSystem_Parse_CommandForUnix(command, 0); + argv.Store(args); +} + std::string cmSystemTools::EscapeWindowsShellArgument(const char* arg, int shell_flags) { diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 6f9147c31..dfc6b7df0 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -237,6 +237,8 @@ public: /** Parse arguments out of a unix command line string. */ static void ParseUnixCommandLine(const char* command, std::vector& args); + static void ParseUnixCommandLine(const char* command, + std::vector& args); /** Compute an escaped version of the given argument for use in a windows shell. See kwsys/System.h.in for details. */ diff --git a/Tests/CMakeLib/run_compile_commands.cxx b/Tests/CMakeLib/run_compile_commands.cxx index cfb7ecec4..a0be2eb63 100644 --- a/Tests/CMakeLib/run_compile_commands.cxx +++ b/Tests/CMakeLib/run_compile_commands.cxx @@ -127,9 +127,8 @@ int main () it = parser.GetTranslationUnits().begin(), end = parser.GetTranslationUnits().end(); it != end; ++it) { - std::vector std_command; - cmSystemTools::ParseUnixCommandLine(it->at("command").c_str(), std_command); - std::vector command(std_command.begin(), std_command.end()); + std::vector command; + cmSystemTools::ParseUnixCommandLine(it->at("command").c_str(), command); if (!cmSystemTools::RunSingleCommand( command, 0, 0, it->at("directory").c_str())) { From 4268e3d7e92eee0871dac1b92f64e18c374c7b43 Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 19 May 2011 08:02:21 -0400 Subject: [PATCH 13/15] run_compile_commands: Cast istream::get() result to char We perform error checking on the stream after reading so this conversion is safe. --- Tests/CMakeLib/run_compile_commands.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/CMakeLib/run_compile_commands.cxx b/Tests/CMakeLib/run_compile_commands.cxx index a0be2eb63..3f141c537 100644 --- a/Tests/CMakeLib/run_compile_commands.cxx +++ b/Tests/CMakeLib/run_compile_commands.cxx @@ -96,7 +96,7 @@ private: void Next() { - this->C = Input->get(); + this->C = char(Input->get()); if (this->Input->bad()) ErrorExit("Unexpected end of file."); } From 7039d1fd9b817a3ab6c81b4ef313a0bd6e19778d Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 19 May 2011 08:11:34 -0400 Subject: [PATCH 14/15] Fix CompileCommandOutput test for Make tools not supporting spaces Use underscores instead of spaces for such Make tools. --- Tests/CMakeLists.txt | 3 +++ Tests/CompileCommandOutput/CMakeLists.txt | 7 ++++++- Tests/CompileCommandOutput/compile_command_output.cxx | 4 ++-- Tests/CompileCommandOutput/file with spaces.cxx | 4 +--- Tests/CompileCommandOutput/file with spaces.h | 1 - Tests/CompileCommandOutput/file_with_underscores.cxx | 3 +++ Tests/CompileCommandOutput/file_with_underscores.h | 1 + 7 files changed, 16 insertions(+), 7 deletions(-) delete mode 100644 Tests/CompileCommandOutput/file with spaces.h create mode 100644 Tests/CompileCommandOutput/file_with_underscores.cxx create mode 100644 Tests/CompileCommandOutput/file_with_underscores.h diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 2344af78c..e9aed1650 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -11,6 +11,7 @@ MACRO(ADD_TEST_MACRO NAME COMMAND) --build-generator ${CMAKE_TEST_GENERATOR} --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} --build-project ${proj} + ${${NAME}_EXTRA_OPTIONS} --test-command ${COMMAND} ${ARGN}) LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${dir}") ENDMACRO(ADD_TEST_MACRO) @@ -2037,6 +2038,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ ENDFOREACH() IF(TEST_CompileCommandOutput) + SET(CompileCommandOutput_EXTRA_OPTIONS + --build-options -DMAKE_SUPPORTS_SPACES=${MAKE_IS_GNU}) ADD_TEST_MACRO(CompileCommandOutput "${CMake_BINARY_DIR}/Tests/CMakeLib/runcompilecommands") ENDIF() diff --git a/Tests/CompileCommandOutput/CMakeLists.txt b/Tests/CompileCommandOutput/CMakeLists.txt index ac39b8bb3..bd8e305c2 100644 --- a/Tests/CompileCommandOutput/CMakeLists.txt +++ b/Tests/CompileCommandOutput/CMakeLists.txt @@ -4,7 +4,12 @@ project (CompileCommandOutput CXX) SET(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_DEBUG_POSTFIX "_test_debug_postfix") -ADD_LIBRARY(test1 STATIC "file with spaces.cxx") +IF(MAKE_SUPPORTS_SPACES) + SET(test1_srcs "file with spaces.cxx") +ELSE() + SET(test1_srcs "file_with_underscores.cxx") +ENDIF() +ADD_LIBRARY(test1 STATIC ${test1_srcs}) ADD_LIBRARY(test2 SHARED "../CompileCommandOutput/relative.cxx") INCLUDE_DIRECTORIES(${CompileCommandOutput_SOURCE_DIR}/../../Source) ADD_EXECUTABLE(CompileCommandOutput compile_command_output.cxx) diff --git a/Tests/CompileCommandOutput/compile_command_output.cxx b/Tests/CompileCommandOutput/compile_command_output.cxx index 9487c896c..145a06426 100644 --- a/Tests/CompileCommandOutput/compile_command_output.cxx +++ b/Tests/CompileCommandOutput/compile_command_output.cxx @@ -1,9 +1,9 @@ -#include "file with spaces.h" +#include "file_with_underscores.h" #include "relative.h" int main (int argc, char** argv) { - file_with_spaces(); + file_with_underscores(); relative(); return 0; } diff --git a/Tests/CompileCommandOutput/file with spaces.cxx b/Tests/CompileCommandOutput/file with spaces.cxx index 5759319df..554e176e4 100644 --- a/Tests/CompileCommandOutput/file with spaces.cxx +++ b/Tests/CompileCommandOutput/file with spaces.cxx @@ -1,3 +1 @@ -#include "file with spaces.h" - -void file_with_spaces() {} +#include "file_with_underscores.cxx" diff --git a/Tests/CompileCommandOutput/file with spaces.h b/Tests/CompileCommandOutput/file with spaces.h deleted file mode 100644 index 49b686c00..000000000 --- a/Tests/CompileCommandOutput/file with spaces.h +++ /dev/null @@ -1 +0,0 @@ -void file_with_spaces(); diff --git a/Tests/CompileCommandOutput/file_with_underscores.cxx b/Tests/CompileCommandOutput/file_with_underscores.cxx new file mode 100644 index 000000000..4f42ccf56 --- /dev/null +++ b/Tests/CompileCommandOutput/file_with_underscores.cxx @@ -0,0 +1,3 @@ +#include "file_with_underscores.h" + +void file_with_underscores() {} diff --git a/Tests/CompileCommandOutput/file_with_underscores.h b/Tests/CompileCommandOutput/file_with_underscores.h new file mode 100644 index 000000000..0d73e3159 --- /dev/null +++ b/Tests/CompileCommandOutput/file_with_underscores.h @@ -0,0 +1 @@ +void file_with_underscores(); From cdc2b41cc2161b21192460bb92da40c6d4c6107f Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 20 May 2011 08:06:35 -0400 Subject: [PATCH 15/15] Fix CompileCommandOutput test build on Windows Add dllexport markup for the shared library. --- Tests/CompileCommandOutput/relative.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Tests/CompileCommandOutput/relative.h b/Tests/CompileCommandOutput/relative.h index 2168035cc..ddfe5519b 100644 --- a/Tests/CompileCommandOutput/relative.h +++ b/Tests/CompileCommandOutput/relative.h @@ -1 +1,11 @@ -void relative(); +#if defined(_WIN32) +# ifdef test2_EXPORTS +# define TEST2_EXPORT __declspec(dllexport) +# else +# define TEST2_EXPORT __declspec(dllimport) +# endif +#else +# define TEST2_EXPORT +#endif + +TEST2_EXPORT void relative();