diff options
author | Norbert Nemec <norbert.nemec@outlook.de> | 2019-07-07 22:12:54 +0200 |
---|---|---|
committer | Jussi Pakkanen <jpakkane@gmail.com> | 2019-07-07 23:12:54 +0300 |
commit | cc3993d1d484f486c3dff162272a90272cb60ba9 (patch) | |
tree | 3700f06c968621e00f9beb6427d5aff289d6a42d /mesonbuild/compilers/compilers.py | |
parent | 85cc424712d4ff8f956a7fca442ac9eb7b420ba2 (diff) | |
download | meson-cc3993d1d484f486c3dff162272a90272cb60ba9.zip meson-cc3993d1d484f486c3dff162272a90272cb60ba9.tar.gz meson-cc3993d1d484f486c3dff162272a90272cb60ba9.tar.bz2 |
move Gnu-specific feature '--print-search-dirs' to GnuLikeCompiler
Diffstat (limited to 'mesonbuild/compilers/compilers.py')
-rw-r--r-- | mesonbuild/compilers/compilers.py | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 50225c0..8800923 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -13,8 +13,10 @@ # limitations under the License. import abc, contextlib, enum, os.path, re, tempfile, shlex +import functools import subprocess from typing import List, Optional, Tuple +from pathlib import Path from ..linkers import StaticLinker from .. import coredata @@ -2005,6 +2007,64 @@ class GnuLikeCompiler(abc.ABC): return parameter_list + @functools.lru_cache() + def _get_search_dirs(self, env): + extra_args = ['--print-search-dirs'] + stdo = None + with self._build_wrapper('', env, extra_args=extra_args, + dependencies=None, mode='compile', + want_output=True) as p: + stdo = p.stdo + return stdo + + def _split_fetch_real_dirs(self, pathstr): + # We need to use the path separator used by the compiler for printing + # lists of paths ("gcc --print-search-dirs"). By default + # we assume it uses the platform native separator. + pathsep = os.pathsep + + # clang uses ':' instead of ';' on Windows https://reviews.llvm.org/D61121 + # so we need to repair things like 'C:\foo:C:\bar' + if pathsep == ';': + pathstr = re.sub(r':([^/\\])', r';\1', pathstr) + + # pathlib treats empty paths as '.', so filter those out + paths = [p for p in pathstr.split(pathsep) if p] + + result = [] + for p in paths: + # GCC returns paths like this: + # /usr/lib/gcc/x86_64-linux-gnu/8/../../../../x86_64-linux-gnu/lib + # It would make sense to normalize them to get rid of the .. parts + # Sadly when you are on a merged /usr fs it also kills these: + # /lib/x86_64-linux-gnu + # since /lib is a symlink to /usr/lib. This would mean + # paths under /lib would be considered not a "system path", + # which is wrong and breaks things. Store everything, just to be sure. + pobj = Path(p) + unresolved = pobj.as_posix() + if pobj.exists(): + if unresolved not in result: + result.append(unresolved) + try: + resolved = Path(p).resolve().as_posix() + if resolved not in result: + result.append(resolved) + except FileNotFoundError: + pass + return tuple(result) + + def get_compiler_dirs(self, env, name): + ''' + Get dirs from the compiler, either `libraries:` or `programs:` + ''' + stdo = self._get_search_dirs(env) + for line in stdo.split('\n'): + if line.startswith(name + ':'): + return self._split_fetch_real_dirs(line.split('=', 1)[1]) + return () + + class GnuCompiler(GnuLikeCompiler): """ GnuCompiler represents an actual GCC in its many incarnations. |