diff options
Diffstat (limited to 'mesonbuild/compilers')
-rw-r--r-- | mesonbuild/compilers/c.py | 10 | ||||
-rw-r--r-- | mesonbuild/compilers/compilers.py | 26 |
2 files changed, 28 insertions, 8 deletions
diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py index 27cf43a..dee5125 100644 --- a/mesonbuild/compilers/c.py +++ b/mesonbuild/compilers/c.py @@ -319,16 +319,16 @@ class CCompiler(Compiler): args += extra_args return args - def compiles(self, code, env, extra_args=None, dependencies=None, mode='compile'): + def compiles(self, code, env, extra_args=None, dependencies=None, mode='compile', want_output=False): args = self._get_compiler_check_args(env, extra_args, dependencies, mode) # We only want to compile; not link with self.compile(code, args.to_native(), mode) as p: return p.returncode == 0 - def _links_wrapper(self, code, env, extra_args, dependencies): + def _links_wrapper(self, code, env, extra_args, dependencies, want_output=False): "Shares common code between self.links and self.run" args = self._get_compiler_check_args(env, extra_args, dependencies, mode='link') - return self.compile(code, args) + return self.compile(code, args, want_output=want_output) def links(self, code, env, extra_args=None, dependencies=None): with self._links_wrapper(code, env, extra_args, dependencies) as p: @@ -337,7 +337,7 @@ class CCompiler(Compiler): def run(self, code, env, extra_args=None, dependencies=None): if self.is_cross and self.exe_wrapper is None: raise CrossNoRunException('Can not run test applications in this cross environment.') - with self._links_wrapper(code, env, extra_args, dependencies) as p: + with self._links_wrapper(code, env, extra_args, dependencies, True) as p: if p.returncode != 0: mlog.debug('Could not compile test file %s: %d\n' % ( p.input_name, @@ -736,7 +736,7 @@ class CCompiler(Compiler): args = self.get_cross_extra_flags(env, link=False) args += self.get_compiler_check_args() n = 'symbols_have_underscore_prefix' - with self.compile(code, args, 'compile') as p: + with self.compile(code, args, 'compile', want_output=True) as p: if p.returncode != 0: m = 'BUG: Unable to compile {!r} check: {}' raise RuntimeError(m.format(n, p.stdo)) diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 69ab6ef..480baa9 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -608,6 +608,8 @@ class Compiler: # Libraries to ignore in find_library() since they are provided by the # compiler or the C library. Currently only used for MSVC. ignore_libs = () + # Cache for the result of compiler checks which can be cached + compiler_check_cache = {} def __init__(self, exelist, version, **kwargs): if isinstance(exelist, str): @@ -760,9 +762,23 @@ class Compiler: return os.path.join(dirname, 'output.' + suffix) @contextlib.contextmanager - def compile(self, code, extra_args=None, mode='link'): + def compile(self, code, extra_args=None, mode='link', want_output=False): if extra_args is None: + textra_args = None extra_args = [] + else: + textra_args = tuple(extra_args) + key = (code, textra_args, mode) + if not want_output: + if key in self.compiler_check_cache: + p = self.compiler_check_cache[key] + mlog.debug('Using cached compile:') + mlog.debug('Cached command line: ', ' '.join(p.commands), '\n') + mlog.debug('Code:\n', code) + mlog.debug('Cached compiler stdout:\n', p.stdo) + mlog.debug('Cached compiler stderr:\n', p.stde) + yield p + raise StopIteration try: with tempfile.TemporaryDirectory() as tmpdirname: if isinstance(code, str): @@ -772,7 +788,6 @@ class Compiler: ofile.write(code) elif isinstance(code, mesonlib.File): srcname = code.fname - output = self._get_compile_output(tmpdirname, mode) # Construct the compiler command-line commands = CompilerArgs(self) @@ -785,6 +800,7 @@ class Compiler: if mode == 'preprocess': commands += self.get_preprocess_only_args() else: + output = self._get_compile_output(tmpdirname, mode) commands += self.get_output_args(output) # Generate full command-line with the exelist commands = self.get_exelist() + commands.to_native() @@ -795,8 +811,12 @@ class Compiler: p, p.stdo, p.stde = Popen_safe(commands, cwd=tmpdirname) mlog.debug('Compiler stdout:\n', p.stdo) mlog.debug('Compiler stderr:\n', p.stde) + p.commands = commands p.input_name = srcname - p.output_name = output + if want_output: + p.output_name = output + else: + self.compiler_check_cache[key] = p yield p except (PermissionError, OSError): # On Windows antivirus programs and the like hold on to files so |