mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-25 01:45:33 +02:00
Bug 575702: Nondeterministic makefile ordering (prelude)
This fixes a small and rarely hit in practice regression regarding
nondeterministic ordering in makefile output introduced in 15c29eb
(bug
505882).
Multiple values for a build output variable were previously output in
definition order. Now they are generated by iterating over a HashSet,
which does not have a deterministic iteration order. Use a TreeSet for
output in a consistently sorted order instead.
Output variables with multiple values are rare (most tools generate one
output file of a particular type) and this case was not exercised in the
existing unit tests. Modify one such that it does (even if in a somewhat
contrived situation). Of note, ${OUTPUT} cannot be used in the
commandLinePattern for such a tool because it squashes the multiple
values into a single quoted file name - misuse ${FLAGS} instead.
Change-Id: Iaa28525c21d74c87dd4d72a03e334ed0e5576727
Signed-off-by: Christian Walther <walther@indel.ch>
This commit is contained in:
parent
a957e8121d
commit
32a6ad1f4d
4 changed files with 56 additions and 2 deletions
|
@ -3613,6 +3613,42 @@
|
|||
outputs="tmp">
|
||||
</outputType>
|
||||
</tool>
|
||||
<tool
|
||||
name="touch"
|
||||
command="touch"
|
||||
commandLinePattern="${COMMAND} -r ${INPUTS} ${FLAGS}"
|
||||
id="test30_2.touch">
|
||||
<optionCategory
|
||||
name="Options"
|
||||
id="test30_2.touch.category">
|
||||
</optionCategory>
|
||||
<option
|
||||
name="Touched Files"
|
||||
category="test30_2.touch.category"
|
||||
command=""${value}""
|
||||
id="test30_2.touch.filenames"
|
||||
valueType="stringList">
|
||||
<listOptionValue value="these"/>
|
||||
<listOptionValue value="file names"/>
|
||||
<listOptionValue value="are"/>
|
||||
<listOptionValue value="not"/>
|
||||
<listOptionValue value="in"/>
|
||||
<listOptionValue value="alphabetical"/>
|
||||
<listOptionValue value="order"/>
|
||||
</option>
|
||||
<inputType
|
||||
id="test30_2.touch.input1"
|
||||
buildVariable="LOGFILE"
|
||||
sources="log">
|
||||
</inputType>
|
||||
<outputType
|
||||
id="test30_2.touch.output"
|
||||
name="Touched files"
|
||||
multipleOfType="true"
|
||||
buildVariable="TOUCHEDFILES"
|
||||
option="test30_2.touch.filenames">
|
||||
</outputType>
|
||||
</tool>
|
||||
</toolChain>
|
||||
</configuration>
|
||||
</projectType>
|
||||
|
|
|
@ -32,6 +32,15 @@ new.tar \
|
|||
LOGFILE += \
|
||||
new.log \
|
||||
|
||||
TOUCHEDFILES += \
|
||||
alphabetical \
|
||||
are \
|
||||
file\ names \
|
||||
in \
|
||||
not \
|
||||
order \
|
||||
these \
|
||||
|
||||
|
||||
# All Target
|
||||
all: main-build
|
||||
|
@ -59,9 +68,15 @@ new.log: $(TAROUT) makefile objects.mk $(OPTIONAL_TOOL_DEPS)
|
|||
@echo 'Finished building: $@'
|
||||
@echo ' '
|
||||
|
||||
these file\ names are not in alphabetical order: $(LOGFILE) makefile objects.mk $(OPTIONAL_TOOL_DEPS)
|
||||
@echo 'Invoking: touch'
|
||||
touch -r $(LOGFILE) "these" "file names" "are" "not" "in" "alphabetical" "order"
|
||||
@echo 'Finished building: $@'
|
||||
@echo ' '
|
||||
|
||||
# Other Targets
|
||||
clean:
|
||||
-$(RM) new.log new.tar test30_2.tmp
|
||||
-$(RM) alphabetical are file\ names in new.log new.tar not order test30_2.tmp these
|
||||
-@echo ' '
|
||||
|
||||
.PHONY: all clean dependents main-build
|
||||
|
|
|
@ -14,6 +14,7 @@ CC_SRCS :=
|
|||
TAROUT :=
|
||||
TERMINAL__DUMMY_OUTPUT__OUTPUTS :=
|
||||
LOGFILE :=
|
||||
TOUCHEDFILES :=
|
||||
|
||||
# Every subdirectory with source files must be described here
|
||||
SUBDIRS := \
|
||||
|
|
|
@ -39,6 +39,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.Vector;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
@ -4035,7 +4036,8 @@ public class GnuMakefileGenerator implements IManagedBuilderMakefileGenerator2 {
|
|||
|
||||
// for projects with specific setting on folders/files do
|
||||
// not clear the macro value on subsequent passes
|
||||
map.putIfAbsent(macroName, new HashSet<>());
|
||||
// use TreeSet for deterministically sorted output
|
||||
map.putIfAbsent(macroName, new TreeSet<>());
|
||||
}
|
||||
|
||||
// Set of input extensions for which macros have been created so far
|
||||
|
|
Loading…
Add table
Reference in a new issue