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.
pull/3695/head
Nirbheek Chauhan 7 years ago committed by Nirbheek Chauhan
parent bc4dd5e201
commit ad0121d259
  1. 19
      mesonbuild/backend/backends.py
  2. 27
      mesonbuild/compilers/c.py
  3. 18
      mesonbuild/compilers/compilers.py

@ -20,7 +20,7 @@ from .. import mlog
from .. import compilers from .. import compilers
import json import json
import subprocess import subprocess
from ..mesonlib import MesonException from ..mesonlib import MesonException, OrderedSet
from ..mesonlib import get_compiler_for_source, classify_unity_sources from ..mesonlib import get_compiler_for_source, classify_unity_sources
from ..mesonlib import File from ..mesonlib import File
from ..compilers import CompilerArgs from ..compilers import CompilerArgs
@ -567,17 +567,22 @@ class Backend:
args.append(d_arg) args.append(d_arg)
return args return args
def get_mingw_extra_paths(self): def get_mingw_extra_paths(self, target):
paths = [] paths = OrderedSet()
# The cross bindir # The cross bindir
root = self.environment.cross_info.get_root() root = self.environment.cross_info.get_root()
if root: if root:
paths.append(os.path.join(root, 'bin')) paths.add(os.path.join(root, 'bin'))
# The toolchain bindir # The toolchain bindir
sys_root = self.environment.cross_info.get_sys_root() sys_root = self.environment.cross_info.get_sys_root()
if sys_root: if sys_root:
paths.append(os.path.join(sys_root, 'bin')) paths.add(os.path.join(sys_root, 'bin'))
return paths # 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): def determine_windows_extra_paths(self, target, extra_bdeps, is_cross=False):
'''On Windows there is no such thing as an rpath. '''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)) dirseg = os.path.join(self.environment.get_build_dir(), self.get_target_dir(ld))
result.add(dirseg) result.add(dirseg)
if is_cross: if is_cross:
result.update(self.get_mingw_extra_paths()) result.update(self.get_mingw_extra_paths(target))
return list(result) return list(result)
def write_benchmark_file(self, datafile): def write_benchmark_file(self, datafile):

@ -45,6 +45,7 @@ from .compilers import (
class CCompiler(Compiler): class CCompiler(Compiler):
library_dirs_cache = {} library_dirs_cache = {}
program_dirs_cache = {}
def __init__(self, exelist, version, is_cross, exe_wrapper=None, **kwargs): 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 # 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 = os.environ.copy()
env['LC_ALL'] = 'C' env['LC_ALL'] = 'C'
stdo = Popen_safe(self.exelist + ['--print-search-dirs'], env=env)[1] stdo = Popen_safe(self.exelist + ['--print-search-dirs'], env=env)[1]
paths = []
for line in stdo.split('\n'): for line in stdo.split('\n'):
if line.startswith('libraries:'): if line.startswith('libraries:'):
libstr = line.split('=', 1)[1] libstr = line.split('=', 1)[1]
return libstr.split(':') paths = [os.path.realpath(p) for p in libstr.split(':')]
return [] return paths
def get_library_dirs(self): def get_library_dirs(self):
key = tuple(self.exelist) key = tuple(self.exelist)
@ -178,6 +180,27 @@ class CCompiler(Compiler):
self.library_dirs_cache[key] = self.get_library_dirs_real() self.library_dirs_cache[key] = self.get_library_dirs_real()
return self.library_dirs_cache[key][:] 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): def get_pic_args(self):
return ['-fPIC'] return ['-fPIC']

@ -1172,13 +1172,27 @@ class ElbrusCompiler(GnuCompiler):
env = os.environ.copy() env = os.environ.copy()
env['LC_ALL'] = 'C' env['LC_ALL'] = 'C'
stdo = Popen_safe(self.exelist + ['--print-search-dirs'], env=env)[1] stdo = Popen_safe(self.exelist + ['--print-search-dirs'], env=env)[1]
paths = []
for line in stdo.split('\n'): for line in stdo.split('\n'):
if line.startswith('libraries:'): if line.startswith('libraries:'):
# lcc does not include '=' in --print-search-dirs output. # lcc does not include '=' in --print-search-dirs output.
libstr = line.split(' ', 1)[1] libstr = line.split(' ', 1)[1]
return libstr.split(':') paths = [os.path.realpath(p) for p in libstr.split(':')]
return [] 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: class ClangCompiler:

Loading…
Cancel
Save