Interpreter: Fix c_stdlib usage
- Exceptions raised during subproject setup were ignored. - Allow c_stdlib in native file, was already half supported. - Eliminate usage of subproject variable name by overriding '<lang>_stdlib' dependency name.
This commit is contained in:
parent
adfee4460a
commit
1c403e20e7
|
@ -10,4 +10,4 @@ endian = 'little'
|
|||
|
||||
[properties]
|
||||
|
||||
c_stdlib = ['mylibc', 'mylibc_dep'] # Subproject name, dependency name
|
||||
c_stdlib = 'mylibc' # Subproject name
|
||||
|
|
|
@ -268,7 +268,7 @@ invocation to use in your cross file is the following:
|
|||
|
||||
```ini
|
||||
[properties]
|
||||
c_stdlib = ['mylibc', 'mylibc_dep'] # Subproject name, dependency name
|
||||
c_stdlib = ['mylibc', 'mylibc_dep'] # Subproject name, variable name
|
||||
```
|
||||
|
||||
This specifies that C standard library is provided in the Meson
|
||||
|
@ -277,6 +277,18 @@ is used on every cross built C target in the entire source tree
|
|||
(including subprojects) and the standard library is disabled. The
|
||||
build definitions of these targets do not need any modification.
|
||||
|
||||
Note that it is supported for any language, not only `c`, using `<lang>_stdlib`
|
||||
property.
|
||||
|
||||
Since *0.56.0* the variable name parameter is no longer required as long as the
|
||||
subproject calls `meson.override_dependency('c_stdlib', mylibc_dep)`.
|
||||
The above example becomes:
|
||||
|
||||
```ini
|
||||
[properties]
|
||||
c_stdlib = 'mylibc'
|
||||
```
|
||||
|
||||
## Changing cross file settings
|
||||
|
||||
Cross file settings are only read when the build directory is set up
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
## Custom standard library
|
||||
|
||||
- It is not limited to cross builds any more, `<lang>_stdlib` property can be
|
||||
set in native files.
|
||||
- The variable name parameter is no longer required as long as the subproject
|
||||
calls `meson.override_dependency('c_stdlib', mylibc_dep)`.
|
|
@ -657,7 +657,7 @@ class Backend:
|
|||
# First, the trivial ones that are impossible to override.
|
||||
#
|
||||
# Add -nostdinc/-nostdinc++ if needed; can't be overridden
|
||||
commands += self.get_cross_stdlib_args(target, compiler)
|
||||
commands += self.get_no_stdlib_args(target, compiler)
|
||||
# Add things like /NOLOGO or -pipe; usually can't be overridden
|
||||
commands += compiler.get_always_args()
|
||||
# Only add warning-flags by default if the buildtype enables it, and if
|
||||
|
|
|
@ -2088,12 +2088,15 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
|
|||
mod_files = _scan_fortran_file_deps(src, srcdir, dirname, tdeps, compiler)
|
||||
return mod_files
|
||||
|
||||
def get_cross_stdlib_args(self, target, compiler):
|
||||
if self.environment.machines.matches_build_machine(target.for_machine):
|
||||
return []
|
||||
if not self.environment.properties.host.has_stdlib(compiler.language):
|
||||
return []
|
||||
return compiler.get_no_stdinc_args()
|
||||
def get_no_stdlib_args(self, target, compiler):
|
||||
if compiler.language in self.build.stdlibs[target.for_machine]:
|
||||
return compiler.get_no_stdinc_args()
|
||||
return []
|
||||
|
||||
def get_no_stdlib_link_args(self, target, linker):
|
||||
if hasattr(linker, 'language') and linker.language in self.build.stdlibs[target.for_machine]:
|
||||
return linker.get_no_stdlib_link_args()
|
||||
return []
|
||||
|
||||
def get_compile_debugfile_args(self, compiler, target, objfile):
|
||||
# The way MSVC uses PDB files is documented exactly nowhere so
|
||||
|
@ -2520,14 +2523,6 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
|
|||
elem.add_item('CROSS', '--cross-host=' + self.environment.machines[target.for_machine].system)
|
||||
self.add_build(elem)
|
||||
|
||||
def get_cross_stdlib_link_args(self, target, linker):
|
||||
if isinstance(target, build.StaticLibrary) or \
|
||||
self.environment.machines.matches_build_machine(target.for_machine):
|
||||
return []
|
||||
if not self.environment.properties.host.has_stdlib(linker.language):
|
||||
return []
|
||||
return linker.get_no_stdlib_link_args()
|
||||
|
||||
def get_import_filename(self, target):
|
||||
return os.path.join(self.get_target_dir(target), target.import_filename)
|
||||
|
||||
|
@ -2689,7 +2684,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
|
|||
linker,
|
||||
isinstance(target, build.SharedModule))
|
||||
# Add -nostdlib if needed; can't be overridden
|
||||
commands += self.get_cross_stdlib_link_args(target, linker)
|
||||
commands += self.get_no_stdlib_link_args(target, linker)
|
||||
# Add things like /NOLOGO; usually can't be overridden
|
||||
commands += linker.get_linker_always_args()
|
||||
# Add buildtype linker args: optimization level, etc.
|
||||
|
|
|
@ -2301,7 +2301,7 @@ def get_dep_identifier(name, kwargs) -> T.Tuple:
|
|||
# 'required' is irrelevant for caching; the caller handles it separately
|
||||
# 'fallback' subprojects cannot be cached -- they must be initialized
|
||||
# 'default_options' is only used in fallback case
|
||||
if key in ('version', 'native', 'required', 'fallback', 'default_options'):
|
||||
if key in ('version', 'native', 'required', 'fallback', 'default_options', 'force_fallback'):
|
||||
continue
|
||||
# All keyword arguments are strings, ints, or lists (or lists of lists)
|
||||
if isinstance(value, list):
|
||||
|
|
|
@ -2572,21 +2572,25 @@ class Interpreter(InterpreterBase):
|
|||
return self.variables
|
||||
|
||||
def check_stdlibs(self):
|
||||
for for_machine in MachineChoice:
|
||||
machine_choices = [MachineChoice.HOST]
|
||||
if self.coredata.is_cross_build():
|
||||
machine_choices.append(MachineChoice.BUILD)
|
||||
for for_machine in machine_choices:
|
||||
props = self.build.environment.properties[for_machine]
|
||||
for l in self.coredata.compilers[for_machine].keys():
|
||||
try:
|
||||
di = mesonlib.stringlistify(props.get_stdlib(l))
|
||||
if len(di) != 2:
|
||||
raise InterpreterException('Stdlib definition for %s should have exactly two elements.'
|
||||
% l)
|
||||
projname, depname = di
|
||||
subproj = self.do_subproject(projname, 'meson', {})
|
||||
self.build.stdlibs.host[l] = subproj.get_variable_method([depname], {})
|
||||
except KeyError:
|
||||
pass
|
||||
except InvalidArguments:
|
||||
pass
|
||||
continue
|
||||
if len(di) == 1:
|
||||
FeatureNew.single_use('stdlib without variable name', '0.56.0', self.subproject)
|
||||
kwargs = {'fallback': di,
|
||||
'native': for_machine is MachineChoice.BUILD,
|
||||
'force_fallback': True,
|
||||
}
|
||||
name = display_name = l + '_stdlib'
|
||||
dep = self.dependency_impl(name, display_name, kwargs)
|
||||
self.build.stdlibs[for_machine][l] = dep
|
||||
|
||||
def import_module(self, modname):
|
||||
if modname in self.modules:
|
||||
|
@ -3682,9 +3686,11 @@ external dependencies (including libraries) must go to "dependencies".''')
|
|||
|
||||
wrap_mode = self.coredata.get_builtin_option('wrap_mode')
|
||||
force_fallback_for = self.coredata.get_builtin_option('force_fallback_for')
|
||||
force_fallback = kwargs.get('force_fallback', False)
|
||||
forcefallback = has_fallback and (wrap_mode == WrapMode.forcefallback or \
|
||||
name in force_fallback_for or \
|
||||
dirname in force_fallback_for)
|
||||
dirname in force_fallback_for or \
|
||||
force_fallback)
|
||||
if name != '' and not forcefallback:
|
||||
self._handle_featurenew_dependencies(name)
|
||||
kwargs['required'] = required and not has_fallback
|
||||
|
@ -4786,8 +4792,7 @@ Try setting b_lundef to false instead.'''.format(self.coredata.base_options['b_s
|
|||
target = targetclass(name, self.subdir, self.subproject, for_machine, sources, objs, self.environment, kwargs)
|
||||
target.project_version = self.project_version
|
||||
|
||||
if not self.environment.machines.matches_build_machine(for_machine):
|
||||
self.add_cross_stdlib_info(target)
|
||||
self.add_stdlib_info(target)
|
||||
l = targetholder(target, self)
|
||||
self.add_target(name, l.held_object)
|
||||
self.project_args_frozen = True
|
||||
|
@ -4811,23 +4816,19 @@ This will become a hard error in the future.''', location=self.current_node)
|
|||
kwargs['d_import_dirs'] = cleaned_items
|
||||
|
||||
def get_used_languages(self, target):
|
||||
result = {}
|
||||
result = set()
|
||||
for i in target.sources:
|
||||
# TODO other platforms
|
||||
for lang, c in self.coredata.compilers.host.items():
|
||||
for lang, c in self.coredata.compilers[target.for_machine].items():
|
||||
if c.can_compile(i):
|
||||
result[lang] = True
|
||||
result.add(lang)
|
||||
break
|
||||
return result
|
||||
|
||||
def add_cross_stdlib_info(self, target):
|
||||
if target.for_machine != MachineChoice.HOST:
|
||||
return
|
||||
def add_stdlib_info(self, target):
|
||||
for l in self.get_used_languages(target):
|
||||
props = self.environment.properties.host
|
||||
if props.has_stdlib(l) \
|
||||
and self.subproject != props.get_stdlib(l)[0]:
|
||||
target.add_deps(self.build.stdlibs.host[l])
|
||||
dep = self.build.stdlibs[target.for_machine].get(l, None)
|
||||
if dep:
|
||||
target.add_deps(dep)
|
||||
|
||||
def check_sources_exist(self, subdir, sources):
|
||||
for s in sources:
|
||||
|
|
|
@ -5054,6 +5054,28 @@ recommended as it is not supported on some platforms''')
|
|||
self.build()
|
||||
self.run_tests()
|
||||
|
||||
@unittest.skipUnless(is_linux(), 'Requires ASM compiler currently only available on Linux CI runners')
|
||||
def test_nostdlib(self):
|
||||
testdir = os.path.join(self.unit_test_dir, '79 nostdlib')
|
||||
machinefile = os.path.join(self.builddir, 'machine.txt')
|
||||
with open(machinefile, 'w') as f:
|
||||
f.write(textwrap.dedent('''
|
||||
[properties]
|
||||
c_stdlib = 'mylibc'
|
||||
'''))
|
||||
|
||||
# Test native C stdlib
|
||||
self.meson_native_file = machinefile
|
||||
self.init(testdir)
|
||||
self.build()
|
||||
|
||||
# Test cross C stdlib
|
||||
self.new_builddir()
|
||||
self.meson_native_file = None
|
||||
self.meson_cross_file = machinefile
|
||||
self.init(testdir)
|
||||
self.build()
|
||||
|
||||
class FailureTests(BasePlatformTests):
|
||||
'''
|
||||
Tests that test failure conditions. Build files here should be dynamically
|
||||
|
|
|
@ -9,3 +9,5 @@ libc = static_library('c', 'libc.c', 'stubstart.s')
|
|||
mylibc_dep = declare_dependency(link_with : libc,
|
||||
include_directories : include_directories('.')
|
||||
)
|
||||
|
||||
meson.override_dependency('c_stdlib', mylibc_dep)
|
Loading…
Reference in New Issue