summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2014-04-03 16:51:51 (GMT)
committerCMake Topic Stage <kwrobot@kitware.com>2014-04-03 16:51:51 (GMT)
commit93054aa84f283de17c58fa2ee19a2a4a1668027d (patch)
tree8b53dac2eb3a77909458cba210a6873915fb45ab
parent1d4366ffac5814441c440d2832d9d8f187841113 (diff)
parent5de63265e3a22d9a8aa5ad437a5030ccfcbcd02d (diff)
downloadCMake-93054aa84f283de17c58fa2ee19a2a4a1668027d.zip
CMake-93054aa84f283de17c58fa2ee19a2a4a1668027d.tar.gz
CMake-93054aa84f283de17c58fa2ee19a2a4a1668027d.tar.bz2
Merge topic 'target-sources-refactor'
5de63265 Genex: Only evaluate TARGET_OBJECTS to determine target sources. aa0a3562 cmGeneratorTarget: Compute target objects on demand 042c1c83 cmTarget: Compute languages from object libraries on demand. fdcefe3c cmGeneratorTarget: Compute consumed object libraries on demand. c355d108 cmComputeTargetDepends: Track object library depends. e5da9e51 cmTarget: Allow any generator expression in SOURCES property. 5702e106 cmTarget: Include TARGET_OBJECTS genex in target SOURCES property. 857d30b5 cmGlobalGenerator: Add interface to call ForceLinkerLanguages 28e1d2f8 cmStringCommand: Add GENEX_STRIP subcommand. bf98cc25 Genex: Evaluate TARGET_OBJECTS as a normal expression. 8cd113ad cmTarget: Store strings instead of cmSourceFile* to represent SOURCES. 4959f341 cmSourceFileLocation: Collapse full path for directory comparisons. fcc92878 cmSourceFileLocation: Remove unused Update method. 59e8740a cmTarget: Remove AddSourceFile method 26d494ba cmTarget: Use string API to add sources to cmTarget objects. d38423ec cmTarget: Add a method to obtain list of filenames for sources. ...
-rw-r--r--Help/command/add_executable.rst7
-rw-r--r--Help/command/add_library.rst6
-rw-r--r--Help/command/string.rst5
-rw-r--r--Help/manual/cmake-generator-expressions.7.rst5
-rw-r--r--Help/manual/cmake-policies.7.rst1
-rw-r--r--Help/policy/CMP0051.rst24
-rw-r--r--Help/release/dev/string-GENEX_STRIP.rst6
-rw-r--r--Help/release/dev/target-SOURCES-genex.rst12
-rw-r--r--Source/cmComputeTargetDepends.cxx29
-rw-r--r--Source/cmFLTKWrapUICommand.cxx2
-rw-r--r--Source/cmGeneratorExpression.cxx4
-rw-r--r--Source/cmGeneratorExpression.h6
-rw-r--r--Source/cmGeneratorExpressionEvaluator.cxx74
-rw-r--r--Source/cmGeneratorExpressionEvaluator.h1
-rw-r--r--Source/cmGeneratorTarget.cxx128
-rw-r--r--Source/cmGeneratorTarget.h8
-rw-r--r--Source/cmGlobalGenerator.cxx56
-rw-r--r--Source/cmGlobalGenerator.h4
-rw-r--r--Source/cmGlobalVisualStudio8Generator.cxx3
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx18
-rw-r--r--Source/cmLocalGenerator.cxx4
-rw-r--r--Source/cmLocalVisualStudio6Generator.cxx16
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx8
-rw-r--r--Source/cmMakefile.cxx4
-rw-r--r--Source/cmMakefileTargetGenerator.cxx3
-rw-r--r--Source/cmNinjaTargetGenerator.cxx11
-rw-r--r--Source/cmPolicies.cxx5
-rw-r--r--Source/cmPolicies.h1
-rw-r--r--Source/cmQtAutoGenerators.cxx17
-rw-r--r--Source/cmSourceFile.cxx12
-rw-r--r--Source/cmSourceFile.h4
-rw-r--r--Source/cmSourceFileLocation.cxx70
-rw-r--r--Source/cmSourceFileLocation.h5
-rw-r--r--Source/cmStringCommand.cxx25
-rw-r--r--Source/cmStringCommand.h1
-rw-r--r--Source/cmTarget.cxx313
-rw-r--r--Source/cmTarget.h9
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx13
-rw-r--r--Tests/GeneratorExpression/CMakeLists.txt2
-rw-r--r--Tests/Properties/CMakeLists.txt2
-rw-r--r--Tests/Properties/SubDir2/CMakeLists.txt5
-rw-r--r--Tests/Properties/subdirtest.cxx9
-rw-r--r--Tests/RunCMake/CMP0051/CMP0051-NEW-result.txt1
-rw-r--r--Tests/RunCMake/CMP0051/CMP0051-NEW-stderr.txt1
-rw-r--r--Tests/RunCMake/CMP0051/CMP0051-NEW.cmake10
-rw-r--r--Tests/RunCMake/CMP0051/CMP0051-OLD-result.txt1
-rw-r--r--Tests/RunCMake/CMP0051/CMP0051-OLD-stderr.txt1
-rw-r--r--Tests/RunCMake/CMP0051/CMP0051-OLD.cmake10
-rw-r--r--Tests/RunCMake/CMP0051/CMP0051-WARN-result.txt1
-rw-r--r--Tests/RunCMake/CMP0051/CMP0051-WARN-stderr.txt15
-rw-r--r--Tests/RunCMake/CMP0051/CMP0051-WARN.cmake8
-rw-r--r--Tests/RunCMake/CMP0051/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0051/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/CMP0051/empty.cpp7
-rw-r--r--Tests/RunCMake/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadSourceExpression1-stderr.txt4
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadSourceExpression2-stderr.txt4
-rw-r--r--Tests/RunCMake/ObjectLibrary/BadSourceExpression3-stderr.txt4
-rw-r--r--Tests/RunCMake/TargetObjects/BadContext-result.txt1
-rw-r--r--Tests/RunCMake/TargetObjects/BadContext-stderr.txt17
-rw-r--r--Tests/RunCMake/TargetObjects/BadContext.cmake4
-rw-r--r--Tests/RunCMake/TargetObjects/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/TargetObjects/RunCMakeTest.cmake3
-rw-r--r--Tests/StringFileTest/CMakeLists.txt6
64 files changed, 778 insertions, 271 deletions
diff --git a/Help/command/add_executable.rst b/Help/command/add_executable.rst
index 231eeed..4ed10e1 100644
--- a/Help/command/add_executable.rst
+++ b/Help/command/add_executable.rst
@@ -35,8 +35,11 @@ If ``EXCLUDE_FROM_ALL`` is given the corresponding property will be set on
the created target. See documentation of the :prop_tgt:`EXCLUDE_FROM_ALL`
target property for details.
-See the :manual:`cmake-buildsystem(7)` manual for more on defining
-buildsystem properties.
+Source arguments to ``add_executable`` may use "generator expressions" with
+the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
+manual for available expressions. See the :manual:`cmake-buildsystem(7)`
+manual for more on defining buildsystem properties.
+
--------------------------------------------------------------------------
diff --git a/Help/command/add_library.rst b/Help/command/add_library.rst
index 0944269..e93ef53 100644
--- a/Help/command/add_library.rst
+++ b/Help/command/add_library.rst
@@ -39,8 +39,10 @@ If ``EXCLUDE_FROM_ALL`` is given the corresponding property will be set on
the created target. See documentation of the :prop_tgt:`EXCLUDE_FROM_ALL`
target property for details.
-See the :manual:`cmake-buildsystem(7)` manual for more on defining buildsystem
-properties.
+Source arguments to ``add_library`` may use "generator expressions" with
+the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
+manual for available expressions. See the :manual:`cmake-buildsystem(7)`
+manual for more on defining buildsystem properties.
--------------------------------------------------------------------------
diff --git a/Help/command/string.rst b/Help/command/string.rst
index af18825..abde6ee 100644
--- a/Help/command/string.rst
+++ b/Help/command/string.rst
@@ -35,6 +35,7 @@ String operations.
string(FIND <string> <substring> <output variable> [REVERSE])
string(TIMESTAMP <output variable> [<format string>] [UTC])
string(MAKE_C_IDENTIFIER <input string> <output variable>)
+ string(GENEX_STRIP <input string> <output variable>)
REGEX MATCH will match the regular expression once and store the match
in the output variable.
@@ -154,3 +155,7 @@ If no explicit <format string> is given it will default to:
MAKE_C_IDENTIFIER will write a string which can be used as an
identifier in C.
+
+``GENEX_STRIP`` will strip any
+:manual:`generator expressions <cmake-generator-expressions(7)>` from the
+``input string`` and store the result in the ``output variable``.
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index ac8c3f8..dfda8dc 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -188,3 +188,8 @@ property is non-empty::
Content of ``...`` converted to upper case.
``$<MAKE_C_IDENTIFIER:...>``
Content of ``...`` converted to a C identifier.
+``$<TARGET_OBJECTS:objLib>``
+ List of objects resulting from build of ``objLib``. ``objLib`` must be an
+ object of type ``OBJECT_LIBRARY``. This expression may only be used in
+ the sources of :command:`add_library` and :command:`add_executable`
+ commands.
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index 8650a58..b763882 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -102,3 +102,4 @@ All Policies
/policy/CMP0048
/policy/CMP0049
/policy/CMP0050
+ /policy/CMP0051
diff --git a/Help/policy/CMP0051.rst b/Help/policy/CMP0051.rst
new file mode 100644
index 0000000..7d85929
--- /dev/null
+++ b/Help/policy/CMP0051.rst
@@ -0,0 +1,24 @@
+CMP0051
+-------
+
+List TARGET_OBJECTS in SOURCES target property.
+
+CMake 3.0 and lower did not include the ``TARGET_OBJECTS``
+:manual:`generator expression <cmake-generator-expressions(7)>` when
+returning the :prop_tgt:`SOURCES` target property.
+
+Configure-time CMake code is not able to handle generator expressions. If
+using the :prop_tgt:`SOURCES` target property at configure time, it may be
+necessary to first remove generator expressions using the
+:command:`string(STRIP_GENEX)` command. Generate-time CMake code such as
+:command:`file(GENERATE)` can handle the content without stripping.
+
+The ``OLD`` behavior for this policy is to omit ``TARGET_OBJECTS``
+expressions from the :prop_tgt:`SOURCES` target property. The ``NEW``
+behavior for this policy is to include ``TARGET_OBJECTS`` expressions
+in the output.
+
+This policy was introduced in CMake version 3.1.
+CMake version |release| warns when the policy is not set and uses
+``OLD`` behavior. Use the :command:`cmake_policy` command to set it
+to ``OLD`` or ``NEW`` explicitly.
diff --git a/Help/release/dev/string-GENEX_STRIP.rst b/Help/release/dev/string-GENEX_STRIP.rst
new file mode 100644
index 0000000..b5b1074
--- /dev/null
+++ b/Help/release/dev/string-GENEX_STRIP.rst
@@ -0,0 +1,6 @@
+string-GENEX_STRIP
+------------------
+
+* The :command:`string` command learned a new ``GENEX_STRIP`` subcommand
+ which removes
+ :manual:`generator expression <cmake-generator-expressions(7)>`.
diff --git a/Help/release/dev/target-SOURCES-genex.rst b/Help/release/dev/target-SOURCES-genex.rst
new file mode 100644
index 0000000..9a65101
--- /dev/null
+++ b/Help/release/dev/target-SOURCES-genex.rst
@@ -0,0 +1,12 @@
+target-SOURCES-genex
+--------------------
+
+* The :prop_tgt:`SOURCES` target property now contains
+ :manual:`generator expression <cmake-generator-expressions(7)>`
+ such as ``TARGET_OBJECTS`` when read at configure time, if
+ policy :policy:`CMP0051` is ``NEW``.
+
+* The :prop_tgt:`SOURCES` target property now generally supports
+ :manual:`generator expression <cmake-generator-expressions(7)>`. The
+ generator expressions may be used in the :command:`add_library` and
+ :command:`add_executable` commands.
diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index 5ba843f..27fc862 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -16,6 +16,7 @@
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmSystemTools.h"
+#include "cmSourceFile.h"
#include "cmTarget.h"
#include "cmake.h"
@@ -213,6 +214,34 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
{
std::set<std::string> emitted;
{
+ cmGeneratorTarget* gt = depender->GetMakefile()->GetLocalGenerator()
+ ->GetGlobalGenerator()
+ ->GetGeneratorTarget(depender);
+ std::vector<cmSourceFile const*> objectFiles;
+ gt->GetExternalObjects(objectFiles);
+ for(std::vector<cmSourceFile const*>::const_iterator
+ it = objectFiles.begin(); it != objectFiles.end(); ++it)
+ {
+ std::string objLib = (*it)->GetObjectLibrary();
+ if (!objLib.empty() && emitted.insert(objLib).second)
+ {
+ if(depender->GetType() != cmTarget::EXECUTABLE &&
+ depender->GetType() != cmTarget::STATIC_LIBRARY &&
+ depender->GetType() != cmTarget::SHARED_LIBRARY &&
+ depender->GetType() != cmTarget::MODULE_LIBRARY)
+ {
+ this->GlobalGenerator->GetCMakeInstance()
+ ->IssueMessage(cmake::FATAL_ERROR,
+ "Only executables and non-OBJECT libraries may "
+ "reference target objects.",
+ depender->GetBacktrace());
+ return;
+ }
+ const_cast<cmTarget*>(depender)->AddUtility(objLib);
+ }
+ }
+ }
+ {
std::vector<std::string> tlibs;
depender->GetDirectLinkLibraries("", tlibs, depender);
// A target should not depend on itself.
diff --git a/Source/cmFLTKWrapUICommand.cxx b/Source/cmFLTKWrapUICommand.cxx
index 0a36b82..e2b114a 100644
--- a/Source/cmFLTKWrapUICommand.cxx
+++ b/Source/cmFLTKWrapUICommand.cxx
@@ -168,7 +168,7 @@ void cmFLTKWrapUICommand::FinalPass()
for(size_t classNum = 0; classNum < lastHeadersClass; classNum++)
{
this->Makefile->GetTargets()[this->Target]
- .AddSourceFile(this->GeneratedSourcesClasses[classNum]);
+ .AddSource(this->GeneratedSourcesClasses[classNum]->GetFullPath());
}
}
}
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index e127f3a..d09e950 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -90,6 +90,7 @@ const char *cmCompiledGeneratorExpression::Evaluate(
context.HadError = false;
context.HadContextSensitiveCondition = false;
context.HeadTarget = headTarget;
+ context.EvaluateForBuildsystem = this->EvaluateForBuildsystem;
context.CurrentTarget = currentTarget ? currentTarget : headTarget;
context.Backtrace = this->Backtrace;
@@ -124,7 +125,8 @@ cmCompiledGeneratorExpression::cmCompiledGeneratorExpression(
cmListFileBacktrace const& backtrace,
const std::string& input)
: Backtrace(backtrace), Input(input),
- HadContextSensitiveCondition(false)
+ HadContextSensitiveCondition(false),
+ EvaluateForBuildsystem(false)
{
cmGeneratorExpressionLexer l;
std::vector<cmGeneratorExpressionToken> tokens =
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h
index d0a6aef..da64515 100644
--- a/Source/cmGeneratorExpression.h
+++ b/Source/cmGeneratorExpression.h
@@ -112,6 +112,11 @@ public:
return this->HadContextSensitiveCondition;
}
+ void SetEvaluateForBuildsystem(bool eval)
+ {
+ this->EvaluateForBuildsystem = eval;
+ }
+
private:
cmCompiledGeneratorExpression(cmListFileBacktrace const& backtrace,
const std::string& input);
@@ -131,6 +136,7 @@ private:
mutable std::set<std::string> SeenTargetProperties;
mutable std::string Output;
mutable bool HadContextSensitiveCondition;
+ bool EvaluateForBuildsystem;
};
#endif
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index 14b2a1a..95227d2 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -15,6 +15,8 @@
#include "cmGeneratorExpressionParser.h"
#include "cmGeneratorExpressionDAGChecker.h"
#include "cmGeneratorExpression.h"
+#include "cmLocalGenerator.h"
+#include "cmSourceFile.h"
#include <cmsys/String.h>
@@ -1240,6 +1242,77 @@ static const struct TargetNameNode : public cmGeneratorExpressionNode
} targetNameNode;
//----------------------------------------------------------------------------
+static const struct TargetObjectsNode : public cmGeneratorExpressionNode
+{
+ TargetObjectsNode() {}
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *content,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ if (!context->EvaluateForBuildsystem)
+ {
+ cmOStringStream e;
+ e << "The evaluation of the TARGET_OBJECTS generator expression "
+ "is only suitable for consumption by CMake. It is not suitable "
+ "for writing out elsewhere.";
+ reportError(context, content->GetOriginalExpression(), e.str());
+ return std::string();
+ }
+
+ std::string tgtName = parameters.front();
+ cmGeneratorTarget* gt =
+ context->Makefile->FindGeneratorTargetToUse(tgtName.c_str());
+ if (!gt)
+ {
+ cmOStringStream e;
+ e << "Objects of target \"" << tgtName
+ << "\" referenced but no such target exists.";
+ reportError(context, content->GetOriginalExpression(), e.str());
+ return std::string();
+ }
+ if (gt->GetType() != cmTarget::OBJECT_LIBRARY)
+ {
+ cmOStringStream e;
+ e << "Objects of target \"" << tgtName
+ << "\" referenced but is not an OBJECT library.";
+ reportError(context, content->GetOriginalExpression(), e.str());
+ return std::string();
+ }
+
+ std::vector<cmSourceFile const*> objectSources;
+ gt->GetObjectSources(objectSources);
+ std::map<cmSourceFile const*, std::string> mapping;
+
+ for(std::vector<cmSourceFile const*>::const_iterator it
+ = objectSources.begin(); it != objectSources.end(); ++it)
+ {
+ mapping[*it];
+ }
+
+ gt->LocalGenerator->ComputeObjectFilenames(mapping, gt);
+
+ std::string obj_dir = gt->ObjectDirectory;
+ std::string result;
+ const char* sep = "";
+ for(std::map<cmSourceFile const*, std::string>::const_iterator it
+ = mapping.begin(); it != mapping.end(); ++it)
+ {
+ assert(!it->second.empty());
+ result += sep;
+ std::string objFile = obj_dir + it->second;
+ cmSourceFile* sf = context->Makefile->GetOrCreateSource(objFile, true);
+ sf->SetObjectLibrary(tgtName);
+ sf->SetProperty("EXTERNAL_OBJECT", "1");
+ result += objFile;
+ sep = ";";
+ }
+ return result;
+ }
+} targetObjectsNode;
+
+//----------------------------------------------------------------------------
static const char* targetPolicyWhitelist[] = {
0
#define TARGET_POLICY_STRING(POLICY) \
@@ -1593,6 +1666,7 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier)
nodeMap["SEMICOLON"] = &semicolonNode;
nodeMap["TARGET_PROPERTY"] = &targetPropertyNode;
nodeMap["TARGET_NAME"] = &targetNameNode;
+ nodeMap["TARGET_OBJECTS"] = &targetObjectsNode;
nodeMap["TARGET_POLICY"] = &targetPolicyNode;
nodeMap["BUILD_INTERFACE"] = &buildInterfaceNode;
nodeMap["INSTALL_INTERFACE"] = &installInterfaceNode;
diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h
index a7099cb..54a2548 100644
--- a/Source/cmGeneratorExpressionEvaluator.h
+++ b/Source/cmGeneratorExpressionEvaluator.h
@@ -34,6 +34,7 @@ struct cmGeneratorExpressionContext
bool Quiet;
bool HadError;
bool HadContextSensitiveCondition;
+ bool EvaluateForBuildsystem;
};
struct cmGeneratorExpressionDAGChecker;
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index b35e859..321dd42 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -311,18 +311,36 @@ cmGeneratorTarget
::GetObjectSources(std::vector<cmSourceFile const*> &data) const
{
IMPLEMENT_VISIT(ObjectSources);
+
+ if (!this->Objects.empty())
+ {
+ return;
+ }
+
+ for(std::vector<cmSourceFile const*>::const_iterator it = data.begin();
+ it != data.end(); ++it)
+ {
+ this->Objects[*it];
+ }
+
+ this->LocalGenerator->ComputeObjectFilenames(this->Objects, this);
}
-//----------------------------------------------------------------------------
-const std::string& cmGeneratorTarget::GetObjectName(cmSourceFile const* file)
+void cmGeneratorTarget::ComputeObjectMapping()
{
- return this->Objects[file];
+ if(!this->Objects.empty())
+ {
+ return;
+ }
+ std::vector<cmSourceFile const*> sourceFiles;
+ this->GetObjectSources(sourceFiles);
}
-void cmGeneratorTarget::AddObject(cmSourceFile const* sf,
- std::string const&name)
+//----------------------------------------------------------------------------
+const std::string& cmGeneratorTarget::GetObjectName(cmSourceFile const* file)
{
- this->Objects[sf] = name;
+ this->ComputeObjectMapping();
+ return this->Objects[file];
}
//----------------------------------------------------------------------------
@@ -334,6 +352,7 @@ void cmGeneratorTarget::AddExplicitObjectName(cmSourceFile const* sf)
//----------------------------------------------------------------------------
bool cmGeneratorTarget::HasExplicitObjectName(cmSourceFile const* file) const
{
+ const_cast<cmGeneratorTarget*>(this)->ComputeObjectMapping();
std::set<cmSourceFile const*>::const_iterator it
= this->ExplicitObjectName.find(file);
return it != this->ExplicitObjectName.end();
@@ -504,58 +523,6 @@ void cmGeneratorTarget::GetSourceFiles(std::vector<cmSourceFile*> &files) const
}
//----------------------------------------------------------------------------
-void cmGeneratorTarget::LookupObjectLibraries()
-{
- std::vector<std::string> const& objLibs =
- this->Target->GetObjectLibraries();
- for(std::vector<std::string>::const_iterator oli = objLibs.begin();
- oli != objLibs.end(); ++oli)
- {
- std::string const& objLibName = *oli;
- if(cmTarget* objLib = this->Makefile->FindTargetToUse(objLibName))
- {
- if(objLib->GetType() == cmTarget::OBJECT_LIBRARY)
- {
- if(this->Target->GetType() != cmTarget::EXECUTABLE &&
- this->Target->GetType() != cmTarget::STATIC_LIBRARY &&
- this->Target->GetType() != cmTarget::SHARED_LIBRARY &&
- this->Target->GetType() != cmTarget::MODULE_LIBRARY)
- {
- this->GlobalGenerator->GetCMakeInstance()
- ->IssueMessage(cmake::FATAL_ERROR,
- "Only executables and non-OBJECT libraries may "
- "reference target objects.",
- this->Target->GetBacktrace());
- return;
- }
- this->Target->AddUtility(objLib->GetName());
- this->ObjectLibraries.push_back(objLib);
- }
- else
- {
- cmOStringStream e;
- e << "Objects of target \"" << objLibName
- << "\" referenced but is not an OBJECT library.";
- this->GlobalGenerator->GetCMakeInstance()
- ->IssueMessage(cmake::FATAL_ERROR, e.str(),
- this->Target->GetBacktrace());
- return;
- }
- }
- else
- {
- cmOStringStream e;
- e << "Objects of target \"" << objLibName
- << "\" referenced but no such target exists.";
- this->GlobalGenerator->GetCMakeInstance()
- ->IssueMessage(cmake::FATAL_ERROR, e.str(),
- this->Target->GetBacktrace());
- return;
- }
- }
-}
-
-//----------------------------------------------------------------------------
std::string cmGeneratorTarget::GetModuleDefinitionFile() const
{
std::string data;
@@ -567,9 +534,26 @@ std::string cmGeneratorTarget::GetModuleDefinitionFile() const
void
cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs) const
{
+ std::vector<cmSourceFile const*> objectFiles;
+ this->GetExternalObjects(objectFiles);
+ std::vector<cmTarget*> objectLibraries;
+ std::set<cmTarget*> emitted;
+ for(std::vector<cmSourceFile const*>::const_iterator
+ it = objectFiles.begin(); it != objectFiles.end(); ++it)
+ {
+ std::string objLib = (*it)->GetObjectLibrary();
+ if (cmTarget* tgt = this->Makefile->FindTargetToUse(objLib))
+ {
+ if (emitted.insert(tgt).second)
+ {
+ objectLibraries.push_back(tgt);
+ }
+ }
+ }
+
for(std::vector<cmTarget*>::const_iterator
- ti = this->ObjectLibraries.begin();
- ti != this->ObjectLibraries.end(); ++ti)
+ ti = objectLibraries.begin();
+ ti != objectLibraries.end(); ++ti)
{
cmTarget* objLib = *ti;
cmGeneratorTarget* ogt =
@@ -600,12 +584,12 @@ private:
cmGlobalGenerator const* GlobalGenerator;
typedef cmGeneratorTarget::SourceEntry SourceEntry;
SourceEntry* CurrentEntry;
- std::queue<cmSourceFile*> SourceQueue;
- std::set<cmSourceFile*> SourcesQueued;
+ std::queue<std::string> SourceQueue;
+ std::set<std::string> SourcesQueued;
typedef std::map<std::string, cmSourceFile*> NameMapType;
NameMapType NameMap;
- void QueueSource(cmSourceFile* sf);
+ void QueueSource(std::string const& name);
void FollowName(std::string const& name);
void FollowNames(std::vector<std::string> const& names);
bool IsUtility(std::string const& dep);
@@ -628,11 +612,11 @@ cmTargetTraceDependencies
this->CurrentEntry = 0;
// Queue all the source files already specified for the target.
- std::vector<cmSourceFile*> sources;
if (this->Target->GetType() != cmTarget::INTERFACE_LIBRARY)
{
+ std::vector<std::string> sources;
this->Target->GetSourceFiles(sources);
- for(std::vector<cmSourceFile*>::const_iterator si = sources.begin();
+ for(std::vector<std::string>::const_iterator si = sources.begin();
si != sources.end(); ++si)
{
this->QueueSource(*si);
@@ -652,7 +636,8 @@ void cmTargetTraceDependencies::Trace()
while(!this->SourceQueue.empty())
{
// Get the next source from the queue.
- cmSourceFile* sf = this->SourceQueue.front();
+ std::string src = this->SourceQueue.front();
+ cmSourceFile* sf = this->Makefile->GetSource(src);
this->SourceQueue.pop();
this->CurrentEntry = &this->GeneratorTarget->SourceEntries[sf];
@@ -680,14 +665,14 @@ void cmTargetTraceDependencies::Trace()
}
//----------------------------------------------------------------------------
-void cmTargetTraceDependencies::QueueSource(cmSourceFile* sf)
+void cmTargetTraceDependencies::QueueSource(std::string const& name)
{
- if(this->SourcesQueued.insert(sf).second)
+ if(this->SourcesQueued.insert(name).second)
{
- this->SourceQueue.push(sf);
+ this->SourceQueue.push(name);
// Make sure this file is in the target.
- this->Target->AddSourceFile(sf);
+ this->Target->AddSource(name);
}
}
@@ -709,8 +694,7 @@ void cmTargetTraceDependencies::FollowName(std::string const& name)
{
this->CurrentEntry->Depends.push_back(sf);
}
-
- this->QueueSource(sf);
+ this->QueueSource(sf->GetFullPath());
}
}
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 53e27c5..38e6510 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -35,7 +35,6 @@ public:
void GetObjectSources(std::vector<cmSourceFile const*> &) const;
const std::string& GetObjectName(cmSourceFile const* file);
- void AddObject(cmSourceFile const* sf, std::string const&name);
bool HasExplicitObjectName(cmSourceFile const* file) const;
void AddExplicitObjectName(cmSourceFile const* sf);
@@ -47,6 +46,8 @@ public:
void GetCustomCommands(std::vector<cmSourceFile const*>&) const;
void GetExpectedResxHeaders(std::set<std::string>&) const;
+ void ComputeObjectMapping();
+
cmTarget* Target;
cmMakefile* Makefile;
cmLocalGenerator* LocalGenerator;
@@ -84,8 +85,6 @@ public:
*/
void TraceDependencies();
- void LookupObjectLibraries();
-
/** Get sources that must be built before the given source. */
std::vector<cmSourceFile*> const*
GetSourceDepends(cmSourceFile const* sf) const;
@@ -125,9 +124,8 @@ private:
typedef std::map<cmSourceFile const*, SourceEntry> SourceEntriesType;
SourceEntriesType SourceEntries;
- std::map<cmSourceFile const*, std::string> Objects;
+ mutable std::map<cmSourceFile const*, std::string> Objects;
std::set<cmSourceFile const*> ExplicitObjectName;
- std::vector<cmTarget*> ObjectLibraries;
mutable std::map<std::string, std::vector<std::string> > SystemIncludesCache;
void ConstructSourceFileFlags() const;
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 3d291f4..a12b68f 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -216,6 +216,11 @@ bool cmGlobalGenerator::GenerateImportFile(const std::string &file)
return false;
}
+void cmGlobalGenerator::ForceLinkerLanguages()
+{
+
+}
+
bool
cmGlobalGenerator::IsExportedTargetsFile(const std::string &filename) const
{
@@ -1196,6 +1201,8 @@ void cmGlobalGenerator::Generate()
// Create per-target generator information.
this->CreateGeneratorTargets();
+ this->ForceLinkerLanguages();
+
#ifdef CMAKE_BUILD_WITH_CMAKE
for (AutogensType::iterator it = autogens.begin(); it != autogens.end();
++it)
@@ -1217,8 +1224,6 @@ void cmGlobalGenerator::Generate()
this->LocalGenerators[i]->GenerateTargetManifest();
}
- this->ComputeGeneratorTargetObjects();
-
this->ProcessEvaluationFiles();
// Compute the inter-target dependencies.
@@ -1409,6 +1414,7 @@ void cmGlobalGenerator::CreateGeneratorTargets(cmMakefile *mf)
{
cmTarget* t = &ti->second;
cmGeneratorTarget* gt = new cmGeneratorTarget(t);
+ this->ComputeTargetObjectDirectory(gt);
this->GeneratorTargets[t] = gt;
generatorTargets[t] = gt;
}
@@ -1434,29 +1440,6 @@ void cmGlobalGenerator::CreateGeneratorTargets()
}
}
-//----------------------------------------------------------------------------
-void cmGlobalGenerator::ComputeGeneratorTargetObjects()
-{
- // Construct per-target generator information.
- for(unsigned int i=0; i < this->LocalGenerators.size(); ++i)
- {
- cmMakefile *mf = this->LocalGenerators[i]->GetMakefile();
- cmGeneratorTargetsType targets = mf->GetGeneratorTargets();
- for(cmGeneratorTargetsType::iterator ti = targets.begin();
- ti != targets.end(); ++ti)
- {
- if (ti->second->Target->IsImported()
- || ti->second->Target->GetType() == cmTarget::INTERFACE_LIBRARY)
- {
- continue;
- }
- cmGeneratorTarget* gt = ti->second;
- this->ComputeTargetObjectDirectory(gt);
- gt->LookupObjectLibraries();
- this->ComputeTargetObjects(gt);
- }
- }
-}
//----------------------------------------------------------------------------
void cmGlobalGenerator::ClearGeneratorMembers()
@@ -1518,29 +1501,6 @@ cmGlobalGenerator::GetGeneratorTarget(cmTarget const* t) const
}
//----------------------------------------------------------------------------
-void cmGlobalGenerator::ComputeTargetObjects(cmGeneratorTarget* gt) const
-{
- std::vector<cmSourceFile const*> objectSources;
- gt->GetObjectSources(objectSources);
-
- std::map<cmSourceFile const*, std::string> mapping;
- for(std::vector<cmSourceFile const*>::const_iterator it
- = objectSources.begin(); it != objectSources.end(); ++it)
- {
- mapping[*it];
- }
-
- gt->LocalGenerator->ComputeObjectFilenames(mapping, gt);
-
- for(std::map<cmSourceFile const*, std::string>::const_iterator it
- = mapping.begin(); it != mapping.end(); ++it)
- {
- assert(!it->second.empty());
- gt->AddObject(it->first, it->second);
- }
-}
-
-//----------------------------------------------------------------------------
void cmGlobalGenerator::ComputeTargetObjectDirectory(cmGeneratorTarget*) const
{
}
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 49a418d..54f5f3b 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -423,6 +423,8 @@ private:
void WriteSummary(cmTarget* target);
void FinalizeTargetCompileInfo();
+ virtual void ForceLinkerLanguages();
+
virtual void PrintCompilerAdvice(std::ostream& os, std::string const& lang,
const char* envVar) const;
void CheckCompilerIdCompatibility(cmMakefile* mf,
@@ -442,8 +444,6 @@ private:
friend class cmake;
void CreateGeneratorTargets(cmMakefile* mf);
void CreateGeneratorTargets();
- void ComputeGeneratorTargetObjects();
- void ComputeTargetObjects(cmGeneratorTarget* gt) const;
void ClearGeneratorMembers();
diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx
index ab4380c..e80df84 100644
--- a/Source/cmGlobalVisualStudio8Generator.cxx
+++ b/Source/cmGlobalVisualStudio8Generator.cxx
@@ -16,6 +16,7 @@
#include "cmVisualStudioWCEPlatformParser.h"
#include "cmake.h"
#include "cmGeneratedFileStream.h"
+#include "cmSourceFile.h"
static const char vs8generatorName[] = "Visual Studio 8 2005";
@@ -323,7 +324,7 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
no_main_dependency, commandLines, "Checking Build System",
no_working_directory, true))
{
- tgt->AddSourceFile(file);
+ tgt->AddSource(file->GetFullPath());
}
else
{
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index d4eb85b..d9d4927 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -343,7 +343,6 @@ void cmGlobalXCodeGenerator::Generate()
// add ALL_BUILD, INSTALL, etc
this->AddExtraTargets(root, it->second);
}
- this->ForceLinkerLanguages();
this->cmGlobalGenerator::Generate();
if(cmSystemTools::GetErrorOccuredFlag())
{
@@ -412,7 +411,7 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
std::string listfile = mf->GetStartDirectory();
listfile += "/";
listfile += "CMakeLists.txt";
- allbuild->AddSource(listfile.c_str());
+ allbuild->AddSourceCMP0049(listfile.c_str());
// Add XCODE depend helper
std::string dir = mf->GetCurrentOutputDirectory();
@@ -495,7 +494,7 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
listfile = lg->GetMakefile()->GetStartDirectory();
listfile += "/";
listfile += "CMakeLists.txt";
- target.AddSource(listfile.c_str());
+ target.AddSourceCMP0049(listfile.c_str());
}
}
}
@@ -988,6 +987,8 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
cmtarget.GetSourceFiles(classes);
std::sort(classes.begin(), classes.end(), cmSourceFilePathCompare());
+ gtgt->ComputeObjectMapping();
+
std::vector<cmXCodeObject*> externalObjFiles;
std::vector<cmXCodeObject*> headerFiles;
std::vector<cmXCodeObject*> resourceFiles;
@@ -1008,7 +1009,10 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
if(filetype &&
filetype->GetString() == "compiled.mach-o.objfile")
{
- externalObjFiles.push_back(xsf);
+ if ((*i)->GetObjectLibrary().empty())
+ {
+ externalObjFiles.push_back(xsf);
+ }
}
else if(this->IsHeaderFile(*i) ||
(tsFlags.Type == cmGeneratorTarget::SourceFileTypePrivateHeader) ||
@@ -1260,7 +1264,7 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmTarget& cmtarget)
if(cmSourceFile* sf = mf->GetOrCreateSource(fname.c_str()))
{
sf->SetProperty("LANGUAGE", llang.c_str());
- cmtarget.AddSourceFile(sf);
+ cmtarget.AddSource(fname);
}
}
@@ -2934,8 +2938,8 @@ void cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root,
if(cmtarget.GetPropertyAsBool("MACOSX_BUNDLE"))
{
std::string plist = this->ComputeInfoPListLocation(cmtarget);
- cmSourceFile* sf = mf->GetOrCreateSource(plist.c_str(), true);
- cmtarget.AddSourceFile(sf);
+ mf->GetOrCreateSource(plist, true);
+ cmtarget.AddSource(plist);
}
std::vector<cmSourceFile*> classes;
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 9cafed1..c840888 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -751,8 +751,8 @@ void cmLocalGenerator::AddBuildTargetRule(const std::string& llang,
comment.c_str(),
this->Makefile->GetStartOutputDirectory()
);
- target.Target->AddSourceFile
- (this->Makefile->GetSource(targetFullPath));
+ this->Makefile->GetSource(targetFullPath);
+ target.Target->AddSource(targetFullPath);
}
diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx
index 2ab25cc..11e9679 100644
--- a/Source/cmLocalVisualStudio6Generator.cxx
+++ b/Source/cmLocalVisualStudio6Generator.cxx
@@ -253,9 +253,9 @@ void cmLocalVisualStudio6Generator::AddDSPBuildRule(cmTarget& tgt)
makefileIn.c_str(), commandLines,
comment.c_str(),
no_working_directory, true);
- if(cmSourceFile* file = this->Makefile->GetSource(makefileIn.c_str()))
+ if(this->Makefile->GetSource(makefileIn.c_str()))
{
- tgt.AddSourceFile(file);
+ tgt.AddSource(makefileIn);
}
else
{
@@ -324,6 +324,11 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout,
for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
i != classes.end(); i++)
{
+ if (!(*i)->GetObjectLibrary().empty())
+ {
+ continue;
+ }
+
// Add the file to the list of sources.
std::string source = (*i)->GetFullPath();
cmSourceGroup* sourceGroup =
@@ -398,6 +403,11 @@ void cmLocalVisualStudio6Generator
for(std::vector<const cmSourceFile *>::const_iterator sf =
sourceFiles.begin(); sf != sourceFiles.end(); ++sf)
{
+ if (!(*sf)->GetObjectLibrary().empty())
+ {
+ continue;
+ }
+
std::string source = (*sf)->GetFullPath();
const cmCustomCommand *command =
(*sf)->GetCustomCommand();
@@ -591,7 +601,7 @@ cmLocalVisualStudio6Generator
origCommand.GetCommandLines(), comment,
origCommand.GetWorkingDirectory().c_str()))
{
- target.AddSourceFile(outsf);
+ target.AddSource(outsf->GetFullPath());
}
// Replace the dependencies with the output of this rule so that the
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 52524aa..8bac10d 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -117,7 +117,7 @@ void cmLocalVisualStudio7Generator::AddCMakeListsRules()
{
if(l->first != CMAKE_CHECK_BUILD_SYSTEM_TARGET)
{
- l->second.AddSourceFile(sf);
+ l->second.AddSource(sf->GetFullPath());
}
}
}
@@ -153,7 +153,7 @@ void cmLocalVisualStudio7Generator::FixGlobalTargets()
force.c_str(), no_depends, no_main_dependency,
force_commands, " ", 0, true))
{
- tgt.AddSourceFile(file);
+ tgt.AddSource(file->GetFullPath());
}
}
}
@@ -1401,6 +1401,10 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
i != classes.end(); i++)
{
+ if (!(*i)->GetObjectLibrary().empty())
+ {
+ continue;
+ }
// Add the file to the list of sources.
std::string source = (*i)->GetFullPath();
if(cmSystemTools::UpperCase((*i)->GetExtension()) == "DEF")
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 621b8ee..b1d6fe2 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -1182,7 +1182,7 @@ cmMakefile::AddCustomCommandOldStyle(const std::string& target,
{
if (this->Targets.find(target) != this->Targets.end())
{
- this->Targets[target].AddSourceFile(sf);
+ this->Targets[target].AddSource(sf->GetFullPath());
}
else
{
@@ -1266,7 +1266,7 @@ cmMakefile::AddUtilityCommand(const std::string& utilityName,
commandLines, comment,
workingDirectory, no_replace,
escapeOldStyle);
- cmSourceFile* sf = target->AddSource(force);
+ cmSourceFile* sf = target->AddSourceCMP0049(force);
// The output is not actually created so mark it symbolic.
if(sf)
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index b3d3f71..5bb7b8b 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -202,9 +202,6 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
// Generate this object file's rule file.
this->WriteObjectRuleFiles(**si);
}
-
- // Add object library contents as external objects.
- this->GeneratorTarget->UseObjectLibraries(this->ExternalObjects);
}
//----------------------------------------------------------------------------
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 8865b3d..b7eab7d 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -525,17 +525,6 @@ cmNinjaTargetGenerator
this->ModuleDefinitionFile = this->ConvertToNinjaPath(def.c_str());
}
- {
- // Add object library contents as external objects.
- std::vector<std::string> objs;
- this->GeneratorTarget->UseObjectLibraries(objs);
- for(std::vector<std::string>::iterator oi = objs.begin();
- oi != objs.end(); ++oi)
- {
- this->Objects.push_back(ConvertToNinjaPath(oi->c_str()));
- }
- }
-
this->GetBuildFileStream() << "\n";
}
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index 2bd553f..759df91 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -343,6 +343,11 @@ cmPolicies::cmPolicies()
CMP0050, "CMP0050",
"Disallow add_custom_command SOURCE signatures.",
3,0,0, cmPolicies::WARN);
+
+ this->DefinePolicy(
+ CMP0051, "CMP0051",
+ "List TARGET_OBJECTS in SOURCES target property.",
+ 3,1,0, cmPolicies::WARN);
}
cmPolicies::~cmPolicies()
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index b77235d..7a08a34 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -104,6 +104,7 @@ public:
CMP0048, ///< project() command manages VERSION variables
CMP0049, ///< Do not expand variables in target source entries
CMP0050, ///< Disallow add_custom_command SOURCE signatures
+ CMP0051, ///< List TARGET_OBJECTS in SOURCES target property
/** \brief Always the last entry.
*
diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx
index a6e6af7..71c4630 100644
--- a/Source/cmQtAutoGenerators.cxx
+++ b/Source/cmQtAutoGenerators.cxx
@@ -187,13 +187,11 @@ bool cmQtAutoGenerators::InitializeAutogenTarget(cmTarget* target)
mocCppFile += "/";
mocCppFile += automocTargetName;
mocCppFile += ".cpp";
- cmSourceFile* mocCppSource = makefile->GetOrCreateSource(
- mocCppFile,
- true);
+ makefile->GetOrCreateSource(mocCppFile, true);
makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES",
mocCppFile.c_str(), false);
- target->AddSourceFile(mocCppSource);
+ target->AddSource(mocCppFile);
}
// create a custom target for running generators at buildtime:
std::string autogenTargetName = getAutogenTargetName(target);
@@ -479,7 +477,7 @@ void cmQtAutoGenerators::SetupSourceFiles(cmTarget const* target)
const char *skipMocSep = "";
const char *skipUicSep = "";
- std::vector<cmSourceFile*> newRccFiles;
+ std::vector<std::string> newRccFiles;
for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();
fileIt != srcFiles.end();
@@ -512,9 +510,8 @@ void cmQtAutoGenerators::SetupSourceFiles(cmTarget const* target)
rcc_output_file += "/qrc_" + basename + ".cpp";
makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES",
rcc_output_file.c_str(), false);
- cmSourceFile* rccCppSource
- = makefile->GetOrCreateSource(rcc_output_file, true);
- newRccFiles.push_back(rccCppSource);
+ makefile->GetOrCreateSource(rcc_output_file, true);
+ newRccFiles.push_back(rcc_output_file);
}
}
@@ -546,11 +543,11 @@ void cmQtAutoGenerators::SetupSourceFiles(cmTarget const* target)
}
}
- for(std::vector<cmSourceFile*>::const_iterator fileIt = newRccFiles.begin();
+ for(std::vector<std::string>::const_iterator fileIt = newRccFiles.begin();
fileIt != newRccFiles.end();
++fileIt)
{
- const_cast<cmTarget*>(target)->AddSourceFile(*fileIt);
+ const_cast<cmTarget*>(target)->AddSource(*fileIt);
}
}
diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx
index b9b6251..0ab30a2 100644
--- a/Source/cmSourceFile.cxx
+++ b/Source/cmSourceFile.cxx
@@ -39,6 +39,18 @@ std::string const& cmSourceFile::GetExtension() const
}
//----------------------------------------------------------------------------
+void cmSourceFile::SetObjectLibrary(std::string const& objlib)
+{
+ this->ObjectLibrary = objlib;
+}
+
+//----------------------------------------------------------------------------
+std::string cmSourceFile::GetObjectLibrary() const
+{
+ return this->ObjectLibrary;
+}
+
+//----------------------------------------------------------------------------
std::string cmSourceFile::GetLanguage()
{
// If the language was set explicitly by the user then use it.
diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h
index 17c96ac..755a2cf 100644
--- a/Source/cmSourceFile.h
+++ b/Source/cmSourceFile.h
@@ -97,6 +97,9 @@ public:
*/
bool Matches(cmSourceFileLocation const&);
+ void SetObjectLibrary(std::string const& objlib);
+ std::string GetObjectLibrary() const;
+
private:
cmSourceFileLocation Location;
cmPropertyMap Properties;
@@ -105,6 +108,7 @@ private:
std::string Language;
std::string FullPath;
bool FindFullPathFailed;
+ std::string ObjectLibrary;
bool FindFullPath(std::string* error);
bool TryFullPath(const std::string& path, const std::string& ext);
diff --git a/Source/cmSourceFileLocation.cxx b/Source/cmSourceFileLocation.cxx
index 30a53cb..c050202 100644
--- a/Source/cmSourceFileLocation.cxx
+++ b/Source/cmSourceFileLocation.cxx
@@ -16,29 +16,57 @@
#include "cmGlobalGenerator.h"
#include "cmSystemTools.h"
+#include "assert.h"
+
//----------------------------------------------------------------------------
-cmSourceFileLocation
-::cmSourceFileLocation(cmMakefile const* mf, const std::string& name)
- : Makefile(mf)
+cmSourceFileLocation::cmSourceFileLocation()
+ : Makefile(0), AmbiguousDirectory(true), AmbiguousExtension(true)
{
- this->AmbiguousDirectory = !cmSystemTools::FileIsFullPath(name.c_str());
- this->AmbiguousExtension = true;
- this->Directory = cmSystemTools::GetFilenamePath(name);
- this->Name = cmSystemTools::GetFilenameName(name);
- this->UpdateExtension(name);
+
}
//----------------------------------------------------------------------------
-void cmSourceFileLocation::Update(const std::string& name)
+cmSourceFileLocation::cmSourceFileLocation(const cmSourceFileLocation& loc)
+ : Makefile(loc.Makefile)
{
- if(this->AmbiguousDirectory)
+ this->AmbiguousDirectory = loc.AmbiguousDirectory;
+ this->AmbiguousExtension = loc.AmbiguousExtension;
+ this->Directory = loc.Directory;
+ this->Name = loc.Name;
+}
+
+//----------------------------------------------------------------------------
+cmSourceFileLocation&
+cmSourceFileLocation::operator=(const cmSourceFileLocation& loc)
+{
+ if(this == &loc)
{
- this->UpdateDirectory(name);
+ return *this;
}
- if(this->AmbiguousExtension)
+ this->Makefile = loc.Makefile;
+ this->AmbiguousDirectory = loc.AmbiguousDirectory;
+ this->AmbiguousExtension = loc.AmbiguousExtension;
+ this->Directory = loc.Directory;
+ this->Name = loc.Name;
+ this->UpdateExtension(this->Name);
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+cmSourceFileLocation
+::cmSourceFileLocation(cmMakefile const* mf, const std::string& name)
+ : Makefile(mf)
+{
+ this->AmbiguousDirectory = !cmSystemTools::FileIsFullPath(name.c_str());
+ this->AmbiguousExtension = true;
+ this->Directory = cmSystemTools::GetFilenamePath(name);
+ if (cmSystemTools::FileIsFullPath(this->Directory.c_str()))
{
- this->UpdateExtension(name);
+ this->Directory
+ = cmSystemTools::CollapseFullPath(this->Directory.c_str());
}
+ this->Name = cmSystemTools::GetFilenameName(name);
+ this->UpdateExtension(name);
}
//----------------------------------------------------------------------------
@@ -59,6 +87,7 @@ void cmSourceFileLocation::Update(cmSourceFileLocation const& loc)
//----------------------------------------------------------------------------
void cmSourceFileLocation::DirectoryUseSource()
{
+ assert(this->Makefile);
if(this->AmbiguousDirectory)
{
this->Directory =
@@ -71,6 +100,7 @@ void cmSourceFileLocation::DirectoryUseSource()
//----------------------------------------------------------------------------
void cmSourceFileLocation::DirectoryUseBinary()
{
+ assert(this->Makefile);
if(this->AmbiguousDirectory)
{
this->Directory =
@@ -83,6 +113,7 @@ void cmSourceFileLocation::DirectoryUseBinary()
//----------------------------------------------------------------------------
void cmSourceFileLocation::UpdateExtension(const std::string& name)
{
+ assert(this->Makefile);
// Check the extension.
std::string ext = cmSystemTools::GetFilenameLastExtension(name);
if(!ext.empty()) { ext = ext.substr(1); }
@@ -137,21 +168,11 @@ void cmSourceFileLocation::UpdateExtension(const std::string& name)
}
//----------------------------------------------------------------------------
-void cmSourceFileLocation::UpdateDirectory(const std::string& name)
-{
- // If a full path was given we know the directory.
- if(cmSystemTools::FileIsFullPath(name.c_str()))
- {
- this->Directory = cmSystemTools::GetFilenamePath(name);
- this->AmbiguousDirectory = false;
- }
-}
-
-//----------------------------------------------------------------------------
bool
cmSourceFileLocation
::MatchesAmbiguousExtension(cmSourceFileLocation const& loc) const
{
+ assert(this->Makefile);
// This location's extension is not ambiguous but loc's extension
// is. See if the names match as-is.
if(this->Name == loc.Name)
@@ -188,6 +209,7 @@ cmSourceFileLocation
//----------------------------------------------------------------------------
bool cmSourceFileLocation::Matches(cmSourceFileLocation const& loc)
{
+ assert(this->Makefile);
if(this->AmbiguousExtension && loc.AmbiguousExtension)
{
// Both extensions are ambiguous. Since only the old fixed set of
diff --git a/Source/cmSourceFileLocation.h b/Source/cmSourceFileLocation.h
index c83e8c0..c37fb1d 100644
--- a/Source/cmSourceFileLocation.h
+++ b/Source/cmSourceFileLocation.h
@@ -34,6 +34,9 @@ public:
* instance with an initial name.
*/
cmSourceFileLocation(cmMakefile const* mf, const std::string& name);
+ cmSourceFileLocation();
+ cmSourceFileLocation(const cmSourceFileLocation& loc);
+ cmSourceFileLocation& operator=(const cmSourceFileLocation& loc);
/**
* Return whether the givne source file location could refers to the
@@ -93,9 +96,7 @@ private:
// Update the location with additional knowledge.
void Update(cmSourceFileLocation const& loc);
- void Update(const std::string& name);
void UpdateExtension(const std::string& name);
- void UpdateDirectory(const std::string& name);
};
#endif
diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx
index 7bc7b05..ea762eb 100644
--- a/Source/cmStringCommand.cxx
+++ b/Source/cmStringCommand.cxx
@@ -101,6 +101,10 @@ bool cmStringCommand
{
return this->HandleMakeCIdentifierCommand(args);
}
+ else if(subCommand == "GENEX_STRIP")
+ {
+ return this->HandleGenexStripCommand(args);
+ }
std::string e = "does not recognize sub-command "+subCommand;
this->SetError(e);
@@ -810,6 +814,27 @@ bool cmStringCommand
}
//----------------------------------------------------------------------------
+bool cmStringCommand
+::HandleGenexStripCommand(std::vector<std::string> const& args)
+{
+ if(args.size() != 3)
+ {
+ this->SetError("sub-command GENEX_STRIP requires two arguments.");
+ return false;
+ }
+
+ const std::string& input = args[1];
+
+ std::string result = cmGeneratorExpression::Preprocess(input,
+ cmGeneratorExpression::StripAllGeneratorExpressions);
+
+ const std::string& variableName = args[2];
+
+ this->Makefile->AddDefinition(variableName, result.c_str());
+ return true;
+}
+
+//----------------------------------------------------------------------------
bool cmStringCommand::HandleStripCommand(
std::vector<std::string> const& args)
{
diff --git a/Source/cmStringCommand.h b/Source/cmStringCommand.h
index b8053c5..5b7412d 100644
--- a/Source/cmStringCommand.h
+++ b/Source/cmStringCommand.h
@@ -75,6 +75,7 @@ protected:
bool HandleFindCommand(std::vector<std::string> const& args);
bool HandleTimestampCommand(std::vector<std::string> const& args);
bool HandleMakeCIdentifierCommand(std::vector<std::string> const& args);
+ bool HandleGenexStripCommand(std::vector<std::string> const& args);
class RegexReplacement
{
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 32aaccc..573b816 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -150,6 +150,7 @@ public:
std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries;
std::vector<TargetPropertyEntry*> CompileOptionsEntries;
std::vector<TargetPropertyEntry*> CompileDefinitionsEntries;
+ std::vector<TargetPropertyEntry*> SourceEntries;
std::vector<cmValueWithOrigin> LinkImplementationPropertyEntries;
mutable std::map<std::string, std::vector<TargetPropertyEntry*> >
@@ -542,35 +543,58 @@ bool cmTarget::IsBundleOnApple() const
}
//----------------------------------------------------------------------------
-void cmTarget::GetSourceFiles(std::vector<cmSourceFile*> &files) const
+void cmTarget::GetSourceFiles(std::vector<std::string> &files) const
{
assert(this->GetType() != INTERFACE_LIBRARY);
- for(std::vector<cmSourceFile*>::const_iterator
- si = this->SourceFiles.begin();
- si != this->SourceFiles.end(); ++si)
+ for(std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
+ si = this->Internal->SourceEntries.begin();
+ si != this->Internal->SourceEntries.end(); ++si)
{
- std::string e;
- if((*si)->GetFullPath(&e).empty())
+ std::vector<std::string> srcs;
+ cmSystemTools::ExpandListArgument((*si)->ge->Evaluate(this->Makefile,
+ "",
+ false,
+ this),
+ srcs);
+
+ for(std::vector<std::string>::const_iterator i = srcs.begin();
+ i != srcs.end(); ++i)
{
- if(!e.empty())
+ std::string src = *i;
+ cmSourceFile* sf = this->Makefile->GetOrCreateSource(src);
+ std::string e;
+ src = sf->GetFullPath(&e);
+ if(src.empty())
{
- cmake* cm = this->Makefile->GetCMakeInstance();
- cm->IssueMessage(cmake::FATAL_ERROR, e,
- this->GetBacktrace());
+ if(!e.empty())
+ {
+ cmake* cm = this->Makefile->GetCMakeInstance();
+ cm->IssueMessage(cmake::FATAL_ERROR, e,
+ this->GetBacktrace());
+ }
+ return;
}
- return;
+ files.push_back(src);
}
}
- files = this->SourceFiles;
}
//----------------------------------------------------------------------------
-void cmTarget::AddSourceFile(cmSourceFile* sf)
+void cmTarget::GetSourceFiles(std::vector<cmSourceFile*> &files) const
{
- if (std::find(this->SourceFiles.begin(), this->SourceFiles.end(), sf)
- == this->SourceFiles.end())
+ std::vector<std::string> srcs;
+ this->GetSourceFiles(srcs);
+
+ std::set<cmSourceFile*> emitted;
+
+ for(std::vector<std::string>::const_iterator i = srcs.begin();
+ i != srcs.end(); ++i)
{
- this->SourceFiles.push_back(sf);
+ cmSourceFile* sf = this->Makefile->GetOrCreateSource(*i);
+ if (emitted.insert(sf).second)
+ {
+ files.push_back(sf);
+ }
}
}
@@ -583,17 +607,17 @@ void cmTarget::AddSources(std::vector<std::string> const& srcs)
const char* src = i->c_str();
if(src[0] == '$' && src[1] == '<')
{
- this->ProcessSourceExpression(*i);
+ this->AddSource(src);
}
else
{
- this->AddSource(src);
+ this->AddSourceCMP0049(src);
}
}
}
//----------------------------------------------------------------------------
-cmSourceFile* cmTarget::AddSource(const std::string& s)
+cmSourceFile* cmTarget::AddSourceCMP0049(const std::string& s)
{
std::string src = s;
@@ -632,28 +656,91 @@ cmSourceFile* cmTarget::AddSource(const std::string& s)
}
}
}
-
- cmSourceFile* sf = this->Makefile->GetOrCreateSource(src);
- this->AddSourceFile(sf);
- return sf;
+ return this->AddSource(src);
}
//----------------------------------------------------------------------------
-void cmTarget::ProcessSourceExpression(std::string const& expr)
+struct CreateLocation
+{
+ cmMakefile const* Makefile;
+
+ CreateLocation(cmMakefile const* mf)
+ : Makefile(mf)
+ {
+
+ }
+
+ cmSourceFileLocation operator()(const std::string& filename)
+ {
+ return cmSourceFileLocation(this->Makefile, filename);
+ }
+};
+
+//----------------------------------------------------------------------------
+struct LocationMatcher
{
- if(cmHasLiteralPrefix(expr.c_str(), "$<TARGET_OBJECTS:") &&
- expr[expr.size()-1] == '>')
+ const cmSourceFileLocation& Needle;
+
+ LocationMatcher(const cmSourceFileLocation& needle)
+ : Needle(needle)
+ {
+
+ }
+
+ bool operator()(cmSourceFileLocation &loc)
+ {
+ return loc.Matches(this->Needle);
+ }
+};
+
+
+//----------------------------------------------------------------------------
+struct TargetPropertyEntryFinder
+{
+private:
+ const cmSourceFileLocation& Needle;
+public:
+ TargetPropertyEntryFinder(const cmSourceFileLocation& needle)
+ : Needle(needle)
+ {
+
+ }
+
+ bool operator()(cmTargetInternals::TargetPropertyEntry* entry)
+ {
+ std::vector<std::string> files;
+ cmSystemTools::ExpandListArgument(entry->ge->GetInput(), files);
+ std::vector<cmSourceFileLocation> locations(files.size());
+ std::transform(files.begin(), files.end(), locations.begin(),
+ CreateLocation(this->Needle.GetMakefile()));
+
+ return std::find_if(locations.begin(), locations.end(),
+ LocationMatcher(this->Needle)) != locations.end();
+ }
+};
+
+//----------------------------------------------------------------------------
+cmSourceFile* cmTarget::AddSource(const std::string& src)
+{
+ cmSourceFileLocation sfl(this->Makefile, src);
+ if (std::find_if(this->Internal->SourceEntries.begin(),
+ this->Internal->SourceEntries.end(),
+ TargetPropertyEntryFinder(sfl))
+ == this->Internal->SourceEntries.end())
{
- std::string objLibName = expr.substr(17, expr.size()-18);
- this->ObjectLibraries.push_back(objLibName);
+ cmListFileBacktrace lfbt;
+ this->Makefile->GetBacktrace(lfbt);
+ cmGeneratorExpression ge(lfbt);
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(src);
+ cge->SetEvaluateForBuildsystem(true);
+ this->Internal->SourceEntries.push_back(
+ new cmTargetInternals::TargetPropertyEntry(cge));
}
- else
+ if (cmGeneratorExpression::Find(src) != std::string::npos)
{
- cmOStringStream e;
- e << "Unrecognized generator expression:\n"
- << " " << expr;
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return 0;
}
+ return this->Makefile->GetOrCreateSource(src);
}
//----------------------------------------------------------------------------
@@ -2766,25 +2853,90 @@ const char *cmTarget::GetProperty(const std::string& prop,
{
cmOStringStream ss;
const char* sep = "";
- for(std::vector<cmSourceFile*>::const_iterator
- i = this->SourceFiles.begin();
- i != this->SourceFiles.end(); ++i)
+ typedef cmTargetInternals::TargetPropertyEntry
+ TargetPropertyEntry;
+ for(std::vector<TargetPropertyEntry*>::const_iterator
+ i = this->Internal->SourceEntries.begin();
+ i != this->Internal->SourceEntries.end(); ++i)
{
- // Separate from the previous list entries.
- ss << sep;
- sep = ";";
+ std::string entry = (*i)->ge->GetInput();
- // Construct what is known about this source file location.
- cmSourceFileLocation const& location = (*i)->GetLocation();
- std::string sname = location.GetDirectory();
- if(!sname.empty())
+ std::vector<std::string> files;
+ cmSystemTools::ExpandListArgument(entry, files);
+ for (std::vector<std::string>::const_iterator
+ li = files.begin(); li != files.end(); ++li)
{
- sname += "/";
- }
- sname += location.GetName();
+ if(cmHasLiteralPrefix(*li, "$<TARGET_OBJECTS:") &&
+ (*li)[li->size() - 1] == '>')
+ {
+ std::string objLibName = li->substr(17, li->size()-18);
+
+ if (cmGeneratorExpression::Find(objLibName) != std::string::npos)
+ {
+ ss << sep;
+ sep = ";";
+ ss << *li;
+ continue;
+ }
+
+ bool addContent = false;
+ bool noMessage = true;
+ cmOStringStream e;
+ cmake::MessageType messageType = cmake::AUTHOR_WARNING;
+ switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0051))
+ {
+ case cmPolicies::WARN:
+ e << (this->Makefile->GetPolicies()
+ ->GetPolicyWarning(cmPolicies::CMP0051)) << "\n";
+ noMessage = false;
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::NEW:
+ addContent = true;
+ }
+ if (!noMessage)
+ {
+ e << "Target \"" << this->Name << "\" contains $<TARGET_OBJECTS> "
+ "generator expression in its sources list. This content was not "
+ "previously part of the SOURCES property when that property was "
+ "read at configure time. Code reading that property needs to be "
+ "adapted to ignore the generator expression using the "
+ "string(GENEX_STRIP) command.";
+ this->Makefile->IssueMessage(messageType, e.str());
+ }
+ if (addContent)
+ {
+ ss << sep;
+ sep = ";";
+ ss << *li;
+ }
+ }
+ else if (cmGeneratorExpression::Find(*li) == std::string::npos)
+ {
+ ss << sep;
+ sep = ";";
+ ss << *li;
+ }
+ else
+ {
+ cmSourceFile *sf = this->Makefile->GetOrCreateSource(*li);
+ // Construct what is known about this source file location.
+ cmSourceFileLocation const& location = sf->GetLocation();
+ std::string sname = location.GetDirectory();
+ if(!sname.empty())
+ {
+ sname += "/";
+ }
+ sname += location.GetName();
- // Append this list entry.
- ss << sname;
+ ss << sep;
+ sep = ";";
+ // Append this list entry.
+ ss << sname;
+ }
+ }
}
this->Properties.SetProperty("SOURCES", ss.str().c_str(),
cmProperty::TARGET);
@@ -4844,8 +4996,10 @@ bool cmTarget::IsLinkInterfaceDependentNumberMaxProperty(const std::string &p,
//----------------------------------------------------------------------------
void cmTarget::GetLanguages(std::set<std::string>& languages) const
{
+ std::vector<cmSourceFile*> sourceFiles;
+ this->GetSourceFiles(sourceFiles);
for(std::vector<cmSourceFile*>::const_iterator
- i = this->SourceFiles.begin(); i != this->SourceFiles.end(); ++i)
+ i = sourceFiles.begin(); i != sourceFiles.end(); ++i)
{
const std::string& lang = (*i)->GetLanguage();
if(!lang.empty())
@@ -4853,6 +5007,53 @@ void cmTarget::GetLanguages(std::set<std::string>& languages) const
languages.insert(lang);
}
}
+
+ std::vector<cmTarget*> objectLibraries;
+ std::vector<cmSourceFile const*> externalObjects;
+ if (this->Makefile->GetGeneratorTargets().empty())
+ {
+ // At configure-time, this method can be called as part of getting the
+ // LOCATION property or to export() a file to be include()d. However
+ // there is no cmGeneratorTarget at configure-time, so search the SOURCES
+ // for TARGET_OBJECTS instead for backwards compatibility with OLD
+ // behavior of CMP0024 and CMP0026 only.
+ std::vector<std::string> srcs;
+ cmSystemTools::ExpandListArgument(this->GetProperty("SOURCES"), srcs);
+ for(std::vector<std::string>::const_iterator it = srcs.begin();
+ it != srcs.end(); ++it)
+ {
+ if (cmHasLiteralPrefix(*it, "$<TARGET_OBJECTS:")
+ && cmHasLiteralSuffix(*it, ">"))
+ {
+ std::string objLibName = it->substr(17, it->size()-18);
+ if (cmTarget* tgt = this->Makefile->FindTargetToUse(objLibName))
+ {
+ objectLibraries.push_back(tgt);
+ }
+ }
+ }
+ }
+ else
+ {
+ cmGeneratorTarget* gt = this->Makefile->GetLocalGenerator()
+ ->GetGlobalGenerator()
+ ->GetGeneratorTarget(this);
+ gt->GetExternalObjects(externalObjects);
+ for(std::vector<cmSourceFile const*>::const_iterator
+ i = externalObjects.begin(); i != externalObjects.end(); ++i)
+ {
+ std::string objLib = (*i)->GetObjectLibrary();
+ if (cmTarget* tgt = this->Makefile->FindTargetToUse(objLib))
+ {
+ objectLibraries.push_back(tgt);
+ }
+ }
+ }
+ for(std::vector<cmTarget*>::const_iterator
+ i = objectLibraries.begin(); i != objectLibraries.end(); ++i)
+ {
+ (*i)->GetLanguages(languages);
+ }
}
//----------------------------------------------------------------------------
@@ -5917,19 +6118,6 @@ cmTarget::ComputeLinkImplementationLanguages(LinkImplementation& impl) const
std::set<std::string> languages;
// Get languages used in our source files.
this->GetLanguages(languages);
- // Get languages used in object library sources.
- for(std::vector<std::string>::const_iterator
- i = this->ObjectLibraries.begin();
- i != this->ObjectLibraries.end(); ++i)
- {
- if(cmTarget* objLib = this->Makefile->FindTargetToUse(*i))
- {
- if(objLib->GetType() == cmTarget::OBJECT_LIBRARY)
- {
- objLib->GetLanguages(languages);
- }
- }
- }
// Copy the set of langauges to the link implementation.
for(std::set<std::string>::iterator li = languages.begin();
li != languages.end(); ++li)
@@ -6395,6 +6583,7 @@ cmTargetInternalPointer::~cmTargetInternalPointer()
deleteAndClear(this->Pointer->IncludeDirectoriesEntries);
deleteAndClear(this->Pointer->CompileOptionsEntries);
deleteAndClear(this->Pointer->CompileDefinitionsEntries);
+ deleteAndClear(this->Pointer->SourceEntries);
delete this->Pointer;
}
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 3ef853b..fcbff93 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -135,17 +135,14 @@ public:
/**
* Get the list of the source files used by this target
*/
+ void GetSourceFiles(std::vector<std::string> &files) const;
void GetSourceFiles(std::vector<cmSourceFile*> &files) const;
- void AddSourceFile(cmSourceFile* sf);
- std::vector<std::string> const& GetObjectLibraries() const
- {
- return this->ObjectLibraries;
- }
/**
* Add sources to the target.
*/
void AddSources(std::vector<std::string> const& srcs);
+ cmSourceFile* AddSourceCMP0049(const std::string& src);
cmSourceFile* AddSource(const std::string& src);
enum LinkLibraryType {GENERAL, DEBUG, OPTIMIZED};
@@ -685,8 +682,6 @@ private:
std::vector<cmCustomCommand> PreLinkCommands;
std::vector<cmCustomCommand> PostBuildCommands;
TargetType TargetTypeValue;
- std::vector<cmSourceFile*> SourceFiles;
- std::vector<std::string> ObjectLibraries;
LinkLibraryVectorType LinkLibraries;
LinkLibraryVectorType PrevLinkedLibraries;
bool LinkLibrariesAnalyzed;
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index bb76b7f..8d10e7c 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -1054,6 +1054,19 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
std::vector<cmSourceFile const*> externalObjects;
this->GeneratorTarget->GetExternalObjects(externalObjects);
+ for(std::vector<cmSourceFile const*>::iterator
+ si = externalObjects.begin();
+ si != externalObjects.end(); )
+ {
+ if (!(*si)->GetObjectLibrary().empty())
+ {
+ si = externalObjects.erase(si);
+ }
+ else
+ {
+ ++si;
+ }
+ }
if(this->LocalGenerator->GetVersion() > cmLocalVisualStudioGenerator::VS10)
{
// For VS >= 11 we use LinkObjects to avoid linking custom command
diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt
index a0e34ef..758165c 100644
--- a/Tests/GeneratorExpression/CMakeLists.txt
+++ b/Tests/GeneratorExpression/CMakeLists.txt
@@ -166,7 +166,7 @@ add_library(imported4 SHARED IMPORTED)
set_property(TARGET imported4 APPEND PROPERTY
INCLUDE_DIRECTORIES $<TARGET_PROPERTY:imported3,INTERFACE_INCLUDE_DIRECTORIES>)
-add_executable(someexe empty.cpp)
+add_executable(someexe $<1:empty.cpp> $<0:does_not_exist>)
add_executable(Alias::SomeExe ALIAS someexe)
add_library(Alias::SomeLib ALIAS empty1)
diff --git a/Tests/Properties/CMakeLists.txt b/Tests/Properties/CMakeLists.txt
index 285d596..11fca45 100644
--- a/Tests/Properties/CMakeLists.txt
+++ b/Tests/Properties/CMakeLists.txt
@@ -143,3 +143,5 @@ set_property(CACHE SOME_ENTRY PROPERTY VALUE "${expect_VALUE}")
set_property(CACHE SOME_ENTRY PROPERTY ADVANCED "${expect_ADVANCED}")
set_property(CACHE SOME_ENTRY PROPERTY STRINGS "${expect_STRINGS}")
check_cache_props()
+
+add_subdirectory(SubDir2)
diff --git a/Tests/Properties/SubDir2/CMakeLists.txt b/Tests/Properties/SubDir2/CMakeLists.txt
new file mode 100644
index 0000000..377dc83
--- /dev/null
+++ b/Tests/Properties/SubDir2/CMakeLists.txt
@@ -0,0 +1,5 @@
+
+set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/../subdirtest.cxx"
+ PROPERTIES COMPILE_DEFINITIONS SUBDIR_TEST)
+
+add_executable(subdirtest "${CMAKE_CURRENT_SOURCE_DIR}/../subdirtest.cxx")
diff --git a/Tests/Properties/subdirtest.cxx b/Tests/Properties/subdirtest.cxx
new file mode 100644
index 0000000..02d8f3d
--- /dev/null
+++ b/Tests/Properties/subdirtest.cxx
@@ -0,0 +1,9 @@
+
+#ifndef SUBDIR_TEST
+#error Expected SUBDIR_TEST
+#endif
+
+int main(int, char**)
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CMP0051/CMP0051-NEW-result.txt b/Tests/RunCMake/CMP0051/CMP0051-NEW-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/CMP0051/CMP0051-NEW-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0051/CMP0051-NEW-stderr.txt b/Tests/RunCMake/CMP0051/CMP0051-NEW-stderr.txt
new file mode 100644
index 0000000..e5578ba
--- /dev/null
+++ b/Tests/RunCMake/CMP0051/CMP0051-NEW-stderr.txt
@@ -0,0 +1 @@
+^Sources: "empty.cpp;\$<TARGET_OBJECTS:objects>"$
diff --git a/Tests/RunCMake/CMP0051/CMP0051-NEW.cmake b/Tests/RunCMake/CMP0051/CMP0051-NEW.cmake
new file mode 100644
index 0000000..f304bf1
--- /dev/null
+++ b/Tests/RunCMake/CMP0051/CMP0051-NEW.cmake
@@ -0,0 +1,10 @@
+
+cmake_policy(SET CMP0051 NEW)
+
+add_library(objects OBJECT empty.cpp)
+
+add_library(empty empty.cpp $<TARGET_OBJECTS:objects>)
+
+get_target_property(srcs empty SOURCES)
+
+message("Sources: \"${srcs}\"")
diff --git a/Tests/RunCMake/CMP0051/CMP0051-OLD-result.txt b/Tests/RunCMake/CMP0051/CMP0051-OLD-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/CMP0051/CMP0051-OLD-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0051/CMP0051-OLD-stderr.txt b/Tests/RunCMake/CMP0051/CMP0051-OLD-stderr.txt
new file mode 100644
index 0000000..cc17f33
--- /dev/null
+++ b/Tests/RunCMake/CMP0051/CMP0051-OLD-stderr.txt
@@ -0,0 +1 @@
+^Sources: "empty.cpp"$
diff --git a/Tests/RunCMake/CMP0051/CMP0051-OLD.cmake b/Tests/RunCMake/CMP0051/CMP0051-OLD.cmake
new file mode 100644
index 0000000..0243e94
--- /dev/null
+++ b/Tests/RunCMake/CMP0051/CMP0051-OLD.cmake
@@ -0,0 +1,10 @@
+
+cmake_policy(SET CMP0051 OLD)
+
+add_library(objects OBJECT empty.cpp)
+
+add_library(empty empty.cpp $<TARGET_OBJECTS:objects>)
+
+get_target_property(srcs empty SOURCES)
+
+message("Sources: \"${srcs}\"")
diff --git a/Tests/RunCMake/CMP0051/CMP0051-WARN-result.txt b/Tests/RunCMake/CMP0051/CMP0051-WARN-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/CMP0051/CMP0051-WARN-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CMP0051/CMP0051-WARN-stderr.txt b/Tests/RunCMake/CMP0051/CMP0051-WARN-stderr.txt
new file mode 100644
index 0000000..f1b0357
--- /dev/null
+++ b/Tests/RunCMake/CMP0051/CMP0051-WARN-stderr.txt
@@ -0,0 +1,15 @@
+CMake Warning \(dev\) at CMP0051-WARN.cmake:6 \(get_target_property\):
+ Policy CMP0051 is not set: List TARGET_OBJECTS in SOURCES target property.
+ Run "cmake --help-policy CMP0051" for policy details. Use the cmake_policy
+ command to set the policy and suppress this warning.
+
+ Target "empty" contains \$<TARGET_OBJECTS> generator expression in its
+ sources list. This content was not previously part of the SOURCES property
+ when that property was read at configure time. Code reading that property
+ needs to be adapted to ignore the generator expression using the
+ string\(GENEX_STRIP\) command.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+Sources: "empty.cpp"$
diff --git a/Tests/RunCMake/CMP0051/CMP0051-WARN.cmake b/Tests/RunCMake/CMP0051/CMP0051-WARN.cmake
new file mode 100644
index 0000000..fd595ce
--- /dev/null
+++ b/Tests/RunCMake/CMP0051/CMP0051-WARN.cmake
@@ -0,0 +1,8 @@
+
+add_library(objects OBJECT empty.cpp)
+
+add_library(empty empty.cpp $<TARGET_OBJECTS:objects>)
+
+get_target_property(srcs empty SOURCES)
+
+message("Sources: \"${srcs}\"")
diff --git a/Tests/RunCMake/CMP0051/CMakeLists.txt b/Tests/RunCMake/CMP0051/CMakeLists.txt
new file mode 100644
index 0000000..3482e6b
--- /dev/null
+++ b/Tests/RunCMake/CMP0051/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.0)
+project(${RunCMake_TEST} CXX)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0051/RunCMakeTest.cmake b/Tests/RunCMake/CMP0051/RunCMakeTest.cmake
new file mode 100644
index 0000000..621192d
--- /dev/null
+++ b/Tests/RunCMake/CMP0051/RunCMakeTest.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(CMP0051-OLD)
+run_cmake(CMP0051-NEW)
+run_cmake(CMP0051-WARN)
diff --git a/Tests/RunCMake/CMP0051/empty.cpp b/Tests/RunCMake/CMP0051/empty.cpp
new file mode 100644
index 0000000..bfbbdde
--- /dev/null
+++ b/Tests/RunCMake/CMP0051/empty.cpp
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 7691f32..4f059d6 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -34,6 +34,7 @@ add_RunCMake_test(CMP0045)
add_RunCMake_test(CMP0046)
add_RunCMake_test(CMP0049)
add_RunCMake_test(CMP0050)
+add_RunCMake_test(CMP0051)
add_RunCMake_test(CTest)
if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Unix Makefiles")
add_RunCMake_test(CompilerChange)
@@ -49,6 +50,7 @@ add_RunCMake_test(GeneratorToolset)
add_RunCMake_test(TargetPropertyGeneratorExpressions)
add_RunCMake_test(Languages)
add_RunCMake_test(ObjectLibrary)
+add_RunCMake_test(TargetObjects)
add_RunCMake_test(find_dependency)
if(NOT WIN32)
add_RunCMake_test(PositionIndependentCode)
diff --git a/Tests/RunCMake/ObjectLibrary/BadSourceExpression1-stderr.txt b/Tests/RunCMake/ObjectLibrary/BadSourceExpression1-stderr.txt
index a1cac36..859dc3f 100644
--- a/Tests/RunCMake/ObjectLibrary/BadSourceExpression1-stderr.txt
+++ b/Tests/RunCMake/ObjectLibrary/BadSourceExpression1-stderr.txt
@@ -1,6 +1,8 @@
CMake Error at BadSourceExpression1.cmake:1 \(add_library\):
- Unrecognized generator expression:
+ Error evaluating generator expression:
\$<BAD_EXPRESSION>
+
+ Expression did not evaluate to a known generator expression
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/BadSourceExpression2-stderr.txt b/Tests/RunCMake/ObjectLibrary/BadSourceExpression2-stderr.txt
index f1fcbe8..7060c61 100644
--- a/Tests/RunCMake/ObjectLibrary/BadSourceExpression2-stderr.txt
+++ b/Tests/RunCMake/ObjectLibrary/BadSourceExpression2-stderr.txt
@@ -1,4 +1,8 @@
CMake Error at BadSourceExpression2.cmake:1 \(add_library\):
+ Error evaluating generator expression:
+
+ \$<TARGET_OBJECTS:DoesNotExist>
+
Objects of target "DoesNotExist" referenced but no such target exists.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/ObjectLibrary/BadSourceExpression3-stderr.txt b/Tests/RunCMake/ObjectLibrary/BadSourceExpression3-stderr.txt
index ad14a35..838b3d8 100644
--- a/Tests/RunCMake/ObjectLibrary/BadSourceExpression3-stderr.txt
+++ b/Tests/RunCMake/ObjectLibrary/BadSourceExpression3-stderr.txt
@@ -1,4 +1,8 @@
CMake Error at BadSourceExpression3.cmake:2 \(add_library\):
+ Error evaluating generator expression:
+
+ \$<TARGET_OBJECTS:NotObjLib>
+
Objects of target "NotObjLib" referenced but is not an OBJECT library.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/TargetObjects/BadContext-result.txt b/Tests/RunCMake/TargetObjects/BadContext-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/TargetObjects/BadContext-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/TargetObjects/BadContext-stderr.txt b/Tests/RunCMake/TargetObjects/BadContext-stderr.txt
new file mode 100644
index 0000000..92f2c91
--- /dev/null
+++ b/Tests/RunCMake/TargetObjects/BadContext-stderr.txt
@@ -0,0 +1,17 @@
+CMake Error at BadContext.cmake:2 \(file\):
+ Error evaluating generator expression:
+
+ \$<TARGET_OBJECTS:NoTarget>
+
+ The evaluation of the TARGET_OBJECTS generator expression is only suitable
+ for consumption by CMake. It is not suitable for writing out elsewhere.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error:
+ Error evaluating generator expression:
+
+ \$<TARGET_OBJECTS:NoTarget>
+
+ The evaluation of the TARGET_OBJECTS generator expression is only suitable
+ for consumption by CMake. It is not suitable for writing out elsewhere.
diff --git a/Tests/RunCMake/TargetObjects/BadContext.cmake b/Tests/RunCMake/TargetObjects/BadContext.cmake
new file mode 100644
index 0000000..67962a4
--- /dev/null
+++ b/Tests/RunCMake/TargetObjects/BadContext.cmake
@@ -0,0 +1,4 @@
+
+file(GENERATE OUTPUT test_output CONTENT $<TARGET_OBJECTS:NoTarget>)
+
+install(FILES $<TARGET_OBJECTS:NoTarget> DESTINATION objects)
diff --git a/Tests/RunCMake/TargetObjects/CMakeLists.txt b/Tests/RunCMake/TargetObjects/CMakeLists.txt
new file mode 100644
index 0000000..be9d403
--- /dev/null
+++ b/Tests/RunCMake/TargetObjects/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.4)
+project(${RunCMake_TEST})
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/TargetObjects/RunCMakeTest.cmake b/Tests/RunCMake/TargetObjects/RunCMakeTest.cmake
new file mode 100644
index 0000000..85c76e2
--- /dev/null
+++ b/Tests/RunCMake/TargetObjects/RunCMakeTest.cmake
@@ -0,0 +1,3 @@
+include(RunCMake)
+
+run_cmake(BadContext)
diff --git a/Tests/StringFileTest/CMakeLists.txt b/Tests/StringFileTest/CMakeLists.txt
index 00383ab..be6d8fe 100644
--- a/Tests/StringFileTest/CMakeLists.txt
+++ b/Tests/StringFileTest/CMakeLists.txt
@@ -286,3 +286,9 @@ string(MAKE_C_IDENTIFIER "1one-two$" MCI_1)
if(NOT MCI_1 STREQUAL _1one_two_)
message(SEND_ERROR "MAKE_C_IDENTIFIER did not create expected result.")
endif()
+
+string(GENEX_STRIP "one;$<1:two;three>;four;$<TARGET_OBJECTS:some_target>" strip_result)
+
+if (NOT strip_result STREQUAL "one;four")
+ message(SEND_ERROR "GENEX_STRIP did not create expected result: ${strip_result}")
+endif()