dependencies: Use a DependencyFactory for threads

This lets us make a number of uses of threads safer, because we can use
the threads_factory instead of the ThreadDependency
This commit is contained in:
Dylan Baker 2020-01-09 11:33:06 -08:00
parent 5d630c663c
commit fbad73c939
6 changed files with 42 additions and 43 deletions

View File

@ -24,7 +24,7 @@ from .dev import ValgrindDependency, gmock_factory, gtest_factory, llvm_factory
from .coarrays import CoarrayDependency from .coarrays import CoarrayDependency
from .mpi import MPIDependency from .mpi import MPIDependency
from .scalapack import ScalapackDependency from .scalapack import ScalapackDependency
from .misc import (BlocksDependency, CursesDependency, OpenMPDependency, ThreadDependency, cups_factory, gpgme_factory, libgcrypt_factory, libwmf_factory, netcdf_factory, pcap_factory, python3_factory, shaderc_factory) from .misc import (BlocksDependency, CursesDependency, OpenMPDependency, cups_factory, gpgme_factory, libgcrypt_factory, libwmf_factory, netcdf_factory, pcap_factory, python3_factory, shaderc_factory, threads_factory)
from .platform import AppleFrameworks from .platform import AppleFrameworks
from .ui import GnuStepDependency, Qt4Dependency, Qt5Dependency, WxDependency, gl_factory, sdl2_factory, vulkan_factory from .ui import GnuStepDependency, Qt4Dependency, Qt5Dependency, WxDependency, gl_factory, sdl2_factory, vulkan_factory
@ -51,7 +51,7 @@ packages.update({
'netcdf': netcdf_factory, 'netcdf': netcdf_factory,
'openmp': OpenMPDependency, 'openmp': OpenMPDependency,
'python3': python3_factory, 'python3': python3_factory,
'threads': ThreadDependency, 'threads': threads_factory,
'pcap': pcap_factory, 'pcap': pcap_factory,
'cups': cups_factory, 'cups': cups_factory,
'libwmf': libwmf_factory, 'libwmf': libwmf_factory,

View File

@ -195,8 +195,8 @@ class Dependency:
return True return True
return False return False
def _add_sub_dependency(self, dep_type: T.Type['Dependency'], env: Environment, def _add_sub_dependency(self, dep_type: T.Type['Dependency'], name: str,
kwargs: T.Dict[str, T.Any], *, env: Environment, kwargs: T.Dict[str, T.Any], *,
method: DependencyMethods = DependencyMethods.AUTO) -> None: method: DependencyMethods = DependencyMethods.AUTO) -> None:
"""Add an internal dependency of of the given type. """Add an internal dependency of of the given type.
@ -207,7 +207,7 @@ class Dependency:
""" """
kwargs = kwargs.copy() kwargs = kwargs.copy()
kwargs['method'] = method kwargs['method'] = method
self.ext_deps.append(dep_type(env, kwargs)) self.ext_deps.append(dep_type(name, env, kwargs))
def get_variable(self, *, cmake: T.Optional[str] = None, pkgconfig: T.Optional[str] = None, def get_variable(self, *, cmake: T.Optional[str] = None, pkgconfig: T.Optional[str] = None,
configtool: T.Optional[str] = None, internal: T.Optional[str] = None, configtool: T.Optional[str] = None, internal: T.Optional[str] = None,

View File

@ -22,7 +22,7 @@ from .. import mesonlib
from ..environment import detect_cpu_family from ..environment import detect_cpu_family
from .base import (DependencyException, ExternalDependency) from .base import (DependencyException, ExternalDependency)
from .misc import ThreadDependency from .misc import threads_factory
# On windows 3 directory layouts are supported: # On windows 3 directory layouts are supported:
# * The default layout (versioned) installed: # * The default layout (versioned) installed:
@ -105,7 +105,9 @@ class BoostDependency(ExternalDependency):
self.requested_modules = self.get_requested(kwargs) self.requested_modules = self.get_requested(kwargs)
if 'thread' in self.requested_modules: if 'thread' in self.requested_modules:
self._add_sub_dependency(ThreadDependency, environment, kwargs) if not self._add_sub_dependency2(threads_factory(environment, self.for_machine, {})):
self.is_found = False
return
self.boost_root = None self.boost_root = None
self.boost_roots = [] self.boost_roots = []

View File

@ -27,7 +27,7 @@ from .base import (
DependencyException, DependencyMethods, ExternalDependency, PkgConfigDependency, DependencyException, DependencyMethods, ExternalDependency, PkgConfigDependency,
strip_system_libdirs, ConfigToolDependency, CMakeDependency, DependencyFactory, strip_system_libdirs, ConfigToolDependency, CMakeDependency, DependencyFactory,
) )
from .misc import ThreadDependency from .misc import threads_factory
if T.TYPE_CHECKING: if T.TYPE_CHECKING:
from .. environment import Environment from .. environment import Environment
@ -50,8 +50,10 @@ class GTestDependencySystem(ExternalDependency):
super().__init__(name, environment, kwargs, language='cpp') super().__init__(name, environment, kwargs, language='cpp')
self.main = kwargs.get('main', False) self.main = kwargs.get('main', False)
self.src_dirs = ['/usr/src/gtest/src', '/usr/src/googletest/googletest/src'] self.src_dirs = ['/usr/src/gtest/src', '/usr/src/googletest/googletest/src']
if not self._add_sub_dependency2(threads_factory(environment, self.for_machine, {})):
self.is_found = False
return
self.detect() self.detect()
self._add_sub_dependency(ThreadDependency, environment, kwargs)
def detect(self): def detect(self):
gtest_detect = self.clib_compiler.find_library("gtest", self.env, []) gtest_detect = self.clib_compiler.find_library("gtest", self.env, [])
@ -117,7 +119,9 @@ class GMockDependencySystem(ExternalDependency):
def __init__(self, name: str, environment, kwargs): def __init__(self, name: str, environment, kwargs):
super().__init__(name, environment, kwargs, language='cpp') super().__init__(name, environment, kwargs, language='cpp')
self.main = kwargs.get('main', False) self.main = kwargs.get('main', False)
self._add_sub_dependency(ThreadDependency, environment, kwargs) if not self._add_sub_dependency2(threads_factory(environment, self.for_machine, {})):
self.is_found = False
return
# If we are getting main() from GMock, we definitely # If we are getting main() from GMock, we definitely
# want to avoid linking in main() from GTest # want to avoid linking in main() from GTest
@ -231,7 +235,9 @@ class LLVMDependencyConfigTool(ConfigToolDependency):
self._set_old_link_args() self._set_old_link_args()
self.link_args = strip_system_libdirs(environment, self.for_machine, self.link_args) self.link_args = strip_system_libdirs(environment, self.for_machine, self.link_args)
self.link_args = self.__fix_bogus_link_args(self.link_args) self.link_args = self.__fix_bogus_link_args(self.link_args)
self._add_sub_dependency(ThreadDependency, environment, kwargs) if not self._add_sub_dependency2(threads_factory(environment, self.for_machine, {})):
self.is_found = False
return
def __fix_bogus_link_args(self, args): def __fix_bogus_link_args(self, args):
"""This function attempts to fix bogus link arguments that llvm-config """This function attempts to fix bogus link arguments that llvm-config
@ -394,7 +400,9 @@ class LLVMDependencyCMake(CMakeDependency):
defs = self.traceparser.get_cmake_var('PACKAGE_DEFINITIONS') defs = self.traceparser.get_cmake_var('PACKAGE_DEFINITIONS')
temp = ['-I' + x for x in inc_dirs] + defs temp = ['-I' + x for x in inc_dirs] + defs
self.compile_args += [x for x in temp if x not in self.compile_args] self.compile_args += [x for x in temp if x not in self.compile_args]
self._add_sub_dependency(ThreadDependency, env, kwargs) if not self._add_sub_dependency2(threads_factory(env, self.for_machine, {})):
self.is_found = False
return
def _main_cmake_file(self) -> str: def _main_cmake_file(self) -> str:
# Use a custom CMakeLists.txt for LLVM # Use a custom CMakeLists.txt for LLVM

View File

@ -105,33 +105,17 @@ class OpenMPDependency(ExternalDependency):
class ThreadDependency(ExternalDependency): class ThreadDependency(ExternalDependency):
def __init__(self, environment, kwargs): def __init__(self, name: str, environment, kwargs):
super().__init__('threads', environment, kwargs) super().__init__(name, environment, kwargs)
self.name = 'threads' self.is_found = True
self.is_found = False # Happens if you are using a language with threads
methods = listify(self.methods) # concept without C, such as plain Cuda.
if DependencyMethods.AUTO in methods: if self.clib_compiler is None:
self.is_found = True self.compile_args = []
# Happens if you are using a language with threads self.link_args = []
# concept without C, such as plain Cuda. else:
if self.clib_compiler is None: self.compile_args = self.clib_compiler.thread_flags(environment)
self.compile_args = [] self.link_args = self.clib_compiler.thread_link_flags(environment)
self.link_args = []
else:
self.compile_args = self.clib_compiler.thread_flags(environment)
self.link_args = self.clib_compiler.thread_link_flags(environment)
return
if DependencyMethods.CMAKE in methods:
# for unit tests and for those who simply want
# dependency('threads', method: 'cmake')
cmakedep = CMakeDependency('Threads', environment, kwargs)
if cmakedep.found():
self.compile_args = cmakedep.get_compile_args()
self.link_args = cmakedep.get_link_args()
self.version = cmakedep.get_version()
self.is_found = True
return
@staticmethod @staticmethod
def get_methods(): def get_methods():
@ -508,3 +492,10 @@ python3_factory = DependencyFactory(
# Python 3 will always be in /Library # Python 3 will always be in /Library
extra_kwargs={'paths': ['/Library/Frameworks']}, extra_kwargs={'paths': ['/Library/Frameworks']},
) )
threads_factory = DependencyFactory(
'threads',
[DependencyMethods.SYSTEM, DependencyMethods.CMAKE],
cmake_name='Threads',
system_class=ThreadDependency,
)

View File

@ -17,6 +17,7 @@ from pathlib import PurePath
from .. import build from .. import build
from .. import dependencies from .. import dependencies
from ..dependencies.misc import ThreadDependency
from .. import mesonlib from .. import mesonlib
from .. import mlog from .. import mlog
from . import ModuleReturnValue from . import ModuleReturnValue
@ -94,7 +95,7 @@ class DependenciesHelper:
self.add_version_reqs(name, version_req) self.add_version_reqs(name, version_req)
elif isinstance(obj, dependencies.Dependency) and not obj.found(): elif isinstance(obj, dependencies.Dependency) and not obj.found():
pass pass
elif isinstance(obj, dependencies.ThreadDependency): elif isinstance(obj, ThreadDependency):
pass pass
else: else:
raise mesonlib.MesonException('requires argument not a string, ' raise mesonlib.MesonException('requires argument not a string, '
@ -125,9 +126,6 @@ class DependenciesHelper:
if obj.found(): if obj.found():
processed_reqs.append(obj.name) processed_reqs.append(obj.name)
self.add_version_reqs(obj.name, obj.version_reqs) self.add_version_reqs(obj.name, obj.version_reqs)
elif isinstance(obj, dependencies.ThreadDependency):
processed_libs += obj.get_compiler().thread_link_flags(obj.env)
processed_cflags += obj.get_compiler().thread_flags(obj.env)
elif isinstance(obj, dependencies.InternalDependency): elif isinstance(obj, dependencies.InternalDependency):
if obj.found(): if obj.found():
processed_libs += obj.get_link_args() processed_libs += obj.get_link_args()