diff options
author | Jussi Pakkanen <jpakkane@gmail.com> | 2016-08-21 13:22:19 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-08-21 13:22:19 +0300 |
commit | 399d65380394556ba5cd1c2a3b364f891d095bfe (patch) | |
tree | 39192e313c0108ef43bef8ae2331ffe8b08dc8ce | |
parent | 5a926172e6e7870574585b5fe742fcf3e48b4398 (diff) | |
parent | 309f7a1b4a7179f44f53b75736b7cd6030f9f40d (diff) | |
download | meson-399d65380394556ba5cd1c2a3b364f891d095bfe.zip meson-399d65380394556ba5cd1c2a3b364f891d095bfe.tar.gz meson-399d65380394556ba5cd1c2a3b364f891d095bfe.tar.bz2 |
Merge pull request #685 from ximion/master
Implement D support
32 files changed, 537 insertions, 5 deletions
diff --git a/authors.txt b/authors.txt index 4244917..e9fceb0 100644 --- a/authors.txt +++ b/authors.txt @@ -40,3 +40,4 @@ Noam Meltzer Vincent Szolnoky Zhe Wang Wim Taymans +Matthias Klumpp diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 1f1c3ca..806a6f3 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -16,6 +16,7 @@ import os, pickle, re from .. import build from .. import dependencies from .. import mesonlib +from .. import compilers import json import subprocess from ..mesonlib import MesonException @@ -233,6 +234,9 @@ class Backend(): def has_swift(self, target): return self.has_source_suffix(target, '.swift') + def has_d(self, target): + return self.has_source_suffix(target, '.d') + def determine_linker(self, target, src): if isinstance(target, build.StaticLibrary): if self.build.static_cross_linker is not None: @@ -358,7 +362,10 @@ class Backend(): if not isinstance(d, build.StaticLibrary) and\ not isinstance(d, build.SharedLibrary): raise RuntimeError('Tried to link with a non-library target "%s".' % d.get_basename()) - args.append(self.get_target_filename_for_linking(d)) + if isinstance(compiler, compilers.LLVMDCompiler): + args.extend(['-L', self.get_target_filename_for_linking(d)]) + else: + args.append(self.get_target_filename_for_linking(d)) # If you have executable e that links to shared lib s1 that links to shared library s2 # you have to specify s2 as well as s1 when linking e even if e does not directly use # s2. Gcc handles this case fine but Clang does not for some reason. Thus we need to diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 0922dfb..94b95c2 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -17,7 +17,7 @@ from . import environment from . import dependencies from . import mlog import copy, os, re -from .mesonlib import File, flatten, MesonException +from .mesonlib import File, flatten, MesonException, stringlistify from .environment import for_windows, for_darwin known_basic_kwargs = {'install' : True, @@ -27,6 +27,7 @@ known_basic_kwargs = {'install' : True, 'cpp_args' : True, 'cs_args' : True, 'vala_args' : True, + 'd_args' : True, 'link_args' : True, 'link_depends': True, 'link_with' : True, @@ -385,6 +386,8 @@ class BuildTarget(): if not isinstance(valalist, list): valalist = [valalist] self.add_compiler_args('vala', valalist) + dlist = stringlistify(kwargs.get('d_args', [])) + self.add_compiler_args('d', dlist) self.link_args = kwargs.get('link_args', []) if not isinstance(self.link_args, list): self.link_args = [self.link_args] diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py index 453fe74..64a1410 100644 --- a/mesonbuild/compilers.py +++ b/mesonbuild/compilers.py @@ -23,7 +23,7 @@ from . import coredata about. To support a new compiler, add its information below. Also add corresponding autodetection code in environment.py.""" -header_suffixes = ['h', 'hh', 'hpp', 'hxx', 'H', 'ipp', 'moc', 'vapi'] +header_suffixes = ['h', 'hh', 'hpp', 'hxx', 'H', 'ipp', 'moc', 'vapi', 'di'] cpp_suffixes = ['cc', 'cpp', 'cxx', 'h', 'hh', 'hpp', 'ipp', 'hxx', 'c++'] c_suffixes = ['c'] clike_suffixes = c_suffixes + cpp_suffixes @@ -108,6 +108,27 @@ rust_buildtype_args = {'plain' : [], 'minsize' : [], } +d_gdc_buildtype_args = {'plain' : [], + 'debug' : ['-g', '-O0'], + 'debugoptimized' : ['-g', '-O'], + 'release' : ['-O3', '-frelease'], + 'minsize' : [], + } + +d_ldc_buildtype_args = {'plain' : [], + 'debug' : ['-g', '-O0'], + 'debugoptimized' : ['-g', '-O'], + 'release' : ['-O3', '-release'], + 'minsize' : [], + } + +d_dmd_buildtype_args = {'plain' : [], + 'debug' : ['-g'], + 'debugoptimized' : ['-g', '-O'], + 'release' : ['-O', '-release'], + 'minsize' : [], + } + mono_buildtype_args = {'plain' : [], 'debug' : ['-debug'], 'debugoptimized': ['-debug', '-optimize+'], @@ -1425,6 +1446,236 @@ class SwiftCompiler(Compiler): suffix = filename.split('.')[-1] return suffix in ('swift') +class DCompiler(Compiler): + def __init__(self, exelist, version, is_cross): + super().__init__(exelist, version) + self.id = 'unknown' + self.language = 'd' + self.is_cross = is_cross + + def sanity_check(self, work_dir, environment): + source_name = os.path.join(work_dir, 'sanity.d') + output_name = os.path.join(work_dir, 'dtest') + ofile = open(source_name, 'w') + ofile.write('''void main() { +} +''') + ofile.close() + pc = subprocess.Popen(self.exelist + self.get_output_args(output_name) + [source_name], cwd=work_dir) + pc.wait() + if pc.returncode != 0: + raise EnvironmentException('D compiler %s can not compile programs.' % self.name_string()) + if subprocess.call(output_name) != 0: + raise EnvironmentException('Executables created by D compiler %s are not runnable.' % self.name_string()) + + def needs_static_linker(self): + return True + + def name_string(self): + return ' '.join(self.exelist) + + def get_exelist(self): + return self.exelist + + def get_id(self): + return self.id + + def get_language(self): + return self.language + + def can_compile(self, fname): + suffix = fname.split('.')[-1] + return suffix in ('d', 'di') + + def get_linker_exelist(self): + return self.exelist[:] + + def depfile_for_object(self, objfile): + return objfile + '.' + self.get_depfile_suffix() + + def get_depfile_suffix(self): + return 'dep' + + def get_pic_args(self): + return ['-fPIC'] + + def get_std_shared_lib_link_args(self): + return ['-shared'] + + def get_soname_args(self, shlib_name, path, soversion): + return [] + + def get_unittest_args(self): + return ['-unittest'] + + def get_buildtype_linker_args(self, buildtype): + return [] + + def get_std_exe_link_args(self): + return [] + + def build_rpath_args(self, build_dir, rpath_paths, install_rpath): + # This method is to be used by LDC and DMD. + # GDC can deal with the verbatim flags. + if len(rpath_paths) == 0 and len(install_rpath) == 0: + return [] + paths = ':'.join([os.path.join(build_dir, p) for p in rpath_paths]) + if len(paths) < len(install_rpath): + padding = 'X'*(len(install_rpath) - len(paths)) + if len(paths) == 0: + paths = padding + else: + paths = paths + ':' + padding + return ['-L-rpath={}'.format(paths)] + + def translate_args_to_nongnu(self, args): + dcargs = [] + # Translate common arguments to flags the LDC/DMD compilers + # can understand. + # The flags might have been added by pkg-config files, + # and are therefore out of the user's control. + for arg in args: + if arg == '-pthread': + continue + if arg.startswith('-Wl,'): + linkargs = arg[arg.index(',')+1:].split(',') + for la in linkargs: + dcargs.append('-L' + la.strip()) + continue + elif arg.startswith(('-l', '-L')): + # translate library link flag + dcargs.append('-L' + arg) + continue + dcargs.append(arg) + + return dcargs + +class GnuDCompiler(DCompiler): + def __init__(self, exelist, version, is_cross): + DCompiler.__init__(self, exelist, version, is_cross) + self.id = 'gcc' + self.warn_args = {'1': ['-Wall', '-Wdeprecated'], + '2': ['-Wall', '-Wextra', '-Wdeprecated'], + '3': ['-Wall', '-Wextra', '-Wdeprecated', '-Wpedantic']} + + def get_dependency_gen_args(self, outtarget, outfile): + # FIXME: Passing -fmake-deps results in a file-not-found message. + # Investigate why. + return [] + + def get_output_args(self, target): + return ['-o', target] + + def get_compile_only_args(self): + return ['-c'] + + def get_linker_output_args(self, target): + return ['-o', target] + + def get_include_args(self, path, is_system): + return ['-I' + path] + + def get_warn_args(self, level): + return self.warn_args[level] + + def get_werror_args(self): + return ['-Werror'] + + def get_buildtype_args(self, buildtype): + return d_gdc_buildtype_args[buildtype] + + def build_rpath_args(self, build_dir, rpath_paths, install_rpath): + return build_unix_rpath_args(build_dir, rpath_paths, install_rpath) + + def get_unittest_args(self): + return ['-funittest'] + +class LLVMDCompiler(DCompiler): + def __init__(self, exelist, version, is_cross): + DCompiler.__init__(self, exelist, version, is_cross) + self.id = 'llvm' + + def get_dependency_gen_args(self, outtarget, outfile): + # LDC using the -deps flag returns a non-Makefile dependency-info file, which + # the backends can not use. So we disable this feature for now. + return [] + + def get_output_args(self, target): + return ['-of', target] + + def get_compile_only_args(self): + return ['-c'] + + def get_linker_output_args(self, target): + return ['-of', target] + + def get_include_args(self, path, is_system): + return ['-I' + path] + + def get_warn_args(self, level): + if level == '2': + return ['-wi'] + else: + return ['-w'] + + def get_coverage_args(self): + return ['-cov'] + + def get_buildtype_args(self, buildtype): + return d_ldc_buildtype_args[buildtype] + + def get_pic_args(self): + return ['-relocation-model=pic'] + + def unix_link_flags_to_native(self, args): + return self.translate_args_to_nongnu(args) + + def unix_compile_flags_to_native(self, args): + return self.translate_args_to_nongnu(args) + +class DmdDCompiler(DCompiler): + def __init__(self, exelist, version, is_cross): + DCompiler.__init__(self, exelist, version, is_cross) + self.id = 'dmd' + + def get_dependency_gen_args(self, outtarget, outfile): + # LDC using the -deps flag returns a non-Makefile dependency-info file, which + # the backends can not use. So we disable this feature for now. + return [] + + def get_output_args(self, target): + return ['-of' + target] + + def get_werror_args(self): + return ['-w'] + + def get_compile_only_args(self): + return ['-c'] + + def get_linker_output_args(self, target): + return ['-of' + target] + + def get_include_args(self, path, is_system): + return ['-I' + path] + + def get_warn_args(self, level): + return [] + + def get_coverage_args(self): + return ['-cov'] + + def get_buildtype_args(self, buildtype): + return d_dmd_buildtype_args[buildtype] + + def get_std_shared_lib_link_args(self): + return ['-shared', '-defaultlib=libphobos2.so'] + + def unix_link_flags_to_native(self, args): + return self.translate_args_to_nongnu(args) + + def unix_compile_flags_to_native(self, args): + return self.translate_args_to_nongnu(args) + class VisualStudioCCompiler(CCompiler): std_warn_args = ['/W3'] std_opt_args= ['/O2'] diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index 16af0d1..b040aa4 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -18,6 +18,7 @@ from . import mesonlib from . import mlog from .compilers import * import configparser +import shutil build_filename = 'meson.build' @@ -580,6 +581,48 @@ class Environment(): return RustCompiler(exelist, version) raise EnvironmentException('Unknown compiler "' + ' '.join(exelist) + '"') + def detect_d_compiler(self): + exelist = None + is_cross = False + # Search for a D compiler. + # We prefer LDC over GDC unless overridden with the DC + # environment variable because LDC has a much more + # up to date language version at time (2016). + if 'DC' in os.environ: + exelist = os.environ['DC'].split() + elif self.is_cross_build() and want_cross: + exelist = [self.cross_info.config['binaries']['d']] + is_cross = True + elif shutil.which("ldc2"): + exelist = ['ldc2'] + elif shutil.which("ldc"): + exelist = ['ldc'] + elif shutil.which("gdc"): + exelist = ['gdc'] + elif shutil.which("dmd"): + exelist = ['dmd'] + else: + raise EnvironmentException('Could not find any supported D compiler.') + + try: + p = subprocess.Popen(exelist + ['--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + except OSError: + raise EnvironmentException('Could not execute D compiler "%s"' % ' '.join(exelist)) + (out, _) = p.communicate() + out = out.decode(errors='ignore') + vmatch = re.search(Environment.version_regex, out) + if vmatch: + version = vmatch.group(0) + else: + version = 'unknown version' + if 'LLVM D compiler' in out: + return LLVMDCompiler(exelist, version, is_cross) + elif 'gdc' in out: + return GnuDCompiler(exelist, version, is_cross) + elif 'Digital Mars' in out: + return DmdDCompiler(exelist, version, is_cross) + raise EnvironmentException('Unknown compiler "' + ' '.join(exelist) + '"') + def detect_swift_compiler(self): exelist = ['swiftc'] try: @@ -712,13 +755,14 @@ def get_args_from_envvars(lang, compiler_is_linker): if val: mlog.log('Appending {} from environment: {!r}'.format(var, val)) - if lang not in ('c', 'cpp', 'objc', 'objcpp', 'fortran'): + if lang not in ('c', 'cpp', 'objc', 'objcpp', 'fortran', 'd'): return ([], []) # Compile flags cflags_mapping = {'c': 'CFLAGS', 'cpp': 'CXXFLAGS', 'objc': 'OBJCFLAGS', 'objcpp': 'OBJCXXFLAGS', - 'fortran': 'FFLAGS'} + 'fortran': 'FFLAGS', + 'd': 'DFLAGS'} compile_flags = os.environ.get(cflags_mapping[lang], '') log_var(cflags_mapping[lang], compile_flags) compile_flags = compile_flags.split() diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index 8645b68..f9841bd 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -597,6 +597,7 @@ class CompilerHolder(InterpreterObject): 'find_library': self.find_library_method, 'has_argument' : self.has_argument_method, 'first_supported_argument' : self.first_supported_argument_method, + 'unittest_args' : self.unittest_args_method, }) def version_method(self, args, kwargs): @@ -650,6 +651,12 @@ class CompilerHolder(InterpreterObject): def get_id_method(self, args, kwargs): return self.compiler.get_id() + def unittest_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.language)) + return self.compiler.get_unittest_args() + def has_member_method(self, args, kwargs): if len(args) != 2: raise InterpreterException('Has_member takes exactly two arguments.') @@ -1566,6 +1573,10 @@ class Interpreter(): comp = self.environment.detect_vala_compiler() if need_cross_compiler: cross_comp = comp # Vala is too (I think). + elif lang == 'd': + comp = self.environment.detect_d_compiler() + if need_cross_compiler: + cross_comp = comp # D as well (AFAIK). elif lang == 'rust': comp = self.environment.detect_rust_compiler() if need_cross_compiler: diff --git a/mesonbuild/optinterpreter.py b/mesonbuild/optinterpreter.py index 409f9dc..e38bdb9 100644 --- a/mesonbuild/optinterpreter.py +++ b/mesonbuild/optinterpreter.py @@ -20,6 +20,7 @@ import os, re forbidden_option_names = coredata.get_builtin_options() forbidden_prefixes = {'c_': True, 'cpp_': True, + 'd_': True, 'rust_': True, 'fortran_': True, 'objc_': True, diff --git a/run_tests.py b/run_tests.py index 34258d8..3e49662 100755 --- a/run_tests.py +++ b/run_tests.py @@ -304,6 +304,17 @@ def gather_tests(testdir): tests = [os.path.join(testdir, t[1]) for t in testlist] return tests +def have_d_compiler(): + if shutil.which("ldc2"): + return True + elif shutil.which("ldc"): + return True + elif shutil.which("gdc"): + return True + elif shutil.which("dmd"): + return True + return False + def detect_tests_to_run(): all_tests = [] all_tests.append(('common', gather_tests('test cases/common'), False)) @@ -318,6 +329,7 @@ def detect_tests_to_run(): all_tests.append(('C#', gather_tests('test cases/csharp'), False if shutil.which('mcs') else True)) all_tests.append(('vala', gather_tests('test cases/vala'), False if shutil.which('valac') else True)) all_tests.append(('rust', gather_tests('test cases/rust'), False if shutil.which('rustc') else True)) + all_tests.append(('d', gather_tests('test cases/d'), False if have_d_compiler() else True)) all_tests.append(('objective c', gather_tests('test cases/objc'), False if not mesonlib.is_windows() else True)) all_tests.append(('fortran', gather_tests('test cases/fortran'), False if shutil.which('gfortran') else True)) all_tests.append(('swift', gather_tests('test cases/swift'), False if shutil.which('swiftc') else True)) diff --git a/test cases/d/1 simple/app.d b/test cases/d/1 simple/app.d new file mode 100644 index 0000000..0be1d2c --- /dev/null +++ b/test cases/d/1 simple/app.d @@ -0,0 +1,8 @@ + +import std.stdio; +import utils; + +void main () +{ + printGreeting ("a Meson D test"); +} diff --git a/test cases/d/1 simple/installed_files.txt b/test cases/d/1 simple/installed_files.txt new file mode 100644 index 0000000..9374c54 --- /dev/null +++ b/test cases/d/1 simple/installed_files.txt @@ -0,0 +1 @@ +usr/bin/dsimpleapp?exe diff --git a/test cases/d/1 simple/meson.build b/test cases/d/1 simple/meson.build new file mode 100644 index 0000000..a10b67b --- /dev/null +++ b/test cases/d/1 simple/meson.build @@ -0,0 +1,4 @@ +project('D Simple Test', 'd') + +e = executable('dsimpleapp', ['app.d', 'utils.d'], install : true) +test('apptest', e) diff --git a/test cases/d/1 simple/utils.d b/test cases/d/1 simple/utils.d new file mode 100644 index 0000000..8645548 --- /dev/null +++ b/test cases/d/1 simple/utils.d @@ -0,0 +1,8 @@ + +import std.stdio; +import std.string : format; + +void printGreeting (string name) +{ + writeln ("Hello, I am %s.".format (name)); +} diff --git a/test cases/d/2 static library/app.d b/test cases/d/2 static library/app.d new file mode 100644 index 0000000..5d84a69 --- /dev/null +++ b/test cases/d/2 static library/app.d @@ -0,0 +1,8 @@ + +import libstuff; + +void main () +{ + immutable ret = printLibraryString ("foo"); + assert (ret == 4); +} diff --git a/test cases/d/2 static library/installed_files.txt b/test cases/d/2 static library/installed_files.txt new file mode 100644 index 0000000..0f2bab4 --- /dev/null +++ b/test cases/d/2 static library/installed_files.txt @@ -0,0 +1,2 @@ +usr/bin/app_s?exe +usr/lib/libstuff.a diff --git a/test cases/d/2 static library/libstuff.d b/test cases/d/2 static library/libstuff.d new file mode 100644 index 0000000..fd3b4d0 --- /dev/null +++ b/test cases/d/2 static library/libstuff.d @@ -0,0 +1,9 @@ + +import std.stdio; +import std.string : format; + +int printLibraryString (string str) +{ + writeln ("Static Library says: %s".format (str)); + return 4; +} diff --git a/test cases/d/2 static library/meson.build b/test cases/d/2 static library/meson.build new file mode 100644 index 0000000..88ed2cb --- /dev/null +++ b/test cases/d/2 static library/meson.build @@ -0,0 +1,5 @@ +project('D Static Library', 'd') + +lstatic = static_library('stuff', 'libstuff.d', install : true) +es = executable('app_s', 'app.d', link_with : lstatic, install : true) +test('linktest_static', es) diff --git a/test cases/d/3 shared library/app.d b/test cases/d/3 shared library/app.d new file mode 100644 index 0000000..5d84a69 --- /dev/null +++ b/test cases/d/3 shared library/app.d @@ -0,0 +1,8 @@ + +import libstuff; + +void main () +{ + immutable ret = printLibraryString ("foo"); + assert (ret == 4); +} diff --git a/test cases/d/3 shared library/installed_files.txt b/test cases/d/3 shared library/installed_files.txt new file mode 100644 index 0000000..d6a4dad --- /dev/null +++ b/test cases/d/3 shared library/installed_files.txt @@ -0,0 +1,2 @@ +usr/bin/app_d?exe +usr/lib/libstuff.so diff --git a/test cases/d/3 shared library/libstuff.d b/test cases/d/3 shared library/libstuff.d new file mode 100644 index 0000000..676a643 --- /dev/null +++ b/test cases/d/3 shared library/libstuff.d @@ -0,0 +1,9 @@ + +import std.stdio; +import std.string : format; + +int printLibraryString (string str) +{ + writeln ("Library says: %s".format (str)); + return 4; +} diff --git a/test cases/d/3 shared library/meson.build b/test cases/d/3 shared library/meson.build new file mode 100644 index 0000000..5dae66b --- /dev/null +++ b/test cases/d/3 shared library/meson.build @@ -0,0 +1,12 @@ +project('D Shared Library', 'd') + +if meson.get_compiler('d').get_id() != 'gcc' + + ldyn = shared_library('stuff', 'libstuff.d', install : true) + ed = executable('app_d', 'app.d', link_with : ldyn, install : true) + test('linktest_dyn', ed) + +else + message('GDC can not build shared libraries. Test skipped.') + install_data('no-installed-files', install_dir : '') +endif diff --git a/test cases/d/3 shared library/no-installed-files b/test cases/d/3 shared library/no-installed-files new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test cases/d/3 shared library/no-installed-files diff --git a/test cases/d/4 library versions/installed_files.txt b/test cases/d/4 library versions/installed_files.txt new file mode 100644 index 0000000..b997e53 --- /dev/null +++ b/test cases/d/4 library versions/installed_files.txt @@ -0,0 +1,9 @@ +usr/lib/libsome.so +usr/lib/libsome.so.0 +usr/lib/libsome.so.1.2.3 +usr/lib/libnoversion.so +usr/lib/libonlyversion.so +usr/lib/libonlyversion.so.1 +usr/lib/libonlyversion.so.1.4.5 +usr/lib/libonlysoversion.so +usr/lib/libonlysoversion.so.5 diff --git a/test cases/d/4 library versions/lib.d b/test cases/d/4 library versions/lib.d new file mode 100644 index 0000000..94df91e --- /dev/null +++ b/test cases/d/4 library versions/lib.d @@ -0,0 +1,10 @@ + +import std.stdio; +import std.string : format; + +@safe +int printLibraryString (string str) +{ + writeln ("Library says: %s".format (str)); + return 4; +} diff --git a/test cases/d/4 library versions/meson.build b/test cases/d/4 library versions/meson.build new file mode 100644 index 0000000..26cc38a --- /dev/null +++ b/test cases/d/4 library versions/meson.build @@ -0,0 +1,25 @@ +project('D library versions', 'd') + +if meson.get_compiler('d').get_id() == 'gcc' + message('GDC can not build shared libraries. Test skipped.') + install_data('no-installed-files', install_dir : '') +else + + shared_library('some', 'lib.d', + version : '1.2.3', + soversion : '0', + install : true) + + shared_library('noversion', 'lib.d', + install : true) + + shared_library('onlyversion', 'lib.d', + version : '1.4.5', + install : true) + + shared_library('onlysoversion', 'lib.d', + # Also test that int soversion is acceptable + soversion : 5, + install : true) + +endif diff --git a/test cases/d/4 library versions/no-installed-files b/test cases/d/4 library versions/no-installed-files new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test cases/d/4 library versions/no-installed-files diff --git a/test cases/d/5 mixed/app.d b/test cases/d/5 mixed/app.d new file mode 100644 index 0000000..6ab5d97 --- /dev/null +++ b/test cases/d/5 mixed/app.d @@ -0,0 +1,8 @@ + +extern(C) int printLibraryString(const char *str); + +void main () +{ + immutable ret = printLibraryString ("C foo"); + assert (ret == 3); +} diff --git a/test cases/d/5 mixed/installed_files.txt b/test cases/d/5 mixed/installed_files.txt new file mode 100644 index 0000000..9e7fccc --- /dev/null +++ b/test cases/d/5 mixed/installed_files.txt @@ -0,0 +1,4 @@ +usr/bin/appdc_d?exe +usr/lib/libstuff.so +usr/bin/appdc_s?exe +usr/lib/libstuff.a diff --git a/test cases/d/5 mixed/libstuff.c b/test cases/d/5 mixed/libstuff.c new file mode 100644 index 0000000..92d6600 --- /dev/null +++ b/test cases/d/5 mixed/libstuff.c @@ -0,0 +1,18 @@ +#if defined _WIN32 || defined __CYGWIN__ + #define DLL_PUBLIC __declspec(dllexport) +#else + #if defined __GNUC__ + #define DLL_PUBLIC __attribute__ ((visibility("default"))) + #else + #pragma message ("Compiler does not support symbol visibility.") + #define DLL_PUBLIC + #endif +#endif + +#include <stdio.h> + +int DLL_PUBLIC printLibraryString(const char *str) +{ + printf("C library says: %s", str); + return 3; +} diff --git a/test cases/d/5 mixed/meson.build b/test cases/d/5 mixed/meson.build new file mode 100644 index 0000000..3dad66d --- /dev/null +++ b/test cases/d/5 mixed/meson.build @@ -0,0 +1,9 @@ +project('Mixing C and D', 'd', 'c') + +ldyn = shared_library('stuff', 'libstuff.c', install : true) +ed = executable('appdc_d', 'app.d', link_with : ldyn, install : true) +test('linktest_cdyn', ed) + +lstatic = static_library('stuff', 'libstuff.c', install : true) +es = executable('appdc_s', 'app.d', link_with : lstatic, install : true) +test('linktest_cstatic', es) diff --git a/test cases/d/6 unittest/app.d b/test cases/d/6 unittest/app.d new file mode 100644 index 0000000..751e754 --- /dev/null +++ b/test cases/d/6 unittest/app.d @@ -0,0 +1,34 @@ + +import std.stdio; + +uint getFour () +{ + auto getTwo () + { + return 1 + 1; + } + + return getTwo () + getTwo (); +} + +void main () +{ + import core.stdc.stdlib : exit; + + writeln ("Four: ", getFour ()); + exit (4); +} + +unittest +{ + writeln ("TEST"); + import core.stdc.stdlib : exit; + + assert (getFour () > 2); + assert (getFour () == 4); + + // we explicitly terminate here to give the unittest program a different exit + // code than the main application has. + // (this prevents the regular main() from being executed) + exit (0); +} diff --git a/test cases/d/6 unittest/installed_files.txt b/test cases/d/6 unittest/installed_files.txt new file mode 100644 index 0000000..e718389 --- /dev/null +++ b/test cases/d/6 unittest/installed_files.txt @@ -0,0 +1 @@ +usr/bin/dapp?exe diff --git a/test cases/d/6 unittest/meson.build b/test cases/d/6 unittest/meson.build new file mode 100644 index 0000000..1551e94 --- /dev/null +++ b/test cases/d/6 unittest/meson.build @@ -0,0 +1,8 @@ +project('D Unittests', 'd') + +e = executable('dapp', 'app.d', install : true) +test('dapp_run', e, should_fail: true) + +e_test = executable('dapp_test', 'app.d', + d_args: meson.get_compiler('d').unittest_args()) +test('dapp_test', e_test) |