diff options
40 files changed, 854 insertions, 135 deletions
diff --git a/Modules/Compiler/NAG-Fortran.cmake b/Modules/Compiler/NAG-Fortran.cmake index 9a89746..18f141e 100644 --- a/Modules/Compiler/NAG-Fortran.cmake +++ b/Modules/Compiler/NAG-Fortran.cmake @@ -32,3 +32,4 @@ set(CMAKE_Fortran_MODDIR_FLAG "-mdir ") set(CMAKE_SHARED_LIBRARY_Fortran_FLAGS "-PIC") set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-fixed") set(CMAKE_Fortran_FORMAT_FREE_FLAG "-free") +set(CMAKE_Fortran_COMPILE_OPTIONS_PIC "-PIC") diff --git a/Modules/GenerateExportHeader.cmake b/Modules/GenerateExportHeader.cmake index ce23d5d..892ebc6 100644 --- a/Modules/GenerateExportHeader.cmake +++ b/Modules/GenerateExportHeader.cmake @@ -47,7 +47,7 @@ # ... # }; # -# The CMake fragment will generate a file in the ${CMAKE_CURRENT_BUILD_DIR} +# The CMake fragment will generate a file in the ${CMAKE_CURRENT_BINARY_DIR} # called somelib_export.h containing the macros SOMELIB_EXPORT, SOMELIB_NO_EXPORT, # SOMELIB_DEPRECATED, SOMELIB_DEPRECATED_EXPORT and SOMELIB_DEPRECATED_NO_EXPORT. # The resulting file should be installed with other headers in the library. @@ -156,16 +156,12 @@ macro(_test_compiler_hidden_visibility) if(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.2") set(GCC_TOO_OLD TRUE) - message(WARNING "GCC version older than 4.2") elseif(CMAKE_COMPILER_IS_GNUC AND CMAKE_C_COMPILER_VERSION VERSION_LESS "4.2") set(GCC_TOO_OLD TRUE) - message(WARNING "GCC version older than 4.2") elseif(CMAKE_CXX_COMPILER_ID MATCHES Intel AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "12.0") set(_INTEL_TOO_OLD TRUE) - message(WARNING "Intel compiler older than 12.0") endif() - # Exclude XL here because it misinterprets -fvisibility=hidden even though # the check_cxx_compiler_flag passes # http://www.cdash.org/CDash/testDetails.php?test=109109951&build=1419259 diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index fde9677..ab62d2b 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -186,6 +186,8 @@ set(SRCS cmExtraCodeBlocksGenerator.h cmExtraEclipseCDT4Generator.cxx cmExtraEclipseCDT4Generator.h + cmExtraSublimeTextGenerator.cxx + cmExtraSublimeTextGenerator.h cmFileTimeComparison.cxx cmFileTimeComparison.h cmGeneratedFileStream.cxx diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 9e00c7c..fdf42bb 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -2,5 +2,5 @@ set(CMake_VERSION_MAJOR 2) set(CMake_VERSION_MINOR 8) set(CMake_VERSION_PATCH 10) -set(CMake_VERSION_TWEAK 20130217) +set(CMake_VERSION_TWEAK 20130225) #set(CMake_VERSION_RC 1) diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx index 4231243..3d5b24b 100644 --- a/Source/cmCacheManager.cxx +++ b/Source/cmCacheManager.cxx @@ -584,23 +584,15 @@ bool cmCacheManager::DeleteCache(const char* path) cmSystemTools::ConvertToUnixSlashes(cacheFile); std::string cmakeFiles = cacheFile; cacheFile += "/CMakeCache.txt"; - cmSystemTools::RemoveFile(cacheFile.c_str()); - // now remove the files in the CMakeFiles directory - // this cleans up language cache files - cmsys::Directory dir; - cmakeFiles += cmake::GetCMakeFilesDirectory(); - dir.Load(cmakeFiles.c_str()); - for (unsigned long fileNum = 0; - fileNum < dir.GetNumberOfFiles(); - ++fileNum) - { - if(!cmSystemTools:: - FileIsDirectory(dir.GetFile(fileNum))) + if(cmSystemTools::FileExists(cacheFile.c_str())) + { + cmSystemTools::RemoveFile(cacheFile.c_str()); + // now remove the files in the CMakeFiles directory + // this cleans up language cache files + cmakeFiles += cmake::GetCMakeFilesDirectory(); + if(cmSystemTools::FileIsDirectory(cmakeFiles.c_str())) { - std::string fullPath = cmakeFiles; - fullPath += "/"; - fullPath += dir.GetFile(fileNum); - cmSystemTools::RemoveFile(fullPath.c_str()); + cmSystemTools::RemoveADirectory(cmakeFiles.c_str()); } } return true; diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index d8a7059..7fd0380 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -757,29 +757,46 @@ void cmExportFileGenerator::GenerateMissingTargetsCheckCode(std::ostream& os, { if (missingTargets.empty()) { + os << "# This file does not depend on other imported targets which have\n" + "# been exported from the same project but in a separate " + "export set.\n\n"; return; } os << "# Make sure the targets which have been exported in some other \n" - "# export set exist.\n"; + "# export set exist.\n" + "unset(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets)\n" + "foreach(_target "; std::set<std::string> emitted; for(unsigned int i=0; i<missingTargets.size(); ++i) { if (emitted.insert(missingTargets[i]).second) { - os << "if(NOT TARGET \"" << missingTargets[i] << "\" )\n" - << " if(CMAKE_FIND_PACKAGE_NAME)\n" - << " set( ${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)\n" - << " set( ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE " - << "\"Required imported target \\\"" << missingTargets[i] - << "\\\" not found ! \")\n" - << " else()\n" - << " message(FATAL_ERROR \"Required imported target \\\"" - << missingTargets[i] << "\\\" not found ! \")\n" - << " endif()\n" - << "endif()\n"; + os << "\"" << missingTargets[i] << "\" "; } } - os << "\n"; + os << ")\n" + " if(NOT TARGET \"${_target}\" )\n" + " set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets \"" + "${${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets} ${_target}\")" + "\n" + " endif()\n" + "endforeach()\n" + "\n" + "if(DEFINED ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets)\n" + " if(CMAKE_FIND_PACKAGE_NAME)\n" + " set( ${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)\n" + " set( ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE " + "\"The following imported targets are " + "referenced, but are missing: " + "${${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets}\")\n" + " else()\n" + " message(FATAL_ERROR \"The following imported targets are " + "referenced, but are missing: " + "${${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets}\")\n" + " endif()\n" + "endif()\n" + "unset(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets)\n" + "\n"; } diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx new file mode 100644 index 0000000..5431401 --- /dev/null +++ b/Source/cmExtraSublimeTextGenerator.cxx @@ -0,0 +1,504 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2004-2009 Kitware, Inc. + Copyright 2004 Alexander Neundorf (neundorf@kde.org) + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmExtraSublimeTextGenerator.h" +#include "cmake.h" +#include "cmGeneratedFileStream.h" +#include "cmGeneratorTarget.h" +#include "cmGlobalUnixMakefileGenerator3.h" +#include "cmLocalGenerator.h" +#include "cmLocalUnixMakefileGenerator3.h" +#include "cmMakefile.h" +#include "cmSourceFile.h" +#include "cmSystemTools.h" +#include "cmTarget.h" +#include "cmXMLSafe.h" + +#include <cmsys/SystemTools.hxx> + +/* +Sublime Text 2 Generator +Author: Morné Chamberlain +This generator was initially based off of the CodeBlocks generator. + +Some useful URLs: +Homepage: +http://www.sublimetext.com/ + +File format docs: +http://www.sublimetext.com/docs/2/projects.html +http://sublimetext.info/docs/en/reference/build_systems.html +*/ + +//---------------------------------------------------------------------------- +void cmExtraSublimeTextGenerator +::GetDocumentation(cmDocumentationEntry& entry, const char*) const +{ + entry.Name = this->GetName(); + entry.Brief = "Generates Sublime Text 2 project files."; + entry.Full = + "Project files for Sublime Text 2 will be created in the top directory " + "and in every subdirectory which features a CMakeLists.txt file " + "containing a PROJECT() call. " + "Additionally Makefiles (or build.ninja files) are generated into the " + "build tree. The appropriate make program can build the project through " + "the default make target. A \"make install\" target is also provided."; +} + +cmExtraSublimeTextGenerator::cmExtraSublimeTextGenerator() +:cmExternalMakefileProjectGenerator() +{ +#if defined(_WIN32) + this->SupportedGlobalGenerators.push_back("MinGW Makefiles"); + this->SupportedGlobalGenerators.push_back("NMake Makefiles"); +// disable until somebody actually tests it: +// this->SupportedGlobalGenerators.push_back("MSYS Makefiles"); +#endif + this->SupportedGlobalGenerators.push_back("Ninja"); + this->SupportedGlobalGenerators.push_back("Unix Makefiles"); +} + + +void cmExtraSublimeTextGenerator::Generate() +{ + // for each sub project in the project create a sublime text 2 project + for (std::map<cmStdString, std::vector<cmLocalGenerator*> >::const_iterator + it = this->GlobalGenerator->GetProjectMap().begin(); + it!= this->GlobalGenerator->GetProjectMap().end(); + ++it) + { + // create a project file + this->CreateProjectFile(it->second); + } +} + + +void cmExtraSublimeTextGenerator::CreateProjectFile( + const std::vector<cmLocalGenerator*>& lgs) +{ + const cmMakefile* mf=lgs[0]->GetMakefile(); + std::string outputDir=mf->GetStartOutputDirectory(); + std::string projectName=mf->GetProjectName(); + + const std::string filename = + outputDir + "/" + projectName + ".sublime-project"; + + this->CreateNewProjectFile(lgs, filename); +} + +void cmExtraSublimeTextGenerator + ::CreateNewProjectFile(const std::vector<cmLocalGenerator*>& lgs, + const std::string& filename) +{ + const cmMakefile* mf=lgs[0]->GetMakefile(); + cmGeneratedFileStream fout(filename.c_str()); + if(!fout) + { + return; + } + + const std::string &sourceRootRelativeToOutput = cmSystemTools::RelativePath( + mf->GetHomeOutputDirectory(), + mf->GetHomeDirectory()); + // Write the folder entries to the project file + fout << "{\n"; + fout << "\t\"folders\":\n\t[\n\t"; + if (!sourceRootRelativeToOutput.empty()) + { + fout << "\t{\n\t\t\t\"path\": \"" << sourceRootRelativeToOutput << "\""; + const std::string &outputRelativeToSourceRoot = + cmSystemTools::RelativePath(mf->GetHomeDirectory(), + mf->GetHomeOutputDirectory()); + if ((!outputRelativeToSourceRoot.empty()) && + ((outputRelativeToSourceRoot.length() < 3) || + (outputRelativeToSourceRoot.substr(0, 3) != "../"))) + { + fout << ",\n\t\t\t\"folder_exclude_patterns\": [\"" << + outputRelativeToSourceRoot << "\"]"; + } + } + else + { + fout << "\t{\n\t\t\t\"path\": \"./\""; + } + fout << "\n\t\t}"; + // End of the folders section + fout << "\n\t]"; + + // Write the beginning of the build systems section to the project file + fout << ",\n\t\"build_systems\":\n\t[\n\t"; + + // Set of include directories over all targets (sublime text/sublimeclang + // doesn't currently support these settings per build system, only project + // wide + MapSourceFileFlags sourceFileFlags; + AppendAllTargets(lgs, mf, fout, sourceFileFlags); + + // End of build_systems + fout << "\n\t]"; + fout << "\n\t}"; +} + + +void cmExtraSublimeTextGenerator:: + AppendAllTargets(const std::vector<cmLocalGenerator*>& lgs, + const cmMakefile* mf, + cmGeneratedFileStream& fout, + MapSourceFileFlags& sourceFileFlags) +{ + std::string make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM"); + std::string compiler = ""; + if (!lgs.empty()) + { + this->AppendTarget(fout, "all", lgs[0], 0, make.c_str(), mf, + compiler.c_str(), sourceFileFlags, true); + this->AppendTarget(fout, "clean", lgs[0], 0, make.c_str(), mf, + compiler.c_str(), sourceFileFlags, false); + } + + // add all executable and library targets and some of the GLOBAL + // and UTILITY targets + for (std::vector<cmLocalGenerator*>::const_iterator lg=lgs.begin(); + lg!=lgs.end(); lg++) + { + cmMakefile* makefile=(*lg)->GetMakefile(); + cmTargets& targets=makefile->GetTargets(); + for (cmTargets::iterator ti = targets.begin(); + ti != targets.end(); ti++) + { + switch(ti->second.GetType()) + { + case cmTarget::GLOBAL_TARGET: + { + bool insertTarget = false; + // Only add the global targets from CMAKE_BINARY_DIR, + // not from the subdirs + if (strcmp(makefile->GetStartOutputDirectory(), + makefile->GetHomeOutputDirectory())==0) + { + insertTarget = true; + // only add the "edit_cache" target if it's not ccmake, because + // this will not work within the IDE + if (ti->first == "edit_cache") + { + const char* editCommand = makefile->GetDefinition + ("CMAKE_EDIT_COMMAND"); + if (editCommand == 0) + { + insertTarget = false; + } + else if (strstr(editCommand, "ccmake")!=NULL) + { + insertTarget = false; + } + } + } + if (insertTarget) + { + this->AppendTarget(fout, ti->first.c_str(), *lg, 0, + make.c_str(), makefile, compiler.c_str(), + sourceFileFlags, false); + } + } + break; + case cmTarget::UTILITY: + // Add all utility targets, except the Nightly/Continuous/ + // Experimental-"sub"targets as e.g. NightlyStart + if (((ti->first.find("Nightly")==0) &&(ti->first!="Nightly")) + || ((ti->first.find("Continuous")==0)&&(ti->first!="Continuous")) + || ((ti->first.find("Experimental")==0) + && (ti->first!="Experimental"))) + { + break; + } + + this->AppendTarget(fout, ti->first.c_str(), *lg, 0, + make.c_str(), makefile, compiler.c_str(), + sourceFileFlags, false); + break; + case cmTarget::EXECUTABLE: + case cmTarget::STATIC_LIBRARY: + case cmTarget::SHARED_LIBRARY: + case cmTarget::MODULE_LIBRARY: + case cmTarget::OBJECT_LIBRARY: + { + this->AppendTarget(fout, ti->first.c_str(), *lg, &ti->second, + make.c_str(), makefile, compiler.c_str(), + sourceFileFlags, false); + std::string fastTarget = ti->first; + fastTarget += "/fast"; + this->AppendTarget(fout, fastTarget.c_str(), *lg, &ti->second, + make.c_str(), makefile, compiler.c_str(), + sourceFileFlags, false); + } + break; + default: + break; + } + } + } +} + +void cmExtraSublimeTextGenerator:: + AppendTarget(cmGeneratedFileStream& fout, + const char* targetName, + cmLocalGenerator* lg, + cmTarget* target, + const char* make, + const cmMakefile* makefile, + const char*, //compiler + MapSourceFileFlags& sourceFileFlags, + bool firstTarget) +{ + + if (target != 0) + { + cmGeneratorTarget *gtgt = this->GlobalGenerator + ->GetGeneratorTarget(target); + std::vector<cmSourceFile*> const& sourceFiles = target->GetSourceFiles(); + std::vector<cmSourceFile*>::const_iterator sourceFilesEnd = + sourceFiles.end(); + for (std::vector<cmSourceFile*>::const_iterator iter = + sourceFiles.begin(); iter != sourceFilesEnd; ++iter) + { + cmSourceFile* sourceFile = *iter; + MapSourceFileFlags::iterator sourceFileFlagsIter = + sourceFileFlags.find(sourceFile->GetFullPath()); + if (sourceFileFlagsIter == sourceFileFlags.end()) + { + sourceFileFlagsIter = + sourceFileFlags.insert(MapSourceFileFlags::value_type( + sourceFile->GetFullPath(), std::vector<std::string>())).first; + } + std::vector<std::string>& flags = sourceFileFlagsIter->second; + std::string flagsString = + this->ComputeFlagsForObject(*iter, lg, target, gtgt); + std::string definesString = + this->ComputeDefines(*iter, lg, target, gtgt); + flags.clear(); + cmsys::RegularExpression flagRegex; + // Regular expression to extract compiler flags from a string + // https://gist.github.com/3944250 + const char* regexString = + "(^|[ ])-[DIOUWfgs][^= ]+(=\\\"[^\"]+\\\"|=[^\"][^ ]+)?"; + flagRegex.compile(regexString); + std::string workString = flagsString + " " + definesString; + while (flagRegex.find(workString)) + { + std::string::size_type start = flagRegex.start(); + if (workString[start] == ' ') + { + start++; + } + flags.push_back(workString.substr(start, + flagRegex.end() - start)); + if (flagRegex.end() < workString.size()) + { + workString = workString.substr(flagRegex.end()); + } + else + { + workString = ""; + } + } + } + } + + // Ninja uses ninja.build files (look for a way to get the output file name + // from cmMakefile or something) + std::string makefileName; + if (strcmp(this->GlobalGenerator->GetName(), "Ninja")==0) + { + makefileName = "build.ninja"; + } + else + { + makefileName = "Makefile"; + } + if (!firstTarget) + { + fout << ",\n\t"; + } + fout << "\t{\n\t\t\t\"name\": \"" << makefile->GetProjectName() << " - " << + targetName << "\",\n"; + fout << "\t\t\t\"cmd\": [" << + this->BuildMakeCommand(make, makefileName.c_str(), targetName) << + "],\n"; + fout << "\t\t\t\"working_dir\": \"${project_path}\",\n"; + fout << "\t\t\t\"file_regex\": \"^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$\"\n"; + fout << "\t\t}"; +} + +// Create the command line for building the given target using the selected +// make +std::string cmExtraSublimeTextGenerator::BuildMakeCommand( + const std::string& make, const char* makefile, const char* target) +{ + std::string command = "\""; + command += make + "\""; + if (strcmp(this->GlobalGenerator->GetName(), "NMake Makefiles")==0) + { + std::string makefileName = cmSystemTools::ConvertToOutputPath(makefile); + command += ", \"/NOLOGO\", \"/f\", \""; + command += makefileName + "\""; + command += ", \"VERBOSE=1\", \""; + command += target; + command += "\""; + } + else if (strcmp(this->GlobalGenerator->GetName(), "Ninja")==0) + { + std::string makefileName = cmSystemTools::ConvertToOutputPath(makefile); + command += ", \"-f\", \""; + command += makefileName + "\""; + command += ", \"-v\", \""; + command += target; + command += "\""; + } + else + { + std::string makefileName; + if (strcmp(this->GlobalGenerator->GetName(), "MinGW Makefiles")==0) + { + // no escaping of spaces in this case, see + // http://public.kitware.com/Bug/view.php?id=10014 + makefileName = makefile; + } + else + { + makefileName = cmSystemTools::ConvertToOutputPath(makefile); + } + command += ", \"-f\", \""; + command += makefileName + "\""; + command += ", \"VERBOSE=1\", \""; + command += target; + command += "\""; + } + return command; +} + +// TODO: Most of the code is picked up from the Ninja generator, refactor it. +std::string +cmExtraSublimeTextGenerator::ComputeFlagsForObject(cmSourceFile* source, + cmLocalGenerator* lg, + cmTarget *target, + cmGeneratorTarget* gtgt) +{ + std::string flags; + + cmMakefile *makefile = lg->GetMakefile(); + const char* language = source->GetLanguage(); + if (language == NULL) + { + language = "C"; + } + const char* config = makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); + // Add language-specific flags. + lg->AddLanguageFlags(flags, language, config); + + lg->AddArchitectureFlags(flags, gtgt, language, config); + + // TODO: Fortran support. + // // Fortran-specific flags computed for this target. + // if(*l == "Fortran") + // { + // this->AddFortranFlags(flags); + // } + + // Add shared-library flags if needed. + lg->AddCMP0018Flags(flags, target, language, config); + + // Add include directory flags. + { + std::vector<std::string> includes; + lg->GetIncludeDirectories(includes, gtgt, language, config); + std::string includeFlags = + lg->GetIncludeFlags(includes, language, true); // full include paths + lg->AppendFlags(flags, includeFlags.c_str()); + } + + // Append old-style preprocessor definition flags. + lg->AppendFlags(flags, makefile->GetDefineFlags()); + + // Add target-specific flags. + if(target->GetProperty("COMPILE_FLAGS")) + { + std::string langIncludeExpr = "CMAKE_"; + langIncludeExpr += language; + langIncludeExpr += "_FLAG_REGEX"; + const char* regex = makefile->GetDefinition(langIncludeExpr.c_str()); + if(regex) + { + cmsys::RegularExpression r(regex); + std::vector<std::string> args; + cmSystemTools:: + ParseWindowsCommandLine(target->GetProperty("COMPILE_FLAGS"), args); + for(std::vector<std::string>::iterator i = args.begin(); + i != args.end(); ++i) + { + if(r.find(i->c_str())) + { + lg->AppendFlags(flags, i->c_str()); + } + } + } + else + { + lg->AppendFlags(flags, target->GetProperty("COMPILE_FLAGS")); + } + } + + // Add source file specific flags. + lg->AppendFlags(flags, target->GetProperty("COMPILE_FLAGS")); + + // TODO: Handle Apple frameworks. + + return flags; +} + +// TODO: Refactor with +// void cmMakefileTargetGenerator::WriteTargetLanguageFlags(). +std::string +cmExtraSublimeTextGenerator:: +ComputeDefines(cmSourceFile *source, cmLocalGenerator* lg, cmTarget *target, + cmGeneratorTarget*) + +{ + std::set<std::string> defines; + cmMakefile *makefile = lg->GetMakefile(); + const char* language = source->GetLanguage(); + if (language == NULL) + { + language = ""; + } + const char* config = makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); + + // Add the export symbol definition for shared library objects. + if(const char* exportMacro = target->GetExportMacro()) + { + lg->AppendDefines(defines, exportMacro); + } + + // Add preprocessor definitions for this target and configuration. + lg->AppendDefines(defines, target->GetCompileDefinitions()); + lg->AppendDefines(defines, source->GetProperty("COMPILE_DEFINITIONS")); + { + std::string defPropName = "COMPILE_DEFINITIONS_"; + defPropName += cmSystemTools::UpperCase(config); + lg->AppendDefines(defines, target->GetCompileDefinitions(config)); + lg->AppendDefines(defines, source->GetProperty(defPropName.c_str())); + } + + std::string definesString; + lg->JoinDefines(defines, definesString, language); + + return definesString; +} diff --git a/Source/cmExtraSublimeTextGenerator.h b/Source/cmExtraSublimeTextGenerator.h new file mode 100644 index 0000000..7902593 --- /dev/null +++ b/Source/cmExtraSublimeTextGenerator.h @@ -0,0 +1,89 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2004-2009 Kitware, Inc. + Copyright 2004 Alexander Neundorf (neundorf@kde.org) + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmExtraSublimeTextGenerator_h +#define cmExtraSublimeTextGenerator_h + +#include "cmExternalMakefileProjectGenerator.h" +#include "cmSourceFile.h" + +class cmLocalGenerator; +class cmMakefile; +class cmTarget; +class cmGeneratedFileStream; +class cmGeneratorTarget; + +/** \class cmExtraSublimeTextGenerator + * \brief Write Sublime Text 2 project files for Makefile based projects + */ +class cmExtraSublimeTextGenerator : public cmExternalMakefileProjectGenerator +{ +public: + typedef std::map<std::string, std::vector<std::string> > MapSourceFileFlags; + cmExtraSublimeTextGenerator(); + + virtual const char* GetName() const + { return cmExtraSublimeTextGenerator::GetActualName();} + static const char* GetActualName() + { return "Sublime Text 2";} + static cmExternalMakefileProjectGenerator* New() + { return new cmExtraSublimeTextGenerator; } + /** Get the documentation entry for this generator. */ + virtual void GetDocumentation(cmDocumentationEntry& entry, + const char* fullName) const; + + virtual void Generate(); +private: + + void CreateProjectFile(const std::vector<cmLocalGenerator*>& lgs); + + void CreateNewProjectFile(const std::vector<cmLocalGenerator*>& lgs, + const std::string& filename); + + /** Appends all targets as build systems to the project file and get all + * include directories and compiler definitions used. + */ + void AppendAllTargets(const std::vector<cmLocalGenerator*>& lgs, + const cmMakefile* mf, + cmGeneratedFileStream& fout, + MapSourceFileFlags& sourceFileFlags); + /** Returns the build command that needs to be executed to build the + * specified target. + */ + std::string BuildMakeCommand(const std::string& make, const char* makefile, + const char* target); + /** Appends the specified target to the generated project file as a Sublime + * Text build system. + */ + void AppendTarget(cmGeneratedFileStream& fout, + const char* targetName, + cmLocalGenerator* lg, + cmTarget* target, + const char* make, + const cmMakefile* makefile, + const char* compiler, + MapSourceFileFlags& sourceFileFlags, bool firstTarget); + /** + * Compute the flags for compilation of object files for a given @a language. + * @note Generally it is the value of the variable whose name is computed + * by LanguageFlagsVarName(). + */ + std::string ComputeFlagsForObject(cmSourceFile *source, + cmLocalGenerator* lg, + cmTarget *target, + cmGeneratorTarget* gtgt); + + std::string ComputeDefines(cmSourceFile *source, cmLocalGenerator* lg, + cmTarget *target, cmGeneratorTarget* gtgt); +}; + +#endif diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index ba29589..f2defbb 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1067,6 +1067,8 @@ bool cmGlobalGenerator::CheckTargets() void cmGlobalGenerator::CreateAutomocTargets() { #ifdef CMAKE_BUILD_WITH_CMAKE + typedef std::vector<std::pair<cmQtAutomoc, cmTarget*> > Automocs; + Automocs automocs; for(unsigned int i=0; i < this->LocalGenerators.size(); ++i) { cmTargets& targets = @@ -1084,11 +1086,17 @@ void cmGlobalGenerator::CreateAutomocTargets() if(target.GetPropertyAsBool("AUTOMOC") && !target.IsImported()) { cmQtAutomoc automoc; - automoc.SetupAutomocTarget(&target); + automoc.InitializeMocSourceFile(&target); + automocs.push_back(std::make_pair(automoc, &target)); } } } } + for (Automocs::iterator it = automocs.begin(); it != automocs.end(); + ++it) + { + it->first.SetupAutomocTarget(it->second); + } #endif } diff --git a/Source/cmGlobalVisualStudio6Generator.cxx b/Source/cmGlobalVisualStudio6Generator.cxx index cb15c30..9f3af71 100644 --- a/Source/cmGlobalVisualStudio6Generator.cxx +++ b/Source/cmGlobalVisualStudio6Generator.cxx @@ -41,11 +41,8 @@ void cmGlobalVisualStudio6Generator bool optional) { cmGlobalVisualStudioGenerator::AddPlatformDefinitions(mf); - mf->AddDefinition("CMAKE_GENERATOR_CC", "cl"); - mf->AddDefinition("CMAKE_GENERATOR_CXX", "cl"); mf->AddDefinition("CMAKE_GENERATOR_RC", "rc"); mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1"); - mf->AddDefinition("CMAKE_GENERATOR_Fortran", "ifort"); this->GenerateConfigurations(mf); this->cmGlobalGenerator::EnableLanguage(lang, mf, optional); } diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx index 71d79a1..154aa32 100644 --- a/Source/cmGlobalVisualStudio7Generator.cxx +++ b/Source/cmGlobalVisualStudio7Generator.cxx @@ -27,11 +27,8 @@ void cmGlobalVisualStudio7Generator ::EnableLanguage(std::vector<std::string>const & lang, cmMakefile *mf, bool optional) { - mf->AddDefinition("CMAKE_GENERATOR_CC", "cl"); - mf->AddDefinition("CMAKE_GENERATOR_CXX", "cl"); mf->AddDefinition("CMAKE_GENERATOR_RC", "rc"); mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1"); - mf->AddDefinition("CMAKE_GENERATOR_FC", "ifort"); this->AddPlatformDefinitions(mf); // Create list of configurations requested by user's cache, if any. diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 9600771..fbddc53 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -237,8 +237,6 @@ void cmGlobalXCodeGenerator::EnableLanguage(std::vector<std::string>const& cmCacheManager::STRING); } } - mf->AddDefinition("CMAKE_GENERATOR_CC", "gcc"); - mf->AddDefinition("CMAKE_GENERATOR_CXX", "g++"); mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1"); if(!this->PlatformToolset.empty()) { @@ -956,6 +954,15 @@ void cmGlobalXCodeGenerator::SetCurrentLocalGenerator(cmLocalGenerator* gen) } //---------------------------------------------------------------------------- +struct cmSourceFilePathCompare +{ + bool operator()(cmSourceFile* l, cmSourceFile* r) + { + return l->GetFullPath() < r->GetFullPath(); + } +}; + +//---------------------------------------------------------------------------- void cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen, std::vector<cmXCodeObject*>& @@ -981,7 +988,9 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen, } // organize the sources - std::vector<cmSourceFile*> const &classes = cmtarget.GetSourceFiles(); + std::vector<cmSourceFile*> classes = cmtarget.GetSourceFiles(); + std::sort(classes.begin(), classes.end(), cmSourceFilePathCompare()); + std::vector<cmXCodeObject*> externalObjFiles; std::vector<cmXCodeObject*> headerFiles; std::vector<cmXCodeObject*> resourceFiles; @@ -2517,47 +2526,25 @@ std::string cmGlobalXCodeGenerator::GetOrCreateId(const char* name, void cmGlobalXCodeGenerator::AddDependTarget(cmXCodeObject* target, cmXCodeObject* dependTarget) { - // make sure a target does not depend on itself - if(target == dependTarget) - { - return; - } - // now avoid circular references if dependTarget already - // depends on target then skip it. Circular references crashes - // xcode - cmXCodeObject* dependTargetDepends = - dependTarget->GetObject("dependencies"); - if(dependTargetDepends) - { - if(dependTargetDepends->HasObject(target->GetPBXTargetDependency())) - { - return; - } - } - - cmXCodeObject* targetdep = dependTarget->GetPBXTargetDependency(); - if(!targetdep) - { - cmXCodeObject* container = - this->CreateObject(cmXCodeObject::PBXContainerItemProxy); - container->SetComment("PBXContainerItemProxy"); - container->AddAttribute("containerPortal", - this->CreateObjectReference(this->RootObject)); - container->AddAttribute("proxyType", this->CreateString("1")); - container->AddAttribute("remoteGlobalIDString", - this->CreateObjectReference(dependTarget)); - container->AddAttribute("remoteInfo", - this->CreateString( - dependTarget->GetTarget()->GetName())); - targetdep = - this->CreateObject(cmXCodeObject::PBXTargetDependency); - targetdep->SetComment("PBXTargetDependency"); - targetdep->AddAttribute("target", - this->CreateObjectReference(dependTarget)); - targetdep->AddAttribute("targetProxy", - this->CreateObjectReference(container)); - dependTarget->SetPBXTargetDependency(targetdep); - } + // This is called once for every edge in the target dependency graph. + cmXCodeObject* container = + this->CreateObject(cmXCodeObject::PBXContainerItemProxy); + container->SetComment("PBXContainerItemProxy"); + container->AddAttribute("containerPortal", + this->CreateObjectReference(this->RootObject)); + container->AddAttribute("proxyType", this->CreateString("1")); + container->AddAttribute("remoteGlobalIDString", + this->CreateObjectReference(dependTarget)); + container->AddAttribute("remoteInfo", + this->CreateString( + dependTarget->GetTarget()->GetName())); + cmXCodeObject* targetdep = + this->CreateObject(cmXCodeObject::PBXTargetDependency); + targetdep->SetComment("PBXTargetDependency"); + targetdep->AddAttribute("target", + this->CreateObjectReference(dependTarget)); + targetdep->AddAttribute("targetProxy", + this->CreateObjectReference(container)); cmXCodeObject* depends = target->GetObject("dependencies"); if(!depends) @@ -2914,7 +2901,7 @@ cmXCodeObject* cmGlobalXCodeGenerator { std::vector<std::string> folders = cmSystemTools::tokenize(sg->GetFullName(), "\\"); - cmStdString curr_folder = cmtarget.GetName(); + cmStdString curr_folder = target; curr_folder += "/"; for(std::vector<std::string>::size_type i = 0; i < folders.size();i++) { diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 84cf6ca..a1c34f0 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -49,29 +49,29 @@ public: /** * Calls TraceVSDependencies() on all targets of this generator. */ - virtual void TraceDependencies(); + void TraceDependencies(); virtual void AddHelperCommands() {} /** * Perform any final calculations prior to generation */ - virtual void ConfigureFinalPass(); + void ConfigureFinalPass(); /** * Generate the install rules files in this directory. */ - virtual void GenerateInstallRules(); + void GenerateInstallRules(); /** * Generate the test files for tests. */ - virtual void GenerateTestFiles(); + void GenerateTestFiles(); /** * Generate a manifest of target files that will be built. */ - virtual void GenerateTargetManifest(); + void GenerateTargetManifest(); ///! Get the makefile for this generator cmMakefile *GetMakefile() { diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index f8e4399..80a1a9b 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -552,7 +552,7 @@ cmNinjaTargetGenerator cmCustomCommand const* cc = (*si)->GetCustomCommand(); const std::vector<std::string>& ccoutputs = cc->GetOutputs(); std::transform(ccoutputs.begin(), ccoutputs.end(), - std::back_inserter(implicitDeps), MapToNinjaPath()); + std::back_inserter(orderOnlyDeps), MapToNinjaPath()); } // If the source file is GENERATED and does not have a custom command diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index 4818f1b..10ce641 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -119,6 +119,22 @@ cmQtAutomoc::cmQtAutomoc() } } +void cmQtAutomoc::InitializeMocSourceFile(cmTarget* target) +{ + std::string automocTargetName = target->GetName(); + cmMakefile *makefile = target->GetMakefile(); + automocTargetName += "_automoc"; + std::string mocCppFile = makefile->GetCurrentOutputDirectory(); + mocCppFile += "/"; + mocCppFile += automocTargetName; + mocCppFile += ".cpp"; + cmSourceFile* mocCppSource = makefile->GetOrCreateSource(mocCppFile.c_str(), + true); + makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES", + mocCppFile.c_str(), false); + + target->AddSourceFile(mocCppSource); +} void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) { @@ -268,17 +284,6 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) outputFile += "/AutomocInfo.cmake"; makefile->ConfigureFile(inputFile.c_str(), outputFile.c_str(), false, true, false); - - std::string mocCppFile = makefile->GetCurrentOutputDirectory(); - mocCppFile += "/"; - mocCppFile += automocTargetName; - mocCppFile += ".cpp"; - cmSourceFile* mocCppSource = makefile->GetOrCreateSource(mocCppFile.c_str(), - true); - target->AddSourceFile(mocCppSource); - - makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES", - mocCppFile.c_str(), false); } diff --git a/Source/cmQtAutomoc.h b/Source/cmQtAutomoc.h index 69da80e..962e254 100644 --- a/Source/cmQtAutomoc.h +++ b/Source/cmQtAutomoc.h @@ -23,6 +23,7 @@ public: cmQtAutomoc(); bool Run(const char* targetDirectory); + void InitializeMocSourceFile(cmTarget* target); void SetupAutomocTarget(cmTarget* target); private: diff --git a/Source/cmXCodeObject.cxx b/Source/cmXCodeObject.cxx index de150ee..6abf6bf 100644 --- a/Source/cmXCodeObject.cxx +++ b/Source/cmXCodeObject.cxx @@ -38,7 +38,6 @@ cmXCodeObject::~cmXCodeObject() cmXCodeObject::cmXCodeObject(PBXType ptype, Type type) { this->Version = 15; - this->PBXTargetDependencyValue = 0; this->Target = 0; this->Object =0; diff --git a/Source/cmXCodeObject.h b/Source/cmXCodeObject.h index bb2d5b2..b89f78c 100644 --- a/Source/cmXCodeObject.h +++ b/Source/cmXCodeObject.h @@ -120,14 +120,6 @@ public: return 0; } - cmXCodeObject* GetPBXTargetDependency() - { - return this->PBXTargetDependencyValue; - } - void SetPBXTargetDependency(cmXCodeObject* d) - { - this->PBXTargetDependencyValue = d; - } void CopyAttributes(cmXCodeObject* ); void AddDependLibrary(const char* configName, @@ -170,7 +162,6 @@ protected: cmStdString Comment; cmStdString String; cmXCodeObject* Object; - cmXCodeObject* PBXTargetDependencyValue; std::vector<cmXCodeObject*> List; std::map<cmStdString, StringVec> DependLibraries; std::map<cmStdString, StringVec> DependTargets; diff --git a/Source/cmake.cxx b/Source/cmake.cxx index d44a36b..e2f80d1 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -88,6 +88,7 @@ #if !defined(CMAKE_BOOT_MINGW) # include "cmExtraCodeBlocksGenerator.h" #endif +#include "cmExtraSublimeTextGenerator.h" #ifdef CMAKE_USE_KDEVELOP # include "cmGlobalKdevelopGenerator.h" @@ -1878,6 +1879,8 @@ void cmake::AddDefaultExtraGenerators() this->AddExtraGenerator(cmExtraCodeBlocksGenerator::GetActualName(), &cmExtraCodeBlocksGenerator::New); + this->AddExtraGenerator(cmExtraSublimeTextGenerator::GetActualName(), + &cmExtraSublimeTextGenerator::New); #ifdef CMAKE_USE_ECLIPSE this->AddExtraGenerator(cmExtraEclipseCDT4Generator::GetActualName(), diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index f8e4afd..13c2aad 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -50,6 +50,26 @@ if(BUILD_TESTING) set(TEST_CompileCommandOutput 1) endif() + set(MAKE_IS_GNU ) + if(${CMAKE_TEST_MAKEPROGRAM} MATCHES make) + execute_process(COMMAND ${CMAKE_TEST_MAKEPROGRAM} no_such_target --version + RESULT_VARIABLE res OUTPUT_VARIABLE out ERROR_VARIABLE out) + if("${res}" STREQUAL "0") + if("${out}" MATCHES "GNU") + set(MAKE_IS_GNU 1) + endif() + endif() + endif() + + # some old versions of make simply cannot handle spaces in paths + if (MAKE_IS_GNU OR + "${CMAKE_TEST_MAKEPROGRAM}" MATCHES "nmake|gmake|wmake" OR + "${CMAKE_TEST_GENERATOR}" MATCHES "Visual Studio|XCode|Borland") + set(MAKE_SUPPORTS_SPACES 1) + else() + set(MAKE_SUPPORTS_SPACES 0) + endif() + set(build_generator_args --build-generator ${CMAKE_TEST_GENERATOR} --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} @@ -327,6 +347,7 @@ if(BUILD_TESTING) --build-project ExternalDataTest --build-noclean --force-new-ctest-process + --build-options -DMAKE_SUPPORTS_SPACES=${MAKE_SUPPORTS_SPACES} --test-command ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE} -V ) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Module/ExternalData") @@ -384,7 +405,8 @@ if(BUILD_TESTING) # mainly it tests that cmake doesn't crash when generating these project files. if(${CMAKE_TEST_GENERATOR} MATCHES "Unix Makefiles" OR ${CMAKE_TEST_GENERATOR} MATCHES "KDevelop") # check which generators we have - exec_program(${CMAKE_CMAKE_COMMAND} ARGS --help OUTPUT_VARIABLE cmakeOutput ) + execute_process(COMMAND ${CMAKE_CMAKE_COMMAND} --help + OUTPUT_VARIABLE cmakeOutput ERROR_VARIABLE cmakeOutput) # check for the Eclipse generator if ("${cmakeOutput}" MATCHES Eclipse) add_test(Simple_EclipseGenerator ${CMAKE_CTEST_COMMAND} @@ -1237,24 +1259,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ ) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/kwsys") endif() - set(MAKE_IS_GNU ) - if(${CMAKE_TEST_MAKEPROGRAM} MATCHES make) - exec_program( - ${CMAKE_TEST_MAKEPROGRAM} ARGS no_such_target --version - RETURN_VALUE res OUTPUT_VARIABLE out - ) - if("${res}" EQUAL 0) - if("${out}" MATCHES "GNU") - set(MAKE_IS_GNU 1) - endif() - endif() - endif() - # only add this test on platforms that support it - # some old versions of make simply cannot handle spaces in paths - if (MAKE_IS_GNU OR - "${CMAKE_TEST_MAKEPROGRAM}" MATCHES "nmake|gmake|wmake" OR - "${CMAKE_TEST_GENERATOR}" MATCHES "Visual Studio|XCode|Borland") + if(MAKE_SUPPORTS_SPACES) add_test(SubDirSpaces ${CMAKE_CTEST_COMMAND} --build-and-test "${CMake_SOURCE_DIR}/Tests/SubDirSpaces" @@ -2397,7 +2403,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ if(TEST_CompileCommandOutput) set(CompileCommandOutput_EXTRA_OPTIONS - --build-options -DMAKE_SUPPORTS_SPACES=${MAKE_IS_GNU}) + --build-options -DMAKE_SUPPORTS_SPACES=${MAKE_SUPPORTS_SPACES}) ADD_TEST_MACRO(CompileCommandOutput "${CMake_BINARY_DIR}/Tests/CMakeLib/runcompilecommands") endif() diff --git a/Tests/Module/ExternalData/CMakeLists.txt b/Tests/Module/ExternalData/CMakeLists.txt index 607e9b9..a379dca 100644 --- a/Tests/Module/ExternalData/CMakeLists.txt +++ b/Tests/Module/ExternalData/CMakeLists.txt @@ -14,10 +14,15 @@ set(ExternalData_URL_TEMPLATES set(ExternalData_BINARY_ROOT "${CMAKE_CURRENT_BINARY_DIR}/ExternalData") file(REMOVE_RECURSE ${ExternalData_BINARY_ROOT}) # clean test +if(MAKE_SUPPORTS_SPACES) + set(Data1CheckSpaces -D "DataSpace=DATA{Data Space.dat}") +endif() + ExternalData_Add_Test(Data1 NAME Data1Check COMMAND ${CMAKE_COMMAND} -D Data=DATA{Data.dat} + ${Data1CheckSpaces} -D SeriesA=DATA{SeriesA.dat,:} -D SeriesB=DATA{SeriesB.dat,:} -D SeriesC=DATA{SeriesC.dat,:} diff --git a/Tests/Module/ExternalData/Data Space.dat.md5 b/Tests/Module/ExternalData/Data Space.dat.md5 new file mode 100644 index 0000000..70e39bd --- /dev/null +++ b/Tests/Module/ExternalData/Data Space.dat.md5 @@ -0,0 +1 @@ +8c018830e3efa5caf3c7415028335a57 diff --git a/Tests/Module/ExternalData/Data1Check.cmake b/Tests/Module/ExternalData/Data1Check.cmake index b99d7ae..f40b76c 100644 --- a/Tests/Module/ExternalData/Data1Check.cmake +++ b/Tests/Module/ExternalData/Data1Check.cmake @@ -2,6 +2,12 @@ file(STRINGS "${Data}" lines LIMIT_INPUT 1024) if(NOT "x${lines}" STREQUAL "xInput file already transformed.") message(SEND_ERROR "Input file:\n ${Data}\ndoes not have expected content, but [[${lines}]]") endif() +if(DEFINED DataSpace) + file(STRINGS "${DataSpace}" lines LIMIT_INPUT 1024) + if(NOT "x${lines}" STREQUAL "xInput file already transformed.") + message(SEND_ERROR "Input file:\n ${DataSpace}\ndoes not have expected content, but [[${lines}]]") + endif() +endif() set(SeriesAn1 "1\\.dat") set(SeriesBn1 "_1\\.dat") set(SeriesCn1 "\\.1\\.dat") diff --git a/Tests/QtAutomoc/CMakeLists.txt b/Tests/QtAutomoc/CMakeLists.txt index 530818e..ebfbb03 100644 --- a/Tests/QtAutomoc/CMakeLists.txt +++ b/Tests/QtAutomoc/CMakeLists.txt @@ -38,3 +38,9 @@ generate_export_header(libC) target_link_libraries(libC LINK_PUBLIC libB) target_link_libraries(foo codeeditorLib ${QT_LIBRARIES} libC) + +add_library(empty STATIC empty.cpp) +set_target_properties(empty PROPERTIES AUTOMOC TRUE) +target_link_libraries(empty no_link_language) +add_library(no_link_language STATIC empty.h) +set_target_properties(no_link_language PROPERTIES AUTOMOC TRUE) diff --git a/Tests/QtAutomoc/empty.cpp b/Tests/QtAutomoc/empty.cpp new file mode 100644 index 0000000..ab32cf6 --- /dev/null +++ b/Tests/QtAutomoc/empty.cpp @@ -0,0 +1 @@ +// No content diff --git a/Tests/QtAutomoc/empty.h b/Tests/QtAutomoc/empty.h new file mode 100644 index 0000000..4566142 --- /dev/null +++ b/Tests/QtAutomoc/empty.h @@ -0,0 +1,9 @@ + +#include <QObject> + +class Empty : public QObject +{ + Q_OBJECT +public: + explicit Empty(QObject *parent = 0) {} +}; diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 320ebcc..c55bb3a 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -52,6 +52,9 @@ if(XCODE_VERSION AND "${XCODE_VERSION}" VERSION_LESS 3) endif() add_RunCMake_test(CMP0019) +if(UNIX AND "${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles") + add_RunCMake_test(CompilerChange) +endif() add_RunCMake_test(ExternalData) add_RunCMake_test(GeneratorExpression) add_RunCMake_test(GeneratorToolset) diff --git a/Tests/RunCMake/CompilerChange/CMakeLists.txt b/Tests/RunCMake/CompilerChange/CMakeLists.txt new file mode 100644 index 0000000..3b92518 --- /dev/null +++ b/Tests/RunCMake/CompilerChange/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 2.8) +if(NOT RunCMake_TEST) + set(RunCMake_TEST "$ENV{RunCMake_TEST}") # needed when cache is deleted +endif() +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/CompilerChange/EmptyCompiler-result.txt b/Tests/RunCMake/CompilerChange/EmptyCompiler-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CompilerChange/EmptyCompiler-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CompilerChange/EmptyCompiler-stderr.txt b/Tests/RunCMake/CompilerChange/EmptyCompiler-stderr.txt new file mode 100644 index 0000000..4745b25 --- /dev/null +++ b/Tests/RunCMake/CompilerChange/EmptyCompiler-stderr.txt @@ -0,0 +1,5 @@ +You have changed variables that require your cache to be deleted. +Configure will be re-run and you may have to reset some variables. +The following variables have changed: +CMAKE_C_COMPILER= *( +|$) diff --git a/Tests/RunCMake/CompilerChange/EmptyCompiler.cmake b/Tests/RunCMake/CompilerChange/EmptyCompiler.cmake new file mode 100644 index 0000000..c87ec49 --- /dev/null +++ b/Tests/RunCMake/CompilerChange/EmptyCompiler.cmake @@ -0,0 +1,3 @@ +enable_language(C) +message(STATUS "CMAKE_C_COMPILER is \"${CMAKE_C_COMPILER}\"") +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cc.cmake" "set(CMAKE_C_COMPILER \"${CMAKE_C_COMPILER}\")\n") diff --git a/Tests/RunCMake/CompilerChange/FindCompiler.cmake b/Tests/RunCMake/CompilerChange/FindCompiler.cmake new file mode 100644 index 0000000..297ab2f --- /dev/null +++ b/Tests/RunCMake/CompilerChange/FindCompiler.cmake @@ -0,0 +1,2 @@ +enable_language(C) +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cc.cmake" "set(CMAKE_C_COMPILER \"${CMAKE_C_COMPILER}\")\n") diff --git a/Tests/RunCMake/CompilerChange/FirstCompiler-stdout.txt b/Tests/RunCMake/CompilerChange/FirstCompiler-stdout.txt new file mode 100644 index 0000000..17621b7 --- /dev/null +++ b/Tests/RunCMake/CompilerChange/FirstCompiler-stdout.txt @@ -0,0 +1 @@ +-- CMAKE_C_COMPILER is ".*/Tests/RunCMake/CompilerChange/cc1.sh" diff --git a/Tests/RunCMake/CompilerChange/FirstCompiler.cmake b/Tests/RunCMake/CompilerChange/FirstCompiler.cmake new file mode 100644 index 0000000..c87ec49 --- /dev/null +++ b/Tests/RunCMake/CompilerChange/FirstCompiler.cmake @@ -0,0 +1,3 @@ +enable_language(C) +message(STATUS "CMAKE_C_COMPILER is \"${CMAKE_C_COMPILER}\"") +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cc.cmake" "set(CMAKE_C_COMPILER \"${CMAKE_C_COMPILER}\")\n") diff --git a/Tests/RunCMake/CompilerChange/RunCMakeTest.cmake b/Tests/RunCMake/CompilerChange/RunCMakeTest.cmake new file mode 100644 index 0000000..d383716 --- /dev/null +++ b/Tests/RunCMake/CompilerChange/RunCMakeTest.cmake @@ -0,0 +1,58 @@ +include(RunCMake) + +# Detect the compiler in use in the current environment. +run_cmake(FindCompiler) +include(${RunCMake_BINARY_DIR}/FindCompiler-build/cc.cmake) +if(NOT CMAKE_C_COMPILER) + message(FATAL_ERROR "FindCompiler provided no compiler!") +endif() +if(NOT IS_ABSOLUTE "${CMAKE_C_COMPILER}") + message(FATAL_ERROR "FindCompiler provided non-absolute path \"${CMAKE_C_COMPILER}\"!") +endif() +if(NOT EXISTS "${CMAKE_C_COMPILER}") + message(FATAL_ERROR "FindCompiler provided non-existing path \"${CMAKE_C_COMPILER}\"!") +endif() + +# Now that we have the full compiler path, hide CC. +unset(ENV{CC}) + +# Wrap around the real compiler so we can change the compiler +# path without changing the underlying compiler. +set(ccIn ${RunCMake_SOURCE_DIR}/cc.sh.in) +set(cc1 ${RunCMake_BINARY_DIR}/cc1.sh) +set(cc2 ${RunCMake_BINARY_DIR}/cc2.sh) +set(cc3 CMAKE_C_COMPILER-NOTFOUND) +configure_file(${ccIn} ${cc1} @ONLY IMMEDIATE) +configure_file(${ccIn} ${cc2} @ONLY IMMEDIATE) + +# Use a single build tree for remaining tests without cleaning. +set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/ChangeCompiler-build) +set(RunCMake_TEST_NO_CLEAN 1) +file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") + +# Check build with compiler wrapper 1. +set(RunCMake_TEST_OPTIONS -DCMAKE_C_COMPILER=${cc1}) +set(ENV{RunCMake_TEST} "FirstCompiler") +run_cmake(FirstCompiler) +include(${RunCMake_TEST_BINARY_DIR}/cc.cmake) +if(NOT "${CMAKE_C_COMPILER}" STREQUAL "${cc1}") + message(FATAL_ERROR "FirstCompiler built with compiler:\n ${CMAKE_C_COMPILER}\nand not with:\n ${cc1}") +endif() + +# Check rebuild with compiler wrapper 2. +set(RunCMake_TEST_OPTIONS -DCMAKE_C_COMPILER=${cc2}) +set(ENV{RunCMake_TEST} "SecondCompiler") +run_cmake(SecondCompiler) +include(${RunCMake_TEST_BINARY_DIR}/cc.cmake) +if(NOT "${CMAKE_C_COMPILER}" STREQUAL "${cc2}") + message(FATAL_ERROR "SecondCompiler built with compiler:\n ${CMAKE_C_COMPILER}\nand not with:\n ${cc2}") +endif() + +# Check failure with an empty compiler string. +set(RunCMake_TEST_OPTIONS -DCMAKE_C_COMPILER=) +set(ENV{RunCMake_TEST} "EmptyCompiler") +run_cmake(EmptyCompiler) +include(${RunCMake_TEST_BINARY_DIR}/cc.cmake) +if(NOT "${CMAKE_C_COMPILER}" STREQUAL "${cc3}") + message(FATAL_ERROR "Empty built with compiler:\n ${CMAKE_C_COMPILER}\nand not with:\n ${cc3}") +endif() diff --git a/Tests/RunCMake/CompilerChange/SecondCompiler-stderr.txt b/Tests/RunCMake/CompilerChange/SecondCompiler-stderr.txt new file mode 100644 index 0000000..3a01c53 --- /dev/null +++ b/Tests/RunCMake/CompilerChange/SecondCompiler-stderr.txt @@ -0,0 +1,4 @@ +You have changed variables that require your cache to be deleted. +Configure will be re-run and you may have to reset some variables. +The following variables have changed: +CMAKE_C_COMPILER=.*/Tests/RunCMake/CompilerChange/cc2.sh diff --git a/Tests/RunCMake/CompilerChange/SecondCompiler-stdout.txt b/Tests/RunCMake/CompilerChange/SecondCompiler-stdout.txt new file mode 100644 index 0000000..26ca964 --- /dev/null +++ b/Tests/RunCMake/CompilerChange/SecondCompiler-stdout.txt @@ -0,0 +1 @@ +-- CMAKE_C_COMPILER is ".*/Tests/RunCMake/CompilerChange/cc2.sh" diff --git a/Tests/RunCMake/CompilerChange/SecondCompiler.cmake b/Tests/RunCMake/CompilerChange/SecondCompiler.cmake new file mode 100644 index 0000000..c87ec49 --- /dev/null +++ b/Tests/RunCMake/CompilerChange/SecondCompiler.cmake @@ -0,0 +1,3 @@ +enable_language(C) +message(STATUS "CMAKE_C_COMPILER is \"${CMAKE_C_COMPILER}\"") +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cc.cmake" "set(CMAKE_C_COMPILER \"${CMAKE_C_COMPILER}\")\n") diff --git a/Tests/RunCMake/CompilerChange/cc.sh.in b/Tests/RunCMake/CompilerChange/cc.sh.in new file mode 100755 index 0000000..1d400e6 --- /dev/null +++ b/Tests/RunCMake/CompilerChange/cc.sh.in @@ -0,0 +1,2 @@ +#!/bin/sh +exec "@CMAKE_C_COMPILER@" "$@" diff --git a/Tests/RunCMake/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake index 40b98d4..00faa4c 100644 --- a/Tests/RunCMake/RunCMake.cmake +++ b/Tests/RunCMake/RunCMake.cmake @@ -26,8 +26,12 @@ function(run_cmake test) endif() endforeach() set(RunCMake_TEST_SOURCE_DIR "${top_src}") - set(RunCMake_TEST_BINARY_DIR "${top_bin}/${test}-build") - file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") + if(NOT RunCMake_TEST_BINARY_DIR) + set(RunCMake_TEST_BINARY_DIR "${top_bin}/${test}-build") + endif() + if(NOT RunCMake_TEST_NO_CLEAN) + file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") + endif() file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") if(NOT DEFINED RunCMake_TEST_OPTIONS) set(RunCMake_TEST_OPTIONS "") |