From caa4b7b88b3845a23d0767b9e63ee6e31ca614e5 Mon Sep 17 00:00:00 2001 From: Clinton Stimpson Date: Thu, 6 Nov 2014 20:56:50 -0700 Subject: [PATCH] genex: Preserve order while evaluating TARGET_OBJECTS The logic introduced in commit v3.1.0-rc1~688^2~9 (Genex: Evaluate TARGET_OBJECTS as a normal expression, 2014-02-26) ordered a map by pointer value and then constructed a list of object files by iterating over the map. This is not deterministic. Since commit v3.1.0-rc1~688^2~5 (cmTarget: Allow any generator expression in SOURCES property, 2014-03-18) the order produced by the above-mentioned logic started being used for the actual list of object files on the link line. Since it is not deterministic, spurious re-links occur after re-running CMake simply because the order of objects changed on the link line. Fix this by iterating over the original vector of source files instead of the map. This has a deterministic order. --- Source/cmGeneratorExpressionEvaluator.cxx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index c1478df72..67a1a6d43 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -1286,12 +1286,16 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode std::string obj_dir = gt->ObjectDirectory; std::string result; const char* sep = ""; - for(std::map::const_iterator it - = mapping.begin(); it != mapping.end(); ++it) + for(std::vector::const_iterator it + = objectSources.begin(); it != objectSources.end(); ++it) { - assert(!it->second.empty()); + // Find the object file name corresponding to this source file. + std::map::const_iterator + map_it = mapping.find(*it); + // It must exist because we populated the mapping just above. + assert(!map_it->second.empty()); result += sep; - std::string objFile = obj_dir + it->second; + std::string objFile = obj_dir + map_it->second; cmSourceFile* sf = context->Makefile->GetOrCreateSource(objFile, true); sf->SetObjectLibrary(tgtName); sf->SetProperty("EXTERNAL_OBJECT", "1");