diff options
Diffstat (limited to 'mesonbuild')
-rw-r--r-- | mesonbuild/backend/ninjabackend.py | 11 | ||||
-rw-r--r-- | mesonbuild/build.py | 78 | ||||
-rw-r--r-- | mesonbuild/interpreter/type_checking.py | 25 |
3 files changed, 69 insertions, 45 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 491f2a6..767baea 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -1937,16 +1937,7 @@ class NinjaBackend(backends.Backend): if main_rust_file is None: raise RuntimeError('A Rust target has no Rust sources. This is weird. Also a bug. Please report') target_name = os.path.join(target.subdir, target.get_filename()) - if isinstance(target, build.Executable): - cratetype = 'bin' - elif hasattr(target, 'rust_crate_type'): - cratetype = target.rust_crate_type - elif isinstance(target, build.SharedLibrary): - cratetype = 'dylib' - elif isinstance(target, build.StaticLibrary): - cratetype = 'rlib' - else: - raise InvalidArguments('Unknown target type for rustc.') + cratetype = target.rust_crate_type args.extend(['--crate-type', cratetype]) # If we're dynamically linking, add those arguments diff --git a/mesonbuild/build.py b/mesonbuild/build.py index fece0be..5820b50 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -115,9 +115,9 @@ known_build_target_kwargs = ( cs_kwargs) known_exe_kwargs = known_build_target_kwargs | {'implib', 'export_dynamic', 'pie'} -known_shlib_kwargs = known_build_target_kwargs | {'version', 'soversion', 'vs_module_defs', 'darwin_versions'} -known_shmod_kwargs = known_build_target_kwargs | {'vs_module_defs'} -known_stlib_kwargs = known_build_target_kwargs | {'pic', 'prelink'} +known_shlib_kwargs = known_build_target_kwargs | {'version', 'soversion', 'vs_module_defs', 'darwin_versions', 'rust_abi'} +known_shmod_kwargs = known_build_target_kwargs | {'vs_module_defs', 'rust_abi'} +known_stlib_kwargs = known_build_target_kwargs | {'pic', 'prelink', 'rust_abi'} known_jar_kwargs = known_exe_kwargs | {'main_class', 'java_resources'} def _process_install_tag(install_tag: T.Optional[T.List[T.Optional[str]]], @@ -1980,6 +1980,13 @@ class Executable(BuildTarget): if create_debug_file: self.debug_filename = self.name + '.pdb' + def process_kwargs(self, kwargs): + super().process_kwargs(kwargs) + + self.rust_crate_type = kwargs.get('rust_crate_type') or 'bin' + if self.rust_crate_type != 'bin': + raise InvalidArguments('Invalid rust_crate_type: must be "bin" for executables.') + def get_default_install_dir(self) -> T.Tuple[str, str]: return self.environment.get_bindir(), '{bindir}' @@ -2052,18 +2059,12 @@ class StaticLibrary(BuildTarget): super().post_init() if 'cs' in self.compilers: raise InvalidArguments('Static libraries not supported for C#.') - if 'rust' in self.compilers: - # If no crate type is specified, or it's the generic lib type, use rlib - if not hasattr(self, 'rust_crate_type') or self.rust_crate_type == 'lib': - mlog.debug('Defaulting Rust static library target crate type to rlib') - self.rust_crate_type = 'rlib' - # Don't let configuration proceed with a non-static crate type - elif self.rust_crate_type not in ['rlib', 'staticlib']: - raise InvalidArguments(f'Crate type "{self.rust_crate_type}" invalid for static libraries; must be "rlib" or "staticlib"') + if self.uses_rust(): # See https://github.com/rust-lang/rust/issues/110460 if self.rust_crate_type == 'rlib' and any(c in self.name for c in ['-', ' ', '.']): - raise InvalidArguments('Rust crate type "rlib" does not allow spaces, periods or dashes in the library name ' - 'due to a limitation of rustc. Replace them with underscores, for example') + raise InvalidArguments(f'Rust crate {self.name} type {self.rust_crate_type} does not allow spaces, ' + 'periods or dashes in the library name due to a limitation of rustc. ' + 'Replace them with underscores, for example') if self.rust_crate_type == 'staticlib': # FIXME: In the case of no-std we should not add those libraries, # but we have no way to know currently. @@ -2085,8 +2086,8 @@ class StaticLibrary(BuildTarget): if not hasattr(self, 'prefix'): self.prefix = 'lib' if not hasattr(self, 'suffix'): - if 'rust' in self.compilers: - if not hasattr(self, 'rust_crate_type') or self.rust_crate_type == 'rlib': + if self.uses_rust(): + if self.rust_crate_type == 'rlib': # default Rust static library suffix self.suffix = 'rlib' elif self.rust_crate_type == 'staticlib': @@ -2107,12 +2108,20 @@ class StaticLibrary(BuildTarget): def process_kwargs(self, kwargs): super().process_kwargs(kwargs) - if 'rust_crate_type' in kwargs: - rust_crate_type = kwargs['rust_crate_type'] - if isinstance(rust_crate_type, str): + + rust_abi = kwargs.get('rust_abi') + rust_crate_type = kwargs.get('rust_crate_type') + if rust_crate_type: + if rust_abi: + raise InvalidArguments('rust_abi and rust_crate_type are mutually exclusive.') + if rust_crate_type == 'lib': + self.rust_crate_type = 'rlib' + elif rust_crate_type in {'rlib', 'staticlib'}: self.rust_crate_type = rust_crate_type else: - raise InvalidArguments(f'Invalid rust_crate_type "{rust_crate_type}": must be a string.') + raise InvalidArguments(f'Crate type {rust_crate_type!r} invalid for static libraries; must be "rlib" or "staticlib"') + else: + self.rust_crate_type = 'staticlib' if rust_abi == 'c' else 'rlib' def is_linkable_target(self): return True @@ -2153,18 +2162,12 @@ class SharedLibrary(BuildTarget): def post_init(self) -> None: super().post_init() - if 'rust' in self.compilers: - # If no crate type is specified, or it's the generic lib type, use dylib - if not hasattr(self, 'rust_crate_type') or self.rust_crate_type == 'lib': - mlog.debug('Defaulting Rust dynamic library target crate type to "dylib"') - self.rust_crate_type = 'dylib' - # Don't let configuration proceed with a non-dynamic crate type - elif self.rust_crate_type not in ['dylib', 'cdylib', 'proc-macro']: - raise InvalidArguments(f'Crate type "{self.rust_crate_type}" invalid for dynamic libraries; must be "dylib", "cdylib", or "proc-macro"') + if self.uses_rust(): # See https://github.com/rust-lang/rust/issues/110460 if self.rust_crate_type != 'cdylib' and any(c in self.name for c in ['-', ' ', '.']): - raise InvalidArguments('Rust crate types "dylib" and "proc-macro" do not allow spaces, periods or dashes in the library name ' - 'due to a limitation of rustc. Replace them with underscores, for example') + raise InvalidArguments(f'Rust crate {self.name} type {self.rust_crate_type} does not allow spaces, ' + 'periods or dashes in the library name due to a limitation of rustc. ' + 'Replace them with underscores, for example') if not hasattr(self, 'prefix'): self.prefix = None @@ -2335,14 +2338,19 @@ class SharedLibrary(BuildTarget): 'a file object or a Custom Target') self.process_link_depends(path) - if 'rust_crate_type' in kwargs: - rust_crate_type = kwargs['rust_crate_type'] - if isinstance(rust_crate_type, str): + rust_abi = kwargs.get('rust_abi') + rust_crate_type = kwargs.get('rust_crate_type') + if rust_crate_type: + if rust_abi: + raise InvalidArguments('rust_abi and rust_crate_type are mutually exclusive.') + if rust_crate_type == 'lib': + self.rust_crate_type = 'dylib' + elif rust_crate_type in {'dylib', 'cdylib', 'proc-macro'}: self.rust_crate_type = rust_crate_type else: - raise InvalidArguments(f'Invalid rust_crate_type "{rust_crate_type}": must be a string.') - if rust_crate_type == 'proc-macro': - FeatureNew.single_use('Rust crate type "proc-macro"', '0.62.0', self.subproject) + raise InvalidArguments(f'Crate type {rust_crate_type!r} invalid for shared libraries; must be "dylib", "cdylib" or "proc-macro"') + else: + self.rust_crate_type = 'cdylib' if rust_abi == 'c' else 'dylib' def get_import_filename(self) -> T.Optional[str]: """ diff --git a/mesonbuild/interpreter/type_checking.py b/mesonbuild/interpreter/type_checking.py index 59dae9a..9a1904d 100644 --- a/mesonbuild/interpreter/type_checking.py +++ b/mesonbuild/interpreter/type_checking.py @@ -498,6 +498,21 @@ TEST_KWS: T.List[KwargInfo] = [ KwargInfo('verbose', bool, default=False, since='0.62.0'), ] +# Cannot have a default value because we need to check that rust_crate_type and +# rust_abi are mutually exclusive. +RUST_CRATE_TYPE_KW: KwargInfo[T.Union[str, None]] = KwargInfo( + 'rust_crate_type', (str, NoneType), + since='0.42.0', + since_values={'proc-macro': '0.62.0'}, + deprecated='1.3.0', + deprecated_message='Use rust_abi or rust.proc_macro() instead.', + validator=in_set_validator({'bin', 'lib', 'rlib', 'dylib', 'cdylib', 'staticlib', 'proc-macro'})) + +RUST_ABI_KW: KwargInfo[T.Union[str, None]] = KwargInfo( + 'rust_abi', (str, NoneType), + since='1.3.0', + validator=in_set_validator({'rust', 'c'})) + # Applies to all build_target like classes _ALL_TARGET_KWS: T.List[KwargInfo] = [ OVERRIDE_OPTIONS_KW, @@ -506,6 +521,7 @@ _ALL_TARGET_KWS: T.List[KwargInfo] = [ # Applies to all build_target classes except jar _BUILD_TARGET_KWS: T.List[KwargInfo] = [ *_ALL_TARGET_KWS, + RUST_CRATE_TYPE_KW, ] def _validate_win_subsystem(value: T.Optional[str]) -> T.Optional[str]: @@ -575,6 +591,11 @@ EXECUTABLE_KWS = [ *_EXCLUSIVE_EXECUTABLE_KWS, ] +# Arguments exclusive to library types +_EXCLUSIVE_LIB_KWS: T.List[KwargInfo] = [ + RUST_ABI_KW, +] + # Arguments exclusive to StaticLibrary. These are separated to make integrating # them into build_target easier _EXCLUSIVE_STATIC_LIB_KWS: T.List[KwargInfo] = [] @@ -583,6 +604,7 @@ _EXCLUSIVE_STATIC_LIB_KWS: T.List[KwargInfo] = [] STATIC_LIB_KWS = [ *_BUILD_TARGET_KWS, *_EXCLUSIVE_STATIC_LIB_KWS, + *_EXCLUSIVE_LIB_KWS, ] # Arguments exclusive to SharedLibrary. These are separated to make integrating @@ -597,6 +619,7 @@ _EXCLUSIVE_SHARED_LIB_KWS: T.List[KwargInfo] = [ SHARED_LIB_KWS = [ *_BUILD_TARGET_KWS, *_EXCLUSIVE_SHARED_LIB_KWS, + *_EXCLUSIVE_LIB_KWS, ] # Arguments exclusive to SharedModule. These are separated to make integrating @@ -607,6 +630,7 @@ _EXCLUSIVE_SHARED_MOD_KWS: T.List[KwargInfo] = [] SHARED_MOD_KWS = [ *_BUILD_TARGET_KWS, *_EXCLUSIVE_SHARED_MOD_KWS, + *_EXCLUSIVE_LIB_KWS, ] # Arguments exclusive to JAR. These are separated to make integrating @@ -625,6 +649,7 @@ JAR_KWS = [ # Arguments used by both_library and library LIBRARY_KWS = [ *_BUILD_TARGET_KWS, + *_EXCLUSIVE_LIB_KWS, *_EXCLUSIVE_SHARED_LIB_KWS, *_EXCLUSIVE_SHARED_MOD_KWS, *_EXCLUSIVE_STATIC_LIB_KWS, |