[Cmake-commits] CMake branch, next, updated. v2.8.10.2-1124-g34de461
Stephen Kelly
steveire at gmail.com
Thu Nov 29 09:27:45 EST 2012
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".
The branch, next has been updated
via 34de461268eaf4f5d267c2781eb7543a07809f1f (commit)
via 9e0921b06a17b50541063adc423162196dcbdebb (commit)
via 5404c6f4483b0092bc412a84c52bf3c8c36ba5a8 (commit)
via b4ab0c15bc19a85f3f6f8f6b5cadb33b287ae403 (commit)
via ed9f5b57baf15bd75cbe20bfa70c999aa64e7abc (commit)
via 82f77804f3ab57ebb1ec60f7d8b6ae26ee637e04 (commit)
via c61ed6d5df0c7c99fc48ee9dea084c1ca7fcc8d7 (commit)
via 7130be0bf25e5844b39962460f8414916e04e4a8 (commit)
via e0575c47e1d2ea82d0effbc6909f1ea4a74938b7 (commit)
via 8f77e06833795f97630105c83b23aa3bf2f2a6ad (commit)
from 20870b7079d68194eb9735f646463afea9459d86 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=34de461268eaf4f5d267c2781eb7543a07809f1f
commit 34de461268eaf4f5d267c2781eb7543a07809f1f
Merge: 20870b7 9e0921b
Author: Stephen Kelly <steveire at gmail.com>
AuthorDate: Thu Nov 29 09:27:41 2012 -0500
Commit: CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Thu Nov 29 09:27:41 2012 -0500
Merge topic 'link-libraries-generator-expression' into next
9e0921b Make targets depend on the (config-specific) union of dependencies.
5404c6f Generate the frameworks linked by a target lazily.
b4ab0c1 Add cmTarget::GetDirectLinkDependencies.
ed9f5b5 Add includes and compile definitions with target_link_libraries.
82f7780 Add the TARGET_DEFINED generator expression
c61ed6d Handle INTERFACE properties transitively for includes and defines.
7130be0 Keep track of INCLUDE_DIRECTORIES as a vector of structs.
e0575c4 Use cmsys::auto_ptr to manage cmCompiledGeneratorExpressions
8f77e06 Genex: Add INTERFACE_LINK_LIBRARIES property
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=9e0921b06a17b50541063adc423162196dcbdebb
commit 9e0921b06a17b50541063adc423162196dcbdebb
Author: Stephen Kelly <steveire at gmail.com>
AuthorDate: Wed Oct 31 17:09:57 2012 +0100
Commit: Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Nov 29 15:10:08 2012 +0100
Make targets depend on the (config-specific) union of dependencies.
Future CMake features will allow linking to dependencies or not
depending on the config. However, generated buildsystems are not
capable of processing config-specific dependencies, so the targets
depend on the union of dependencies for all configs.
diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index ab77c6b..2acbfff 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -200,20 +200,44 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
// Get the depender.
cmTarget* depender = this->Targets[depender_index];
- // Loop over all targets linked directly.
+ // Loop over all targets linked directly in all configs.
+ // We need to make targets depend on the union of all config-specific
+ // dependencies in all targets, because the generated build-systems can't
+ // deal with config-specific dependencies.
{
- cmTarget::LinkLibraryVectorType const& tlibs =
- depender->GetOriginalLinkLibraries();
+ std::vector<std::string> configs;
+ depender->GetMakefile()->GetConfigurations(configs);
std::set<cmStdString> emitted;
+ {
+ std::vector<std::string> tlibs;
+ depender->GetDirectLinkLibraries(0, tlibs);
// A target should not depend on itself.
emitted.insert(depender->GetName());
- for(cmTarget::LinkLibraryVectorType::const_iterator lib = tlibs.begin();
+ for(std::vector<std::string>::const_iterator lib = tlibs.begin();
lib != tlibs.end(); ++lib)
{
// Don't emit the same library twice for this target.
- if(emitted.insert(lib->first).second)
+ if(emitted.insert(*lib).second)
+ {
+ this->AddTargetDepend(depender_index, lib->c_str(), true);
+ }
+ }
+ }
+ for (std::vector<std::string>::const_iterator it = configs.begin();
+ it != configs.end(); ++it)
+ {
+ std::vector<std::string> tlibs;
+ depender->GetDirectLinkLibraries(it->c_str(), tlibs);
+ // A target should not depend on itself.
+ emitted.insert(depender->GetName());
+ for(std::vector<std::string>::const_iterator lib = tlibs.begin();
+ lib != tlibs.end(); ++lib)
{
- this->AddTargetDepend(depender_index, lib->first.c_str(), true);
+ // Don't emit the same library twice for this target.
+ if(emitted.insert(*lib).second)
+ {
+ this->AddTargetDepend(depender_index, lib->c_str(), true);
+ }
}
}
}
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=5404c6f4483b0092bc412a84c52bf3c8c36ba5a8
commit 5404c6f4483b0092bc412a84c52bf3c8c36ba5a8
Author: Stephen Kelly <steveire at gmail.com>
AuthorDate: Thu Nov 1 10:41:53 2012 +0100
Commit: Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Nov 29 15:10:07 2012 +0100
Generate the frameworks linked by a target lazily.
As this is only needed at generate-time, it can depend on the
config.
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 9bbeeaf..d9b586e 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -1997,7 +1997,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
dirs.Add(incpath.c_str());
}
}
- std::vector<std::string>& frameworks = target.GetFrameworks();
+ std::vector<std::string> frameworks;
+ target.GetFrameworks(configName, frameworks);
if(frameworks.size())
{
for(std::vector<std::string>::iterator fmIt = frameworks.begin();
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 2b89c79..f46edf3 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -1565,7 +1565,8 @@ std::string cmMakefileTargetGenerator::GetFrameworkFlags()
}
std::string flags;
- std::vector<std::string>& frameworks = this->Target->GetFrameworks();
+ std::vector<std::string> frameworks;
+ this->Target->GetFrameworks(config, frameworks);
for(i = frameworks.begin();
i != frameworks.end(); ++i)
{
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index e54786e..5ab9bdc 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -2110,23 +2110,27 @@ bool cmTarget::NameResolvesToFramework(const std::string& libname)
}
//----------------------------------------------------------------------------
-bool cmTarget::AddFramework(const std::string& libname, LinkLibraryType)
+void cmTarget::GetFrameworks(const char *config,
+ std::vector<std::string> &frameworks)
{
- if(this->NameResolvesToFramework(libname.c_str()))
+ std::vector<std::string> llibs;
+ this->GetDirectLinkLibraries(config, llibs);
+ for(std::vector<std::string>::const_iterator li = llibs.begin();
+ li != llibs.end(); ++li)
{
- std::string frameworkDir = libname;
- frameworkDir += "/../";
- frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir.c_str());
- std::vector<std::string>::iterator i =
- std::find(this->Frameworks.begin(),
- this->Frameworks.end(), frameworkDir);
- if(i == this->Frameworks.end())
+ if(this->NameResolvesToFramework(li->c_str()))
{
- this->Frameworks.push_back(frameworkDir);
+ std::string frameworkDir = *li + "/../";
+ frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir.c_str());
+ std::vector<std::string>::iterator i =
+ std::find(frameworks.begin(),
+ frameworks.end(), frameworkDir);
+ if(i == frameworks.end())
+ {
+ frameworks.push_back(frameworkDir);
+ }
}
- return true;
}
- return false;
}
//----------------------------------------------------------------------------
@@ -2194,7 +2198,6 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf,
return;
}
- this->AddFramework(pplib, llt);
cmTarget::LibraryID tmp;
tmp.first = pplib;
tmp.second = llt;
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index c72e4c5..3cd35f4 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -114,7 +114,8 @@ public:
{return this->PostBuildCommands;}
///! Return the list of frameworks being linked to this target
- std::vector<std::string> &GetFrameworks() {return this->Frameworks;}
+ void GetFrameworks(const char *config,
+ std::vector<std::string> &frameworks);
/**
* Get the list of the source files used by this target
@@ -185,7 +186,6 @@ public:
// Check to see if a library is a framework and treat it different on Mac
bool NameResolvesToFramework(const std::string& libname);
- bool AddFramework(const std::string& lib, LinkLibraryType llt);
void AddLinkLibrary(cmMakefile& mf,
const char *target, const char* lib,
LinkLibraryType llt);
@@ -580,7 +580,6 @@ private:
LinkLibraryVectorType LinkLibraries;
LinkLibraryVectorType PrevLinkedLibraries;
bool LinkLibrariesAnalyzed;
- std::vector<std::string> Frameworks;
std::vector<std::string> LinkDirectories;
std::set<cmStdString> LinkDirectoriesEmmitted;
bool HaveInstallRule;
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b4ab0c15bc19a85f3f6f8f6b5cadb33b287ae403
commit b4ab0c15bc19a85f3f6f8f6b5cadb33b287ae403
Author: Stephen Kelly <steveire at gmail.com>
AuthorDate: Thu Nov 1 00:29:30 2012 +0100
Commit: Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Nov 29 15:10:07 2012 +0100
Add cmTarget::GetDirectLinkDependencies.
This will be used at generate-time and can use generator expressions.
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 3a22d73..e54786e 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -2130,6 +2130,48 @@ bool cmTarget::AddFramework(const std::string& libname, LinkLibraryType)
}
//----------------------------------------------------------------------------
+void cmTarget::GetDirectLinkLibraries(const char *config,
+ std::vector<std::string> &libs) const
+{
+ const char *prop = const_cast<cmTarget*>(this)
+ ->GetProperty("LINK_LIBRARIES");
+ if (prop)
+ {
+ cmListFileBacktrace lfbt;
+ cmGeneratorExpression ge(lfbt);
+
+ cmGeneratorExpressionDAGChecker dagChecker(lfbt,
+ this->GetName(),
+ "LINK_LIBRARIES", 0, 0);
+ cmSystemTools::ExpandListArgument(ge.Parse(prop)->Evaluate(this->Makefile,
+ config,
+ false,
+ const_cast<cmTarget*>(this),
+ &dagChecker),
+ libs);
+ }
+}
+
+//----------------------------------------------------------------------------
+static std::string generatorIface(const std::string &value,
+ cmTarget::LinkLibraryType llt)
+{
+ if (llt == cmTarget::DEBUG)
+ {
+ return "$<$<CONFIG:Debug>:"
+ + value
+ + ">";
+ }
+ else if (llt == cmTarget::OPTIMIZED)
+ {
+ return "$<$<NOT:$<CONFIG:Debug>>:"
+ + value
+ + ">";
+ }
+ return value;
+}
+
+//----------------------------------------------------------------------------
void cmTarget::AddLinkLibrary(cmMakefile& mf,
const char *target, const char* lib,
LinkLibraryType llt)
@@ -2139,9 +2181,22 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf,
{
return;
}
- this->AddFramework(lib, llt);
+
+ this->AppendProperty("LINK_LIBRARIES",
+ generatorIface(lib, llt).c_str());
+
+ std::string pplib = cmGeneratorExpression::Preprocess(
+ lib,
+ cmGeneratorExpression::StripAllGeneratorExpressions);
+
+ if (pplib.empty())
+ {
+ return;
+ }
+
+ this->AddFramework(pplib, llt);
cmTarget::LibraryID tmp;
- tmp.first = lib;
+ tmp.first = pplib;
tmp.second = llt;
this->LinkLibraries.push_back( tmp );
this->OriginalLinkLibraries.push_back(tmp);
@@ -2178,7 +2233,7 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf,
break;
}
dependencies += ";";
- dependencies += lib;
+ dependencies += pplib;
dependencies += ";";
mf.AddCacheDefinition( targetEntry.c_str(), dependencies.c_str(),
"Dependencies for the target",
@@ -5028,21 +5083,19 @@ void cmTarget::ComputeLinkImplementation(const char* config,
cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config);
// Collect libraries directly linked in this configuration.
- LinkLibraryVectorType const& llibs = this->GetOriginalLinkLibraries();
- for(cmTarget::LinkLibraryVectorType::const_iterator li = llibs.begin();
+ std::vector<std::string> llibs;
+ this->GetDirectLinkLibraries(config, llibs);
+ for(std::vector<std::string>::const_iterator li = llibs.begin();
li != llibs.end(); ++li)
{
// Skip entries that resolve to the target itself or are empty.
- std::string item = this->CheckCMP0004(li->first);
+ std::string item = this->CheckCMP0004(*li);
if(item == this->GetName() || item.empty())
{
continue;
}
- if(li->second == cmTarget::GENERAL || li->second == linkType)
- {
- // The entry is meant for this configuration.
- impl.Libraries.push_back(item);
- }
+ // The entry is meant for this configuration.
+ impl.Libraries.push_back(item);
}
LinkLibraryVectorType const& oldllibs = this->GetOriginalLinkLibraries();
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index a6090e5..c72e4c5 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -172,6 +172,8 @@ public:
return this->LinkLibraries;}
const LinkLibraryVectorType &GetOriginalLinkLibraries() const
{return this->OriginalLinkLibraries;}
+ void GetDirectLinkLibraries(const char *config,
+ std::vector<std::string> &) const;
/** Compute the link type to use for the given configuration. */
LinkLibraryType ComputeLinkType(const char* config);
diff --git a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
index 92c9338..1e3094c 100644
--- a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
+++ b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
@@ -37,11 +37,11 @@ target_link_libraries(depB LINK_PRIVATE depA)
add_library(depC SHARED depC.cpp)
generate_export_header(depC)
-target_link_libraries(depC LINK_PUBLIC depA)
+target_link_libraries(depC LINK_PUBLIC $<1:depA>)
assert_property(depA LINK_INTERFACE_LIBRARIES "")
assert_property(depB LINK_INTERFACE_LIBRARIES "")
-assert_property(depC LINK_INTERFACE_LIBRARIES "depA")
+assert_property(depC LINK_INTERFACE_LIBRARIES "$<1:depA>")
add_executable(targetA targetA.cpp)
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ed9f5b57baf15bd75cbe20bfa70c999aa64e7abc
commit ed9f5b57baf15bd75cbe20bfa70c999aa64e7abc
Author: Stephen Kelly <steveire at gmail.com>
AuthorDate: Mon Nov 5 12:43:28 2012 +0100
Commit: Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Nov 29 15:09:48 2012 +0100
Add includes and compile definitions with target_link_libraries.
The compile-related properties are required for linking so it makes
sense to add the interface includes for dependencies.
This requires adding a policy to handle the change in behavior of
code such as:
add_executable(foo ...)
target_link_libraries(foo bar bat)
include_directories(${bat_INCLUDE_DIRS} ${bar_INCLUDE_DIRS})
which will change order of generated includes after this patch if
bar or bat are TARGETS with an INTERFACE_INCLUDE_DIRECTORIES
property.
This includes a workaround for broken std::remove on some Borland
compilers.
I don't have enough information about which versions of Borland
are affected, but if this workaround works, then it could be
put elsewhere such as cmsys.
http://qc.embarcadero.com/wc/qcmain.aspx?d=4957
http://www.gamedev.net/topic/366171-stdremove/
http://www.delphigroups.info/3/5/7456.html
http://bytes.com/topic/c/answers/59791-std-remove-syntax
http://forums.devx.com/showthread.php?94489-About-std-remove
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 8498d72..5fa10f2 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -1665,8 +1665,14 @@ void cmMakefile::AddIncludeDirectory(const char* inc, bool before)
l != this->Targets.end(); ++l)
{
cmTarget &t = l->second;
- prop = t.GetProperties().GetOrCreateProperty("INCLUDE_DIRECTORIES");
- AddStringToProperty(prop, "INCLUDE_DIRECTORIES", inc, before);
+ if (before)
+ {
+ t.PrependTLLIncludeDirectories(inc);
+ }
+ else
+ {
+ t.AppendTLLIncludeDirectories(inc);
+ }
}
}
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index 4c89dd6..13e36c8 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -511,6 +511,23 @@ cmPolicies::cmPolicies()
"the value of the (IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)? target "
"property",
2,8,11,0, cmPolicies::WARN);
+
+ this->DefinePolicy(
+ CMP0020, "CMP0020",
+ "Use INCLUDE_DIRECTORIES order implied by target_link_libraries.",
+ "CMake 2.8.11 introduced a feature where using target_link_libraries "
+ "can read the INTERFACE_INCLUDE_DIRECTORIES property of a target and "
+ "use the value as include directories when compiling. Because the "
+ "target_link_libraries call might occur before the include_directories "
+ "call, this could change the order of includes in the compile step."
+ "\n"
+ "The OLD behavior for this policy is to let the include_directories call "
+ "determine the order of includes."
+ "\n"
+ "The NEW behavior for this policy is to use the order of includes "
+ "determined by the order of all calls to target_link_libraries and "
+ "include_directories",
+ 2,8,11,0, cmPolicies::WARN);
}
cmPolicies::~cmPolicies()
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index b6b8e39..94154ee 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -69,6 +69,7 @@ public:
/// POSITION_INDEPENDENT_CODE property and *_COMPILE_OPTIONS_PI{E,C}
/// instead.
CMP0019, ///< Use new-style INTERFACE_LINK_LIBRARIES
+ CMP0020, ///< Use INCLUDE_DIRECTORIES order from target_link_libraries
/** \brief Always the last entry.
*
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index cde8169..3a22d73 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -121,10 +121,13 @@ public:
SourceEntriesType SourceEntries;
struct IncludeDirectoriesEntry {
- IncludeDirectoriesEntry(cmsys::auto_ptr<cmCompiledGeneratorExpression> cge)
- : ge(cge)
+ IncludeDirectoriesEntry(
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge,
+ bool tllEntry = false)
+ : ge(cge), ImpliedByTargetLinkLibraries(tllEntry)
{}
const cmsys::auto_ptr<cmCompiledGeneratorExpression> ge;
+ const bool ImpliedByTargetLinkLibraries;
};
std::vector<IncludeDirectoriesEntry*> IncludeDirectoriesEntries;
std::string IncludeDirectoriesString;
@@ -2536,6 +2539,50 @@ void cmTarget::AppendProperty(const char* prop, const char* value,
}
//----------------------------------------------------------------------------
+void cmTarget::AppendTLLIncludeDirectories(const std::string &includes)
+{
+ cmListFileBacktrace lfbt;
+ cmGeneratorExpression ge(lfbt);
+ this->Internal->IncludeDirectoriesEntries.push_back(
+ new cmTargetInternals::IncludeDirectoriesEntry(ge.Parse(includes),
+ true)
+ );
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::PrependTLLIncludeDirectories(const std::string &includes)
+{
+ cmListFileBacktrace lfbt;
+ cmGeneratorExpression ge(lfbt);
+ this->Internal->IncludeDirectoriesEntries.insert(
+ this->Internal->IncludeDirectoriesEntries.begin(),
+ new cmTargetInternals::IncludeDirectoriesEntry(ge.Parse(includes),
+ true)
+ );
+}
+
+// A Borland machine on the dashboard has a faulty std::remove.
+template <typename ForwardIterator, typename T>
+ForwardIterator cmStdRemove(ForwardIterator first,
+ ForwardIterator last,
+ const T& value)
+{
+#if defined(__BORLANDC__) || (defined(__GNUC__) && __GNUC__ < 3)
+ ForwardIterator result = first;
+ for ( ; first != last; ++first)
+ {
+ if (!(*first == value))
+ {
+ *result++ = *first;
+ }
+ }
+ return result;
+#else
+ return std::remove<ForwardIterator, T>(first, last, value);
+#endif
+}
+
+//----------------------------------------------------------------------------
std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config)
{
std::set<std::string> fromTll;
@@ -2568,8 +2615,44 @@ std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config)
cmSystemTools::ConvertToUnixSlashes(inc);
}
+ if (!(*it)->ImpliedByTargetLinkLibraries)
+ {
+ if (fromTll.find(*li) != fromTll.end())
+ {
+ switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0020))
+ {
+ case cmPolicies::WARN:
+ {
+ cmOStringStream e;
+ e << "The include directory " << *li << " was specified "
+ "implicitly by an earlier call to target_link_libraries. "
+ "Preserving the order of includes as if the earlier use of "
+ "target_link_libraries had not added it."
+ << this->Makefile->GetPolicies()->GetPolicyWarning(
+ cmPolicies::CMP0020);
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, e.str());
+ }
+ // Fall through to OLD behavior
+ case cmPolicies::OLD:
+ includes.erase(cmStdRemove(includes.begin(),
+ includes.end(), *li),
+ includes.end());
+ fromTll.erase(*li);
+ includes.push_back(*li);
+ break;
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::NEW:
+ break;
+ }
+ }
+ }
if(uniqueIncludes.insert(inc).second)
{
+ if ((*it)->ImpliedByTargetLinkLibraries)
+ {
+ fromTll.insert(*li);
+ }
includes.push_back(*li);
}
}
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 60a105e..a6090e5 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -478,6 +478,9 @@ public:
/** @return the Mac framework directory without the base. */
std::string GetFrameworkDirectory(const char* config = 0);
+ void AppendTLLIncludeDirectories(const std::string &includes);
+ void PrependTLLIncludeDirectories(const std::string &includes);
+
std::vector<std::string> GetIncludeDirectories(const char *config);
private:
diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx
index d7a1443..2ccdc01 100644
--- a/Source/cmTargetLinkLibrariesCommand.cxx
+++ b/Source/cmTargetLinkLibrariesCommand.cxx
@@ -273,10 +273,52 @@ static std::string generatorIface(const std::string &value,
}
//----------------------------------------------------------------------------
+static std::string compileProperty(const std::string &lib,
+ const std::string &property,
+ cmTarget::LinkLibraryType llt)
+{
+ return generatorIface(std::string("$<$<TARGET_DEFINED:" + lib + ">"
+ ":$<TARGET_PROPERTY:")
+ + lib
+ + ",INTERFACE_" + property + ">>", 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);
+}
+
+//----------------------------------------------------------------------------
+static bool isList(const char *lib)
+{
+ std::vector<std::string> result;
+ cmSystemTools::ExpandListArgument(lib, result);
+ return result.size() > 1;
+}
+
+//----------------------------------------------------------------------------
void
cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
cmTarget::LinkLibraryType llt)
{
+ cmTarget *tgt = this->Makefile->FindTargetToUse(lib);
+ const bool isNonImportedTarget = tgt && !tgt->IsImported();
+ const bool isGenex = isGeneratorExpression(lib);
+ const std::string nsLib =
+ std::string(isNonImportedTarget && !isList(lib)
+ ? "$<EXPORT_NAMESPACE>" : "") + lib;
+ if (tgt || isGenex)
+ {
+ this->Target->AppendTLLIncludeDirectories(compileProperty(nsLib,
+ "INCLUDE_DIRECTORIES", llt));
+ this->Target->AppendProperty("COMPILE_DEFINITIONS",
+ compileProperty(nsLib,
+ "COMPILE_DEFINITIONS", llt).c_str());
+ }
+
// Handle normal case first.
if(this->CurrentProcessingState != ProcessingLinkInterface)
{
@@ -290,7 +332,13 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
}
this->Target->AppendProperty("INTERFACE_LINK_LIBRARIES",
- generatorIface(lib, llt).c_str());
+ generatorIface(nsLib, llt).c_str());
+ this->Target->AppendProperty("INTERFACE_COMPILE_DEFINITIONS",
+ compileProperty(nsLib,
+ "COMPILE_DEFINITIONS", llt).c_str());
+ this->Target->AppendProperty("INTERFACE_INCLUDE_DIRECTORIES",
+ compileProperty(nsLib,
+ "INCLUDE_DIRECTORIES", llt).c_str());
// Get the list of configurations considered to be DEBUG.
std::vector<std::string> const& debugConfigs =
diff --git a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
index 95cfd15..92c9338 100644
--- a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
+++ b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
@@ -74,3 +74,27 @@ add_executable(targetB targetB.cpp)
target_link_libraries(targetB depD depE)
# cmake_policy(POP)
+
+
+macro(create_header _name)
+ file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${_name}")
+ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_name}/${_name}.h" "//${_name}.h\n")
+endmacro()
+
+create_header(foo)
+create_header(bar)
+
+add_library(depF SHARED depF.cpp)
+generate_export_header(depF)
+set_property(TARGET depF PROPERTY
+ INTERFACE_INCLUDE_DIRECTORIES
+ ${CMAKE_CURRENT_BINARY_DIR}/foo
+ ${CMAKE_CURRENT_BINARY_DIR}/bar
+)
+set_property(TARGET depF PROPERTY
+ INTERFACE_COMPILE_DEFINITIONS
+ TEST_DEF
+)
+
+add_library(targetC targetC.cpp)
+target_link_libraries(targetC depF)
diff --git a/Tests/CMakeCommands/target_link_libraries/depF.cpp b/Tests/CMakeCommands/target_link_libraries/depF.cpp
new file mode 100644
index 0000000..1fd29c4
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_libraries/depF.cpp
@@ -0,0 +1,7 @@
+
+#include "depF.h"
+
+int DepF::foo()
+{
+ return 0;
+}
diff --git a/Tests/CMakeCommands/target_link_libraries/depF.h b/Tests/CMakeCommands/target_link_libraries/depF.h
new file mode 100644
index 0000000..95d6b14
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_libraries/depF.h
@@ -0,0 +1,7 @@
+
+#include "depf_export.h"
+
+struct DEPF_EXPORT DepF
+{
+ int foo();
+};
diff --git a/Tests/CMakeCommands/target_link_libraries/targetC.cpp b/Tests/CMakeCommands/target_link_libraries/targetC.cpp
new file mode 100644
index 0000000..ac33c67
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_libraries/targetC.cpp
@@ -0,0 +1,16 @@
+
+#include "depF.h"
+
+#include "foo.h"
+#include "bar.h"
+
+#ifndef TEST_DEF
+#error Expected TEST_DEF definition
+#endif
+
+int main(int argc, char **argv)
+{
+ DepF f;
+
+ return f.foo();
+}
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=82f77804f3ab57ebb1ec60f7d8b6ae26ee637e04
commit 82f77804f3ab57ebb1ec60f7d8b6ae26ee637e04
Author: Stephen Kelly <steveire at gmail.com>
AuthorDate: Mon Nov 19 23:56:12 2012 +0100
Commit: Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Nov 29 15:09:47 2012 +0100
Add the TARGET_DEFINED generator expression
This tests whether the parameter is a usable target.
diff --git a/Source/cmDocumentGeneratorExpressions.h b/Source/cmDocumentGeneratorExpressions.h
index 445fd0e..4866f0d 100644
--- a/Source/cmDocumentGeneratorExpressions.h
+++ b/Source/cmDocumentGeneratorExpressions.h
@@ -27,6 +27,7 @@
" $<COMMA> = A literal ','. Used to compare " \
"strings which contain a ',' for example.\n" \
" $<TARGET_FILE:tgt> = main file (.exe, .so.1.2, .a)\n" \
+ " $<TARGET_DEFINED:tgt> = '1' if tgt is a target, else '0'\n" \
" $<TARGET_LINKER_FILE:tgt> = file used to link (.a, .lib, .so)\n" \
" $<TARGET_SONAME_FILE:tgt> = file with soname (.so.3)\n" \
"where \"tgt\" is the name of a target. " \
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index 57d75e0..9c6ea23 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -286,6 +286,23 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
} configurationTestNode;
//----------------------------------------------------------------------------
+static const struct TargetTestNode : public cmGeneratorExpressionNode
+{
+ TargetTestNode() {}
+
+ virtual int NumExpectedParameters() const { return 1; }
+
+ std::string Evaluate(const std::vector<std::string> ¶meters,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ return context->Makefile->FindTargetToUse(parameters.front().c_str())
+ ? "1" : "0";
+ }
+} targetTestNode;
+
+//----------------------------------------------------------------------------
static const char* targetPropertyTransitiveWhitelist[] = {
"INTERFACE_INCLUDE_DIRECTORIES"
, "INTERFACE_COMPILE_DEFINITIONS"
@@ -648,6 +665,8 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier)
return &installInterfaceNode;
else if (identifier == "EXPORT_NAMESPACE")
return &nullNode;
+ else if (identifier == "TARGET_DEFINED")
+ return &targetTestNode;
return 0;
}
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=c61ed6d5df0c7c99fc48ee9dea084c1ca7fcc8d7
commit c61ed6d5df0c7c99fc48ee9dea084c1ca7fcc8d7
Author: Stephen Kelly <steveire at gmail.com>
AuthorDate: Sun Sep 23 13:45:17 2012 +0200
Commit: Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Nov 29 15:09:47 2012 +0100
Handle INTERFACE properties transitively for includes and defines.
Contextually, the behavior is as if the properties content from another
target is included in the string and then the result is evaluated.
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index a86f8c4..c67486a 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -41,6 +41,12 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
cmGeneratorExpression::BuildInterface,
properties);
}
+ this->PopulateInterfaceProperty("INTERFACE_INCLUDE_DIRECTORIES", te,
+ cmGeneratorExpression::BuildInterface,
+ properties);
+ this->PopulateInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS", te,
+ cmGeneratorExpression::BuildInterface,
+ properties);
this->GenerateInterfaceProperties(te, os, properties);
}
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index 4fef08e..c22abf4 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -59,6 +59,14 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
cmGeneratorExpression::InstallInterface,
properties);
}
+ this->PopulateInterfaceProperty("INTERFACE_INCLUDE_DIRECTORIES",
+ te->Target,
+ cmGeneratorExpression::InstallInterface,
+ properties);
+ this->PopulateInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS",
+ te->Target,
+ cmGeneratorExpression::InstallInterface,
+ properties);
this->GenerateInterfaceProperties(te->Target, os, properties);
}
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index 07f46be..57d75e0 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -286,6 +286,12 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
} configurationTestNode;
//----------------------------------------------------------------------------
+static const char* targetPropertyTransitiveWhitelist[] = {
+ "INTERFACE_INCLUDE_DIRECTORIES"
+ , "INTERFACE_COMPILE_DEFINITIONS"
+};
+
+//----------------------------------------------------------------------------
static const struct TargetPropertyNode : public cmGeneratorExpressionNode
{
TargetPropertyNode() {}
@@ -387,7 +393,27 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
}
const char *prop = target->GetProperty(propertyName.c_str());
- return prop ? prop : "";
+ if (!prop)
+ {
+ return std::string();
+ }
+
+ for (size_t i = 0;
+ i < (sizeof(targetPropertyTransitiveWhitelist) /
+ sizeof(*targetPropertyTransitiveWhitelist));
+ ++i)
+ {
+ if (targetPropertyTransitiveWhitelist[i] == propertyName)
+ {
+ cmGeneratorExpression ge(context->Backtrace);
+ return ge.Parse(prop)->Evaluate(context->Makefile,
+ context->Config,
+ context->Quiet,
+ context->Target,
+ &dagChecker);
+ }
+ }
+ return prop;
}
} targetPropertyNode;
diff --git a/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt
index 7cb1b42..2a0d1a8 100644
--- a/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt
+++ b/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt
@@ -45,3 +45,23 @@ set_property(TARGET TargetIncludeDirectories
APPEND PROPERTY INCLUDE_DIRECTORIES
"$<TARGET_PROPERTY:somelib::withcolons,INTERFACE_INCLUDE_DIRECTORIES>"
)
+
+create_header(fee)
+create_header(fiy)
+create_header(foh)
+create_header(fum)
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib1.cpp" "#include \"fee.h\"\n")
+add_library(lib1 "${CMAKE_CURRENT_BINARY_DIR}/lib1.cpp")
+set_property(TARGET lib1 APPEND PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/fee")
+set_property(TARGET lib1 APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/fiy")
+set_property(TARGET lib1 APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:${CMAKE_CURRENT_BINARY_DIR}/foh>")
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib2.cpp" "#include \"fiy.h\"\n")
+add_library(lib2 "${CMAKE_CURRENT_BINARY_DIR}/lib2.cpp")
+set_property(TARGET lib2 APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/fum;$<TARGET_PROPERTY:lib1,INTERFACE_INCLUDE_DIRECTORIES>")
+set_property(TARGET lib2 APPEND PROPERTY INCLUDE_DIRECTORIES "$<TARGET_PROPERTY:lib1,INTERFACE_INCLUDE_DIRECTORIES>")
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/main3.cpp" "#include \"fiy.h\"\n#include \"foh.h\"\n#include \"fum.h\"\nint main(int,char**) { return 0; }\n")
+add_executable(exe3 "${CMAKE_CURRENT_BINARY_DIR}/main3.cpp")
+set_property(TARGET exe3 APPEND PROPERTY INCLUDE_DIRECTORIES "$<TARGET_PROPERTY:lib2,INTERFACE_INCLUDE_DIRECTORIES>")
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=7130be0bf25e5844b39962460f8414916e04e4a8
commit 7130be0bf25e5844b39962460f8414916e04e4a8
Author: Stephen Kelly <steveire at gmail.com>
AuthorDate: Mon Nov 19 22:47:30 2012 +0100
Commit: Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Nov 29 15:09:47 2012 +0100
Keep track of INCLUDE_DIRECTORIES as a vector of structs.
The struct can keep track of where the include came from, which gives
us proper backtraces, and will allow us to implement a policy later
relating to order of include directories.
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 55507dd..62ee26a 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -252,45 +252,7 @@ const char* cmGeneratorTarget::GetCreateRuleVariable()
std::vector<std::string> cmGeneratorTarget::GetIncludeDirectories(
const char *config)
{
- std::vector<std::string> includes;
- const char *prop = this->Target->GetProperty("INCLUDE_DIRECTORIES");
- if(!prop)
- {
- return includes;
- }
-
- cmListFileBacktrace lfbt;
- cmGeneratorExpression ge(lfbt);
-
- cmGeneratorExpressionDAGChecker dagChecker(lfbt,
- this->GetName(),
- "INCLUDE_DIRECTORIES", 0, 0);
-
- cmSystemTools::ExpandListArgument(ge.Parse(prop)
- ->Evaluate(this->Makefile,
- config,
- false,
- this->Target,
- &dagChecker),
- includes);
-
- std::set<std::string> uniqueIncludes;
- std::vector<std::string> orderedAndUniqueIncludes;
- for(std::vector<std::string>::const_iterator
- li = includes.begin(); li != includes.end(); ++li)
- {
- std::string inc = *li;
- if (!cmSystemTools::IsOff(inc.c_str()))
- {
- cmSystemTools::ConvertToUnixSlashes(inc);
- }
- if(uniqueIncludes.insert(inc).second)
- {
- orderedAndUniqueIncludes.push_back(inc);
- }
- }
-
- return orderedAndUniqueIncludes;
+ return this->Target->GetIncludeDirectories(config);
}
//----------------------------------------------------------------------------
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 0e83878..cde8169 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -119,6 +119,15 @@ public:
struct SourceEntry { std::vector<cmSourceFile*> Depends; };
typedef std::map<cmSourceFile*, SourceEntry> SourceEntriesType;
SourceEntriesType SourceEntries;
+
+ struct IncludeDirectoriesEntry {
+ IncludeDirectoriesEntry(cmsys::auto_ptr<cmCompiledGeneratorExpression> cge)
+ : ge(cge)
+ {}
+ const cmsys::auto_ptr<cmCompiledGeneratorExpression> ge;
+ };
+ std::vector<IncludeDirectoriesEntry*> IncludeDirectoriesEntries;
+ std::string IncludeDirectoriesString;
};
//----------------------------------------------------------------------------
@@ -2471,6 +2480,20 @@ void cmTarget::GatherDependencies( const cmMakefile& mf,
}
//----------------------------------------------------------------------------
+void deleteAndClear(
+ std::vector<cmTargetInternals::IncludeDirectoriesEntry*> &entries)
+{
+ for (std::vector<cmTargetInternals::IncludeDirectoriesEntry*>::const_iterator
+ it = entries.begin(),
+ end = entries.end();
+ it != end; ++it)
+ {
+ delete *it;
+ }
+ entries.clear();
+}
+
+//----------------------------------------------------------------------------
void cmTarget::SetProperty(const char* prop, const char* value)
{
if (!prop)
@@ -2478,6 +2501,16 @@ void cmTarget::SetProperty(const char* prop, const char* value)
return;
}
+ if(strcmp(prop,"INCLUDE_DIRECTORIES") == 0)
+ {
+ cmListFileBacktrace lfbt;
+ cmGeneratorExpression ge(lfbt);
+ deleteAndClear(this->Internal->IncludeDirectoriesEntries);
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
+ this->Internal->IncludeDirectoriesEntries.push_back(
+ new cmTargetInternals::IncludeDirectoriesEntry(cge));
+ return;
+ }
this->Properties.SetProperty(prop, value, cmProperty::TARGET);
this->MaybeInvalidatePropertyCache(prop);
}
@@ -2490,11 +2523,61 @@ void cmTarget::AppendProperty(const char* prop, const char* value,
{
return;
}
+ if(strcmp(prop,"INCLUDE_DIRECTORIES") == 0)
+ {
+ cmListFileBacktrace lfbt;
+ cmGeneratorExpression ge(lfbt);
+ this->Internal->IncludeDirectoriesEntries.push_back(
+ new cmTargetInternals::IncludeDirectoriesEntry(ge.Parse(value)));
+ return;
+ }
this->Properties.AppendProperty(prop, value, cmProperty::TARGET, asString);
this->MaybeInvalidatePropertyCache(prop);
}
//----------------------------------------------------------------------------
+std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config)
+{
+ std::set<std::string> fromTll;
+ std::vector<std::string> includes;
+ std::set<std::string> uniqueIncludes;
+ cmListFileBacktrace lfbt;
+
+ cmGeneratorExpressionDAGChecker dagChecker(lfbt,
+ this->GetName(),
+ "INCLUDE_DIRECTORIES", 0, 0);
+
+ for (std::vector<cmTargetInternals::IncludeDirectoriesEntry*>::const_iterator
+ it = this->Internal->IncludeDirectoriesEntries.begin(),
+ end = this->Internal->IncludeDirectoriesEntries.end();
+ it != end; ++it)
+ {
+ std::vector<std::string> entryIncludes;
+ cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(this->Makefile,
+ config,
+ false,
+ this,
+ &dagChecker),
+ entryIncludes);
+ for(std::vector<std::string>::const_iterator
+ li = entryIncludes.begin(); li != entryIncludes.end(); ++li)
+ {
+ std::string inc = *li;
+ if (!cmSystemTools::IsOff(inc.c_str()))
+ {
+ cmSystemTools::ConvertToUnixSlashes(inc);
+ }
+
+ if(uniqueIncludes.insert(inc).second)
+ {
+ includes.push_back(*li);
+ }
+ }
+ }
+ return includes;
+}
+
+//----------------------------------------------------------------------------
void cmTarget::MaybeInvalidatePropertyCache(const char* prop)
{
// Wipe out maps caching information affected by this property.
@@ -2820,6 +2903,23 @@ const char *cmTarget::GetProperty(const char* prop,
}
}
}
+ if(strcmp(prop,"INCLUDE_DIRECTORIES") == 0)
+ {
+ this->Internal->IncludeDirectoriesString = "";
+ std::string sep;
+ typedef cmTargetInternals::IncludeDirectoriesEntry
+ IncludeDirectoriesEntry;
+ for (std::vector<IncludeDirectoriesEntry*>::const_iterator
+ it = this->Internal->IncludeDirectoriesEntries.begin(),
+ end = this->Internal->IncludeDirectoriesEntries.end();
+ it != end; ++it)
+ {
+ this->Internal->IncludeDirectoriesString += sep;
+ this->Internal->IncludeDirectoriesString += (*it)->ge->GetInput();
+ sep = ";";
+ }
+ return this->Internal->IncludeDirectoriesString.c_str();
+ }
}
if (strcmp(prop,"IMPORTED") == 0)
@@ -5086,6 +5186,7 @@ cmTargetInternalPointer
//----------------------------------------------------------------------------
cmTargetInternalPointer::~cmTargetInternalPointer()
{
+ deleteAndClear(this->Pointer->IncludeDirectoriesEntries);
delete this->Pointer;
}
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 7c55933..60a105e 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -478,6 +478,8 @@ public:
/** @return the Mac framework directory without the base. */
std::string GetFrameworkDirectory(const char* config = 0);
+ std::vector<std::string> GetIncludeDirectories(const char *config);
+
private:
/**
* A list of direct dependencies. Use in conjunction with DependencyMap.
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e0575c47e1d2ea82d0effbc6909f1ea4a74938b7
commit e0575c47e1d2ea82d0effbc6909f1ea4a74938b7
Author: Stephen Kelly <steveire at gmail.com>
AuthorDate: Mon Nov 19 19:30:56 2012 +0100
Commit: Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Nov 29 15:09:47 2012 +0100
Use cmsys::auto_ptr to manage cmCompiledGeneratorExpressions
The compiled generator expressions need to outlive the creating
type. For the same reason, store the input string in a std::string.
diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx
index 07df7d5..f2f77ee 100644
--- a/Source/cmCustomCommandGenerator.cxx
+++ b/Source/cmCustomCommandGenerator.cxx
@@ -47,7 +47,7 @@ std::string cmCustomCommandGenerator::GetCommand(unsigned int c) const
{
return target->GetLocation(this->Config);
}
- return this->GE->Parse(argv0).Evaluate(this->Makefile, this->Config);
+ return this->GE->Parse(argv0)->Evaluate(this->Makefile, this->Config);
}
//----------------------------------------------------------------------------
@@ -58,7 +58,7 @@ cmCustomCommandGenerator
cmCustomCommandLine const& commandLine = this->CC.GetCommandLines()[c];
for(unsigned int j=1;j < commandLine.size(); ++j)
{
- std::string arg = this->GE->Parse(commandLine[j]).Evaluate(this->Makefile,
+ std::string arg = this->GE->Parse(commandLine[j])->Evaluate(this->Makefile,
this->Config);
cmd += " ";
if(this->OldStyle)
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index 2bcced1..97a0581 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -25,44 +25,29 @@
//----------------------------------------------------------------------------
cmGeneratorExpression::cmGeneratorExpression(
cmListFileBacktrace const& backtrace):
- Backtrace(backtrace), CompiledExpression(0)
+ Backtrace(backtrace)
{
}
//----------------------------------------------------------------------------
-const cmCompiledGeneratorExpression &
+cmsys::auto_ptr<cmCompiledGeneratorExpression>
cmGeneratorExpression::Parse(std::string const& input)
{
return this->Parse(input.c_str());
}
//----------------------------------------------------------------------------
-const cmCompiledGeneratorExpression &
+cmsys::auto_ptr<cmCompiledGeneratorExpression>
cmGeneratorExpression::Parse(const char* input)
{
- cmGeneratorExpressionLexer l;
- std::vector<cmGeneratorExpressionToken> tokens = l.Tokenize(input);
- bool needsParsing = l.GetSawGeneratorExpression();
- std::vector<cmGeneratorExpressionEvaluator*> evaluators;
-
- if (needsParsing)
- {
- cmGeneratorExpressionParser p(tokens);
- p.Parse(evaluators);
- }
-
- delete this->CompiledExpression;
- this->CompiledExpression = new cmCompiledGeneratorExpression(
- this->Backtrace,
- evaluators,
- input,
- needsParsing);
- return *this->CompiledExpression;
+ return cmsys::auto_ptr<cmCompiledGeneratorExpression>(
+ new cmCompiledGeneratorExpression(
+ this->Backtrace,
+ input));
}
cmGeneratorExpression::~cmGeneratorExpression()
{
- delete this->CompiledExpression;
}
//----------------------------------------------------------------------------
@@ -73,7 +58,7 @@ const char *cmCompiledGeneratorExpression::Evaluate(
{
if (!this->NeedsParsing)
{
- return this->Input;
+ return this->Input.c_str();
}
this->Output = "";
@@ -108,12 +93,19 @@ const char *cmCompiledGeneratorExpression::Evaluate(
cmCompiledGeneratorExpression::cmCompiledGeneratorExpression(
cmListFileBacktrace const& backtrace,
- const std::vector<cmGeneratorExpressionEvaluator*> &evaluators,
- const char *input, bool needsParsing)
- : Backtrace(backtrace), Evaluators(evaluators), Input(input),
- NeedsParsing(needsParsing)
+ const char *input)
+ : Backtrace(backtrace), Input(input ? input : "")
{
+ cmGeneratorExpressionLexer l;
+ std::vector<cmGeneratorExpressionToken> tokens =
+ l.Tokenize(this->Input.c_str());
+ this->NeedsParsing = l.GetSawGeneratorExpression();
+ if (this->NeedsParsing)
+ {
+ cmGeneratorExpressionParser p(tokens);
+ p.Parse(this->Evaluators);
+ }
}
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h
index 5e3352b..c3daf84 100644
--- a/Source/cmGeneratorExpression.h
+++ b/Source/cmGeneratorExpression.h
@@ -14,10 +14,12 @@
#define cmGeneratorExpression_h
#include "cmStandardIncludes.h"
+#include "cmListFileCache.h"
#include <stack>
#include <cmsys/RegularExpression.hxx>
+#include <cmsys/auto_ptr.hxx>
class cmTarget;
class cmMakefile;
@@ -44,8 +46,9 @@ public:
cmGeneratorExpression(cmListFileBacktrace const& backtrace);
~cmGeneratorExpression();
- const cmCompiledGeneratorExpression& Parse(std::string const& input);
- const cmCompiledGeneratorExpression& Parse(const char* input);
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> Parse(
+ std::string const& input);
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> Parse(const char* input);
enum PreprocessContext {
StripAllGeneratorExpressions,
@@ -62,7 +65,6 @@ private:
void operator=(const cmGeneratorExpression &);
cmListFileBacktrace const& Backtrace;
- cmCompiledGeneratorExpression *CompiledExpression;
};
class cmCompiledGeneratorExpression
@@ -79,20 +81,24 @@ public:
~cmCompiledGeneratorExpression();
+ std::string GetInput() const
+ {
+ return this->Input;
+ }
+
private:
cmCompiledGeneratorExpression(cmListFileBacktrace const& backtrace,
- const std::vector<cmGeneratorExpressionEvaluator*> &evaluators,
- const char *input, bool needsParsing);
+ const char *input);
friend class cmGeneratorExpression;
cmCompiledGeneratorExpression(const cmCompiledGeneratorExpression &);
void operator=(const cmCompiledGeneratorExpression &);
- cmListFileBacktrace const& Backtrace;
- const std::vector<cmGeneratorExpressionEvaluator*> Evaluators;
- const char* const Input;
- const bool NeedsParsing;
+ cmListFileBacktrace Backtrace;
+ std::vector<cmGeneratorExpressionEvaluator*> Evaluators;
+ const std::string Input;
+ bool NeedsParsing;
mutable std::set<cmTarget*> Targets;
mutable std::string Output;
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index de8b5e3..55507dd 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -267,7 +267,7 @@ std::vector<std::string> cmGeneratorTarget::GetIncludeDirectories(
"INCLUDE_DIRECTORIES", 0, 0);
cmSystemTools::ExpandListArgument(ge.Parse(prop)
- .Evaluate(this->Makefile,
+ ->Evaluate(this->Makefile,
config,
false,
this->Target,
@@ -315,7 +315,7 @@ std::string cmGeneratorTarget::GetCompileDefinitions(const char *config)
cmGeneratorExpressionDAGChecker dagChecker(lfbt,
this->GetName(),
defPropName, 0, 0);
- return ge.Parse(prop).Evaluate(this->Makefile,
+ return ge.Parse(prop)->Evaluate(this->Makefile,
config,
false,
this->Target,
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 59b8f0a..0e83878 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -1732,9 +1732,10 @@ cmTargetTraceDependencies
for(cmCustomCommandLine::const_iterator cli = cit->begin();
cli != cit->end(); ++cli)
{
- const cmCompiledGeneratorExpression &cge = ge.Parse(*cli);
- cge.Evaluate(this->Makefile, 0, true);
- std::set<cmTarget*> geTargets = cge.GetTargets();
+ const cmsys::auto_ptr<cmCompiledGeneratorExpression> cge
+ = ge.Parse(*cli);
+ cge->Evaluate(this->Makefile, 0, true);
+ std::set<cmTarget*> geTargets = cge->GetTargets();
for(std::set<cmTarget*>::const_iterator it = geTargets.begin();
it != geTargets.end(); ++it)
{
@@ -4478,7 +4479,7 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
this->GetName(),
"INTERFACE_LINK_LIBRARIES", 0, 0);
cmSystemTools::ExpandListArgument(ge.Parse(newStyleLibsProp)
- .Evaluate(this->Makefile,
+ ->Evaluate(this->Makefile,
desired_config.c_str(),
false,
this,
@@ -4666,7 +4667,7 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface)
this->GetName(),
"INTERFACE_LINK_LIBRARIES", 0, 0);
- cmSystemTools::ExpandListArgument(ge.Parse(newLibrariesProp).Evaluate(
+ cmSystemTools::ExpandListArgument(ge.Parse(newLibrariesProp)->Evaluate(
this->Makefile,
config,
false,
diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx
index 2f650e7..42f511e 100644
--- a/Source/cmTestGenerator.cxx
+++ b/Source/cmTestGenerator.cxx
@@ -112,7 +112,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
else
{
// Use the command name given.
- exe = ge.Parse(exe.c_str()).Evaluate(mf, config);
+ exe = ge.Parse(exe.c_str())->Evaluate(mf, config);
cmSystemTools::ConvertToUnixSlashes(exe);
}
@@ -122,7 +122,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
for(std::vector<std::string>::const_iterator ci = command.begin()+1;
ci != command.end(); ++ci)
{
- os << " " << lg->EscapeForCMake(ge.Parse(*ci).Evaluate(mf, config));
+ os << " " << lg->EscapeForCMake(ge.Parse(*ci)->Evaluate(mf, config));
}
// Finish the test command.
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=8f77e06833795f97630105c83b23aa3bf2f2a6ad
commit 8f77e06833795f97630105c83b23aa3bf2f2a6ad
Author: Stephen Kelly <steveire at gmail.com>
AuthorDate: Thu Nov 1 00:32:10 2012 +0100
Commit: Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Nov 29 15:08:58 2012 +0100
Genex: Add INTERFACE_LINK_LIBRARIES property
This new property is a replacement for
the (IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)? properties as
it can contain generator expressions. It is also part of the generated
IMPORTED targets generated by the export() and install(EXPORT) commands.
User code may already populate
the (IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)? properties, so
policy CMP0019 is added to handle that.
If the policy is NEW, the old properties are ignored and
the INTERFACE_LINK_LIBRARIES property is used.
Otherwise if the policy is OLD the old properties are used and the
new INTERFACE_LINK_LIBRARIES is ignored.
The policy emits a warning if the old-style property and new-style
property differ in their content.
The policy also affects the IMPORTED targets generated by export()
and install(EXPORT). If the policy is NEW, that means that the user
has bumped their cmake requirement to 2.8.11. As we'll therefore be
generating INTERFACE_LINK_LIBRARIES properties in the IMPORTED
targets, we need to ensure that consumers can use the new property,
so 2.8.11 will be required for the consumers too.
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index fb3f39f..a86f8c4 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -12,6 +12,7 @@
#include "cmExportBuildFileGenerator.h"
#include "cmExportCommand.h"
+#include "cmGeneratorExpression.h"
//----------------------------------------------------------------------------
cmExportBuildFileGenerator::cmExportBuildFileGenerator()
@@ -31,6 +32,17 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
if(this->ExportedTargets.insert(te).second)
{
this->GenerateImportTargetCode(os, te);
+
+ ImportPropertyMap properties;
+
+ if ((*tei)->GetPolicyStatusCMP0019() == cmPolicies::NEW)
+ {
+ this->PopulateInterfaceProperty("INTERFACE_LINK_LIBRARIES", te,
+ cmGeneratorExpression::BuildInterface,
+ properties);
+ }
+
+ this->GenerateInterfaceProperties(te, os, properties);
}
else
{
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 8dffae4..a67c3ee 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -125,6 +125,50 @@ void cmExportFileGenerator::GenerateImportConfig(std::ostream& os,
}
//----------------------------------------------------------------------------
+void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName,
+ cmTarget *target,
+ cmGeneratorExpression::PreprocessContext preprocessRule,
+ ImportPropertyMap &properties)
+{
+ const char *input = target->GetProperty(propName);
+ if (input)
+ {
+ if (!*input)
+ {
+ // Set to empty
+ properties[propName] = "";
+ return;
+ }
+ std::string prepro = cmGeneratorExpression::Preprocess(input,
+ preprocessRule,
+ this->Namespace.c_str());
+ if (!prepro.empty())
+ {
+ properties[propName] = prepro;
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmExportFileGenerator::GenerateInterfaceProperties(cmTarget *target,
+ std::ostream& os,
+ const ImportPropertyMap &properties)
+{
+ if (!properties.empty())
+ {
+ std::string targetName = this->Namespace;
+ targetName += target->GetName();
+ 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 << ")\n\n";
+ }
+}
+
+//----------------------------------------------------------------------------
void
cmExportFileGenerator
::SetImportDetailProperties(const char* config, std::string const& suffix,
diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h
index 70bc65d..3aee1b8 100644
--- a/Source/cmExportFileGenerator.h
+++ b/Source/cmExportFileGenerator.h
@@ -13,6 +13,7 @@
#define cmExportFileGenerator_h
#include "cmCommand.h"
+#include "cmGeneratorExpression.h"
/** \class cmExportFileGenerator
* \brief Generate a file exporting targets from a build or install tree.
@@ -91,6 +92,12 @@ protected:
cmMakefile* mf,
cmTarget* depender,
cmTarget* dependee) = 0;
+ void PopulateInterfaceProperty(const char *,
+ cmTarget *target,
+ cmGeneratorExpression::PreprocessContext,
+ ImportPropertyMap &properties);
+ void GenerateInterfaceProperties(cmTarget *target, std::ostream& os,
+ const ImportPropertyMap &properties);
// The namespace in which the exports are placed in the generated file.
std::string Namespace;
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index 7841731..4fef08e 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -19,6 +19,7 @@
#include "cmInstallExportGenerator.h"
#include "cmInstallTargetGenerator.h"
#include "cmTargetExport.h"
+#include "cmGeneratorExpression.h"
//----------------------------------------------------------------------------
cmExportInstallFileGenerator
@@ -48,6 +49,18 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
if(this->ExportedTargets.insert(te->Target).second)
{
this->GenerateImportTargetCode(os, te->Target);
+
+ ImportPropertyMap properties;
+
+ if ((*tei)->Target->GetPolicyStatusCMP0019() == cmPolicies::NEW)
+ {
+ this->PopulateInterfaceProperty("INTERFACE_LINK_LIBRARIES",
+ te->Target,
+ cmGeneratorExpression::InstallInterface,
+ properties);
+ }
+
+ this->GenerateInterfaceProperties(te->Target, os, properties);
}
else
{
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index 6aef502..4c89dd6 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -491,6 +491,26 @@ cmPolicies::cmPolicies()
"CMAKE_SHARED_LIBRARY_<Lang>_FLAGS whether it is modified or not and "
"honor the POSITION_INDEPENDENT_CODE target property.",
2,8,9,0, cmPolicies::WARN);
+
+ this->DefinePolicy(
+ CMP0019, "CMP0019",
+ "Use INTERFACE_LINK_LIBRARIES instead of LINK_INTERFACE_LIBRARIES.",
+ "CMake 2.8.10 used the (IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)? "
+ "properties to determine the link interface. CMake 2.8.11 and higher "
+ "prefer instead to use the INTERFACE_LINK_LIBRARIES target property to "
+ "determine the link interface, while ignoring "
+ "(IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)? completely. The new "
+ "INTERFACE_LINK_LIBRARIES target property can use generator expressions "
+ "to specify config-specific link libraries."
+ "\n"
+ "The OLD behavior for this policy is to ignore the "
+ "INTERFACE_LINK_LIBRARIES property for all targets and use the "
+ "value of (IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)? instead."
+ "\n"
+ "The NEW behavior for this policy is to ignore "
+ "the value of the (IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)? target "
+ "property",
+ 2,8,11,0, cmPolicies::WARN);
}
cmPolicies::~cmPolicies()
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 6932565..b6b8e39 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -68,6 +68,7 @@ public:
CMP0018, ///< Ignore language flags for shared libs, and adhere to
/// POSITION_INDEPENDENT_CODE property and *_COMPILE_OPTIONS_PI{E,C}
/// instead.
+ CMP0019, ///< Use new-style INTERFACE_LINK_LIBRARIES
/** \brief Always the last entry.
*
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index be20464..59b8f0a 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -21,6 +21,7 @@
#include "cmDocumentLocationUndefined.h"
#include "cmListFileCache.h"
#include "cmGeneratorExpression.h"
+#include "cmGeneratorExpressionDAGChecker.h"
#include <cmsys/RegularExpression.hxx>
#include <map>
#include <set>
@@ -127,6 +128,7 @@ cmTarget::cmTarget()
this->PolicyStatusCMP0003 = cmPolicies::WARN;
this->PolicyStatusCMP0004 = cmPolicies::WARN;
this->PolicyStatusCMP0008 = cmPolicies::WARN;
+ this->PolicyStatusCMP0019 = cmPolicies::WARN;
this->LinkLibrariesAnalyzed = false;
this->HaveInstallRule = false;
this->DLLPlatform = false;
@@ -1409,6 +1411,8 @@ void cmTarget::SetMakefile(cmMakefile* mf)
this->Makefile->GetPolicyStatus(cmPolicies::CMP0004);
this->PolicyStatusCMP0008 =
this->Makefile->GetPolicyStatus(cmPolicies::CMP0008);
+ this->PolicyStatusCMP0019 =
+ this->Makefile->GetPolicyStatus(cmPolicies::CMP0019);
}
//----------------------------------------------------------------------------
@@ -4238,6 +4242,28 @@ cmTarget::GetImportInfo(const char* config)
return &i->second;
}
+
+bool handleCMP0019(const std::vector<std::string> &newLinkLibraries,
+ const std::vector<std::string> &oldLinkLibraries)
+{
+ if (newLinkLibraries.size() != oldLinkLibraries.size())
+ {
+ return false;
+ }
+ for(std::vector<std::string>::const_iterator
+ oll = oldLinkLibraries.begin(), nll = newLinkLibraries.begin();
+ oll != oldLinkLibraries.end() && nll != newLinkLibraries.end();
+ ++oll, ++nll)
+ {
+ if (*oll != *nll)
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+
//----------------------------------------------------------------------------
void cmTarget::ComputeImportInfo(std::string const& desired_config,
ImportInfo& info)
@@ -4441,21 +4467,79 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
// Get the link interface.
{
+ std::vector<std::string> newInterfaceLibs;
+ const char* newStyleLibsProp = this->GetProperty("INTERFACE_LINK_LIBRARIES");
+ if(newStyleLibsProp)
+ {
+ cmListFileBacktrace lfbt;
+ cmGeneratorExpression ge(lfbt);
+
+ cmGeneratorExpressionDAGChecker dagChecker(lfbt,
+ this->GetName(),
+ "INTERFACE_LINK_LIBRARIES", 0, 0);
+ cmSystemTools::ExpandListArgument(ge.Parse(newStyleLibsProp)
+ .Evaluate(this->Makefile,
+ desired_config.c_str(),
+ false,
+ this,
+ &dagChecker),
+ newInterfaceLibs);
+ }
+
std::string linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES";
- linkProp += suffix;
- if(const char* config_libs = this->GetProperty(linkProp.c_str()))
+ std::vector<std::string> oldInterfaceLibs;
+ const char *oldProp = this->GetProperty((linkProp + suffix).c_str());
+ if(oldProp)
{
- cmSystemTools::ExpandListArgument(config_libs,
- info.LinkInterface.Libraries);
+ linkProp += suffix;
+ cmSystemTools::ExpandListArgument(oldProp,
+ oldInterfaceLibs);
}
- else if(const char* libs =
- this->GetProperty("IMPORTED_LINK_INTERFACE_LIBRARIES"))
+ else
+ {
+ oldProp = this->GetProperty("IMPORTED_LINK_INTERFACE_LIBRARIES");
+ if(oldProp)
+ {
+ cmSystemTools::ExpandListArgument(oldProp,
+ oldInterfaceLibs);
+ }
+ }
+
+ std::vector<std::string> usedLinkLibraries;
+ switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0019))
{
- cmSystemTools::ExpandListArgument(libs,
- info.LinkInterface.Libraries);
+ case cmPolicies::WARN:
+ {
+ if (newStyleLibsProp && oldProp
+ && !handleCMP0019(newInterfaceLibs, oldInterfaceLibs))
+ {
+ cmOStringStream e;
+ e << "The " << linkProp << " and "
+ "LINK_INTERFACE_LIBRARIES are not the same for target \""
+ << this->GetName() << "\". NEW content is \""
+ << (newStyleLibsProp ? newStyleLibsProp : "(unset)") << "\"\n"
+ "OLD content is \""
+ << (oldProp ? oldProp : "(unset)") << "\"\n"
+ << this->Makefile->GetPolicies()->GetPolicyWarning(
+ cmPolicies::CMP0019);
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, e.str());
+ }
+ // fall through to OLD behaviour
+ }
+ case cmPolicies::OLD:
+ usedLinkLibraries = oldInterfaceLibs;
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ default:
+ usedLinkLibraries = newInterfaceLibs;
}
+ info.LinkInterface.Libraries.insert(info.LinkInterface.Libraries.end(),
+ usedLinkLibraries.begin(), usedLinkLibraries.end());
}
+
// Get the link dependencies.
{
std::string linkProp = "IMPORTED_LINK_DEPENDENT_LIBRARIES";
@@ -4562,21 +4646,82 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface)
// An explicit list of interface libraries may be set for shared
// libraries and executables that export symbols.
- const char* explicitLibraries = 0;
+ bool explicitLibraries = false;
+ std::vector<std::string> usedLinkLibraries;
if(this->GetType() == cmTarget::SHARED_LIBRARY ||
this->IsExecutableWithExports())
{
+ const char *newLibrariesProp =
+ this->GetProperty("INTERFACE_LINK_LIBRARIES");
+
+ std::vector<std::string> newInterfaceLibs;
+ std::vector<std::string> oldInterfaceLibs;
+
+ if(newLibrariesProp)
+ {
+ cmListFileBacktrace lfbt;
+ cmGeneratorExpression ge(lfbt);
+
+ cmGeneratorExpressionDAGChecker dagChecker(lfbt,
+ this->GetName(),
+ "INTERFACE_LINK_LIBRARIES", 0, 0);
+
+ cmSystemTools::ExpandListArgument(ge.Parse(newLibrariesProp).Evaluate(
+ this->Makefile,
+ config,
+ false,
+ this,
+ &dagChecker), newInterfaceLibs);
+ }
// Lookup the per-configuration property.
std::string propName = "LINK_INTERFACE_LIBRARIES";
propName += suffix;
- explicitLibraries = this->GetProperty(propName.c_str());
+ const char *oldLibrariesProp = this->GetProperty(propName.c_str());
// If not set, try the generic property.
- if(!explicitLibraries)
+ if(!oldLibrariesProp)
+ {
+ oldLibrariesProp = this->GetProperty("LINK_INTERFACE_LIBRARIES");
+ }
+ if(oldLibrariesProp)
+ {
+ cmSystemTools::ExpandListArgument(oldLibrariesProp, oldInterfaceLibs);
+ }
+
+ {
+ switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0019))
{
- explicitLibraries = this->GetProperty("LINK_INTERFACE_LIBRARIES");
+ case cmPolicies::WARN:
+ {
+ if (newLibrariesProp && oldLibrariesProp
+ && !handleCMP0019(newInterfaceLibs, oldInterfaceLibs))
+ {
+ cmOStringStream e;
+ e << "The INTERFACE_LINK_LIBRARIES and LINK_INTERFACE_LIBRARIES are "
+ "not the same for target \"" << this->GetName() << "\".\n"
+ "NEW content is \""
+ << (newLibrariesProp ? newLibrariesProp : "(unset)") << "\"\n"
+ "OLD content is \""
+ << (oldLibrariesProp ? oldLibrariesProp : "(unset)") << "\"\n"
+ << this->Makefile->GetPolicies()->GetPolicyWarning(
+ cmPolicies::CMP0019);
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, e.str());
+ }
+ // fall through to OLD behaviour
+ }
+ case cmPolicies::OLD:
+ explicitLibraries = oldLibrariesProp ? true : false;
+ usedLinkLibraries = oldInterfaceLibs;
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ default:
+ usedLinkLibraries = newInterfaceLibs;
+ explicitLibraries = newLibrariesProp ? true : false;
}
}
+ }
// There is no implicit link interface for executables or modules
// so if none was explicitly set then there is no link interface.
@@ -4592,7 +4737,8 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface)
if(explicitLibraries)
{
// The interface libraries have been explicitly set.
- cmSystemTools::ExpandListArgument(explicitLibraries, iface.Libraries);
+ iface.Libraries.insert(iface.Libraries.end(),
+ usedLinkLibraries.begin(), usedLinkLibraries.end());
if(this->GetType() == cmTarget::SHARED_LIBRARY)
{
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 9efd638..7c55933 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -99,6 +99,10 @@ public:
cmPolicies::PolicyStatus GetPolicyStatusCMP0008() const
{ return this->PolicyStatusCMP0008; }
+ /** Get the status of policy CMP0019 when the target was created. */
+ cmPolicies::PolicyStatus GetPolicyStatusCMP0019() const
+ { return this->PolicyStatusCMP0019; }
+
/**
* Get the list of the custom commands for this target
*/
@@ -618,6 +622,7 @@ private:
cmPolicies::PolicyStatus PolicyStatusCMP0003;
cmPolicies::PolicyStatus PolicyStatusCMP0004;
cmPolicies::PolicyStatus PolicyStatusCMP0008;
+ cmPolicies::PolicyStatus PolicyStatusCMP0019;
// Internal representation details.
friend class cmTargetInternals;
diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx
index f42b0f6..d7a1443 100644
--- a/Source/cmTargetLinkLibrariesCommand.cxx
+++ b/Source/cmTargetLinkLibrariesCommand.cxx
@@ -232,7 +232,11 @@ bool cmTargetLinkLibrariesCommand
{
this->Target->SetProperty("LINK_INTERFACE_LIBRARIES", "");
}
-
+ if(this->CurrentProcessingState != ProcessingLinkLibraries &&
+ !this->Target->GetProperty("INTERFACE_LINK_LIBRARIES"))
+ {
+ this->Target->SetProperty("INTERFACE_LINK_LIBRARIES", "");
+ }
return true;
}
@@ -250,6 +254,25 @@ cmTargetLinkLibrariesCommand
}
//----------------------------------------------------------------------------
+static std::string generatorIface(const std::string &value,
+ cmTarget::LinkLibraryType llt)
+{
+ if (llt == cmTarget::DEBUG)
+ {
+ return "$<$<CONFIG:Debug>:"
+ + value
+ + ">";
+ }
+ else if (llt == cmTarget::OPTIMIZED)
+ {
+ return "$<$<NOT:$<CONFIG:Debug>>:"
+ + value
+ + ">";
+ }
+ return value;
+}
+
+//----------------------------------------------------------------------------
void
cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
cmTarget::LinkLibraryType llt)
@@ -266,6 +289,9 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
}
}
+ this->Target->AppendProperty("INTERFACE_LINK_LIBRARIES",
+ generatorIface(lib, 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/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
index 1faa888..95cfd15 100644
--- a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
+++ b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
@@ -56,3 +56,21 @@ assert_property(targetA LINK_INTERFACE_LIBRARIES "")
target_link_libraries(targetA depB depC)
assert_property(targetA LINK_INTERFACE_LIBRARIES "")
+
+# cmake_policy(PUSH)
+
+cmake_policy(SET CMP0019 NEW)
+
+add_library(depD SHARED depD.cpp)
+generate_export_header(depD)
+set_property(TARGET depD APPEND PROPERTY INTERFACE_LINK_LIBRARIES $<1:depA>)
+
+add_library(depE SHARED depE.cpp)
+generate_export_header(depE)
+target_link_libraries(depE LINK_PRIVATE depB)
+target_link_libraries(depE LINK_INTERFACE_LIBRARIES $<1:depB>)
+
+add_executable(targetB targetB.cpp)
+target_link_libraries(targetB depD depE)
+
+# cmake_policy(POP)
diff --git a/Tests/CMakeCommands/target_link_libraries/depD.cpp b/Tests/CMakeCommands/target_link_libraries/depD.cpp
new file mode 100644
index 0000000..b02c76c
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_libraries/depD.cpp
@@ -0,0 +1,13 @@
+
+#include "depD.h"
+
+int DepD::foo()
+{
+ return 0;
+}
+
+DepA DepD::getA()
+{
+ DepA a;
+ return a;
+}
diff --git a/Tests/CMakeCommands/target_link_libraries/depD.h b/Tests/CMakeCommands/target_link_libraries/depD.h
new file mode 100644
index 0000000..d24ff5f
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_libraries/depD.h
@@ -0,0 +1,11 @@
+
+#include "depd_export.h"
+
+#include "depA.h"
+
+struct DEPD_EXPORT DepD
+{
+ int foo();
+
+ DepA getA();
+};
diff --git a/Tests/CMakeCommands/target_link_libraries/depE.cpp b/Tests/CMakeCommands/target_link_libraries/depE.cpp
new file mode 100644
index 0000000..1a3da4a
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_libraries/depE.cpp
@@ -0,0 +1,13 @@
+
+#include "depE.h"
+
+int DepE::foo()
+{
+ return 0;
+}
+
+DepB DepE::getB()
+{
+ DepB a;
+ return a;
+}
diff --git a/Tests/CMakeCommands/target_link_libraries/depE.h b/Tests/CMakeCommands/target_link_libraries/depE.h
new file mode 100644
index 0000000..2273e17
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_libraries/depE.h
@@ -0,0 +1,11 @@
+
+#include "depe_export.h"
+
+#include "depB.h"
+
+struct DEPE_EXPORT DepE
+{
+ int foo();
+
+ DepB getB();
+};
diff --git a/Tests/CMakeCommands/target_link_libraries/targetB.cpp b/Tests/CMakeCommands/target_link_libraries/targetB.cpp
new file mode 100644
index 0000000..c6a1264
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_libraries/targetB.cpp
@@ -0,0 +1,14 @@
+
+#include "depD.h"
+#include "depE.h"
+
+int main(int argc, char **argv)
+{
+ DepD d;
+ DepA a = d.getA();
+
+ DepE e;
+ DepB b = e.getB();
+
+ return d.foo() + a.foo() + e.foo() + b.foo();
+}
-----------------------------------------------------------------------
Summary of changes:
hooks/post-receive
--
CMake
More information about the Cmake-commits
mailing list