An update will be applied December 9th, between 12PM and 1:00PM EST (UTC -5:00). The site may be slow during that time.

Commit 5de63265 authored by Stephen Kelly's avatar Stephen Kelly
Browse files

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.
parent aa0a3562
......@@ -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.
file-GENERATE-TARGET_OBJECTS
----------------------------
* The :command:`file(GENERATE)` subcommand learned to evaluate the
``TARGET_OBJECTS``
:manual:`generator expression <cmake-generator-expressions(7)>`.
......@@ -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 =
......
......@@ -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
......@@ -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());
......
......@@ -34,6 +34,7 @@ struct cmGeneratorExpressionContext
bool Quiet;
bool HadError;
bool HadContextSensitiveCondition;
bool EvaluateForBuildsystem;
};
struct cmGeneratorExpressionDAGChecker;
......
......@@ -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));
}
......
......@@ -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
)
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()
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.
file(GENERATE OUTPUT test_output CONTENT $<TARGET_OBJECTS:NoTarget>)
install(FILES $<TARGET_OBJECTS:NoTarget> DESTINATION objects)
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\)
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\)
add_library(StaticLib empty.cpp)
file(GENERATE OUTPUT test_output CONTENT $<TARGET_OBJECTS:StaticLib>)
include(RunCMake)
run_cmake(NoTarget)
run_cmake(NotObjlibTarget)
run_cmake(BadContext)
#ifdef _WIN32
__declspec(dllexport)
#endif
int empty()
{
return 0;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment