Genex: Only evaluate TARGET_OBJECTS to determine target sources.

The output of this expression may contain macros for IDEs to replace
such as $(Configuration), $(CURRENT_ARCH) etc.  To avoid generating
content which is not usable in other contexts, report an error if
there is an attempt to use it in other contexts.

This commit may be reverted in the future if a solution to the
above difference is implemented.
This commit is contained in:
Stephen Kelly 2014-03-20 15:37:12 +01:00
parent aa0a3562dd
commit 5de63265e3
20 changed files with 44 additions and 110 deletions

View File

@ -190,4 +190,6 @@ property is non-empty::
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``.
object of type ``OBJECT_LIBRARY``. This expression may only be used in
the sources of :command:`add_library` and :command:`add_executable`
commands.

View File

@ -1,6 +0,0 @@
file-GENERATE-TARGET_OBJECTS
----------------------------
* The :command:`file(GENERATE)` subcommand learned to evaluate the
``TARGET_OBJECTS``
:manual:`generator expression <cmake-generator-expressions(7)>`.

View File

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

View File

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

View File

@ -1251,6 +1251,16 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
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());

View File

@ -34,6 +34,7 @@ struct cmGeneratorExpressionContext
bool Quiet;
bool HadError;
bool HadContextSensitiveCondition;
bool EvaluateForBuildsystem;
};
struct cmGeneratorExpressionDAGChecker;

View File

@ -732,6 +732,7 @@ cmSourceFile* cmTarget::AddSource(const std::string& src)
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));
}

View File

@ -258,17 +258,3 @@ set(CMP0044_TYPE NEW)
add_subdirectory(CMP0044 ${CMAKE_BINARY_DIR}/CMP0044-NEW)
set(CMP0044_TYPE OLD)
add_subdirectory(CMP0044 ${CMAKE_BINARY_DIR}/CMP0044-OLD)
add_library(objlib OBJECT objlib1.c objlib2.c)
file(GENERATE
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/objlib_files"
CONTENT "$<JOIN:$<TARGET_OBJECTS:objlib>,\n>\n"
)
add_custom_target(check_object_files ALL
COMMAND ${CMAKE_COMMAND}
"-DOBJLIB_LISTFILE=${CMAKE_CURRENT_BINARY_DIR}/objlib_files"
-DTEST_CONFIGURATION=${CMAKE_BUILD_TYPE}
-DEXPECTED_NUM_OBJECTFILES=2
-P "${CMAKE_CURRENT_SOURCE_DIR}/check_object_files.cmake"
DEPENDS objlib
)

View File

@ -1,48 +0,0 @@
if (NOT EXISTS ${OBJLIB_LISTFILE})
message(SEND_ERROR "Object listing file \"${OBJLIB_LISTFILE}\" not found!")
endif()
file(STRINGS ${OBJLIB_LISTFILE} objlib_files)
list(LENGTH objlib_files num_objectfiles)
if (NOT EXPECTED_NUM_OBJECTFILES EQUAL num_objectfiles)
message(SEND_ERROR "Unexpected number of entries in object list file (${num_objectfiles} instead of ${EXPECTED_NUM_OBJECTFILES})")
endif()
foreach(objlib_file ${objlib_files})
set(file_exists False)
if (EXISTS ${objlib_file})
set(file_exists True)
endif()
if (NOT file_exists)
if (objlib_file MATCHES ".(CURRENT_ARCH)")
string(REPLACE "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)" "*" config_file "${objlib_file}")
string(REPLACE "$(PROJECT_NAME)" "GeneratorExpression" config_file "${config_file}")
string(REPLACE "$(CURRENT_ARCH)" "*" config_file "${config_file}")
file(GLOB_RECURSE files "${config_file}")
list(LENGTH files num_files)
if (NOT files)
message(SEND_ERROR "Got no files for expression ${config_file}")
endif()
set(file_exists True)
else()
foreach(config_macro "$(Configuration)" "$(OutDir)" "$(IntDir)")
string(REPLACE "${config_macro}" "${TEST_CONFIGURATION}" config_file "${objlib_file}")
list(APPEND attempts ${config_file})
if (EXISTS ${config_file})
set(file_exists True)
endif()
endforeach()
endif()
endif()
if (NOT file_exists)
if(attempts)
list(REMOVE_DUPLICATES attempts)
set(tried " Tried ${attempts}")
endif()
message(SEND_ERROR "File \"${objlib_file}\" does not exist!${tried}")
endif()
endforeach()

View File

@ -1,5 +0,0 @@
void objlib1()
{
}

View File

@ -1,5 +0,0 @@
void objlib2()
{
}

View File

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

View File

@ -1,2 +1,4 @@
file(GENERATE OUTPUT test_output CONTENT $<TARGET_OBJECTS:NoTarget>)
install(FILES $<TARGET_OBJECTS:NoTarget> DESTINATION objects)

View File

@ -1,8 +0,0 @@
CMake Error at NoTarget.cmake:2 \(file\):
Error evaluating generator expression:
\$<TARGET_OBJECTS:NoTarget>
Objects of target "NoTarget" referenced but no such target exists.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -1,8 +0,0 @@
CMake Error at NotObjlibTarget.cmake:4 \(file\):
Error evaluating generator expression:
\$<TARGET_OBJECTS:StaticLib>
Objects of target "StaticLib" referenced but is not an OBJECT library.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -1,4 +0,0 @@
add_library(StaticLib empty.cpp)
file(GENERATE OUTPUT test_output CONTENT $<TARGET_OBJECTS:StaticLib>)

View File

@ -1,4 +1,3 @@
include(RunCMake)
run_cmake(NoTarget)
run_cmake(NotObjlibTarget)
run_cmake(BadContext)

View File

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