1
0
Fork 0
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:
Christian Walther 2021-10-29 13:24:59 +02:00
parent a957e8121d
commit 32a6ad1f4d
4 changed files with 56 additions and 2 deletions

View file

@ -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="&quot;${value}&quot;"
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>

View file

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

View file

@ -14,6 +14,7 @@ CC_SRCS :=
TAROUT :=
TERMINAL__DUMMY_OUTPUT__OUTPUTS :=
LOGFILE :=
TOUCHEDFILES :=
# Every subdirectory with source files must be described here
SUBDIRS := \

View file

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