From b887212bee8ec86086670f31ff7dff3e39cf7bf8 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Thu, 11 Jun 2020 11:42:31 -0700 Subject: [PATCH] compilers: Use enum for for deupdlication returns in CompilerArgs --- mesonbuild/compilers/compilers.py | 63 ++++++++++++++++++------------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index c80ffb00b..cfe0fdf87 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -18,6 +18,7 @@ from collections import deque import itertools import typing as T from functools import lru_cache +import enum from ..linkers import ( GnuLikeDynamicLinkerMixin, LinkerEnvVarsMixin, SolarisDynamicLinker, @@ -409,6 +410,28 @@ class RunResult: self.stdout = stdout self.stderr = stderr + +class Dedup(enum.Enum): + + """What kind of deduplication can be done to compiler args. + + OVERRIDEN - Whether an argument can be 'overridden' by a later argument. + For example, -DFOO defines FOO and -UFOO undefines FOO. In this case, + we can safely remove the previous occurrence and add a new one. The + same is true for include paths and library paths with -I and -L. + UNIQUE - Arguments that once specified cannot be undone, such as `-c` or + `-pipe`. New instances of these can be completely skipped. + NO_DEDUP - Whether it matters where or how many times on the command-line + a particular argument is present. This can matter for symbol + resolution in static or shared libraries, so we cannot de-dup or + reorder them. + """ + + NO_DEDUP = 0 + UNIQUE = 1 + OVERRIDEN = 2 + + class CompilerArgs(collections.abc.MutableSequence): ''' List-like class that manages a list of compiler arguments. Should be used @@ -486,13 +509,13 @@ class CompilerArgs(collections.abc.MutableSequence): dedup = self._can_dedup(a) if a not in pre_flush_set: pre_flush.append(a) - if dedup == 2: + if dedup is Dedup.OVERRIDEN: pre_flush_set.add(a) for a in reversed(self.post): dedup = self._can_dedup(a) if a not in post_flush_set: post_flush.appendleft(a) - if dedup == 2: + if dedup is Dedup.OVERRIDEN: post_flush_set.add(a) #pre and post will overwrite every element that is in the container @@ -551,29 +574,15 @@ class CompilerArgs(collections.abc.MutableSequence): @classmethod @lru_cache(maxsize=None) - def _can_dedup(cls, arg): - ''' - Returns whether the argument can be safely de-duped. This is dependent - on three things: - - a) Whether an argument can be 'overridden' by a later argument. For - example, -DFOO defines FOO and -UFOO undefines FOO. In this case, we - can safely remove the previous occurrence and add a new one. The same - is true for include paths and library paths with -I and -L. For - these we return `2`. See `dedup2_prefixes` and `dedup2_args`. - b) Arguments that once specified cannot be undone, such as `-c` or - `-pipe`. New instances of these can be completely skipped. For these - we return `1`. See `dedup1_prefixes` and `dedup1_args`. - c) Whether it matters where or how many times on the command-line - a particular argument is present. This can matter for symbol - resolution in static or shared libraries, so we cannot de-dup or - reorder them. For these we return `0`. This is the default. + def _can_dedup(cls, arg: str) -> Dedup: + """Returns whether the argument can be safely de-duped. In addition to these, we handle library arguments specially. - With GNU ld, we surround library arguments with -Wl,--start/end-group + With GNU ld, we surround library arguments with -Wl,--start/end-gr -> Dedupoup to recursively search for symbols in the libraries. This is not needed with other linkers. - ''' + """ + # A standalone argument must never be deduplicated because it is # defined by what comes _after_ it. Thus dedupping this: # -D FOO -D BAR @@ -583,7 +592,7 @@ class CompilerArgs(collections.abc.MutableSequence): # FOO -D BAR # both of which are invalid. if arg in cls.dedup2_prefixes: - return 0 + return Dedup.NO_DEDUP if arg.startswith('-L='): # DMD and LDC proxy all linker arguments using -L=; in conjunction # with ld64 on macOS this can lead to command line arguments such @@ -592,17 +601,17 @@ class CompilerArgs(collections.abc.MutableSequence): # spaces and quoting does not work. if we deduplicate these then # one of the -L=0 arguments will be removed and the version # argument will consume the next argument instead. - return 0 + return Dedup.NO_DEDUP if arg in cls.dedup2_args or \ arg.startswith(cls.dedup2_prefixes) or \ arg.endswith(cls.dedup2_suffixes): - return 2 + return Dedup.OVERRIDEN if arg in cls.dedup1_args or \ arg.startswith(cls.dedup1_prefixes) or \ arg.endswith(cls.dedup1_suffixes) or \ re.search(cls.dedup1_regex, arg): - return 1 - return 0 + return Dedup.UNIQUE + return Dedup.NO_DEDUP @classmethod @lru_cache(maxsize=None) @@ -725,7 +734,7 @@ class CompilerArgs(collections.abc.MutableSequence): # previous occurrence of it and adding a new one, or not adding the # new occurrence. dedup = self._can_dedup(arg) - if dedup == 1: + if dedup is Dedup.UNIQUE: # Argument already exists and adding a new instance is useless if arg in self.__container or arg in self.pre or arg in self.post: continue