From 5de63265e3a22d9a8aa5ad437a5030ccfcbcd02d Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Thu, 20 Mar 2014 15:37:12 +0100 Subject: [PATCH] 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. --- Help/manual/cmake-generator-expressions.7.rst | 4 +- .../dev/file-GENERATE-TARGET_OBJECTS.rst | 6 --- Source/cmGeneratorExpression.cxx | 4 +- Source/cmGeneratorExpression.h | 6 +++ Source/cmGeneratorExpressionEvaluator.cxx | 10 ++++ Source/cmGeneratorExpressionEvaluator.h | 1 + Source/cmTarget.cxx | 1 + Tests/GeneratorExpression/CMakeLists.txt | 14 ------ .../check_object_files.cmake | 48 ------------------- Tests/GeneratorExpression/objlib1.c | 5 -- Tests/GeneratorExpression/objlib2.c | 5 -- ...arget-result.txt => BadContext-result.txt} | 0 .../TargetObjects/BadContext-stderr.txt | 17 +++++++ .../{NoTarget.cmake => BadContext.cmake} | 2 + .../TargetObjects/NoTarget-stderr.txt | 8 ---- .../TargetObjects/NotObjlibTarget-result.txt | 1 - .../TargetObjects/NotObjlibTarget-stderr.txt | 8 ---- .../TargetObjects/NotObjlibTarget.cmake | 4 -- .../RunCMake/TargetObjects/RunCMakeTest.cmake | 3 +- Tests/RunCMake/TargetObjects/empty.cpp | 7 --- 20 files changed, 44 insertions(+), 110 deletions(-) delete mode 100644 Help/release/dev/file-GENERATE-TARGET_OBJECTS.rst delete mode 100644 Tests/GeneratorExpression/check_object_files.cmake delete mode 100644 Tests/GeneratorExpression/objlib1.c delete mode 100644 Tests/GeneratorExpression/objlib2.c rename Tests/RunCMake/TargetObjects/{NoTarget-result.txt => BadContext-result.txt} (100%) create mode 100644 Tests/RunCMake/TargetObjects/BadContext-stderr.txt rename Tests/RunCMake/TargetObjects/{NoTarget.cmake => BadContext.cmake} (52%) delete mode 100644 Tests/RunCMake/TargetObjects/NoTarget-stderr.txt delete mode 100644 Tests/RunCMake/TargetObjects/NotObjlibTarget-result.txt delete mode 100644 Tests/RunCMake/TargetObjects/NotObjlibTarget-stderr.txt delete mode 100644 Tests/RunCMake/TargetObjects/NotObjlibTarget.cmake delete mode 100644 Tests/RunCMake/TargetObjects/empty.cpp diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index 17263d4468..dfda8dcb58 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -190,4 +190,6 @@ property is non-empty:: Content of ``...`` converted to a C identifier. ``$`` 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. diff --git a/Help/release/dev/file-GENERATE-TARGET_OBJECTS.rst b/Help/release/dev/file-GENERATE-TARGET_OBJECTS.rst deleted file mode 100644 index 853a803afb..0000000000 --- a/Help/release/dev/file-GENERATE-TARGET_OBJECTS.rst +++ /dev/null @@ -1,6 +0,0 @@ -file-GENERATE-TARGET_OBJECTS ----------------------------- - -* The :command:`file(GENERATE)` subcommand learned to evaluate the - ``TARGET_OBJECTS`` - :manual:`generator expression `. diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index e127f3a90d..d09e950458 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 tokens = diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h index d0a6aef5ff..da64515fd4 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 SeenTargetProperties; mutable std::string Output; mutable bool HadContextSensitiveCondition; + bool EvaluateForBuildsystem; }; #endif diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 669694c00e..95227d257c 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -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()); diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h index a7099cbc04..54a2548108 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/cmTarget.cxx b/Source/cmTarget.cxx index 61260be2eb..aeb477dc5b 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -732,6 +732,7 @@ cmSourceFile* cmTarget::AddSource(const std::string& src) this->Makefile->GetBacktrace(lfbt); cmGeneratorExpression ge(lfbt); cmsys::auto_ptr cge = ge.Parse(src); + cge->SetEvaluateForBuildsystem(true); this->Internal->SourceEntries.push_back( new cmTargetInternals::TargetPropertyEntry(cge)); } diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt index b5068536c1..758165c807 100644 --- a/Tests/GeneratorExpression/CMakeLists.txt +++ b/Tests/GeneratorExpression/CMakeLists.txt @@ -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 "$,\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 -) diff --git a/Tests/GeneratorExpression/check_object_files.cmake b/Tests/GeneratorExpression/check_object_files.cmake deleted file mode 100644 index 889fe809fc..0000000000 --- a/Tests/GeneratorExpression/check_object_files.cmake +++ /dev/null @@ -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() diff --git a/Tests/GeneratorExpression/objlib1.c b/Tests/GeneratorExpression/objlib1.c deleted file mode 100644 index aa8de0a27b..0000000000 --- a/Tests/GeneratorExpression/objlib1.c +++ /dev/null @@ -1,5 +0,0 @@ - -void objlib1() -{ - -} diff --git a/Tests/GeneratorExpression/objlib2.c b/Tests/GeneratorExpression/objlib2.c deleted file mode 100644 index 3c7307af7a..0000000000 --- a/Tests/GeneratorExpression/objlib2.c +++ /dev/null @@ -1,5 +0,0 @@ - -void objlib2() -{ - -} diff --git a/Tests/RunCMake/TargetObjects/NoTarget-result.txt b/Tests/RunCMake/TargetObjects/BadContext-result.txt similarity index 100% rename from Tests/RunCMake/TargetObjects/NoTarget-result.txt rename to Tests/RunCMake/TargetObjects/BadContext-result.txt diff --git a/Tests/RunCMake/TargetObjects/BadContext-stderr.txt b/Tests/RunCMake/TargetObjects/BadContext-stderr.txt new file mode 100644 index 0000000000..92f2c918ab --- /dev/null +++ b/Tests/RunCMake/TargetObjects/BadContext-stderr.txt @@ -0,0 +1,17 @@ +CMake Error at BadContext.cmake:2 \(file\): + Error evaluating generator expression: + + \$ + + 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: + + \$ + + 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/NoTarget.cmake b/Tests/RunCMake/TargetObjects/BadContext.cmake similarity index 52% rename from Tests/RunCMake/TargetObjects/NoTarget.cmake rename to Tests/RunCMake/TargetObjects/BadContext.cmake index f203c2310b..67962a4800 100644 --- a/Tests/RunCMake/TargetObjects/NoTarget.cmake +++ b/Tests/RunCMake/TargetObjects/BadContext.cmake @@ -1,2 +1,4 @@ file(GENERATE OUTPUT test_output CONTENT $) + +install(FILES $ DESTINATION objects) diff --git a/Tests/RunCMake/TargetObjects/NoTarget-stderr.txt b/Tests/RunCMake/TargetObjects/NoTarget-stderr.txt deleted file mode 100644 index 2c4f877e82..0000000000 --- a/Tests/RunCMake/TargetObjects/NoTarget-stderr.txt +++ /dev/null @@ -1,8 +0,0 @@ -CMake Error at NoTarget.cmake:2 \(file\): - Error evaluating generator expression: - - \$ - - Objects of target "NoTarget" referenced but no such target exists. -Call Stack \(most recent call first\): - CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/TargetObjects/NotObjlibTarget-result.txt b/Tests/RunCMake/TargetObjects/NotObjlibTarget-result.txt deleted file mode 100644 index d00491fd7e..0000000000 --- a/Tests/RunCMake/TargetObjects/NotObjlibTarget-result.txt +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/Tests/RunCMake/TargetObjects/NotObjlibTarget-stderr.txt b/Tests/RunCMake/TargetObjects/NotObjlibTarget-stderr.txt deleted file mode 100644 index bb83934034..0000000000 --- a/Tests/RunCMake/TargetObjects/NotObjlibTarget-stderr.txt +++ /dev/null @@ -1,8 +0,0 @@ -CMake Error at NotObjlibTarget.cmake:4 \(file\): - Error evaluating generator expression: - - \$ - - Objects of target "StaticLib" referenced but is not an OBJECT library. -Call Stack \(most recent call first\): - CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/TargetObjects/NotObjlibTarget.cmake b/Tests/RunCMake/TargetObjects/NotObjlibTarget.cmake deleted file mode 100644 index c7f8a71da4..0000000000 --- a/Tests/RunCMake/TargetObjects/NotObjlibTarget.cmake +++ /dev/null @@ -1,4 +0,0 @@ - -add_library(StaticLib empty.cpp) - -file(GENERATE OUTPUT test_output CONTENT $) diff --git a/Tests/RunCMake/TargetObjects/RunCMakeTest.cmake b/Tests/RunCMake/TargetObjects/RunCMakeTest.cmake index 30b9fee533..85c76e240c 100644 --- a/Tests/RunCMake/TargetObjects/RunCMakeTest.cmake +++ b/Tests/RunCMake/TargetObjects/RunCMakeTest.cmake @@ -1,4 +1,3 @@ include(RunCMake) -run_cmake(NoTarget) -run_cmake(NotObjlibTarget) +run_cmake(BadContext) diff --git a/Tests/RunCMake/TargetObjects/empty.cpp b/Tests/RunCMake/TargetObjects/empty.cpp deleted file mode 100644 index bfbbddeb90..0000000000 --- a/Tests/RunCMake/TargetObjects/empty.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#ifdef _WIN32 -__declspec(dllexport) -#endif -int empty() -{ - return 0; -}