12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#!/usr/bin/env python
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# Copyright (c) 2013 The Chromium Authors. All rights reserved.
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# found in the LICENSE file.
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)"""
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Tries to compile given code, produces different output depending on success.
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)This is similar to checks done by ./configure scripts.
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)"""
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import optparse
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import os
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import shutil
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import subprocess
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import sys
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import tempfile
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)def DoMain(argv):
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  parser = optparse.OptionParser()
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  parser.add_option('--code')
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  parser.add_option('--run-linker', action='store_true')
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  parser.add_option('--on-success', default='')
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  parser.add_option('--on-failure', default='')
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  options, args = parser.parse_args(argv)
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if not options.code:
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    parser.error('Missing required --code switch.')
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  # The environment variable might expand to a string with spaces,
3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  # e.g. "ccache g++". Convert it to a list suitable for argv.
3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  cxx = os.environ.get('CXX', 'g++').split()
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tmpdir = tempfile.mkdtemp()
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  try:
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    cxx_path = os.path.join(tmpdir, 'test.cc')
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    with open(cxx_path, 'w') as f:
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      f.write(options.code.decode('string-escape'))
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    o_path = os.path.join(tmpdir, 'test.o')
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    cxx_cmdline = cxx + [cxx_path, '-o', o_path]
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if not options.run_linker:
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      cxx_cmdline.append('-c')
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    # Pass remaining arguments to the compiler.
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    cxx_cmdline += args
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    cxx_popen = subprocess.Popen(cxx_cmdline,
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 stdout=subprocess.PIPE,
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 stderr=subprocess.PIPE)
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    cxx_stdout, cxx_stderr = cxx_popen.communicate()
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if cxx_popen.returncode == 0:
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      print options.on_success
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else:
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      print options.on_failure
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  finally:
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    shutil.rmtree(tmpdir)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return 0
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)if __name__ == '__main__':
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sys.exit(DoMain(sys.argv[1:]))
66