aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/compilers/compilers.py
diff options
context:
space:
mode:
authorNorbert Nemec <norbert.nemec@outlook.de>2019-07-07 22:12:54 +0200
committerJussi Pakkanen <jpakkane@gmail.com>2019-07-07 23:12:54 +0300
commitcc3993d1d484f486c3dff162272a90272cb60ba9 (patch)
tree3700f06c968621e00f9beb6427d5aff289d6a42d /mesonbuild/compilers/compilers.py
parent85cc424712d4ff8f956a7fca442ac9eb7b420ba2 (diff)
downloadmeson-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.py60
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.