diff options
-rw-r--r-- | mesonbuild/arglist.py | 93 | ||||
-rw-r--r-- | mesonbuild/compilers/mixins/clike.py | 56 |
2 files changed, 71 insertions, 78 deletions
diff --git a/mesonbuild/arglist.py b/mesonbuild/arglist.py index dcc670b..bb16f38 100644 --- a/mesonbuild/arglist.py +++ b/mesonbuild/arglist.py @@ -31,7 +31,6 @@ UNIXY_COMPILER_INTERNAL_LIBS = ['m', 'c', 'pthread', 'dl', 'rt'] # type: T.List # execinfo is a compiler lib on FreeBSD and NetBSD if mesonlib.is_freebsd() or mesonlib.is_netbsd(): UNIXY_COMPILER_INTERNAL_LIBS.append('execinfo') -SOREGEX = re.compile(r'.*\.so(\.[0-9]+)?(\.[0-9]+)?(\.[0-9]+)?$') class Dedup(enum.Enum): @@ -112,11 +111,11 @@ class CompilerArgs(collections.abc.MutableSequence): def __init__(self, compiler: T.Union['Compiler', 'StaticLinker'], iterable: T.Optional[T.Iterable[str]] = None): self.compiler = compiler - self.__container = list(iterable) if iterable is not None else [] # type: T.List[str] + self._container = list(iterable) if iterable is not None else [] # type: T.List[str] self.pre = collections.deque() # type: T.Deque[str] self.post = collections.deque() # type: T.Deque[str] - # Flush the saved pre and post list into the __container list + # Flush the saved pre and post list into the _container list # # This correctly deduplicates the entries after _can_dedup definition # Note: This function is designed to work without delete operations, as deletions are worsening the performance a lot. @@ -141,19 +140,19 @@ class CompilerArgs(collections.abc.MutableSequence): post_flush_set.add(a) #pre and post will overwrite every element that is in the container - #only copy over args that are in __container but not in the post flush or pre flush set + #only copy over args that are in _container but not in the post flush or pre flush set - for a in self.__container: + for a in self._container: if a not in post_flush_set and a not in pre_flush_set: pre_flush.append(a) - self.__container = list(pre_flush) + list(post_flush) + self._container = list(pre_flush) + list(post_flush) self.pre.clear() self.post.clear() def __iter__(self) -> T.Iterator[str]: self.flush_pre_post() - return iter(self.__container) + return iter(self._container) @T.overload # noqa: F811 def __getitem__(self, index: int) -> str: # noqa: F811 @@ -165,7 +164,7 @@ class CompilerArgs(collections.abc.MutableSequence): def __getitem__(self, index): # noqa: F811 self.flush_pre_post() - return self.__container[index] + return self._container[index] @T.overload # noqa: F811 def __setitem__(self, index: int, value: str) -> None: # noqa: F811 @@ -177,22 +176,22 @@ class CompilerArgs(collections.abc.MutableSequence): def __setitem__(self, index, value) -> None: # noqa: F811 self.flush_pre_post() - self.__container[index] = value + self._container[index] = value def __delitem__(self, index: T.Union[int, slice]) -> None: self.flush_pre_post() - del self.__container[index] + del self._container[index] def __len__(self) -> int: - return len(self.__container) + len(self.pre) + len(self.post) + return len(self._container) + len(self.pre) + len(self.post) def insert(self, index: int, value: str) -> None: self.flush_pre_post() - self.__container.insert(index, value) + self._container.insert(index, value) def copy(self) -> 'CompilerArgs': self.flush_pre_post() - return type(self)(self.compiler, self.__container.copy()) + return type(self)(self.compiler, self._container.copy()) @classmethod @lru_cache(maxsize=None) @@ -231,16 +230,7 @@ class CompilerArgs(collections.abc.MutableSequence): def _should_prepend(cls, arg: str) -> bool: return arg.startswith(cls.prepend_prefixes) - def need_to_split_linker_args(self) -> bool: - # XXX: gross - from .compilers import Compiler - return isinstance(self.compiler, Compiler) and self.compiler.get_language() == 'd' - def to_native(self, copy: bool = False) -> T.List[str]: - # XXX: gross - from .compilers import Compiler - from .linkers import GnuLikeDynamicLinkerMixin, SolarisDynamicLinker - # Check if we need to add --start/end-group for circular dependencies # between static libraries, and for recursively searching for symbols # needed by static libraries that are provided by object files or @@ -250,54 +240,7 @@ class CompilerArgs(collections.abc.MutableSequence): new = self.copy() else: new = self - # To proxy these arguments with D you need to split the - # arguments, thus you get `-L=-soname -L=lib.so` we don't - # want to put the lib in a link -roup - split_linker_args = self.need_to_split_linker_args() - # This covers all ld.bfd, ld.gold, ld.gold, and xild on Linux, which - # all act like (or are) gnu ld - # TODO: this could probably be added to the DynamicLinker instead - if (isinstance(self.compiler, Compiler) and - self.compiler.linker is not None and - isinstance(self.compiler.linker, (GnuLikeDynamicLinkerMixin, SolarisDynamicLinker))): - group_start = -1 - group_end = -1 - is_soname = False - for i, each in enumerate(new): - if is_soname: - is_soname = False - continue - elif split_linker_args and '-soname' in each: - is_soname = True - continue - if not each.startswith(('-Wl,-l', '-l')) and not each.endswith('.a') and \ - not SOREGEX.match(each): - continue - group_end = i - if group_start < 0: - # First occurrence of a library - group_start = i - if group_start >= 0: - # Last occurrence of a library - new.insert(group_end + 1, '-Wl,--end-group') - new.insert(group_start, '-Wl,--start-group') - # Remove system/default include paths added with -isystem - if hasattr(self.compiler, 'get_default_include_dirs'): - default_dirs = self.compiler.get_default_include_dirs() - bad_idx_list = [] # type: T.List[int] - for i, each in enumerate(new): - # Remove the -isystem and the path if the path is a default path - if (each == '-isystem' and - i < (len(new) - 1) and - new[i + 1] in default_dirs): - bad_idx_list += [i, i + 1] - elif each.startswith('-isystem=') and each[9:] in default_dirs: - bad_idx_list += [i] - elif each.startswith('-isystem') and each[8:] in default_dirs: - bad_idx_list += [i] - for i in reversed(bad_idx_list): - new.pop(i) - return self.compiler.unix_args_to_native(new.__container) + return self.compiler.unix_args_to_native(new._container) def append_direct(self, arg: str) -> None: ''' @@ -309,7 +252,7 @@ class CompilerArgs(collections.abc.MutableSequence): if os.path.isabs(arg): self.append(arg) else: - self.__container.append(arg) + self._container.append(arg) def extend_direct(self, iterable: T.Iterable[str]) -> None: ''' @@ -353,7 +296,7 @@ class CompilerArgs(collections.abc.MutableSequence): dedup = self._can_dedup(arg) 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: + if arg in self._container or arg in self.pre or arg in self.post: continue if self._should_prepend(arg): tmp_pre.appendleft(arg) @@ -373,9 +316,9 @@ class CompilerArgs(collections.abc.MutableSequence): self.flush_pre_post() # Only allow equality checks against other CompilerArgs and lists instances if isinstance(other, CompilerArgs): - return self.compiler == other.compiler and self.__container == other.__container + return self.compiler == other.compiler and self._container == other._container elif isinstance(other, list): - return self.__container == other + return self._container == other return NotImplemented def append(self, arg: str) -> None: @@ -386,4 +329,4 @@ class CompilerArgs(collections.abc.MutableSequence): def __repr__(self) -> str: self.flush_pre_post() - return '{}({!r}, {!r})'.format(self.__name__, self.compiler, self.__container) + return 'CompilerArgs({!r}, {!r})'.format(self.compiler, self._container) diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py index 455fbe2..47e97d2 100644 --- a/mesonbuild/compilers/mixins/clike.py +++ b/mesonbuild/compilers/mixins/clike.py @@ -32,7 +32,7 @@ from pathlib import Path from ... import arglist from ... import mesonlib from ... import mlog -from ...arglist import CompilerArgs +from ...linkers import GnuLikeDynamicLinkerMixin, SolarisDynamicLinker from ...mesonlib import LibType from .. import compilers from .visualstudio import VisualStudioLikeCompiler @@ -40,8 +40,9 @@ from .visualstudio import VisualStudioLikeCompiler if T.TYPE_CHECKING: from ...environment import Environment +SOREGEX = re.compile(r'.*\.so(\.[0-9]+)?(\.[0-9]+)?(\.[0-9]+)?$') -class CLikeCompilerArgs(CompilerArgs): +class CLikeCompilerArgs(arglist.CompilerArgs): prepend_prefixes = ('-I', '-L') dedup2_prefixes = ('-I', '-isystem', '-L', '-D', '-U') @@ -49,9 +50,58 @@ class CLikeCompilerArgs(CompilerArgs): # https://github.com/mesonbuild/meson/pull/4593#pullrequestreview-182016038 dedup1_prefixes = ('-l', '-Wl,-l', '-Wl,--export-dynamic') dedup1_suffixes = ('.lib', '.dll', '.so', '.dylib', '.a') - dedup1_args = ('-c', '-S', '-E', '-pipe', '-pthread') + def to_native(self, copy: bool = False) -> T.List[str]: + # Check if we need to add --start/end-group for circular dependencies + # between static libraries, and for recursively searching for symbols + # needed by static libraries that are provided by object files or + # shared libraries. + self.flush_pre_post() + if copy: + new = self.copy() + else: + new = self + # This covers all ld.bfd, ld.gold, ld.gold, and xild on Linux, which + # all act like (or are) gnu ld + # TODO: this could probably be added to the DynamicLinker instead + if isinstance(self.compiler.linker, (GnuLikeDynamicLinkerMixin, SolarisDynamicLinker)): + group_start = -1 + group_end = -1 + for i, each in enumerate(new): + if not each.startswith(('-Wl,-l', '-l')) and not each.endswith('.a') and \ + not SOREGEX.match(each): + continue + group_end = i + if group_start < 0: + # First occurrence of a library + group_start = i + if group_start >= 0: + # Last occurrence of a library + new.insert(group_end + 1, '-Wl,--end-group') + new.insert(group_start, '-Wl,--start-group') + # Remove system/default include paths added with -isystem + if hasattr(self.compiler, 'get_default_include_dirs'): + default_dirs = self.compiler.get_default_include_dirs() + bad_idx_list = [] # type: T.List[int] + for i, each in enumerate(new): + # Remove the -isystem and the path if the path is a default path + if (each == '-isystem' and + i < (len(new) - 1) and + new[i + 1] in default_dirs): + bad_idx_list += [i, i + 1] + elif each.startswith('-isystem=') and each[9:] in default_dirs: + bad_idx_list += [i] + elif each.startswith('-isystem') and each[8:] in default_dirs: + bad_idx_list += [i] + for i in reversed(bad_idx_list): + new.pop(i) + return self.compiler.unix_args_to_native(new._container) + + def __repr__(self) -> str: + self.flush_pre_post() + return 'CLikeCompilerArgs({!r}, {!r})'.format(self.compiler, self._container) + class CLikeCompiler: |