diff options
-rw-r--r-- | compilers.py | 95 | ||||
-rw-r--r-- | interpreter.py | 20 | ||||
-rw-r--r-- | mesonlib.py | 10 | ||||
-rw-r--r-- | test cases/linuxlike/2 external library/meson.build | 19 |
4 files changed, 98 insertions, 46 deletions
diff --git a/compilers.py b/compilers.py index 72e9f30..ee5cc10 100644 --- a/compilers.py +++ b/compilers.py @@ -132,7 +132,7 @@ class Compiler(): elif type(exelist) == type([]): self.exelist = exelist else: - raise TypeError('Unknown argument to CCompiler') + raise TypeError('Unknown argument to Compiler') self.version = version def get_always_args(self): @@ -150,6 +150,24 @@ class Compiler(): def get_option_link_args(self, options): return [] + def has_header(self, hname): + raise EnvironmentException('Language %s does not support header checks.' % self.language) + + def compiles(self, code): + raise EnvironmentException('Language %s does not support compile checks.' % self.language) + + def run(self, code): + raise EnvironmentException('Language %s does not support run checks.' % self.language) + + def sizeof(self, element, prefix, env): + raise EnvironmentException('Language %s does not support sizeof checks.' % self.language) + + def alignment(self, typename, env): + raise EnvironmentException('Language %s does not support alignment checks.' % self.language) + + def has_function(self, funcname, prefix, env): + raise EnvironmentException('Language %s does not support function checks.' % self.language) + class CCompiler(Compiler): def __init__(self, exelist, version, is_cross, exe_wrapper=None): super().__init__(exelist, version) @@ -295,18 +313,11 @@ int someSymbolHereJustForFun; ''' return self.compiles(templ % hname) - def compiles(self, code, extra_args = []): - suflen = len(self.default_suffix) - (fd, srcname) = tempfile.mkstemp(suffix='.'+self.default_suffix) - os.close(fd) - ofile = open(srcname, 'w') - ofile.write(code) - ofile.close() + def compile(self, code, srcname, extra_args=[]): commands = self.get_exelist() commands += extra_args - commands += self.get_compile_only_args() commands.append(srcname) - mlog.debug('Running compile test.') + mlog.debug('Running compile:') mlog.debug('Command line: ', ' '.join(commands)) mlog.debug('Code:\n', code) p = subprocess.Popen(commands, cwd=os.path.split(srcname)[0], stdout=subprocess.PIPE, stderr=subprocess.PIPE) @@ -316,6 +327,17 @@ int someSymbolHereJustForFun; mlog.debug('Compiler stdout:\n', stdo) mlog.debug('Compiler stderr:\n', stde) os.remove(srcname) + return p + + def compiles(self, code, extra_args = []): + suflen = len(self.default_suffix) + (fd, srcname) = tempfile.mkstemp(suffix='.'+self.default_suffix) + os.close(fd) + ofile = open(srcname, 'w') + ofile.write(code) + ofile.close() + extra_args = extra_args + self.get_compile_only_args() + p = self.compile(code, srcname, extra_args) try: trial = srcname[:-suflen] + 'o' os.remove(trial) @@ -327,6 +349,23 @@ int someSymbolHereJustForFun; pass return p.returncode == 0 + def links(self, code, extra_args = []): + suflen = len(self.default_suffix) + (fd, srcname) = tempfile.mkstemp(suffix='.'+self.default_suffix) + os.close(fd) + (fd, dstname) = tempfile.mkstemp() + os.close(fd) + ofile = open(srcname, 'w') + ofile.write(code) + ofile.close() + extra_args = extra_args + self.get_output_args(dstname) + p = self.compile(code, srcname, extra_args) + try: + os.remove(dstname) + except FileNotFoundError: + pass + return p.returncode == 0 + def run(self, code): mlog.debug('Running code:\n\n', code) if self.is_cross and self.exe_wrapper is None: @@ -678,24 +717,6 @@ class MonoCompiler(Compiler): def needs_static_linker(self): return False - def has_header(self, hname): - raise EnvironmentException('Mono does not support header checks.') - - def compiles(self, code): - raise EnvironmentException('Mono does not support compile checks.') - - def run(self, code): - raise EnvironmentException('Mono does not support run checks.') - - def sizeof(self, element, prefix, env): - raise EnvironmentException('Mono does not support sizeof checks.') - - def alignment(self, typename, env): - raise EnvironmentException('Mono does not support alignment checks.') - - def has_function(self, funcname, prefix, env): - raise EnvironmentException('Mono does not support function checks.') - def get_buildtype_args(self, buildtype): return mono_buildtype_args[buildtype] @@ -809,24 +830,6 @@ class JavaCompiler(Compiler): def needs_static_linker(self): return False - def has_header(self, hname): - raise EnvironmentException('Java does not support header checks.') - - def compiles(self, code): - raise EnvironmentException('Java does not support compile checks.') - - def run(self, code): - raise EnvironmentException('Java does not support run checks.') - - def sizeof(self, element, prefix, env): - raise EnvironmentException('Java does not support sizeof checks.') - - def alignment(self, typename, env): - raise EnvironmentException('Java does not support alignment checks.') - - def has_function(self, funcname, prefix, env): - raise EnvironmentException('Java does not support function checks.') - class ValaCompiler(Compiler): def __init__(self, exelist, version): super().__init__(exelist, version) diff --git a/interpreter.py b/interpreter.py index 968b2b9..9d57136 100644 --- a/interpreter.py +++ b/interpreter.py @@ -564,6 +564,7 @@ class CompilerHolder(InterpreterObject): self.compiler = compiler self.environment = env self.methods.update({'compiles': self.compiles_method, + 'links': self.links_method, 'get_id': self.get_id_method, 'sizeof': self.sizeof_method, 'has_header': self.has_header_method, @@ -692,6 +693,25 @@ class CompilerHolder(InterpreterObject): mlog.log('Checking if "', mlog.bold(testname), '" compiles : ', h, sep='') return result + def links_method(self, args, kwargs): + if len(args) != 1: + raise InterpreterException('links method takes exactly one argument.') + check_stringlist(args) + string = args[0] + testname = kwargs.get('name', '') + if not isinstance(testname, str): + raise InterpreterException('Testname argument must be a string.') + args = kwargs.get('args', []) + args = mesonlib.stringlistify(args) + result = self.compiler.links(string, args) + if len(testname) > 0: + if result: + h = mlog.green('YES') + else: + h = mlog.red('NO') + mlog.log('Checking if "', mlog.bold(testname), '" links : ', h, sep='') + return result + def has_header_method(self, args, kwargs): if len(args) != 1: raise InterpreterException('has_header method takes exactly one argument.') diff --git a/mesonlib.py b/mesonlib.py index 0c7c308..4060d3f 100644 --- a/mesonlib.py +++ b/mesonlib.py @@ -255,6 +255,16 @@ def replace_if_different(dst, dst_tmp): pass os.replace(dst_tmp, dst) +def stringlistify(item): + if isinstance(item, str): + item = [item] + if not isinstance(item, list): + raise MesonException('Item is not an array') + for i in item: + if not isinstance(i, str): + raise MesonException('List item not a string.') + return item + class UserOption: def __init__(self, name, description): super().__init__() diff --git a/test cases/linuxlike/2 external library/meson.build b/test cases/linuxlike/2 external library/meson.build index a57864b..8be4daa 100644 --- a/test cases/linuxlike/2 external library/meson.build +++ b/test cases/linuxlike/2 external library/meson.build @@ -1,5 +1,24 @@ project('external library', 'c') zlib = find_library('z') + +# Verify that link testing works. +linkcode = '''#include<zlib.h> +int main(int argc, char **argv) { + void *ptr = (void*)(deflate); + return ptr == 0; +} +''' + +nolinkcode='''int nonexisting(); +int main(int argc, char **argv) { + void *ptr = (void*)(nonexisting); + return ptr == 0; +} +''' +cc = meson.get_compiler('c') +assert(cc.links(linkcode, args : '-lz', name : 'Test link against zlib'), 'Linking test failed.') +assert(not cc.links(nolinkcode, name : 'Failing link'), 'Linking succeeded when it should have failed.') + e = executable('zprog', 'prog.c', dependencies : zlib) test('libtest', e) |