diff options
author | Jussi Pakkanen <jpakkane@gmail.com> | 2017-03-23 16:02:40 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-03-23 16:02:40 -0400 |
commit | df1480fe11e5d4f20b7305abc2129d3c6494d1b5 (patch) | |
tree | e5166265aa96aba3972d5c3d111d31474536b454 /mesonbuild/compilers.py | |
parent | 1efab9b5a9e9cd361658226ede35ff455f954a44 (diff) | |
parent | 2f11e2e4630a7770eddbce7efdd7ce9b63de5ba1 (diff) | |
download | meson-df1480fe11e5d4f20b7305abc2129d3c6494d1b5.zip meson-df1480fe11e5d4f20b7305abc2129d3c6494d1b5.tar.gz meson-df1480fe11e5d4f20b7305abc2129d3c6494d1b5.tar.bz2 |
Merge pull request #1456 from ieei/compute_int
Add compute_int, fixes #435
Diffstat (limited to 'mesonbuild/compilers.py')
-rw-r--r-- | mesonbuild/compilers.py | 91 |
1 files changed, 62 insertions, 29 deletions
diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py index f8c3f6b..519a7d5 100644 --- a/mesonbuild/compilers.py +++ b/mesonbuild/compilers.py @@ -1001,44 +1001,75 @@ class CCompiler(Compiler): mlog.debug(se) return RunResult(True, pe.returncode, so, se) - def _bisect_compiles(self, t, fargs, env, extra_args, dependencies): - # FIXME: Does not actually do bisection right now - for i in range(1, 1024): - fargs['size'] = i - if self.compiles(t.format(**fargs), env, extra_args, dependencies): - if self.id == 'msvc': - # MSVC refuses to construct an array of zero size, so - # the test only succeeds when i is sizeof(element) + 1 - return i - 1 - return i + def _compile_int(self, expression, prefix, env, extra_args, dependencies): + fargs = {'prefix': prefix, 'expression': expression} + t = '''#include <stdio.h> + {prefix} + int main() {{ static int a[1-2*!({expression})]; a[0]=0; return 0; }}''' + return self.compiles(t.format(**fargs), env, extra_args, dependencies) + + def cross_compute_int(self, expression, l, h, guess, prefix, env, extra_args, dependencies): + if isinstance(guess, int): + if self._compile_int('%s == %d' % (expression, guess), prefix, env, extra_args, dependencies): + return guess + + cur = l + while l < h: + cur = int((l + h) / 2) + if cur == l: + break + + if self._compile_int('%s >= %d' % (expression, cur), prefix, env, extra_args, dependencies): + l = cur + else: + h = cur + + if self._compile_int('%s == %d' % (expression, cur), prefix, env, extra_args, dependencies): + return cur raise EnvironmentException('Cross-compile check overflowed') - def cross_sizeof(self, element, prefix, env, extra_args=None, dependencies=None): + def compute_int(self, expression, l, h, guess, prefix, env, extra_args=None, dependencies=None): + if extra_args is None: + extra_args = [] + if self.is_cross: + return self.cross_compute_int(expression, l, h, guess, prefix, env, extra_args, dependencies) + fargs = {'prefix': prefix, 'expression': expression} + t = '''#include<stdio.h> + {prefix} + int main(int argc, char **argv) {{ + printf("%ld\\n", (long)({expression})); + return 0; + }};''' + res = self.run(t.format(**fargs), env, extra_args, dependencies) + if not res.compiled: + return -1 + if res.returncode != 0: + raise EnvironmentException('Could not run compute_int test binary.') + return int(res.stdout) + + def cross_sizeof(self, typename, prefix, env, extra_args=None, dependencies=None): if extra_args is None: extra_args = [] - fargs = {'prefix': prefix, 'name': element} + fargs = {'prefix': prefix, 'type': typename} t = '''#include <stdio.h> {prefix} int main(int argc, char **argv) {{ - {name} something; + {type} something; }}''' if not self.compiles(t.format(**fargs), env, extra_args, dependencies): return -1 - t = '''#include <stdio.h> - {prefix} - int temparray[{size}-sizeof({name})];''' - return self._bisect_compiles(t, fargs, env, extra_args, dependencies) + return self.cross_compute_int('sizeof(%s)' % typename, 1, 128, None, prefix, env, extra_args, dependencies) - def sizeof(self, element, prefix, env, extra_args=None, dependencies=None): + def sizeof(self, typename, prefix, env, extra_args=None, dependencies=None): if extra_args is None: extra_args = [] - fargs = {'prefix': prefix, 'name': element} + fargs = {'prefix': prefix, 'type': typename} if self.is_cross: - return self.cross_sizeof(element, prefix, env, extra_args, dependencies) + return self.cross_sizeof(typename, prefix, env, extra_args, dependencies) t = '''#include<stdio.h> {prefix} int main(int argc, char **argv) {{ - printf("%ld\\n", (long)(sizeof({name}))); + printf("%ld\\n", (long)(sizeof({type}))); return 0; }};''' res = self.run(t.format(**fargs), env, extra_args, dependencies) @@ -1048,32 +1079,34 @@ class CCompiler(Compiler): raise EnvironmentException('Could not run sizeof test binary.') return int(res.stdout) - def cross_alignment(self, typename, env, extra_args=None, dependencies=None): + def cross_alignment(self, typename, prefix, env, extra_args=None, dependencies=None): if extra_args is None: extra_args = [] - fargs = {'type': typename} + fargs = {'prefix': prefix, 'type': typename} t = '''#include <stdio.h> + {prefix} int main(int argc, char **argv) {{ {type} something; }}''' if not self.compiles(t.format(**fargs), env, extra_args, dependencies): return -1 t = '''#include <stddef.h> + {prefix} struct tmp {{ char c; {type} target; - }}; - int testarray[{size}-offsetof(struct tmp, target)];''' - return self._bisect_compiles(t, fargs, env, extra_args, dependencies) + }};''' + return self.cross_compute_int('offsetof(struct tmp, target)', 1, 1024, None, t.format(**fargs), env, extra_args, dependencies) - def alignment(self, typename, env, extra_args=None, dependencies=None): + def alignment(self, typename, prefix, env, extra_args=None, dependencies=None): if extra_args is None: extra_args = [] if self.is_cross: - return self.cross_alignment(typename, env, extra_args, dependencies) - fargs = {'type': typename} + return self.cross_alignment(typename, prefix, env, extra_args, dependencies) + fargs = {'prefix': prefix, 'type': typename} t = '''#include <stdio.h> #include <stddef.h> + {prefix} struct tmp {{ char c; {type} target; |