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