aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFFY00 <filipe.lains@gmail.com>2018-08-25 23:33:20 +0100
committerFFY00 <filipe.lains@gmail.com>2018-08-29 20:22:01 +0100
commit124cedde38de07b1b166cb0e74b74e8b16eb9432 (patch)
tree94dd44bc1511d8350c6311c0f8a5f007291a8a31
parentb86f2fd17f1f0825e16b1df2b1f3f598c0d77b85 (diff)
downloadmeson-124cedde38de07b1b166cb0e74b74e8b16eb9432.zip
meson-124cedde38de07b1b166cb0e74b74e8b16eb9432.tar.gz
meson-124cedde38de07b1b166cb0e74b74e8b16eb9432.tar.bz2
dub: enhance dependency handling
fixes #4032: meson now checks properly for the compiler used to compile dub dependencies fixes #3568: applied the following patch https://paste.debian.net/1039317/ meson now adds flags for native dependencies required by dub modules meson now checks for the D version implemented by the compiler used to build dub dependencies (execpt gdc which doesn't support this)
-rw-r--r--mesonbuild/compilers/d.py9
-rw-r--r--mesonbuild/dependencies/base.py125
2 files changed, 106 insertions, 28 deletions
diff --git a/mesonbuild/compilers/d.py b/mesonbuild/compilers/d.py
index a03af3e..7398301 100644
--- a/mesonbuild/compilers/d.py
+++ b/mesonbuild/compilers/d.py
@@ -95,6 +95,9 @@ class DCompiler(Compiler):
def name_string(self):
return ' '.join(self.exelist)
+ def get_exelist(self):
+ return self.exelist
+
def get_linker_exelist(self):
return self.exelist[:]
@@ -294,6 +297,11 @@ class DCompiler(Compiler):
# a linker search path.
dcargs.append('-L' + arg)
continue
+ elif arg.startswith('/') or arg.startswith('./'):
+ # absolute (or relative) paths passed to the linker may be static libraries
+ # or other objects that we need to link.
+ dcargs.append('-L' + arg)
+ continue
elif arg.startswith('-mscrtlib='):
mscrtlib = arg[10:].lower()
@@ -309,6 +317,7 @@ class DCompiler(Compiler):
dcargs.append('-L/DEFAULTLIB:legacy_stdio_definitions.lib')
dcargs.append(arg)
+
continue
dcargs.append(arg)
diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py
index 04c4701..e375f10 100644
--- a/mesonbuild/dependencies/base.py
+++ b/mesonbuild/dependencies/base.py
@@ -24,6 +24,7 @@ import json
import shlex
import shutil
import textwrap
+import platform
from enum import Enum
from pathlib import PurePath
@@ -849,12 +850,13 @@ class DubDependency(ExternalDependency):
super().__init__('dub', environment, 'd', kwargs)
self.name = name
self.compiler = super().get_compiler()
+ self.module_path = None
if 'required' in kwargs:
self.required = kwargs.get('required')
if DubDependency.class_dubbin is None:
- self.dubbin = self.check_dub()
+ self.dubbin = self._check_dub()
DubDependency.class_dubbin = self.dubbin
else:
self.dubbin = DubDependency.class_dubbin
@@ -875,20 +877,33 @@ class DubDependency(ExternalDependency):
self.is_found = False
return
- j = json.loads(res)
comp = self.compiler.get_id().replace('llvm', 'ldc').replace('gcc', 'gdc')
+ packages = []
+ j = json.loads(res)
for package in j['packages']:
+ packages.append(package['name'])
if package['name'] == name:
- if j['compiler'] != comp:
- msg = ['Dependency', mlog.bold(name), 'found but it was compiled with']
- msg += [mlog.bold(j['compiler']), 'and we are using', mlog.bold(comp)]
- mlog.error(*msg)
+ self.is_found = True
+
+ not_lib = True
+ if 'targetType' in package:
+ if package['targetType'] == 'library':
+ not_lib = False
+
+ if not_lib:
+ mlog.error(mlog.bold(name), 'found but it isn\'t a library')
+ self.is_found = False
+ return
+
+ self.module_path = self._find_right_lib_path(package['path'], comp, j, True, package['targetFileName'])
+
+ if not os.path.exists(self.module_path):
+ mlog.error(mlog.bold(name), 'found but it wasn\'t compiled with', mlog.bold(comp))
self.is_found = False
return
self.version = package['version']
self.pkg = package
- break
if self.pkg['targetFileName'].endswith('.a'):
self.static = True
@@ -899,39 +914,93 @@ class DubDependency(ExternalDependency):
for path in self.pkg['importPaths']:
self.compile_args.append('-I' + os.path.join(self.pkg['path'], path))
- self.link_args = []
+ self.link_args = self.raw_link_args = []
for flag in self.pkg['lflags']:
self.link_args.append(flag)
- search_paths = []
- search_paths.append(os.path.join(self.pkg['path'], self.pkg['targetPath']))
- found, res = self.__search_paths(search_paths, self.pkg['targetFileName'])
- for file in res:
- self.link_args.append(file)
-
- self.is_found = found
+ self.link_args.append(os.path.join(self.module_path, self.pkg['targetFileName']))
+
+ # Handle dependencies
+ libs = []
+
+ def add_lib_args(field_name, target):
+ if field_name in target['buildSettings']:
+ if os.name is 'nt':
+ for lib in target['buildSettings'][field_name]:
+ if lib not in target['buildSettings'][field_name]:
+ libs.append(lib)
+ # TODO: Use CCompiler.find_library to find the path of the .lib files
+ else: # posix and everything else
+ for lib in target['buildSettings'][field_name]:
+ if lib not in libs:
+ libs.append(lib)
+ pkgdep = PkgConfigDependency(lib, environment, {'required': 'true', 'silent': 'true'})
+ for arg in pkgdep.get_compile_args():
+ self.compile_args.append(arg)
+ for arg in pkgdep.get_link_args():
+ self.link_args.append(arg)
+ for arg in pkgdep.get_link_args(raw=True):
+ self.raw_link_args.append(arg)
+
+ for target in j['targets']:
+ if target['rootPackage'] in packages:
+ add_lib_args('libs', target)
+ add_lib_args('libs-{}'.format(platform.machine()), target)
+ for file in target['buildSettings']['linkerFiles']:
+ self.link_args.append(self._find_right_lib_path(file, comp, j))
def get_compiler(self):
return self.compiler
- def __search_paths(self, search_paths, target_file):
- found = False
- res = []
- if target_file == '':
- return True, res
- for path in search_paths:
- if os.path.isdir(path):
- for file in os.listdir(path):
- if file == target_file:
- res.append(os.path.join(path, file))
- found = True
- return found, res
+ def _find_right_lib_path(self, default_path, comp, j, folder_only=False, file_name=''):
+ path = ''
+
+ module_build_path = lib_file_name = ''
+ if folder_only:
+ module_build_path = default_path
+ lib_file_name = file_name
+ else:
+ module_build_path = os.path.dirname(default_path)
+ lib_file_name = os.path.basename(default_path)
+
+ # Get D version implemented in the compiler
+ # gdc doesn't support this
+ ret, res = self._call_dubbin(['--version'])
+
+ if ret != 0:
+ mlog.error('Failed to run {!r}', mlog.bold(comp))
+ self.is_found = False
+ return
+
+ d_ver = re.search('v[0-9].[0-9][0-9][0-9].[0-9]', res) # Ex.: v2.081.2
+ if d_ver is not None:
+ d_ver = d_ver.group().rsplit('.', 1)[0].replace('v', '').replace('.', '') # Fix structure. Ex.: 2081
+ else:
+ d_ver = '' # gdc
+
+ # Ex.: library-debug-linux.posix-x86_64-ldc_2081-EF934983A3319F8F8FF2F0E107A363BA
+ build_name = 'library-{}-{}.{}-{}-{}_{}'.format(j['buildType'], j['platform'][0], j['platform'][1], platform.machine(), comp, d_ver)
+ for entry in os.listdir(os.path.join(module_build_path, '.dub', 'build')):
+ if entry.startswith(build_name):
+ for file in os.listdir(os.path.join(module_build_path, '.dub', 'build', entry)):
+ if file == lib_file_name:
+ if folder_only:
+ path = os.path.join(module_build_path, '.dub', 'build', entry)
+ else:
+ path = os.path.join(module_build_path, '.dub', 'build', entry, lib_file_name)
+ break
+
+ return path
def _call_dubbin(self, args, env=None):
p, out = Popen_safe(self.dubbin.get_command() + args, env=env)[0:2]
return p.returncode, out.strip()
- def check_dub(self):
+ def _call_copmbin(self, args, env=None):
+ p, out = Popen_safe(self.compiler.get_exelist() + args, env=env)[0:2]
+ return p.returncode, out.strip()
+
+ def _check_dub(self):
dubbin = ExternalProgram('dub', silent=True)
if dubbin.found():
try: