d: Add easy way to use D-specific features

Of course D compilers have different flags to set some important
D-specific settings. This adds a simple method to change these flags in
a compiler-agnostic way in Meson.

This replaces the previous `unittest_args` method with a more generic
variant.
pull/2263/head
Matthias Klumpp 8 years ago
parent e1fc17ef2a
commit d83c289442
  1. 55
      mesonbuild/compilers/d.py
  2. 17
      mesonbuild/interpreter.py
  3. 51
      test cases/d/9 features/app.d
  4. 6
      test cases/d/9 features/data/food.txt
  5. 5
      test cases/d/9 features/data/people.txt
  6. 28
      test cases/d/9 features/meson.build

@ -27,6 +27,20 @@ from .compilers import (
CompilerArgs,
)
d_feature_args = {'gcc': {'unittest': '-funittest',
'version': '-fversion',
'import_dir': '-J'
},
'llvm': {'unittest': '-unittest',
'version': '-d-version',
'import_dir': '-J'
},
'dmd': {'unittest': '-unittest',
'version': '-version',
'import_dir': '-J'
}
}
class DCompiler(Compiler):
def __init__(self, exelist, version, is_cross):
self.language = 'd'
@ -79,8 +93,42 @@ class DCompiler(Compiler):
# FIXME: Make this work for Windows, MacOS and cross-compiling
return get_gcc_soname_args(GCC_STANDARD, prefix, shlib_name, suffix, path, soversion, is_shared_module)
def get_unittest_args(self):
return ['-unittest']
def get_feature_args(self, args, kwargs):
res = []
if 'unittest' in kwargs:
unittest = kwargs.pop('unittest')
unittest_arg = d_feature_args[self.id]['unittest']
if not unittest_arg:
raise EnvironmentException('D compiler %s does not support the "unittest" feature.' % self.name_string())
if unittest:
res.append(unittest_arg)
if 'versions' in kwargs:
versions = kwargs.pop('versions')
if not isinstance(versions, list):
versions = [versions]
version_arg = d_feature_args[self.id]['version']
if not version_arg:
raise EnvironmentException('D compiler %s does not support the "feature versions" feature.' % self.name_string())
for v in versions:
res.append('{0}={1}'.format(version_arg, v))
if 'import_dirs' in kwargs:
import_dirs = kwargs.pop('import_dirs')
if not isinstance(import_dirs, list):
import_dirs = [import_dirs]
import_dir_arg = d_feature_args[self.id]['import_dir']
if not import_dir_arg:
raise EnvironmentException('D compiler %s does not support the "string import directories" feature.' % self.name_string())
for d in import_dirs:
res.append('{0}{1}'.format(import_dir_arg, d))
if kwargs:
raise EnvironmentException('Unknown D compiler feature(s) selected: %s' % ', '.join(kwargs.keys()))
return res
def get_buildtype_linker_args(self, buildtype):
return []
@ -217,9 +265,6 @@ class GnuDCompiler(DCompiler):
def build_rpath_args(self, build_dir, from_dir, rpath_paths, build_rpath, install_rpath):
return self.build_unix_rpath_args(build_dir, from_dir, rpath_paths, build_rpath, install_rpath)
def get_unittest_args(self):
return ['-funittest']
class LLVMDCompiler(DCompiler):
def __init__(self, exelist, version, is_cross):

@ -655,6 +655,7 @@ class CompilerHolder(InterpreterObject):
'get_supported_arguments': self.get_supported_arguments_method,
'first_supported_argument': self.first_supported_argument_method,
'unittest_args': self.unittest_args_method,
'feature_args': self.feature_args_method,
'symbols_have_underscore_prefix': self.symbols_have_underscore_prefix_method,
})
@ -751,11 +752,19 @@ class CompilerHolder(InterpreterObject):
'''
return self.compiler.symbols_have_underscore_prefix(self.environment)
def unittest_args_method(self, args, kwargs):
def feature_args_method(self, args, kwargs):
# At time, only D compilers have this feature.
if not hasattr(self.compiler, 'get_unittest_args'):
raise InterpreterException('This {} compiler has no unittest arguments.'.format(self.compiler.get_display_language()))
return self.compiler.get_unittest_args()
if not hasattr(self.compiler, 'get_feature_args'):
raise InterpreterException('This {} compiler has no feature arguments.'.format(self.compiler.get_display_language()))
return self.compiler.get_feature_args(args, kwargs)
def unittest_args_method(self, args, kwargs):
'''
This function is deprecated and should not be used.
'''
if not hasattr(self.compiler, 'get_feature_args'):
raise InterpreterException('This {} compiler has no feature arguments.'.format(self.compiler.get_display_language()))
return self.compiler.get_feature_args(args, {'unittest': 'true'})
def has_member_method(self, args, kwargs):
if len(args) != 2:

@ -0,0 +1,51 @@
import std.stdio;
import std.array : split;
import std.string : strip;
auto getMenu ()
{
auto foods = import ("food.txt").strip.split ("\n");
return foods;
}
auto getPeople ()
{
return import ("people.txt").strip.split ("\n");
}
void main (string[] args)
{
import std.array : join;
import core.stdc.stdlib : exit;
immutable request = args[1];
if (request == "menu") {
version (No_Menu) {
} else {
writeln ("On the menu: ", getMenu.join (", "));
exit (0);
}
}
version (With_People) {
if (request == "people") {
writeln ("People: ", getPeople.join (", "));
exit (0);
}
}
// we fail here
exit (1);
}
unittest
{
writeln ("TEST");
import core.stdc.stdlib : exit;
writeln(getMenu);
assert (getMenu () == ["Spam", "Eggs", "Spam", "Baked Beans", "Spam", "Spam"]);
exit (0);
}

@ -0,0 +1,6 @@
Spam
Eggs
Spam
Baked Beans
Spam
Spam

@ -0,0 +1,5 @@
Rick
Morty
Summer
Beth
Jerry

@ -0,0 +1,28 @@
project('D Features', 'd')
dc = meson.get_compiler('d')
# directory for data
data_dir = join_paths(meson.current_source_dir(), 'data')
# test string import dirs only
dfeatures_simple = dc.feature_args(import_dirs: [data_dir])
e_plain = executable('dapp_menu', 'app.d', d_args: dfeatures_simple)
test('dapp_menu_t_fail', e_plain, should_fail: true)
test('dapp_menu_t', e_plain, args: ['menu'])
# test feature versions and string imports
dfeatures_version = dc.feature_args(import_dirs: [data_dir], versions: ['No_Menu', 'With_People'])
e_versions = executable('dapp_versions', 'app.d', d_args: dfeatures_version)
test('dapp_versions_t_fail', e_versions, args: ['menu'], should_fail: true)
test('dapp_versions_t', e_versions, args: ['people'])
# test everything and unittests
dfeatures_test = dc.feature_args(
import_dirs: [data_dir],
versions: ['No_Menu', 'With_People'],
unittest: true
)
e_test = executable('dapp_test', 'app.d',
d_args: dfeatures_test)
test('dapp_test', e_test)
Loading…
Cancel
Save