summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeLists.txt2
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/cmComputeLinkInformation.cxx53
-rw-r--r--Source/cmDocumentGeneratorExpressions.h8
-rw-r--r--Source/cmDocumentVariables.cxx10
-rw-r--r--Source/cmExportFileGenerator.cxx83
-rw-r--r--Source/cmExportFileGenerator.h4
-rw-r--r--Source/cmExportInstallFileGenerator.h3
-rw-r--r--Source/cmExtraSublimeTextGenerator.cxx504
-rw-r--r--Source/cmExtraSublimeTextGenerator.h89
-rw-r--r--Source/cmFileCommand.cxx3
-rw-r--r--Source/cmFindPackageCommand.cxx20
-rw-r--r--Source/cmGeneratorExpression.cxx28
-rw-r--r--Source/cmGeneratorExpression.h8
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.cxx7
-rw-r--r--Source/cmGeneratorExpressionEvaluator.cxx192
-rw-r--r--Source/cmGlobalVisualStudio6Generator.cxx3
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx3
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx17
-rw-r--r--Source/cmListFileCache.h9
-rw-r--r--Source/cmLocalGenerator.cxx5
-rw-r--r--Source/cmLocalGenerator.h3
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx27
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx22
-rw-r--r--Source/cmMakefile.cxx33
-rw-r--r--Source/cmMakefile.h9
-rw-r--r--Source/cmMakefileIncludeDirectoriesEntry.h28
-rw-r--r--Source/cmNinjaTargetGenerator.cxx2
-rw-r--r--Source/cmQtAutomoc.cxx53
-rw-r--r--Source/cmQtAutomoc.h12
-rw-r--r--Source/cmTarget.cxx328
-rw-r--r--Source/cmTarget.h12
-rw-r--r--Source/cmTargetCompileDefinitionsCommand.cxx2
-rw-r--r--Source/cmTargetIncludeDirectoriesCommand.cxx14
-rw-r--r--Source/cmTargetLinkLibrariesCommand.cxx63
-rw-r--r--Source/cmTargetPropCommandBase.cxx9
-rw-r--r--Source/cmake.cxx18
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> &parameters,
- 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;
}