cmTarget: Include TARGET_OBJECTS genex in target SOURCES property.

Add policy CMP0051 to control this behavior.
This commit is contained in:
Stephen Kelly 2014-03-18 16:15:15 +01:00
parent 857d30b52e
commit 5702e10677
19 changed files with 161 additions and 12 deletions

View File

@ -102,3 +102,4 @@ All Policies
/policy/CMP0048 /policy/CMP0048
/policy/CMP0049 /policy/CMP0049
/policy/CMP0050 /policy/CMP0050
/policy/CMP0051

24
Help/policy/CMP0051.rst Normal file
View File

@ -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.

View File

@ -0,0 +1,7 @@
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``.

View File

@ -343,6 +343,11 @@ cmPolicies::cmPolicies()
CMP0050, "CMP0050", CMP0050, "CMP0050",
"Disallow add_custom_command SOURCE signatures.", "Disallow add_custom_command SOURCE signatures.",
3,0,0, cmPolicies::WARN); 3,0,0, cmPolicies::WARN);
this->DefinePolicy(
CMP0051, "CMP0051",
"List TARGET_OBJECTS in SOURCES target property.",
3,1,0, cmPolicies::WARN);
} }
cmPolicies::~cmPolicies() cmPolicies::~cmPolicies()

View File

@ -104,6 +104,7 @@ public:
CMP0048, ///< project() command manages VERSION variables CMP0048, ///< project() command manages VERSION variables
CMP0049, ///< Do not expand variables in target source entries CMP0049, ///< Do not expand variables in target source entries
CMP0050, ///< Disallow add_custom_command SOURCE signatures CMP0050, ///< Disallow add_custom_command SOURCE signatures
CMP0051, ///< List TARGET_OBJECTS in SOURCES target property
/** \brief Always the last entry. /** \brief Always the last entry.
* *

View File

@ -556,6 +556,10 @@ void cmTarget::GetSourceFiles(std::vector<std::string> &files) const
i != srcs.end(); ++i) i != srcs.end(); ++i)
{ {
std::string src = *i; std::string src = *i;
if (cmGeneratorExpression::Find(src) != std::string::npos)
{
continue;
}
cmSourceFile* sf = this->Makefile->GetOrCreateSource(src); cmSourceFile* sf = this->Makefile->GetOrCreateSource(src);
std::string e; std::string e;
src = sf->GetFullPath(&e); src = sf->GetFullPath(&e);
@ -743,6 +747,7 @@ void cmTarget::ProcessSourceExpression(std::string const& expr)
{ {
std::string objLibName = expr.substr(17, expr.size()-18); std::string objLibName = expr.substr(17, expr.size()-18);
this->ObjectLibraries.push_back(objLibName); this->ObjectLibraries.push_back(objLibName);
this->AddSource(expr);
} }
else else
{ {
@ -2876,20 +2881,62 @@ const char *cmTarget::GetProperty(const std::string& prop,
for (std::vector<std::string>::const_iterator for (std::vector<std::string>::const_iterator
li = files.begin(); li != files.end(); ++li) li = files.begin(); li != files.end(); ++li)
{ {
cmSourceFile *sf = this->Makefile->GetOrCreateSource(*li); if(cmHasLiteralPrefix(*li, "$<TARGET_OBJECTS:") &&
// Construct what is known about this source file location. (*li)[li->size() - 1] == '>')
cmSourceFileLocation const& location = sf->GetLocation();
std::string sname = location.GetDirectory();
if(!sname.empty())
{ {
sname += "/"; std::string objLibName = li->substr(17, li->size()-18);
}
sname += location.GetName();
ss << sep; bool addContent = false;
sep = ";"; bool noMessage = true;
// Append this list entry. cmOStringStream e;
ss << sname; 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
{
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();
ss << sep;
sep = ";";
// Append this list entry.
ss << sname;
}
} }
} }
this->Properties.SetProperty("SOURCES", ss.str().c_str(), this->Properties.SetProperty("SOURCES", ss.str().c_str(),

View File

@ -0,0 +1 @@
0

View File

@ -0,0 +1 @@
^Sources: "empty.cpp;\$<TARGET_OBJECTS:objects>"$

View File

@ -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}\"")

View File

@ -0,0 +1 @@
0

View File

@ -0,0 +1 @@
^Sources: "empty.cpp"$

View File

@ -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}\"")

View File

@ -0,0 +1 @@
0

View File

@ -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"$

View File

@ -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}\"")

View File

@ -0,0 +1,3 @@
cmake_minimum_required(VERSION 3.0)
project(${RunCMake_TEST} CXX)
include(${RunCMake_TEST}.cmake)

View File

@ -0,0 +1,5 @@
include(RunCMake)
run_cmake(CMP0051-OLD)
run_cmake(CMP0051-NEW)
run_cmake(CMP0051-WARN)

View File

@ -0,0 +1,7 @@
#ifdef _WIN32
__declspec(dllexport)
#endif
int empty()
{
return 0;
}

View File

@ -34,6 +34,7 @@ add_RunCMake_test(CMP0045)
add_RunCMake_test(CMP0046) add_RunCMake_test(CMP0046)
add_RunCMake_test(CMP0049) add_RunCMake_test(CMP0049)
add_RunCMake_test(CMP0050) add_RunCMake_test(CMP0050)
add_RunCMake_test(CMP0051)
add_RunCMake_test(CTest) add_RunCMake_test(CTest)
if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Unix Makefiles") if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Unix Makefiles")
add_RunCMake_test(CompilerChange) add_RunCMake_test(CompilerChange)