diff options
author | Nirbheek Chauhan <nirbheek@centricular.com> | 2016-11-11 06:12:34 +0530 |
---|---|---|
committer | Jussi Pakkanen <jpakkane@gmail.com> | 2016-11-12 13:56:17 -0500 |
commit | 085650a1e3769366ac47f7d8a59386ed6d5a1ef5 (patch) | |
tree | 406344ab18e2708757534a95cf1b2ec0ff2c39c0 /mesonbuild/compilers.py | |
parent | 4cdd22f0944d46e6759be93cd4310e23ee94dd2e (diff) | |
download | meson-085650a1e3769366ac47f7d8a59386ed6d5a1ef5.zip meson-085650a1e3769366ac47f7d8a59386ed6d5a1ef5.tar.gz meson-085650a1e3769366ac47f7d8a59386ed6d5a1ef5.tar.bz2 |
vala: Implement valac.find_library
Move CCompiler.compile to Compiler.compile so that ValaCompiler can use
it. Also rewrite ValaCompiler.sanity_check to use it since it does
a simple compile check.
At the same time, it enhances ExternalLibrary to support arguments for
languages other than C-like.
Includes a test for this that links against zlib through Vala.
Closes #983
Diffstat (limited to 'mesonbuild/compilers.py')
-rw-r--r-- | mesonbuild/compilers.py | 133 |
1 files changed, 77 insertions, 56 deletions
diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py index 9b76f29..1505807 100644 --- a/mesonbuild/compilers.py +++ b/mesonbuild/compilers.py @@ -430,6 +430,51 @@ class Compiler(): extra_flags += environment.cross_info.config['properties'].get(lang_link_args_key, []) return extra_flags + @contextlib.contextmanager + def compile(self, code, extra_args=None): + if extra_args is None: + extra_args = [] + + try: + with tempfile.TemporaryDirectory() as tmpdirname: + if isinstance(code, str): + srcname = os.path.join(tmpdirname, + 'testfile.' + self.default_suffix) + with open(srcname, 'w') as ofile: + ofile.write(code) + elif isinstance(code, mesonlib.File): + srcname = code.fname + + # Extension only matters if running results; '.exe' is + # guaranteed to be executable on every platform. + output = os.path.join(tmpdirname, 'output.exe') + + commands = self.get_exelist() + commands.append(srcname) + commands += extra_args + commands += self.get_output_args(output) + mlog.debug('Running compile:') + mlog.debug('Working directory: ', tmpdirname) + mlog.debug('Command line: ', ' '.join(commands), '\n') + mlog.debug('Code:\n', code) + p = subprocess.Popen(commands, cwd=tmpdirname, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + (stde, stdo) = p.communicate() + stde = stde.decode() + stdo = stdo.decode() + mlog.debug('Compiler stdout:\n', stdo) + mlog.debug('Compiler stderr:\n', stde) + + p.input_name = srcname + p.output_name = output + yield p + except (PermissionError, OSError): + # On Windows antivirus programs and the like hold on to files so + # they can't be deleted. There's not much to do in this case. Also, + # catch OSError because the directory is then no longer empty. + pass + def get_colorout_args(self, colortype): return [] @@ -659,51 +704,6 @@ int main () {{ args = extra_args + self.get_compiler_check_args() return self.compiles(templ.format(hname, symbol, prefix), env, args, dependencies) - @contextlib.contextmanager - def compile(self, code, extra_args=None): - if extra_args is None: - extra_args = [] - - try: - with tempfile.TemporaryDirectory() as tmpdirname: - if isinstance(code, str): - srcname = os.path.join(tmpdirname, - 'testfile.' + self.default_suffix) - with open(srcname, 'w') as ofile: - ofile.write(code) - elif isinstance(code, mesonlib.File): - srcname = code.fname - - # Extension only matters if running results; '.exe' is - # guaranteed to be executable on every platform. - output = os.path.join(tmpdirname, 'output.exe') - - commands = self.get_exelist() - commands.append(srcname) - commands += extra_args - commands += self.get_output_args(output) - mlog.debug('Running compile:') - mlog.debug('Working directory: ', tmpdirname) - mlog.debug('Command line: ', ' '.join(commands), '\n') - mlog.debug('Code:\n', code) - p = subprocess.Popen(commands, cwd=tmpdirname, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - (stde, stdo) = p.communicate() - stde = stde.decode() - stdo = stdo.decode() - mlog.debug('Compiler stdout:\n', stdo) - mlog.debug('Compiler stderr:\n', stde) - - p.input_name = srcname - p.output_name = output - yield p - except (PermissionError, OSError): - # On Windows antivirus programs and the like hold on to files so - # they can't be deleted. There's not much to do in this case. Also, - # catch OSError because the directory is then no longer empty. - pass - def compiles(self, code, env, extra_args=None, dependencies=None): if extra_args is None: extra_args = [] @@ -1330,27 +1330,48 @@ class ValaCompiler(Compiler): def needs_static_linker(self): return False # Because compiles into C. + def get_output_args(self, target): + return ['-o', target] + def get_werror_args(self): return ['--fatal-warnings'] def sanity_check(self, work_dir, environment): - src = 'valatest.vala' - source_name = os.path.join(work_dir, src) - with open(source_name, 'w') as ofile: - ofile.write('''class SanityCheck : Object { -} -''') - extra_flags = self.get_cross_extra_flags(environment, compile=True, link=False) - pc = subprocess.Popen(self.exelist + extra_flags + ['-C', '-c', src], cwd=work_dir) - pc.wait() - if pc.returncode != 0: - raise EnvironmentException('Vala compiler %s can not compile programs.' % self.name_string()) + code = 'class MesonSanityCheck : Object { }' + args = self.get_cross_extra_flags(environment, compile=True, link=False) + args += ['-C'] + with self.compile(code, args) as p: + if p.returncode != 0: + msg = 'Vala compiler {!r} can not compile programs' \ + ''.format(self.name_string()) + raise EnvironmentException(msg) def get_buildtype_args(self, buildtype): if buildtype == 'debug' or buildtype == 'debugoptimized' or buildtype == 'minsize': return ['--debug'] return [] + def find_library(self, libname, env, extra_dirs): + if extra_dirs and isinstance(extra_dirs, str): + extra_dirs = [extra_dirs] + # Valac always looks in the default vapi dir, so only search there if + # no extra dirs are specified. + if len(extra_dirs) == 0: + code = 'class MesonFindLibrary : Object { }' + vapi_args = ['--pkg', libname] + args = self.get_cross_extra_flags(env, compile=True, link=False) + args += ['-C'] + vapi_args + with self.compile(code, args) as p: + if p.returncode == 0: + return vapi_args + # Not found? Try to find the vapi file itself. + for d in extra_dirs: + vapi = os.path.join(d, libname + '.vapi') + if os.path.isfile(vapi): + return vapi + mlog.debug('Searched {!r} and {!r} wasn\'t found'.format(extra_dirs, libname)) + return None + class RustCompiler(Compiler): def __init__(self, exelist, version): self.language = 'rust' |