aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2020-06-11 14:05:14 -0700
committerDylan Baker <dylan@pnwbakers.com>2020-06-22 12:06:10 -0700
commit4f6bd29ac9c697e042a2a808344f1db3efd1d6cb (patch)
treebe1735dfd7b12e3ffe5f7efe4d576fe4c62ec7a0 /mesonbuild
parent93c3ec7e2dd6d425baff5fd80e5a46c88d152cb0 (diff)
downloadmeson-4f6bd29ac9c697e042a2a808344f1db3efd1d6cb.zip
meson-4f6bd29ac9c697e042a2a808344f1db3efd1d6cb.tar.gz
meson-4f6bd29ac9c697e042a2a808344f1db3efd1d6cb.tar.bz2
arglist: Split the C/C++ specifics parts into a subclass for CLike
This means that we don't need work arounds for D-like compilers, as the special c-like hanlding wont be used for D compilers.
Diffstat (limited to 'mesonbuild')
-rw-r--r--mesonbuild/arglist.py93
-rw-r--r--mesonbuild/compilers/mixins/clike.py56
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: