From de85f5c689467499c104e9296dbef7f3bc2232c4 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Sun, 3 Jun 2018 18:10:54 +0530 Subject: Add prog/lib dirs from the mingw cross-compiler to PATH These directories contain DLLs that the executable may need, such as libstdc++-6.dll, libwinpthread, etc. --- mesonbuild/backend/backends.py | 19 ++++++++++++------- mesonbuild/compilers/c.py | 27 +++++++++++++++++++++++++-- mesonbuild/compilers/compilers.py | 18 ++++++++++++++++-- 3 files changed, 53 insertions(+), 11 deletions(-) diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index d02f2ddbe..7a50431bf 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -20,7 +20,7 @@ from .. import mlog from .. import compilers import json import subprocess -from ..mesonlib import MesonException +from ..mesonlib import MesonException, OrderedSet from ..mesonlib import get_compiler_for_source, classify_unity_sources from ..mesonlib import File from ..compilers import CompilerArgs @@ -567,17 +567,22 @@ class Backend: args.append(d_arg) return args - def get_mingw_extra_paths(self): - paths = [] + def get_mingw_extra_paths(self, target): + paths = OrderedSet() # The cross bindir root = self.environment.cross_info.get_root() if root: - paths.append(os.path.join(root, 'bin')) + paths.add(os.path.join(root, 'bin')) # The toolchain bindir sys_root = self.environment.cross_info.get_sys_root() if sys_root: - paths.append(os.path.join(sys_root, 'bin')) - return paths + paths.add(os.path.join(sys_root, 'bin')) + # Get program and library dirs from all target compilers + if isinstance(target, build.BuildTarget): + for cc in target.compilers.values(): + paths.update(cc.get_program_dirs()) + paths.update(cc.get_library_dirs()) + return list(paths) def determine_windows_extra_paths(self, target, extra_bdeps, is_cross=False): '''On Windows there is no such thing as an rpath. @@ -600,7 +605,7 @@ class Backend: dirseg = os.path.join(self.environment.get_build_dir(), self.get_target_dir(ld)) result.add(dirseg) if is_cross: - result.update(self.get_mingw_extra_paths()) + result.update(self.get_mingw_extra_paths(target)) return list(result) def write_benchmark_file(self, datafile): diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py index 4cc966054..354124ab2 100644 --- a/mesonbuild/compilers/c.py +++ b/mesonbuild/compilers/c.py @@ -45,6 +45,7 @@ from .compilers import ( class CCompiler(Compiler): library_dirs_cache = {} + program_dirs_cache = {} def __init__(self, exelist, version, is_cross, exe_wrapper=None, **kwargs): # If a child ObjC or CPP class has already set it, don't set it ourselves @@ -166,11 +167,12 @@ class CCompiler(Compiler): env = os.environ.copy() env['LC_ALL'] = 'C' stdo = Popen_safe(self.exelist + ['--print-search-dirs'], env=env)[1] + paths = [] for line in stdo.split('\n'): if line.startswith('libraries:'): libstr = line.split('=', 1)[1] - return libstr.split(':') - return [] + paths = [os.path.realpath(p) for p in libstr.split(':')] + return paths def get_library_dirs(self): key = tuple(self.exelist) @@ -178,6 +180,27 @@ class CCompiler(Compiler): self.library_dirs_cache[key] = self.get_library_dirs_real() return self.library_dirs_cache[key][:] + def get_program_dirs_real(self): + env = os.environ.copy() + env['LC_ALL'] = 'C' + stdo = Popen_safe(self.exelist + ['--print-search-dirs'], env=env)[1] + paths = [] + for line in stdo.split('\n'): + if line.startswith('programs:'): + libstr = line.split('=', 1)[1] + paths = [os.path.realpath(p) for p in libstr.split(':')] + return paths + + def get_program_dirs(self): + ''' + Programs used by the compiler. Also where toolchain DLLs such as + libstdc++-6.dll are found with MinGW. + ''' + key = tuple(self.exelist) + if key not in self.program_dirs_cache: + self.program_dirs_cache[key] = self.get_program_dirs_real() + return self.program_dirs_cache[key][:] + def get_pic_args(self): return ['-fPIC'] diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index c5f7df3dd..9bd9bb231 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -1172,13 +1172,27 @@ class ElbrusCompiler(GnuCompiler): env = os.environ.copy() env['LC_ALL'] = 'C' stdo = Popen_safe(self.exelist + ['--print-search-dirs'], env=env)[1] + paths = [] for line in stdo.split('\n'): if line.startswith('libraries:'): # lcc does not include '=' in --print-search-dirs output. libstr = line.split(' ', 1)[1] - return libstr.split(':') - return [] + paths = [os.path.realpath(p) for p in libstr.split(':')] + break + return paths + def get_program_dirs(self): + env = os.environ.copy() + env['LC_ALL'] = 'C' + stdo = Popen_safe(self.exelist + ['--print-search-dirs'], env=env)[1] + paths = [] + for line in stdo.split('\n'): + if line.startswith('programs:'): + # lcc does not include '=' in --print-search-dirs output. + libstr = line.split(' ', 1)[1] + paths = [os.path.realpath(p) for p in libstr.split(':')] + break + return paths class ClangCompiler: -- cgit v1.2.1