aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compilers.py95
-rw-r--r--interpreter.py20
-rw-r--r--mesonlib.py10
-rw-r--r--test cases/linuxlike/2 external library/meson.build19
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)