aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2018-10-02 21:49:29 +0300
committerGitHub <noreply@github.com>2018-10-02 21:49:29 +0300
commite6395c6f44fb0fcf2d388dcf3aca8ee22c6d32f2 (patch)
tree8c5dcc0052cc54c7ae57947359aac59e7d444268
parent829d7bf6f9c696b526c9c0f99635634389dd1b5d (diff)
parentc4b885bfd18cda9578409fa67d986151b32e7afd (diff)
downloadmeson-e6395c6f44fb0fcf2d388dcf3aca8ee22c6d32f2.zip
meson-e6395c6f44fb0fcf2d388dcf3aca8ee22c6d32f2.tar.gz
meson-e6395c6f44fb0fcf2d388dcf3aca8ee22c6d32f2.tar.bz2
Merge pull request #4051 from GoaLitiuM/d-debug
D: Add conditional debug compilation flags
-rw-r--r--docs/markdown/D.md10
-rw-r--r--docs/markdown/Reference-manual.md3
-rw-r--r--mesonbuild/build.py6
-rw-r--r--mesonbuild/compilers/d.py50
-rw-r--r--test cases/d/9 features/app.d24
-rw-r--r--test cases/d/9 features/meson.build62
6 files changed, 147 insertions, 8 deletions
diff --git a/docs/markdown/D.md b/docs/markdown/D.md
index 15de2f7..2b0eaac 100644
--- a/docs/markdown/D.md
+++ b/docs/markdown/D.md
@@ -14,15 +14,21 @@ project('myapp', 'd')
executable('myapp', 'app.d')
```
-## Compiling different versions
+## [Conditional compilation](https://dlang.org/spec/version.html)
-If you are using the [version()](https://dlang.org/spec/version.html) feature for conditional compilation,
+If you are using the [version()](https://dlang.org/spec/version.html#version-specification) feature for conditional compilation,
you can use it using the `d_module_versions` target property:
```meson
project('myapp', 'd')
executable('myapp', 'app.d', d_module_versions: ['Demo', 'FeatureA'])
```
+For debugging, [debug()](https://dlang.org/spec/version.html#debug) conditions are compiled automatically in debug builds, and extra identifiers can be added with the `d_debug` argument:
+```meson
+project('myapp', 'd')
+executable('myapp', 'app.d', d_debug: [3, 'DebugFeatureA'])
+```
+
## Using embedded unittests
If you are using embedded [unittest functions](https://dlang.org/spec/unittest.html), your source code needs
diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md
index 7902f19..3bd2bfa 100644
--- a/docs/markdown/Reference-manual.md
+++ b/docs/markdown/Reference-manual.md
@@ -537,7 +537,8 @@ be passed to [shared and static libraries](#library).
- `d_import_dirs` list of directories to look in for string imports used
in the D programming language
- `d_unittest`, when set to true, the D modules are compiled in debug mode
-- `d_module_versions` list of module versions set when compiling D sources
+- `d_module_versions` list of module version identifiers set when compiling D sources
+- `d_debug` list of module debug identifiers set when compiling D sources
The list of `sources`, `objects`, and `dependencies` is always
flattened, which means you can freely nest and add lists while
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index eb0e294..ee99806 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -37,6 +37,7 @@ lang_arg_kwargs = set([
'd_import_dirs',
'd_unittest',
'd_module_versions',
+ 'd_debug',
'fortran_args',
'java_args',
'objc_args',
@@ -737,9 +738,12 @@ just like those detected with the dependency() function.''')
dfeature_unittest = kwargs.get('d_unittest', False)
if dfeature_unittest:
dfeatures['unittest'] = dfeature_unittest
- dfeature_versions = kwargs.get('d_module_versions', None)
+ dfeature_versions = kwargs.get('d_module_versions', [])
if dfeature_versions:
dfeatures['versions'] = dfeature_versions
+ dfeature_debug = kwargs.get('d_debug', [])
+ if dfeature_debug:
+ dfeatures['debug'] = dfeature_debug
if 'd_import_dirs' in kwargs:
dfeature_import_dirs = extract_as_list(kwargs, 'd_import_dirs', unholder=True)
for d in dfeature_import_dirs:
diff --git a/mesonbuild/compilers/d.py b/mesonbuild/compilers/d.py
index e9ceafb..2865b1f 100644
--- a/mesonbuild/compilers/d.py
+++ b/mesonbuild/compilers/d.py
@@ -30,14 +30,17 @@ from .compilers import (
)
d_feature_args = {'gcc': {'unittest': '-funittest',
+ 'debug': '-fdebug',
'version': '-fversion',
'import_dir': '-J'
},
'llvm': {'unittest': '-unittest',
+ 'debug': '-d-debug',
'version': '-d-version',
'import_dir': '-J'
},
'dmd': {'unittest': '-unittest',
+ 'debug': '-debug',
'version': '-version',
'import_dir': '-J'
}
@@ -168,16 +171,53 @@ class DCompiler(Compiler):
if unittest:
res.append(unittest_arg)
+ if 'debug' in kwargs:
+ debug_level = -1
+ debugs = kwargs.pop('debug')
+ if not isinstance(debugs, list):
+ debugs = [debugs]
+
+ debug_arg = d_feature_args[self.id]['debug']
+ if not debug_arg:
+ raise EnvironmentException('D compiler %s does not support conditional debug identifiers.' % self.name_string())
+
+ # Parse all debug identifiers and the largest debug level identifier
+ for d in debugs:
+ if isinstance(d, int):
+ if d > debug_level:
+ debug_level = d
+ elif isinstance(d, str) and d.isdigit():
+ if int(d) > debug_level:
+ debug_level = int(d)
+ else:
+ res.append('{0}={1}'.format(debug_arg, d))
+
+ if debug_level >= 0:
+ res.append('{0}={1}'.format(debug_arg, debug_level))
+
if 'versions' in kwargs:
+ version_level = -1
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())
+ raise EnvironmentException('D compiler %s does not support conditional version identifiers.' % self.name_string())
+
+ # Parse all version identifiers and the largest version level identifier
for v in versions:
- res.append('{0}={1}'.format(version_arg, v))
+ if isinstance(v, int):
+ if v > version_level:
+ version_level = v
+ elif isinstance(v, str) and v.isdigit():
+ if int(v) > version_level:
+ version_level = int(v)
+ else:
+ res.append('{0}={1}'.format(version_arg, v))
+
+ if version_level >= 0:
+ res.append('{0}={1}'.format(version_arg, version_level))
if 'import_dirs' in kwargs:
import_dirs = kwargs.pop('import_dirs')
@@ -378,7 +418,11 @@ class DCompiler(Compiler):
return args
def get_debug_args(self, is_debug):
- return clike_debug_args[is_debug]
+ ddebug_args = []
+ if is_debug:
+ ddebug_args = [d_feature_args[self.id]['debug']]
+
+ return clike_debug_args[is_debug] + ddebug_args
def get_crt_args(self, crt_val, buildtype):
if not is_windows():
diff --git a/test cases/d/9 features/app.d b/test cases/d/9 features/app.d
index 6b43bf0..05c56ca 100644
--- a/test cases/d/9 features/app.d
+++ b/test cases/d/9 features/app.d
@@ -41,6 +41,30 @@ void main (string[] args)
exit (1);
}
}
+
+ version (With_VersionInteger)
+ version(3) exit(0);
+
+ version (With_Debug)
+ debug exit(0);
+
+ version (With_DebugInteger)
+ debug(3) exit(0);
+
+ version (With_DebugIdentifier)
+ debug(DebugIdentifier) exit(0);
+
+ version (With_DebugAll) {
+ int dbg = 0;
+ debug dbg++;
+ debug(2) dbg++;
+ debug(3) dbg++;
+ debug(4) dbg++;
+ debug(DebugIdentifier) dbg++;
+
+ if (dbg == 5)
+ exit(0);
+ }
// we fail here
exit (1);
diff --git a/test cases/d/9 features/meson.build b/test cases/d/9 features/meson.build
index 694e488..06f0341 100644
--- a/test cases/d/9 features/meson.build
+++ b/test cases/d/9 features/meson.build
@@ -1,4 +1,4 @@
-project('D Features', 'd')
+project('D Features', 'd', default_options : ['debug=false'])
# ONLY FOR BACKWARDS COMPATIBILITY.
# DO NOT DO THIS IN NEW CODE!
@@ -44,3 +44,63 @@ e_test = executable('dapp_test',
d_unittest: true
)
test('dapp_test', e_test)
+
+# test version level
+e_version_int = executable('dapp_version_int',
+ test_src,
+ d_import_dirs: [data_dir],
+ d_module_versions: ['With_VersionInteger', 3],
+)
+test('dapp_version_int_t', e_version_int, args: ['debug'])
+
+# test version level failure
+e_version_int_fail = executable('dapp_version_int_fail',
+ test_src,
+ d_import_dirs: [data_dir],
+ d_module_versions: ['With_VersionInteger', 2],
+)
+test('dapp_version_int_t_fail', e_version_int_fail, args: ['debug'], should_fail: true)
+
+# test debug conditions: disabled
+e_no_debug = executable('dapp_no_debug',
+ test_src,
+ d_import_dirs: [data_dir],
+ d_module_versions: ['With_Debug'],
+)
+test('dapp_no_debug_t_fail', e_no_debug, args: ['debug'], should_fail: true)
+
+# test debug conditions: enabled
+e_debug = executable('dapp_debug',
+ test_src,
+ d_import_dirs: [data_dir],
+ d_module_versions: ['With_Debug'],
+ d_debug: 1,
+)
+test('dapp_debug_t', e_debug, args: ['debug'])
+
+# test debug conditions: integer
+e_debug_int = executable('dapp_debug_int',
+ test_src,
+ d_import_dirs: [data_dir],
+ d_module_versions: ['With_DebugInteger'],
+ d_debug: 3,
+)
+test('dapp_debug_int_t', e_debug_int, args: ['debug'])
+
+# test debug conditions: identifier
+e_debug_ident = executable('dapp_debug_ident',
+ test_src,
+ d_import_dirs: [data_dir],
+ d_module_versions: ['With_DebugIdentifier'],
+ d_debug: 'DebugIdentifier',
+)
+test('dapp_debug_ident_t', e_debug_ident, args: ['debug'])
+
+# test with all debug conditions at once, and with redundant values
+e_debug_all = executable('dapp_debug_all',
+ test_src,
+ d_import_dirs: [data_dir],
+ d_module_versions: ['With_DebugAll'],
+ d_debug: ['4', 'DebugIdentifier', 2, 'DebugIdentifierUnused'],
+)
+test('dapp_debug_all_t', e_debug_all, args: ['debug'])