diff options
Diffstat (limited to 'Source')
37 files changed, 1138 insertions, 550 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 675f576..7808f23 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -184,6 +184,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 1b33cde..a03488f 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 20130208) +set(CMake_VERSION_TWEAK 20130220) #set(CMake_VERSION_RC 1) diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index 08cdcb5..84714f3 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -1784,6 +1784,22 @@ cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath) } //---------------------------------------------------------------------------- +static void cmCLI_ExpandListUnique(const char* str, + std::vector<std::string>& out, + std::set<cmStdString>& emitted) +{ + std::vector<std::string> tmp; + cmSystemTools::ExpandListArgument(str, tmp); + for(std::vector<std::string>::iterator i = tmp.begin(); i != tmp.end(); ++i) + { + if(emitted.insert(*i).second) + { + out.push_back(*i); + } + } +} + +//---------------------------------------------------------------------------- void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs, bool for_install) { @@ -1808,10 +1824,11 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs, this->Target->GetPropertyAsBool("INSTALL_RPATH_USE_LINK_PATH"); // Construct the RPATH. + std::set<cmStdString> emitted; if(use_install_rpath) { const char* install_rpath = this->Target->GetProperty("INSTALL_RPATH"); - cmSystemTools::ExpandListArgument(install_rpath, runtimeDirs); + cmCLI_ExpandListUnique(install_rpath, runtimeDirs, emitted); } if(use_build_rpath || use_link_rpath) { @@ -1823,7 +1840,10 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs, // support or if using the link path as an rpath. if(use_build_rpath) { - runtimeDirs.push_back(*ri); + if(emitted.insert(*ri).second) + { + runtimeDirs.push_back(*ri); + } } else if(use_link_rpath) { @@ -1835,15 +1855,40 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs, !cmSystemTools::IsSubDirectory(ri->c_str(), topSourceDir) && !cmSystemTools::IsSubDirectory(ri->c_str(), topBinaryDir)) { - runtimeDirs.push_back(*ri); + if(emitted.insert(*ri).second) + { + runtimeDirs.push_back(*ri); + } } } } } + // Add runtime paths required by the languages to always be + // present. This is done even when skipping rpath support. + { + cmTarget::LinkClosure const* lc = + this->Target->GetLinkClosure(this->Config, this->HeadTarget); + for(std::vector<std::string>::const_iterator li = lc->Languages.begin(); + li != lc->Languages.end(); ++li) + { + std::string useVar = "CMAKE_" + *li + + "_USE_IMPLICIT_LINK_DIRECTORIES_IN_RUNTIME_PATH"; + if(this->Makefile->IsOn(useVar.c_str())) + { + std::string dirVar = "CMAKE_" + *li + + "_IMPLICIT_LINK_DIRECTORIES"; + if(const char* dirs = this->Makefile->GetDefinition(dirVar.c_str())) + { + cmCLI_ExpandListUnique(dirs, runtimeDirs, emitted); + } + } + } + } + // Add runtime paths required by the platform to always be // present. This is done even when skipping rpath support. - cmSystemTools::ExpandListArgument(this->RuntimeAlways.c_str(), runtimeDirs); + cmCLI_ExpandListUnique(this->RuntimeAlways.c_str(), runtimeDirs, emitted); } //---------------------------------------------------------------------------- diff --git a/Source/cmDocumentGeneratorExpressions.h b/Source/cmDocumentGeneratorExpressions.h index 3993f7d..8b80a8a 100644 --- a/Source/cmDocumentGeneratorExpressions.h +++ b/Source/cmDocumentGeneratorExpressions.h @@ -51,14 +51,6 @@ "on the target tgt.\n" \ "Note that tgt is not added as a dependency of the target this " \ "expression is evaluated on.\n" \ - " $<LINKED:item> = An empty string if item is not a " \ - "target. If item is a target then the " \ - "INTERFACE_INCLUDE_DIRECTORIES or INTERFACE_COMPILE_DEFINITIONS " \ - "content is read from the target. " \ - "This generator expression can only be used in evaluation of the " \ - "INCLUDE_DIRECTORIES or COMPILE_DEFINITIONS property. Note that " \ - "this expression is for internal use and may be changed or removed " \ - "in the future.\n" \ " $<TARGET_POLICY:pol> = '1' if the policy was NEW when " \ "the 'head' target was created, else '0'. If the policy was not " \ "set, the warning message for the policy will be emitted. This " \ diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index 9f7c0c1..204bd9a 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -1167,9 +1167,10 @@ void cmDocumentVariables::DefineVariables(cmake* cm) ("CMAKE_BUILD_INTERFACE_INCLUDES", cmProperty::VARIABLE, "Automatically add the current source- and build directories " "to the INTERFACE_INCLUDE_DIRECTORIES.", - "If this variable is enabled, CMake automatically adds for each " - "target ${CMAKE_CURRENT_SOURCE_DIR} and ${CMAKE_CURRENT_BINARY_DIR} " - "to the INTERFACE_INCLUDE_DIRECTORIES." + "If this variable is enabled, CMake automatically adds for each shared " + "library target, static library target, module target and executable " + "target, ${CMAKE_CURRENT_SOURCE_DIR} and ${CMAKE_CURRENT_BINARY_DIR} to " + "the INTERFACE_INCLUDE_DIRECTORIES." "By default CMAKE_BUILD_INTERFACE_INCLUDES is OFF.", false, "Variables that Control the Build"); @@ -1866,6 +1867,9 @@ void cmDocumentVariables::DefineVariables(cmake* cm) cmProperty::VARIABLE,0,0); cm->DefineProperty("CMAKE_PLATFORM_REQUIRED_RUNTIME_PATH", cmProperty::VARIABLE,0,0); + cm->DefineProperty( + "CMAKE_<LANG>_USE_IMPLICIT_LINK_DIRECTORIES_IN_RUNTIME_PATH", + cmProperty::VARIABLE,0,0); cm->DefineProperty("CMAKE_SHARED_MODULE_CREATE_<LANG>_FLAGS", cmProperty::VARIABLE,0,0); cm->DefineProperty("CMAKE_SHARED_MODULE_<LANG>_FLAGS", diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 7e4c3df..ef4ea38 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -25,8 +25,6 @@ #include <cmsys/auto_ptr.hxx> -#include "assert.h" - //---------------------------------------------------------------------------- cmExportFileGenerator::cmExportFileGenerator() { @@ -162,7 +160,7 @@ void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName, preprocessRule); if (!prepro.empty()) { - this->ResolveTargetsInGeneratorExpressions(prepro, target, propName, + this->ResolveTargetsInGeneratorExpressions(prepro, target, missingTargets); properties[outputName] = prepro; } @@ -266,16 +264,15 @@ void cmExportFileGenerator::GenerateInterfaceProperties(cmTarget *target, { if (!properties.empty()) { - os << "if(NOT ${CMAKE_FIND_PACKAGE_NAME}_NO_INTERFACES)\n"; std::string targetName = this->Namespace; targetName += target->GetName(); - os << " set_target_properties(" << targetName << " PROPERTIES\n"; + os << "set_target_properties(" << targetName << " PROPERTIES\n"; for(ImportPropertyMap::const_iterator pi = properties.begin(); pi != properties.end(); ++pi) { - os << " " << pi->first << " \"" << pi->second << "\"\n"; + os << " " << pi->first << " \"" << pi->second << "\"\n"; } - os << " )\nendif()\n\n"; + os << ")\n\n"; } } @@ -315,25 +312,16 @@ cmExportFileGenerator::AddTargetNamespace(std::string &input, } //---------------------------------------------------------------------------- -static bool isGeneratorExpression(const std::string &lib) -{ - const std::string::size_type openpos = lib.find("$<"); - return (openpos != std::string::npos) - && (lib.find(">", openpos) != std::string::npos); -} - -//---------------------------------------------------------------------------- void cmExportFileGenerator::ResolveTargetsInGeneratorExpressions( std::string &input, - cmTarget* target, const char *propName, + cmTarget* target, std::vector<std::string> &missingTargets, FreeTargetsReplace replace) { if (replace == NoReplaceFreeTargets) { - this->ResolveTargetsInGeneratorExpression(input, target, propName, - missingTargets); + this->ResolveTargetsInGeneratorExpression(input, target, missingTargets); return; } std::vector<std::string> parts; @@ -344,7 +332,7 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpressions( for(std::vector<std::string>::iterator li = parts.begin(); li != parts.end(); ++li) { - if (!isGeneratorExpression(*li)) + if (cmGeneratorExpression::Find(*li) == std::string::npos) { this->AddTargetNamespace(*li, target, missingTargets); } @@ -352,7 +340,7 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpressions( { this->ResolveTargetsInGeneratorExpression( *li, - target, propName, + target, missingTargets); } input += sep + *li; @@ -364,7 +352,7 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpressions( void cmExportFileGenerator::ResolveTargetsInGeneratorExpression( std::string &input, - cmTarget* target, const char *propName, + cmTarget* target, std::vector<std::string> &missingTargets) { std::string::size_type pos = 0; @@ -401,57 +389,6 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpression( std::string errorString; pos = 0; lastPos = pos; - while((pos = input.find("$<LINKED:", lastPos)) != input.npos) - { - std::string::size_type nameStartPos = pos + sizeof("$<LINKED:") - 1; - std::string::size_type endPos = input.find(">", nameStartPos); - if (endPos == input.npos) - { - errorString = "$<LINKED:...> expression incomplete"; - break; - } - std::string targetName = input.substr(nameStartPos, - endPos - nameStartPos); - if(targetName.find("$<") != input.npos) - { - errorString = "$<LINKED:...> requires its parameter to be a " - "literal."; - break; - } - if (this->AddTargetNamespace(targetName, target, missingTargets)) - { - assert(propName); // The link libraries strings will - // never contain $<LINKED> - std::string replacement = "$<TARGET_PROPERTY:" - + targetName + "," + propName; - input.replace(pos, endPos - pos, replacement); - lastPos = pos + replacement.size() + 1; - } - else - { - if (pos != 0) - { - if (input[pos - 1] == ';') - { - --pos; - } - } - else if (input[endPos + 1] == ';') - { - ++endPos; - } - input.replace(pos, endPos - pos + 1, ""); - lastPos = pos; - } - } - if (!errorString.empty()) - { - mf->IssueMessage(cmake::FATAL_ERROR, errorString); - return; - } - - pos = 0; - lastPos = pos; while((pos = input.find("$<TARGET_NAME:", lastPos)) != input.npos) { std::string::size_type nameStartPos = pos + sizeof("$<TARGET_NAME:") - 1; @@ -545,7 +482,7 @@ cmExportFileGenerator preprocessRule); if (!prepro.empty()) { - this->ResolveTargetsInGeneratorExpressions(prepro, target, 0, + this->ResolveTargetsInGeneratorExpressions(prepro, target, missingTargets, ReplaceFreeTargets); properties["IMPORTED_LINK_INTERFACE_LIBRARIES" + suffix] = prepro; diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h index 5ad27bf..776be61 100644 --- a/Source/cmExportFileGenerator.h +++ b/Source/cmExportFileGenerator.h @@ -119,7 +119,7 @@ protected: }; void ResolveTargetsInGeneratorExpressions(std::string &input, - cmTarget* target, const char *propName, + cmTarget* target, std::vector<std::string> &missingTargets, FreeTargetsReplace replace = NoReplaceFreeTargets); @@ -150,7 +150,7 @@ private: std::vector<std::string> &missingTargets); void ResolveTargetsInGeneratorExpression(std::string &input, - cmTarget* target, const char *propName, + cmTarget* target, std::vector<std::string> &missingTargets); virtual void ReplaceInstallPrefix(std::string &input); diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h index 7a70431..20dd57a 100644 --- a/Source/cmExportInstallFileGenerator.h +++ b/Source/cmExportInstallFileGenerator.h @@ -15,10 +15,7 @@ #include "cmExportFileGenerator.h" class cmInstallExportGenerator; -class cmInstallFilesGenerator; class cmInstallTargetGenerator; -class cmTargetExport; -class cmExportSet; /** \class cmExportInstallFileGenerator * \brief Generate a file exporting targets from an install tree. 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/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 0cdbb82..018ce7e 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -2409,7 +2409,8 @@ bool cmFileCommand::HandleRemove(std::vector<std::string> const& args, fileName += "/" + *i; } - if(cmSystemTools::FileIsDirectory(fileName.c_str()) && recurse) + if(cmSystemTools::FileIsDirectory(fileName.c_str()) && + !cmSystemTools::FileIsSymlink(fileName.c_str()) && recurse) { cmSystemTools::RemoveADirectory(fileName.c_str()); } diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index 6e78bd7..470ceca 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -376,26 +376,6 @@ void cmFindPackageCommand::GenerateDocumentation() "The package configuration file may set <package>_FOUND to false " "to tell find_package that component requirements are not satisfied." "\n" - "A package configuration file may include() a <package>Targets.cmake " - "file, created by install(EXPORT) in the upstream source, to import " - "targets into the downstream consumer. " - "When a new version of the upstream adds INTERFACE properties not " - "present in a previous version it can change behavior for existing " - "downstreams. " - "In order to remain source compatible the upstream package configuration " - "file may set <package>_NO_INTERFACES to disable INTERFACE properties. " - "For example, code of the form:\n" - " if(<package>_FIND_VERSION VERSION_LESS <new-version>\n" - " AND NOT <package>_INTERFACES)\n" - " set(<package>_NO_INTERFACES 1)\n" - " endif()\n" - " include(\"${CMAKE_CURRENT_LIST_DIR}/<package>Targets.cmake\")\n" - "tells <package>Targets.cmake not to provide the INTERFACE properties " - "unless the downstream requests at least <new-version> or sets " - "<package>_INTERFACES to explicitly request them. " - "This allows consumers to decide when to enable the new interfaces when " - "upgrading." - "\n" "See the cmake_policy() command documentation for discussion of the " "NO_POLICY_SCOPE option." ; diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index 7add1bf..5d162fe 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx @@ -95,14 +95,13 @@ const char *cmCompiledGeneratorExpression::Evaluate( for ( ; it != end; ++it) { - const std::string result = (*it)->Evaluate(&context, dagChecker); - this->Output += result; + this->Output += (*it)->Evaluate(&context, dagChecker); for(std::set<cmStdString>::const_iterator p = context.SeenTargetProperties.begin(); p != context.SeenTargetProperties.end(); ++p) { - this->SeenTargetProperties[*p] += result + ";"; + this->SeenTargetProperties.insert(*p); } if (context.HadError) { @@ -365,3 +364,26 @@ std::string cmGeneratorExpression::Preprocess(const std::string &input, assert(!"cmGeneratorExpression::Preprocess called with invalid args"); return std::string(); } + +//---------------------------------------------------------------------------- +std::string::size_type cmGeneratorExpression::Find(const std::string &input) +{ + const std::string::size_type openpos = input.find("$<"); + if (openpos != std::string::npos + && input.find(">", openpos) != std::string::npos) + { + return openpos; + } + return std::string::npos; +} + +//---------------------------------------------------------------------------- +bool cmGeneratorExpression::IsValidTargetName(const std::string &input) +{ + cmsys::RegularExpression targetNameValidator; + // The ':' is supported to allow use with IMPORTED targets. At least + // Qt 4 and 5 IMPORTED targets use ':' as the namespace delimiter. + targetNameValidator.compile("^[A-Za-z0-9_.:-]+$"); + + return targetNameValidator.find(input.c_str()); +} diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h index 700fe03..489b052 100644 --- a/Source/cmGeneratorExpression.h +++ b/Source/cmGeneratorExpression.h @@ -62,6 +62,10 @@ public: static void Split(const std::string &input, std::vector<std::string> &output); + static std::string::size_type Find(const std::string &input); + + static bool IsValidTargetName(const std::string &input); + private: cmGeneratorExpression(const cmGeneratorExpression &); void operator=(const cmGeneratorExpression &); @@ -86,7 +90,7 @@ public: std::set<cmTarget*> const& GetTargets() const { return this->Targets; } - std::map<cmStdString, cmStdString> const& GetSeenTargetProperties() const + std::set<cmStdString> const& GetSeenTargetProperties() const { return this->SeenTargetProperties; } ~cmCompiledGeneratorExpression(); @@ -120,7 +124,7 @@ private: bool NeedsParsing; mutable std::set<cmTarget*> Targets; - mutable std::map<cmStdString, cmStdString> SeenTargetProperties; + mutable std::set<cmStdString> SeenTargetProperties; mutable std::string Output; mutable bool HadContextSensitiveCondition; }; diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx index b9069ef..57e7358 100644 --- a/Source/cmGeneratorExpressionDAGChecker.cxx +++ b/Source/cmGeneratorExpressionDAGChecker.cxx @@ -148,8 +148,8 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries() return (strcmp(prop, "LINK_LIBRARIES") == 0 || strcmp(prop, "LINK_INTERFACE_LIBRARIES") == 0 || strcmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES") == 0 - || strncmp(prop, "LINK_INTERFACE_LIBRARIES_", 26) == 0 - || strncmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES_", 35) == 0); + || strncmp(prop, "LINK_INTERFACE_LIBRARIES_", 25) == 0 + || strncmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES_", 34) == 0); } //---------------------------------------------------------------------------- @@ -165,5 +165,6 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingCompileDefinitions() { const char *prop = this->Property.c_str(); return (strcmp(prop, "COMPILE_DEFINITIONS") == 0 - || strcmp(prop, "INTERFACE_COMPILE_DEFINITIONS") == 0 ); + || strcmp(prop, "INTERFACE_COMPILE_DEFINITIONS") == 0 + || strncmp(prop, "COMPILE_DEFINITIONS_", 20) == 0); } diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 5d94718..cd6a40b 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -333,10 +333,6 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode "$<TARGET_PROPERTY:...> expression requires one or two parameters"); return std::string(); } - cmsys::RegularExpression targetNameValidator; - // The ':' is supported to allow use with IMPORTED targets. At least - // Qt 4 and 5 IMPORTED targets use ':' as the namespace delimiter. - targetNameValidator.compile("^[A-Za-z0-9_.:-]+$"); cmsys::RegularExpression propertyNameValidator; propertyNameValidator.compile("^[A-Za-z0-9_]+$"); @@ -372,7 +368,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode std::string targetName = parameters.front(); propertyName = parameters[1]; - if (!targetNameValidator.find(targetName.c_str())) + if (!cmGeneratorExpression::IsValidTargetName(targetName)) { if (!propertyNameValidator.find(propertyName.c_str())) { @@ -402,7 +398,8 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode { // Keep track of the properties seen while processing. // The evaluation of the LINK_LIBRARIES generator expressions - // will check this to ensure that properties form a DAG. + // will check this to ensure that properties have one consistent + // value for all evaluations. context->SeenTargetProperties.insert(propertyName); } @@ -438,28 +435,84 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode // No error. We just skip cyclic references. return std::string(); case cmGeneratorExpressionDAGChecker::ALREADY_SEEN: - // No error. We're not going to find anything new here. - return std::string(); + for (size_t i = 0; + i < (sizeof(targetPropertyTransitiveWhitelist) / + sizeof(*targetPropertyTransitiveWhitelist)); + ++i) + { + if (targetPropertyTransitiveWhitelist[i] == propertyName) + { + // No error. We're not going to find anything new here. + return std::string(); + } + } case cmGeneratorExpressionDAGChecker::DAG: break; } const char *prop = target->GetProperty(propertyName.c_str()); - if (!prop) + + std::string linkedTargetsContent; + + if (dagCheckerParent) { - if (target->IsImported()) + if (dagCheckerParent->EvaluatingLinkLibraries()) { - return std::string(); + if(!prop) + { + return std::string(); + } } - if (dagCheckerParent && dagCheckerParent->EvaluatingLinkLibraries()) + else { - return std::string(); + assert(dagCheckerParent->EvaluatingIncludeDirectories() + || dagCheckerParent->EvaluatingCompileDefinitions()); + + if (propertyName == "INTERFACE_INCLUDE_DIRECTORIES" + || propertyName == "INTERFACE_COMPILE_DEFINITIONS") + { + const cmTarget::LinkInterface *iface = target->GetLinkInterface( + context->Config, + context->HeadTarget); + if(iface) + { + cmGeneratorExpression ge(context->Backtrace); + + std::string sep; + std::string depString; + for (std::vector<std::string>::const_iterator + it = iface->Libraries.begin(); + it != iface->Libraries.end(); ++it) + { + if (context->Makefile->FindTargetToUse(it->c_str())) + { + depString += + sep + "$<TARGET_PROPERTY:" + *it + "," + propertyName + ">"; + sep = ";"; + } + } + cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = + ge.Parse(depString); + linkedTargetsContent = cge->Evaluate(context->Makefile, + context->Config, + context->Quiet, + context->HeadTarget, + target, + &dagChecker); + if (cge->GetHadContextSensitiveCondition()) + { + context->HadContextSensitiveCondition = true; + } + } + } } - if (propertyName == "POSITION_INDEPENDENT_CODE") + } + + if (!prop) + { + if (target->IsImported()) { - context->HadContextSensitiveCondition = true; - return target->GetLinkInterfaceDependentBoolProperty( - "POSITION_INDEPENDENT_CODE", context->Config) ? "1" : "0"; + return linkedTargetsContent; } if (target->IsLinkInterfaceDependentBoolProperty(propertyName, context->Config)) @@ -480,7 +533,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode return propContent ? propContent : ""; } - return std::string(); + return linkedTargetsContent; } for (size_t i = 0; @@ -503,6 +556,10 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode { context->HadContextSensitiveCondition = true; } + if (!linkedTargetsContent.empty()) + { + result += (result.empty() ? "" : ";") + linkedTargetsContent; + } return result; } } @@ -656,98 +713,6 @@ static const struct InstallPrefixNode : public cmGeneratorExpressionNode } installPrefixNode; //---------------------------------------------------------------------------- -static const struct LinkedNode : public cmGeneratorExpressionNode -{ - LinkedNode() {} - - virtual bool GeneratesContent() const { return true; } - virtual int NumExpectedParameters() const { return 1; } - virtual bool RequiresLiteralInput() const { return true; } - - std::string Evaluate(const std::vector<std::string> ¶meters, - cmGeneratorExpressionContext *context, - const GeneratorExpressionContent *content, - cmGeneratorExpressionDAGChecker *dagChecker) const - { - if (dagChecker->EvaluatingIncludeDirectories()) - { - return this->GetInterfaceProperty(parameters.front(), - "INCLUDE_DIRECTORIES", - context, content, dagChecker); - } - if (dagChecker->EvaluatingCompileDefinitions()) - { - return this->GetInterfaceProperty(parameters.front(), - "COMPILE_DEFINITIONS", - context, content, dagChecker); - } - - reportError(context, content->GetOriginalExpression(), - "$<LINKED:...> may only be used in INCLUDE_DIRECTORIES and " - "COMPILE_DEFINITIONS properties."); - - return std::string(); - } - -private: - std::string GetInterfaceProperty(const std::string &item, - const std::string &prop, - cmGeneratorExpressionContext *context, - const GeneratorExpressionContent *content, - cmGeneratorExpressionDAGChecker *dagCheckerParent) const - { - cmTarget *target = context->CurrentTarget - ->GetMakefile()->FindTargetToUse(item.c_str()); - if (!target) - { - return std::string(); - } - std::string propertyName = "INTERFACE_" + prop; - const char *propContent = target->GetProperty(propertyName.c_str()); - if (!propContent) - { - return std::string(); - } - - cmGeneratorExpressionDAGChecker dagChecker(context->Backtrace, - target->GetName(), - propertyName, - content, - dagCheckerParent); - - switch (dagChecker.check()) - { - case cmGeneratorExpressionDAGChecker::SELF_REFERENCE: - dagChecker.reportError(context, content->GetOriginalExpression()); - return std::string(); - case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE: - // No error. We just skip cyclic references. - return std::string(); - case cmGeneratorExpressionDAGChecker::ALREADY_SEEN: - // No error. We're not going to find anything new here. - return std::string(); - case cmGeneratorExpressionDAGChecker::DAG: - break; - } - - cmGeneratorExpression ge(context->Backtrace); - cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(propContent); - std::string result = cge->Evaluate(context->Makefile, - context->Config, - context->Quiet, - context->HeadTarget, - target, - &dagChecker); - if (cge->GetHadContextSensitiveCondition()) - { - context->HadContextSensitiveCondition = true; - } - return result; - } - -} linkedNode; - -//---------------------------------------------------------------------------- template<bool linker, bool soname> struct TargetFilesystemArtifactResultCreator { @@ -867,10 +832,7 @@ struct TargetFilesystemArtifact : public cmGeneratorExpressionNode // Lookup the referenced target. std::string name = *parameters.begin(); - cmsys::RegularExpression targetValidator; - // The ':' is supported to allow use with IMPORTED targets. - targetValidator.compile("^[A-Za-z0-9_.:-]+$"); - if (!targetValidator.find(name.c_str())) + if (!cmGeneratorExpression::IsValidTargetName(name)) { ::reportError(context, content->GetOriginalExpression(), "Expression syntax not recognized."); @@ -984,8 +946,6 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier) return &targetDefinedNode; else if (identifier == "INSTALL_PREFIX") return &installPrefixNode; - else if (identifier == "LINKED") - return &linkedNode; return 0; } 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..b50dc23 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; @@ -2914,7 +2923,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/cmListFileCache.h b/Source/cmListFileCache.h index c057754..fec3d07 100644 --- a/Source/cmListFileCache.h +++ b/Source/cmListFileCache.h @@ -76,4 +76,13 @@ struct cmListFile std::vector<cmListFileFunction> Functions; }; +struct cmValueWithOrigin { + cmValueWithOrigin(const std::string &value, + const cmListFileBacktrace &bt) + : Value(value), Backtrace(bt) + {} + std::string Value; + cmListFileBacktrace Backtrace; +}; + #endif diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index ecf6b41..dc39fdc 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1212,7 +1212,8 @@ cmLocalGenerator::ConvertToIncludeReference(std::string const& path) //---------------------------------------------------------------------------- std::string cmLocalGenerator::GetIncludeFlags( const std::vector<std::string> &includes, - const char* lang, bool forResponseFile) + const char* lang, bool forResponseFile, + const char *config) { if(!lang) { @@ -1285,7 +1286,7 @@ std::string cmLocalGenerator::GetIncludeFlags( if(!flagUsed || repeatFlag) { if(sysIncludeFlag && - this->Makefile->IsSystemIncludeDirectory(i->c_str())) + this->Makefile->IsSystemIncludeDirectory(i->c_str(), config)) { includeFlags << sysIncludeFlag; } diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index b2ff0c4..84cf6ca 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -149,7 +149,8 @@ public: virtual void AppendFlags(std::string& flags, const char* newFlags); ///! Get the include flags for the current makefile and language std::string GetIncludeFlags(const std::vector<std::string> &includes, - const char* lang, bool forResponseFile = false); + const char* lang, bool forResponseFile = false, + const char *config = 0); /** * Encode a list of preprocessor definitions for the compiler diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index d629e71..f6ab0d0 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -1961,34 +1961,17 @@ void cmLocalUnixMakefileGenerator3 } // Build a list of preprocessor definitions for the target. - std::vector<std::string> defines; - { - std::string defPropName = "COMPILE_DEFINITIONS_"; - defPropName += cmSystemTools::UpperCase(this->ConfigurationName); - if(const char* ddefs = this->Makefile->GetProperty("COMPILE_DEFINITIONS")) - { - cmSystemTools::ExpandListArgument(ddefs, defines); - } - if(const char* cdefs = target.GetProperty("COMPILE_DEFINITIONS")) - { - cmSystemTools::ExpandListArgument(cdefs, defines); - } - if(const char* dcdefs = this->Makefile->GetProperty(defPropName.c_str())) - { - cmSystemTools::ExpandListArgument(dcdefs, defines); - } - if(const char* ccdefs = target.GetProperty(defPropName.c_str())) - { - cmSystemTools::ExpandListArgument(ccdefs, defines); - } - } + std::set<std::string> defines; + this->AppendDefines(defines, target.GetCompileDefinitions()); + this->AppendDefines(defines, target.GetCompileDefinitions( + this->ConfigurationName.c_str())); if(!defines.empty()) { cmakefileStream << "\n" << "# Preprocessor definitions for this target.\n" << "SET(CMAKE_TARGET_DEFINITIONS\n"; - for(std::vector<std::string>::const_iterator di = defines.begin(); + for(std::set<std::string>::const_iterator di = defines.begin(); di != defines.end(); ++di) { cmakefileStream diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index f9df861..f07ebef 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -1134,6 +1134,17 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, { fout << "\t\t\t\tGenerateDebugInformation=\"TRUE\"\n"; } + if(this->WindowsCEProject) + { + if(this->GetVersion() < VS9) + { + fout << "\t\t\t\tSubSystem=\"9\"\n"; + } + else + { + fout << "\t\t\t\tSubSystem=\"8\"\n"; + } + } std::string stackVar = "CMAKE_"; stackVar += linkLanguage; stackVar += "_STACK_SIZE"; @@ -1223,8 +1234,15 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, } if ( this->WindowsCEProject ) { - fout << "\t\t\t\tSubSystem=\"9\"\n" - << "\t\t\t\tEntryPointSymbol=\"" + if(this->GetVersion() < VS9) + { + fout << "\t\t\t\tSubSystem=\"9\"\n"; + } + else + { + fout << "\t\t\t\tSubSystem=\"8\"\n"; + } + fout << "\t\t\t\tEntryPointSymbol=\"" << (isWin32Executable ? "WinMainCRTStartup" : "mainACRTStartup") << "\"\n"; } diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index dbd0c36..25ccbc7 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -23,6 +23,7 @@ #include "cmListFileCache.h" #include "cmCommandArgumentParserHelper.h" #include "cmDocumentCompileDefinitions.h" +#include "cmGeneratorExpression.h" #include "cmTest.h" #ifdef CMAKE_BUILD_WITH_CMAKE # include "cmVariableWatch.h" @@ -1486,7 +1487,7 @@ void cmMakefile::InitializeFromParent() // Initialize definitions with the closure of the parent scope. this->Internal->VarStack.top() = parent->Internal->VarStack.top().Closure(); - const std::vector<IncludeDirectoriesEntry> parentIncludes = + const std::vector<cmValueWithOrigin> parentIncludes = parent->GetIncludeDirectoriesEntries(); this->IncludeDirectoriesEntries.insert(this->IncludeDirectoriesEntries.end(), parentIncludes.begin(), @@ -1635,13 +1636,13 @@ void cmMakefile::AddIncludeDirectories(const std::vector<std::string> &incs, sep = ";"; } - std::vector<IncludeDirectoriesEntry>::iterator position = + std::vector<cmValueWithOrigin>::iterator position = before ? this->IncludeDirectoriesEntries.begin() : this->IncludeDirectoriesEntries.end(); cmListFileBacktrace lfbt; this->GetBacktrace(lfbt); - IncludeDirectoriesEntry entry(incString, lfbt); + cmValueWithOrigin entry(incString, lfbt); this->IncludeDirectoriesEntries.insert(position, entry); // Property on each target: @@ -1665,10 +1666,24 @@ cmMakefile::AddSystemIncludeDirectories(const std::set<cmStdString> &incs) } //---------------------------------------------------------------------------- -bool cmMakefile::IsSystemIncludeDirectory(const char* dir) +bool cmMakefile::IsSystemIncludeDirectory(const char* dir, const char *config) { - return (this->SystemIncludeDirectories.find(dir) != - this->SystemIncludeDirectories.end()); + for (std::set<cmStdString>::const_iterator + it = this->SystemIncludeDirectories.begin(); + it != this->SystemIncludeDirectories.end(); ++it) + { + cmListFileBacktrace lfbt; + cmGeneratorExpression ge(lfbt); + + std::vector<std::string> incs; + cmSystemTools::ExpandListArgument(ge.Parse(*it) + ->Evaluate(this, config, false), incs); + if (std::find(incs.begin(), incs.end(), dir) != incs.end()) + { + return true; + } + } + return false; } void cmMakefile::AddDefinition(const char* name, const char* value) @@ -3446,7 +3461,7 @@ void cmMakefile::SetProperty(const char* prop, const char* value) cmListFileBacktrace lfbt; this->GetBacktrace(lfbt); this->IncludeDirectoriesEntries.push_back( - IncludeDirectoriesEntry(value, lfbt)); + cmValueWithOrigin(value, lfbt)); return; } @@ -3485,7 +3500,7 @@ void cmMakefile::AppendProperty(const char* prop, const char* value, cmListFileBacktrace lfbt; this->GetBacktrace(lfbt); this->IncludeDirectoriesEntries.push_back( - IncludeDirectoriesEntry(value, lfbt)); + cmValueWithOrigin(value, lfbt)); return; } if ( propname == "LINK_DIRECTORIES" ) @@ -3602,7 +3617,7 @@ const char *cmMakefile::GetProperty(const char* prop, else if (!strcmp("INCLUDE_DIRECTORIES",prop)) { std::string sep; - for (std::vector<IncludeDirectoriesEntry>::const_iterator + for (std::vector<cmValueWithOrigin>::const_iterator it = this->IncludeDirectoriesEntries.begin(), end = this->IncludeDirectoriesEntries.end(); it != end; ++it) diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index a2783f2..74a731d 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -22,7 +22,6 @@ #include "cmNewLineStyle.h" #include "cmGeneratorTarget.h" #include "cmake.h" -#include "cmMakefileIncludeDirectoriesEntry.h" #if defined(CMAKE_BUILD_WITH_CMAKE) #include "cmSourceGroup.h" @@ -547,7 +546,7 @@ public: * Mark include directories as system directories. */ void AddSystemIncludeDirectories(const std::set<cmStdString> &incs); - bool IsSystemIncludeDirectory(const char* dir); + bool IsSystemIncludeDirectory(const char* dir, const char *config); /** Expand out any arguements in the vector that have ; separated * strings into multiple arguements. A new vector is created @@ -863,9 +862,7 @@ public: /** Set whether or not to report a CMP0000 violation. */ void SetCheckCMP0000(bool b) { this->CheckCMP0000 = b; } - typedef cmMakefileIncludeDirectoriesEntry IncludeDirectoriesEntry; - - std::vector<IncludeDirectoriesEntry> GetIncludeDirectoriesEntries() const + std::vector<cmValueWithOrigin> GetIncludeDirectoriesEntries() const { return this->IncludeDirectoriesEntries; } @@ -921,7 +918,7 @@ protected: std::vector<std::string> HeaderFileExtensions; std::string DefineFlags; - std::vector<IncludeDirectoriesEntry> IncludeDirectoriesEntries; + std::vector<cmValueWithOrigin> IncludeDirectoriesEntries; // Track the value of the computed DEFINITIONS property. void AddDefineFlag(const char*, std::string&); diff --git a/Source/cmMakefileIncludeDirectoriesEntry.h b/Source/cmMakefileIncludeDirectoriesEntry.h deleted file mode 100644 index f35642d..0000000 --- a/Source/cmMakefileIncludeDirectoriesEntry.h +++ /dev/null @@ -1,28 +0,0 @@ -/*============================================================================ - CMake - Cross Platform Makefile Generator - Copyright 2012 Stephen Kelly <steveire@gmail.com> - - 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 cmMakefileIncludeDirectoriesEntry_h -#define cmMakefileIncludeDirectoriesEntry_h - -#include <string> -#include "cmListFileCache.h" - -struct cmMakefileIncludeDirectoriesEntry { - cmMakefileIncludeDirectoriesEntry(const std::string &value, - const cmListFileBacktrace &bt) - : Value(value), Backtrace(bt) - {} - std::string Value; - cmListFileBacktrace Backtrace; -}; - -#endif 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 cc42175..4818f1b 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -44,14 +44,14 @@ static bool containsQ_OBJECT(const std::string& text) static std::string findMatchingHeader(const std::string& absPath, const std::string& mocSubDir, const std::string& basename, - const std::list<std::string>& headerExtensions) + const std::vector<std::string>& headerExtensions) { std::string header; - for(std::list<std::string>::const_iterator ext = headerExtensions.begin(); + for(std::vector<std::string>::const_iterator ext = headerExtensions.begin(); ext != headerExtensions.end(); ++ext) { - std::string sourceFilePath = absPath + basename + (*ext); + std::string sourceFilePath = absPath + basename + "." + (*ext); if (cmsys::SystemTools::FileExists(sourceFilePath.c_str())) { header = sourceFilePath; @@ -59,7 +59,7 @@ static std::string findMatchingHeader(const std::string& absPath, } if (!mocSubDir.empty()) { - sourceFilePath = mocSubDir + basename + (*ext); + sourceFilePath = mocSubDir + basename + "." + (*ext); if (cmsys::SystemTools::FileExists(sourceFilePath.c_str())) { header = sourceFilePath; @@ -296,7 +296,7 @@ bool cmQtAutomoc::Run(const char* targetDirectory) if (this->QtMajorVersion == "4" || this->QtMajorVersion == "5") { - success = this->RunAutomoc(); + success = this->RunAutomoc(makefile); } this->WriteOldMocDefinitionsFile(targetDirectory); @@ -504,7 +504,7 @@ void cmQtAutomoc::Init() } -bool cmQtAutomoc::RunAutomoc() +bool cmQtAutomoc::RunAutomoc(cmMakefile* makefile) { if (!cmsys::SystemTools::FileExists(this->OutMocCppFilename.c_str()) || (this->OldCompileSettingsStr != this->CurrentCompileSettingsStr)) @@ -528,22 +528,8 @@ bool cmQtAutomoc::RunAutomoc() std::vector<std::string> sourceFiles; cmSystemTools::ExpandListArgument(this->Sources, sourceFiles); - std::list<std::string> headerExtensions; - headerExtensions.push_back(".h"); - headerExtensions.push_back(".hpp"); - headerExtensions.push_back(".hxx"); -#if defined(_WIN32) - // not case sensitive, don't add ".H" -#elif defined(__APPLE__) - // detect case-sensitive filesystem - long caseSensitive = pathconf(this->Srcdir.c_str(), _PC_CASE_SENSITIVE); - if (caseSensitive == 1) - { - headerExtensions.push_back(".H"); - } -#else - headerExtensions.push_back(".H"); -#endif + const std::vector<std::string>& headerExtensions = + makefile->GetHeaderExtensions(); for (std::vector<std::string>::const_iterator it = sourceFiles.begin(); it != sourceFiles.end(); @@ -643,7 +629,7 @@ bool cmQtAutomoc::RunAutomoc() void cmQtAutomoc::ParseCppFile(const std::string& absFilename, - const std::list<std::string>& headerExtensions, + const std::vector<std::string>& headerExtensions, std::map<std::string, std::string>& includedMocs) { cmsys::RegularExpression mocIncludeRegExp( @@ -821,7 +807,7 @@ void cmQtAutomoc::ParseCppFile(const std::string& absFilename, void cmQtAutomoc::StrictParseCppFile(const std::string& absFilename, - const std::list<std::string>& headerExtensions, + const std::vector<std::string>& headerExtensions, std::map<std::string, std::string>& includedMocs) { cmsys::RegularExpression mocIncludeRegExp( @@ -932,8 +918,8 @@ void cmQtAutomoc::StrictParseCppFile(const std::string& absFilename, void cmQtAutomoc::SearchHeadersForCppFile(const std::string& absFilename, - const std::list<std::string>& headerExtensions, - std::set<std::string>& absHeaders) + const std::vector<std::string>& headerExtensions, + std::set<std::string>& absHeaders) { // search for header files and private header files we may need to moc: const std::string basename = @@ -941,22 +927,22 @@ void cmQtAutomoc::SearchHeadersForCppFile(const std::string& absFilename, const std::string absPath = cmsys::SystemTools::GetFilenamePath( cmsys::SystemTools::GetRealPath(absFilename.c_str())) + '/'; - for(std::list<std::string>::const_iterator ext = headerExtensions.begin(); + for(std::vector<std::string>::const_iterator ext = headerExtensions.begin(); ext != headerExtensions.end(); ++ext) { - const std::string headerName = absPath + basename + (*ext); + const std::string headerName = absPath + basename + "." + (*ext); if (cmsys::SystemTools::FileExists(headerName.c_str())) { absHeaders.insert(headerName); break; } } - for(std::list<std::string>::const_iterator ext = headerExtensions.begin(); + for(std::vector<std::string>::const_iterator ext = headerExtensions.begin(); ext != headerExtensions.end(); ++ext) { - const std::string privateHeaderName = absPath+basename+"_p"+(*ext); + const std::string privateHeaderName = absPath+basename+"_p."+(*ext); if (cmsys::SystemTools::FileExists(privateHeaderName.c_str())) { absHeaders.insert(privateHeaderName); @@ -1077,7 +1063,8 @@ bool cmQtAutomoc::GenerateMoc(const std::string& sourceFile, } -std::string cmQtAutomoc::Join(const std::list<std::string>& lst,char separator) +std::string cmQtAutomoc::Join(const std::vector<std::string>& lst, + char separator) { if (lst.empty()) { @@ -1085,11 +1072,11 @@ std::string cmQtAutomoc::Join(const std::list<std::string>& lst,char separator) } std::string result; - for (std::list<std::string>::const_iterator it = lst.begin(); + for (std::vector<std::string>::const_iterator it = lst.begin(); it != lst.end(); ++it) { - result += (*it) + separator; + result += "." + (*it) + separator; } result.erase(result.end() - 1); return result; diff --git a/Source/cmQtAutomoc.h b/Source/cmQtAutomoc.h index a737477..69da80e 100644 --- a/Source/cmQtAutomoc.h +++ b/Source/cmQtAutomoc.h @@ -37,18 +37,18 @@ private: std::string MakeCompileSettingsString(cmMakefile* makefile); - bool RunAutomoc(); + bool RunAutomoc(cmMakefile* makefile); bool GenerateMoc(const std::string& sourceFile, const std::string& mocFileName); void ParseCppFile(const std::string& absFilename, - const std::list<std::string>& headerExtensions, + const std::vector<std::string>& headerExtensions, std::map<std::string, std::string>& includedMocs); void StrictParseCppFile(const std::string& absFilename, - const std::list<std::string>& headerExtensions, + const std::vector<std::string>& headerExtensions, std::map<std::string, std::string>& includedMocs); void SearchHeadersForCppFile(const std::string& absFilename, - const std::list<std::string>& headerExtensions, - std::set<std::string>& absHeaders); + const std::vector<std::string>& headerExtensions, + std::set<std::string>& absHeaders); void ParseHeaders(const std::set<std::string>& absHeaders, const std::map<std::string, std::string>& includedMocs, @@ -56,7 +56,7 @@ private: void Init(); - std::string Join(const std::list<std::string>& lst, char separator); + std::string Join(const std::vector<std::string>& lst, char separator); bool EndsWith(const std::string& str, const std::string& with); bool StartsWith(const std::string& str, const std::string& with); std::string ReadAll(const std::string& filename); diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index ca0e24b..003f3d8 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -137,6 +137,7 @@ public: std::vector<std::string> CachedIncludes; }; std::vector<IncludeDirectoriesEntry*> IncludeDirectoriesEntries; + std::vector<cmValueWithOrigin> LinkInterfaceIncludeDirectoriesEntries; }; //---------------------------------------------------------------------------- @@ -900,24 +901,30 @@ void cmTarget::DefineProperties(cmake *cm) "Properties which must be compatible with their link interface", "The COMPATIBLE_INTERFACE_BOOL property may contain a list of properties" "for this target which must be consistent when evaluated as a boolean " - "in the INTERFACE of all linked dependencies. For example, if a " - "property \"FOO\" appears in the list, then the \"INTERFACE_FOO\" " - "property content in all dependencies must be consistent with each " - "other, and with the \"FOO\" property in this target. " - "Consistency in this sense has the meaning that if the property is set," - "then it must have the same boolean value as all others, and if the " - "property is not set, then it is ignored."); + "in the INTERFACE of all linked dependees. For example, if a " + "property \"FOO\" appears in the list, then for each dependee, the " + "\"INTERFACE_FOO\" property content in all of its dependencies must be " + "consistent with each other, and with the \"FOO\" property in the " + "dependee. Consistency in this sense has the meaning that if the " + "property is set, then it must have the same boolean value as all " + "others, and if the property is not set, then it is ignored. Note that " + "for each dependee, the set of properties from this property must not " + "intersect with the set of properties from the " + "COMPATIBLE_INTERFACE_STRING property."); cm->DefineProperty ("COMPATIBLE_INTERFACE_STRING", cmProperty::TARGET, "Properties which must be string-compatible with their link interface", "The COMPATIBLE_INTERFACE_STRING property may contain a list of " "properties for this target which must be the same when evaluated as " - "a string in the INTERFACE of all linked dependencies. For example, " - "if a property \"FOO\" appears in the list, then the \"INTERFACE_FOO\" " - "property content in all dependencies must be equal with each " - "other, and with the \"FOO\" property in this target. If the " - "property is not set, then it is ignored."); + "a string in the INTERFACE of all linked dependees. For example, " + "if a property \"FOO\" appears in the list, then for each dependee, the " + "\"INTERFACE_FOO\" property content in all of its dependencies must be " + "equal with each other, and with the \"FOO\" property in the dependee. " + "If the property is not set, then it is ignored. Note that for each " + "dependee, the set of properties from this property must not intersect " + "with the set of properties from the COMPATIBLE_INTERFACE_BOOL " + "property."); cm->DefineProperty ("POST_INSTALL_SCRIPT", cmProperty::TARGET, @@ -1490,10 +1497,10 @@ void cmTarget::SetMakefile(cmMakefile* mf) // Initialize the INCLUDE_DIRECTORIES property based on the current value // of the same directory property: - const std::vector<cmMakefileIncludeDirectoriesEntry> parentIncludes = + const std::vector<cmValueWithOrigin> parentIncludes = this->Makefile->GetIncludeDirectoriesEntries(); - for (std::vector<cmMakefileIncludeDirectoriesEntry>::const_iterator it + for (std::vector<cmValueWithOrigin>::const_iterator it = parentIncludes.begin(); it != parentIncludes.end(); ++it) { this->InsertInclude(*it); @@ -2227,7 +2234,15 @@ void cmTarget::GetDirectLinkLibraries(const char *config, &dagChecker), libs); - this->AddLinkDependentTargetsForProperties(cge->GetSeenTargetProperties()); + std::set<cmStdString> seenProps = cge->GetSeenTargetProperties(); + for (std::set<cmStdString>::const_iterator it = seenProps.begin(); + it != seenProps.end(); ++it) + { + if (!this->GetProperty(it->c_str())) + { + this->LinkImplicitNullProperties.insert(*it); + } + } } } @@ -2270,14 +2285,6 @@ static std::string targetNameGenex(const char *lib) } //---------------------------------------------------------------------------- -static bool isGeneratorExpression(const std::string &lib) -{ - const std::string::size_type openpos = lib.find("$<"); - return (openpos != std::string::npos) - && (lib.find(">", openpos) != std::string::npos); -} - -//---------------------------------------------------------------------------- void cmTarget::AddLinkLibrary(cmMakefile& mf, const char *target, const char* lib, LinkLibraryType llt) @@ -2300,7 +2307,7 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf, llt).c_str()); } - if (isGeneratorExpression(lib)) + if (cmGeneratorExpression::Find(lib) != std::string::npos) { return; } @@ -2708,6 +2715,13 @@ void cmTarget::AppendProperty(const char* prop, const char* value, //---------------------------------------------------------------------------- void cmTarget::AppendBuildInterfaceIncludes() { + if(this->GetType() != cmTarget::SHARED_LIBRARY && + this->GetType() != cmTarget::STATIC_LIBRARY && + this->GetType() != cmTarget::MODULE_LIBRARY && + !this->IsExecutableWithExports()) + { + return; + } if (this->BuildInterfaceIncludesAppended) { return; @@ -2730,7 +2744,13 @@ void cmTarget::AppendBuildInterfaceIncludes() } //---------------------------------------------------------------------------- -void cmTarget::InsertInclude(const cmMakefileIncludeDirectoriesEntry &entry, +void cmTarget::AppendTllInclude(const cmValueWithOrigin &entry) +{ + this->Internal->LinkInterfaceIncludeDirectoriesEntries.push_back(entry); +} + +//---------------------------------------------------------------------------- +void cmTarget::InsertInclude(const cmValueWithOrigin &entry, bool before) { cmGeneratorExpression ge(entry.Backtrace); @@ -2744,42 +2764,18 @@ void cmTarget::InsertInclude(const cmMakefileIncludeDirectoriesEntry &entry, } //---------------------------------------------------------------------------- -std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config) +static void processIncludeDirectories(cmTarget *tgt, + const std::vector<cmTargetInternals::IncludeDirectoriesEntry*> &entries, + std::vector<std::string> &includes, + std::set<std::string> &uniqueIncludes, + cmGeneratorExpressionDAGChecker *dagChecker, + const char *config, bool debugIncludes) { - std::vector<std::string> includes; - std::set<std::string> uniqueIncludes; - cmListFileBacktrace lfbt; - - cmGeneratorExpressionDAGChecker dagChecker(lfbt, - this->GetName(), - "INCLUDE_DIRECTORIES", 0, 0); - - - std::vector<std::string> debugProperties; - const char *debugProp = - this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES"); - if (debugProp) - { - cmSystemTools::ExpandListArgument(debugProp, debugProperties); - } - - bool debugIncludes = !this->DebugIncludesDone - && std::find(debugProperties.begin(), - debugProperties.end(), - "INCLUDE_DIRECTORIES") - != debugProperties.end(); - - if (this->Makefile->IsGeneratingBuildSystem()) - { - this->DebugIncludesDone = true; - } + cmMakefile *mf = tgt->GetMakefile(); for (std::vector<cmTargetInternals::IncludeDirectoriesEntry*>::const_iterator - it = this->Internal->IncludeDirectoriesEntries.begin(), - end = this->Internal->IncludeDirectoriesEntries.end(); - it != end; ++it) + it = entries.begin(), end = entries.end(); it != end; ++it) { - bool testIsOff = true; bool cacheIncludes = false; std::vector<std::string> entryIncludes = (*it)->CachedIncludes; @@ -2789,13 +2785,14 @@ std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config) } else { - cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(this->Makefile, + cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf, config, false, - this, - &dagChecker), + tgt, + dagChecker), entryIncludes); - if (!(*it)->ge->GetHadContextSensitiveCondition()) + if (mf->IsGeneratingBuildSystem() + && !(*it)->ge->GetHadContextSensitiveCondition()) { cacheIncludes = true; } @@ -2825,11 +2822,90 @@ std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config) } if (!usedIncludes.empty()) { - this->Makefile->GetCMakeInstance()->IssueMessage(cmake::LOG, - "Used includes for target " + this->Name + ":\n" + mf->GetCMakeInstance()->IssueMessage(cmake::LOG, + std::string("Used includes for target ") + + tgt->GetName() + ":\n" + usedIncludes, (*it)->ge->GetBacktrace()); } } +} + +//---------------------------------------------------------------------------- +std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config) +{ + std::vector<std::string> includes; + std::set<std::string> uniqueIncludes; + cmListFileBacktrace lfbt; + + cmGeneratorExpressionDAGChecker dagChecker(lfbt, + this->GetName(), + "INCLUDE_DIRECTORIES", 0, 0); + + this->AppendBuildInterfaceIncludes(); + + std::vector<std::string> debugProperties; + const char *debugProp = + this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES"); + if (debugProp) + { + cmSystemTools::ExpandListArgument(debugProp, debugProperties); + } + + bool debugIncludes = !this->DebugIncludesDone + && std::find(debugProperties.begin(), + debugProperties.end(), + "INCLUDE_DIRECTORIES") + != debugProperties.end(); + + if (this->Makefile->IsGeneratingBuildSystem()) + { + this->DebugIncludesDone = true; + } + + processIncludeDirectories(this, + this->Internal->IncludeDirectoriesEntries, + includes, + uniqueIncludes, + &dagChecker, + config, + debugIncludes); + + std::vector<cmTargetInternals::IncludeDirectoriesEntry*> + linkInterfaceIncludeDirectoriesEntries; + + for (std::vector<cmValueWithOrigin>::const_iterator + it = this->Internal->LinkInterfaceIncludeDirectoriesEntries.begin(), + end = this->Internal->LinkInterfaceIncludeDirectoriesEntries.end(); + it != end; ++it) + { + { + cmGeneratorExpression ge(lfbt); + cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(it->Value); + std::string result = cge->Evaluate(this->Makefile, config, + false, this, 0, 0); + if (!this->Makefile->FindTargetToUse(result.c_str())) + { + continue; + } + } + cmGeneratorExpression ge(it->Backtrace); + cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse( + "$<TARGET_PROPERTY:" + it->Value + ",INTERFACE_INCLUDE_DIRECTORIES>"); + + linkInterfaceIncludeDirectoriesEntries.push_back( + new cmTargetInternals::IncludeDirectoriesEntry(cge)); + } + + processIncludeDirectories(this, + linkInterfaceIncludeDirectoriesEntries, + includes, + uniqueIncludes, + &dagChecker, + config, + debugIncludes); + + deleteAndClear(linkInterfaceIncludeDirectoriesEntries); + return includes; } @@ -2843,23 +2919,57 @@ std::string cmTarget::GetCompileDefinitions(const char *config) } const char *prop = this->GetProperty(defPropName.c_str()); + cmListFileBacktrace lfbt; + cmGeneratorExpressionDAGChecker dagChecker(lfbt, + this->GetName(), + defPropName, 0, 0); - if (!prop) + std::string result; + if (prop) { - return ""; + cmGeneratorExpression ge(lfbt); + + result = ge.Parse(prop)->Evaluate(this->Makefile, + config, + false, + this, + &dagChecker); } - cmListFileBacktrace lfbt; - cmGeneratorExpression ge(lfbt); + std::vector<std::string> libs; + this->GetDirectLinkLibraries(config, libs, this); - cmGeneratorExpressionDAGChecker dagChecker(lfbt, - this->GetName(), - defPropName, 0, 0); - return ge.Parse(prop)->Evaluate(this->Makefile, - config, - false, - this, - &dagChecker); + if (libs.empty()) + { + return result; + } + + std::string sep; + std::string depString; + for (std::vector<std::string>::const_iterator it = libs.begin(); + it != libs.end(); ++it) + { + if (this->Makefile->FindTargetToUse(it->c_str())) + { + depString += sep + "$<TARGET_PROPERTY:" + + *it + ",INTERFACE_COMPILE_DEFINITIONS>"; + sep = ";"; + } + } + + cmGeneratorExpression ge2(lfbt); + cmsys::auto_ptr<cmCompiledGeneratorExpression> cge2 = ge2.Parse(depString); + std::string depResult = cge2->Evaluate(this->Makefile, + config, + false, + this, + &dagChecker); + if (!depResult.empty()) + { + result += (result.empty() ? "" : ";") + depResult; + } + + return result; } //---------------------------------------------------------------------------- @@ -4522,18 +4632,6 @@ const char* cmTarget::GetExportMacro() } //---------------------------------------------------------------------------- -void cmTarget::GetLinkDependentTargetsForProperty(const std::string &p, - std::set<std::string> &targets) -{ - const std::map<cmStdString, std::set<std::string> >::const_iterator findIt - = this->LinkDependentProperties.find(p); - if (findIt != this->LinkDependentProperties.end()) - { - targets = findIt->second; - } -} - -//---------------------------------------------------------------------------- bool cmTarget::IsNullImpliedByLinkLibraries(const std::string &p) { return this->LinkImplicitNullProperties.find(p) @@ -4541,24 +4639,6 @@ bool cmTarget::IsNullImpliedByLinkLibraries(const std::string &p) } //---------------------------------------------------------------------------- -void cmTarget::AddLinkDependentTargetsForProperties( - const std::map<cmStdString, cmStdString> &map) -{ - for (std::map<cmStdString, cmStdString>::const_iterator it = map.begin(); - it != map.end(); ++it) - { - std::vector<std::string> targets; - cmSystemTools::ExpandListArgument(it->second.c_str(), targets); - this->LinkDependentProperties[it->first].insert(targets.begin(), - targets.end()); - if (!this->GetProperty(it->first.c_str())) - { - this->LinkImplicitNullProperties.insert(it->first); - } - } -} - -//---------------------------------------------------------------------------- template<typename PropertyType> PropertyType getTypedProperty(cmTarget *tgt, const char *prop, PropertyType *); @@ -4613,9 +4693,6 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt, const bool explicitlySet = tgt->GetProperties() .find(p.c_str()) != tgt->GetProperties().end(); - std::set<std::string> dependentTargets; - tgt->GetLinkDependentTargetsForProperty(p, - dependentTargets); const bool impliedByUse = tgt->IsNullImpliedByLinkLibraries(p); assert((impliedByUse ^ explicitlySet) @@ -4799,7 +4876,12 @@ bool isLinkDependentProperty(cmTarget *tgt, const std::string &p, bool cmTarget::IsLinkInterfaceDependentBoolProperty(const std::string &p, const char *config) { - return isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_BOOL", + if (this->TargetTypeValue == OBJECT_LIBRARY) + { + return false; + } + return (p == "POSITION_INDEPENDENT_CODE") || + isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_BOOL", config); } @@ -4807,6 +4889,10 @@ bool cmTarget::IsLinkInterfaceDependentBoolProperty(const std::string &p, bool cmTarget::IsLinkInterfaceDependentStringProperty(const std::string &p, const char *config) { + if (this->TargetTypeValue == OBJECT_LIBRARY) + { + return false; + } return isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_STRING", config); } @@ -5624,7 +5710,8 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info, { const cmComputeLinkInformation::ItemVector &deps = info->GetItems(); - std::set<cmStdString> emitted; + std::set<cmStdString> emittedBools; + std::set<cmStdString> emittedStrings; for(cmComputeLinkInformation::ItemVector::const_iterator li = deps.begin(); @@ -5637,19 +5724,36 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info, checkPropertyConsistency<bool>(this, li->Target, "COMPATIBLE_INTERFACE_BOOL", - emitted, config, 0); + emittedBools, config, 0); if (cmSystemTools::GetErrorOccuredFlag()) { return; } checkPropertyConsistency<const char *>(this, li->Target, "COMPATIBLE_INTERFACE_STRING", - emitted, config, 0); + emittedStrings, config, 0); if (cmSystemTools::GetErrorOccuredFlag()) { return; } } + + for(std::set<cmStdString>::const_iterator li = emittedBools.begin(); + li != emittedBools.end(); ++li) + { + const std::set<cmStdString>::const_iterator si = emittedStrings.find(*li); + if (si != emittedStrings.end()) + { + cmOStringStream e; + e << "Property \"" << *li << "\" appears in both the " + "COMPATIBLE_INTERFACE_BOOL and the COMPATIBLE_INTERFACE_STRING " + "property in the dependencies of target \"" << this->GetName() << + "\". This is not allowed. A property may only require compatibility " + "in a boolean interpretation or a string interpretation, but not both."; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); + break; + } + } } //---------------------------------------------------------------------------- diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 7577a59..e659baf 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -15,7 +15,7 @@ #include "cmCustomCommand.h" #include "cmPropertyMap.h" #include "cmPolicies.h" -#include "cmMakefileIncludeDirectoriesEntry.h" +#include "cmListFileCache.h" #include <cmsys/auto_ptr.hxx> @@ -493,22 +493,18 @@ public: std::string GetFrameworkDirectory(const char* config = 0); std::vector<std::string> GetIncludeDirectories(const char *config); - void InsertInclude(const cmMakefileIncludeDirectoriesEntry &entry, + void InsertInclude(const cmValueWithOrigin &entry, bool before = false); + void AppendTllInclude(const cmValueWithOrigin &entry); void AppendBuildInterfaceIncludes(); - void GetLinkDependentTargetsForProperty(const std::string &p, - std::set<std::string> &targets); bool IsNullImpliedByLinkLibraries(const std::string &p); bool IsLinkInterfaceDependentBoolProperty(const std::string &p, const char *config); bool IsLinkInterfaceDependentStringProperty(const std::string &p, const char *config); - void AddLinkDependentTargetsForProperties( - const std::map<cmStdString, cmStdString> &map); - bool GetLinkInterfaceDependentBoolProperty(const std::string &p, const char *config); @@ -627,8 +623,6 @@ private: bool IsApple; bool IsImportedTarget; bool DebugIncludesDone; - mutable std::map<cmStdString, std::set<std::string> > - LinkDependentProperties; mutable std::set<std::string> LinkImplicitNullProperties; bool BuildInterfaceIncludesAppended; diff --git a/Source/cmTargetCompileDefinitionsCommand.cxx b/Source/cmTargetCompileDefinitionsCommand.cxx index 7645833..ba0ad59 100644 --- a/Source/cmTargetCompileDefinitionsCommand.cxx +++ b/Source/cmTargetCompileDefinitionsCommand.cxx @@ -11,8 +11,6 @@ ============================================================================*/ #include "cmTargetCompileDefinitionsCommand.h" -#include "cmMakefileIncludeDirectoriesEntry.h" - bool cmTargetCompileDefinitionsCommand ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &) { diff --git a/Source/cmTargetIncludeDirectoriesCommand.cxx b/Source/cmTargetIncludeDirectoriesCommand.cxx index eaacfa9..12d0a51 100644 --- a/Source/cmTargetIncludeDirectoriesCommand.cxx +++ b/Source/cmTargetIncludeDirectoriesCommand.cxx @@ -11,8 +11,6 @@ ============================================================================*/ #include "cmTargetIncludeDirectoriesCommand.h" -#include "cmMakefileIncludeDirectoriesEntry.h" - //---------------------------------------------------------------------------- bool cmTargetIncludeDirectoriesCommand ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &) @@ -41,14 +39,6 @@ void cmTargetIncludeDirectoriesCommand } //---------------------------------------------------------------------------- -static bool isGeneratorExpression(const std::string &lib) -{ - const std::string::size_type openpos = lib.find("$<"); - return (openpos != std::string::npos) - && (lib.find(">", openpos) != std::string::npos); -} - -//---------------------------------------------------------------------------- std::string cmTargetIncludeDirectoriesCommand ::Join(const std::vector<std::string> &content) { @@ -59,7 +49,7 @@ std::string cmTargetIncludeDirectoriesCommand it != content.end(); ++it) { if (cmSystemTools::FileIsFullPath(it->c_str()) - || isGeneratorExpression(*it)) + || cmGeneratorExpression::Find(*it) != std::string::npos) { dirs += sep + *it; } @@ -79,6 +69,6 @@ void cmTargetIncludeDirectoriesCommand { cmListFileBacktrace lfbt; this->Makefile->GetBacktrace(lfbt); - cmMakefileIncludeDirectoriesEntry entry(this->Join(content), lfbt); + cmValueWithOrigin entry(this->Join(content), lfbt); tgt->InsertInclude(entry, prepend); } diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx index cb913f5..3f652c9 100644 --- a/Source/cmTargetLinkLibrariesCommand.cxx +++ b/Source/cmTargetLinkLibrariesCommand.cxx @@ -11,6 +11,8 @@ ============================================================================*/ #include "cmTargetLinkLibrariesCommand.h" +#include "cmGeneratorExpression.h" + const char* cmTargetLinkLibrariesCommand::LinkLibraryTypeNames[3] = { "general", @@ -250,54 +252,21 @@ cmTargetLinkLibrariesCommand } //---------------------------------------------------------------------------- -static std::string compileProperty(cmTarget *tgt, const std::string &lib, - bool isGenex, - const std::string &property, - cmTarget::LinkLibraryType llt) -{ - std::string value = !isGenex ? "$<LINKED:" + lib + ">" - : "$<$<TARGET_DEFINED:" + lib + ">:" + - "$<TARGET_PROPERTY:" + lib + - ",INTERFACE_" + property + ">" - ">"; - - return tgt->GetDebugGeneratorExpressions(value, llt); -} - -//---------------------------------------------------------------------------- -static bool isGeneratorExpression(const std::string &lib) -{ - const std::string::size_type openpos = lib.find("$<"); - return (openpos != std::string::npos) - && (lib.find(">", openpos) != std::string::npos); -} - -//---------------------------------------------------------------------------- void cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib, cmTarget::LinkLibraryType llt) { - const bool isGenex = isGeneratorExpression(lib); - - cmsys::RegularExpression targetNameValidator; - targetNameValidator.compile("^[A-Za-z0-9_.:-]+$"); - const bool potentialTargetName = targetNameValidator.find(lib); - - if (potentialTargetName || isGenex) - { - this->Target->AppendProperty("INCLUDE_DIRECTORIES", - compileProperty(this->Target, lib, - isGenex, - "INCLUDE_DIRECTORIES", llt).c_str()); - this->Target->AppendProperty("COMPILE_DEFINITIONS", - compileProperty(this->Target, lib, - isGenex, - "COMPILE_DEFINITIONS", llt).c_str()); - } - // Handle normal case first. if(this->CurrentProcessingState != ProcessingLinkInterface) { + { + cmListFileBacktrace lfbt; + this->Makefile->GetBacktrace(lfbt); + cmValueWithOrigin entry(this->Target->GetDebugGeneratorExpressions(lib, + llt), + lfbt); + this->Target->AppendTllInclude(entry); + } this->Makefile ->AddLinkLibraryForTarget(this->Target->GetName(), lib, llt); if (this->CurrentProcessingState != ProcessingPublicInterface) @@ -307,18 +276,6 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib, } } - if (potentialTargetName || isGenex) - { - this->Target->AppendProperty("INTERFACE_COMPILE_DEFINITIONS", - compileProperty(this->Target, lib, - isGenex, - "COMPILE_DEFINITIONS", llt).c_str()); - this->Target->AppendProperty("INTERFACE_INCLUDE_DIRECTORIES", - compileProperty(this->Target, lib, - isGenex, - "INCLUDE_DIRECTORIES", llt).c_str()); - } - // Get the list of configurations considered to be DEBUG. std::vector<std::string> const& debugConfigs = this->Makefile->GetCMakeInstance()->GetDebugConfigs(); diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx index 18a1d2a..771097c 100644 --- a/Source/cmTargetPropCommandBase.cxx +++ b/Source/cmTargetPropCommandBase.cxx @@ -38,6 +38,15 @@ bool cmTargetPropCommandBase this->HandleMissingTarget(args[0]); return false; } + if ((this->Target->GetType() != cmTarget::SHARED_LIBRARY) + && (this->Target->GetType() != cmTarget::STATIC_LIBRARY) + && (this->Target->GetType() != cmTarget::OBJECT_LIBRARY) + && (this->Target->GetType() != cmTarget::MODULE_LIBRARY) + && (this->Target->GetType() != cmTarget::EXECUTABLE)) + { + this->SetError("called with non-compilable target type"); + return false; + } unsigned int argIndex = 1; diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 036440a..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(), @@ -4033,10 +4036,18 @@ static bool cmakeCheckStampFile(const char* stampName) } // The build system is up to date. The stamp file has been removed - // by the VS IDE due to a "rebuild" request. Just restore it. - std::ofstream stamp(stampName); + // by the VS IDE due to a "rebuild" request. Restore it atomically. + cmOStringStream stampTempStream; + stampTempStream << stampName << ".tmp" << cmSystemTools::RandomSeed(); + std::string stampTempString = stampTempStream.str(); + const char* stampTemp = stampTempString.c_str(); + { + // TODO: Teach cmGeneratedFileStream to use a random temp file (with + // multiple tries in unlikely case of conflict) and use that here. + std::ofstream stamp(stampTemp); stamp << "# CMake generation timestamp file this directory.\n"; - if(stamp) + } + if(cmSystemTools::RenameFile(stampTemp, stampName)) { // Notify the user why CMake is not re-running. It is safe to // just print to stdout here because this code is only reachable @@ -4047,6 +4058,7 @@ static bool cmakeCheckStampFile(const char* stampName) } else { + cmSystemTools::RemoveFile(stampTemp); cmSystemTools::Error("Cannot restore timestamp ", stampName); return false; } |