Merge pull request #4084 from FFY00/pr-fix-dub-dependencies

dub: enhance dependency handling
pull/4055/merge
Jussi Pakkanen 6 years ago committed by GitHub
commit 9bcd498a2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      ciimage/Dockerfile
  2. 9
      mesonbuild/compilers/d.py
  3. 125
      mesonbuild/dependencies/base.py
  4. 3
      test cases/failing/85 dub libray/meson.build
  5. 3
      test cases/failing/86 dub executable/meson.build
  6. 3
      test cases/failing/87 dub compiler/meson.build

@ -13,9 +13,13 @@ RUN apt-get -y update && apt-get -y upgrade \
&& apt-get -y install python-dev \
&& apt-get -y install libomp-dev openssh-client \
&& apt-get -y install -y clang libclang-dev llvm-dev flex \
&& apt-get -y install gdc ldc \
&& python3 -m pip install hotdoc codecov \
&& dub fetch urld \
&& dub build urld --compiler=gdc
&& dub build urld --compiler=gdc \
&& dub fetch dubtestproject \
&& dub build dubtestproject:test1 --compiler=ldc2 \
&& dub build dubtestproject:test2 --compiler=ldc2
# OpenSSH client is needed to run openmpi binaries.

@ -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[:]
@ -292,6 +295,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()
@ -307,6 +315,7 @@ class DCompiler(Compiler):
dcargs.append('-L/DEFAULTLIB:legacy_stdio_definitions.lib')
dcargs.append(arg)
continue
dcargs.append(arg)

@ -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:

@ -0,0 +1,3 @@
project('dub', 'd', meson_version: '0.48.0')
dependency('dubtestproject', method: 'dub') # Not library (none)

@ -0,0 +1,3 @@
project('dub', 'd', meson_version: '0.48.0')
dependency('dubtestproject:test1', method: 'dub') # Not library (executable)

@ -0,0 +1,3 @@
project('dub', 'd', meson_version: '0.48.0')
dependency('dubtestproject:test2', method: 'dub') # Compiler mismatch
Loading…
Cancel
Save