Index: lnt/tests/test_suite.py =================================================================== --- lnt/tests/test_suite.py +++ lnt/tests/test_suite.py @@ -25,6 +25,7 @@ from lnt.testing.util.commands import note, fatal, warning from lnt.testing.util.commands import mkdir_p from lnt.testing.util.commands import resolve_command_path, isexecfile +from lnt.testing.util.commands import capture, which from lnt.tests.builtintest import BuiltinTest @@ -167,6 +168,33 @@ return _lit_json_to_template(json_reports, template_engine) +def _populate_cc_cxx_from_cmake_toolchain_file(cmake_toolchain_file): + """ + Let cmake print out the cross-compiling C and C++ binaries it's + going to use, and return these. + """ + # It'd be nicer if this could be done in a less convoluted way, but here + # it's done by creating a temporary project, that as part of creating its + # build directory, will print out the C and C++ cross-compilers used. + tmpdir = tempfile.mkdtemp() + # create source project to print out C and C++ compilers + with open(os.path.join(tmpdir, "CMakeLists.txt"), 'w') as f: + f.write('message(STATUS "CMAKE_C_COMPILER: ${CMAKE_C_COMPILER}")\n') + f.write('message(STATUS "CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}")\n') + cmd = [which('cmake'), + '-DCMAKE_TOOLCHAIN_FILE=%s' % cmake_toolchain_file, + '.'] + cwd = os.getcwd() + os.chdir(tmpdir) + cmake_output = capture(cmd, include_stderr=True) + os.chdir(cwd) + m = re.search("CMAKE_C_COMPILER: (.+)$", cmake_output, flags=re.MULTILINE) + cc = m.group(1) + m = re.search("CMAKE_CXX_COMPILER: (.+)$", cmake_output, flags=re.MULTILINE) + cxx = m.group(1) + shutil.rmtree(tmpdir) + return cc, cxx + class TestSuiteTest(BuiltinTest): def __init__(self): super(TestSuiteTest, self).__init__() @@ -220,19 +248,11 @@ type=str, default=None, help="Path to the C++ compiler to test (inferred from" " --cc where possible") - group.add_option("", "--llvm-arch", dest="llvm_arch", - type='choice', default=None, - help="Override the CMake-inferred architecture", - choices=TEST_SUITE_KNOWN_ARCHITECTURES) - group.add_option("", "--cross-compiling", dest="cross_compiling", - action="store_true", default=False, - help="Inform CMake that it should be cross-compiling") - group.add_option("", "--cross-compiling-system-name", type=str, - default=None, dest="cross_compiling_system_name", - help="The parameter to pass to CMAKE_SYSTEM_NAME when" - " cross-compiling. By default this is 'Linux' " - "unless -arch is in the cflags, in which case " - "it is 'Darwin'") + group.add_option("", "--cross-compiling-toolchain-file", + dest="cross_compiling_toolchain_file", + type=str, default=None, + help="Specify CMAKE_TOOLCHAIN_FILE to be used during" + + " cross-compiling") group.add_option("", "--cppflags", type=str, action="append", dest="cppflags", default=[], help="Extra flags to pass the compiler in C or C++ mode. " @@ -359,15 +379,20 @@ else: parser.error("Expected no positional arguments (got: %r)" % (args,)) - for a in ['cross_compiling', 'cross_compiling_system_name', 'llvm_arch']: - if getattr(opts, a): - parser.error('option "%s" is not yet implemented!' % a) - if self.opts.sandbox_path is None: parser.error('--sandbox is required') - if self.opts.cc is None: - parser.error('--cc is required') + if self.opts.cc is None and \ + self.opts.cross_compiling_toolchain_file is None: + parser.error('--cc is required when not cross-compiling') + + if self.opts.cc is not None and \ + self.opts.cross_compiling_toolchain_file is not None: + parser.error('--cc must not be specified when cross-compiling') + + if self.opts.cross_compiling_toolchain_file: + opts.cc, opts.cxx = _populate_cc_cxx_from_cmake_toolchain_file( + opts.cross_compiling_toolchain_file) # Option validation. opts.cc = resolve_command_path(opts.cc) @@ -598,6 +623,10 @@ all_cxx_flags = ' '.join([self.opts.cppflags, self.opts.cxxflags]) defs['CMAKE_CXX_FLAGS'] = self._unix_quote_args(all_cxx_flags) + if self.opts.cross_compiling_toolchain_file: + defs['CMAKE_TOOLCHAIN_FILE'] = \ + self.opts.cross_compiling_toolchain_file + if self.opts.run_under: defs['TEST_SUITE_RUN_UNDER'] = self._unix_quote_args(self.opts.run_under) if self.opts.benchmarking_only: