Index: lit/Breakpoint/case-sensitive.test =================================================================== --- lit/Breakpoint/case-sensitive.test +++ lit/Breakpoint/case-sensitive.test @@ -1,6 +1,6 @@ # REQUIRES: nowindows # -# RUN: %clang %p/Inputs/case-sensitive.c -g -o %t +# RUN: %build %p/Inputs/case-sensitive.c --nodefaultlib -o %t # RUN: lldb-test breakpoints %t %s | FileCheck %s breakpoint set -f case-sensitive.c -l 3 Index: lit/BuildScript/toolchain-clang.test =================================================================== --- /dev/null +++ lit/BuildScript/toolchain-clang.test @@ -0,0 +1,14 @@ +RUN: %build -n --verbose --arch=32 --compiler=clang --mode=compile-and-link -o %t/foo.exe foobar.c \ +RUN: | FileCheck --check-prefix=CHECK --check-prefix=CHECK-32 %s + +RUN: %build -n --verbose --arch=64 --compiler=clang --mode=compile-and-link -o %t/foo.exe foobar.c \ +RUN: | FileCheck --check-prefix=CHECK --check-prefix=CHECK-64 %s + +CHECK: Cleaning {{.*}}toolchain-clang.test.tmp{{.}}foo.exe-foobar.o +CHECK: Cleaning {{.*}}toolchain-clang.test.tmp{{.}}foo.exe +CHECK: compiling foobar.c -> foo.exe-foobar.o +CHECK-32: {{.*}}clang++{{(.exe)?}} -m32 -g -O0 -c -o {{.*}}foo.exe-foobar.o {{.*}}foobar.c +CHECK-64: {{.*}}clang++{{(.exe)?}} -m64 -g -O0 -c -o {{.*}}foo.exe-foobar.o {{.*}}foobar.c +CHECK: linking foo.exe-foobar.o -> foo.exe +CHECK-32: {{.*}}clang++{{(.exe)?}} -m32 -o {{.*}}foo.exe {{.*}}foo.exe-foobar.o +CHECK-64: {{.*}}clang++{{(.exe)?}} -m64 -o {{.*}}foo.exe {{.*}}foo.exe-foobar.o Index: lit/helper/build.py =================================================================== --- lit/helper/build.py +++ lit/helper/build.py @@ -1,3 +1,5 @@ +#! /usr/bin/env python + from __future__ import print_function import argparse @@ -207,7 +209,7 @@ return 'unknown' class Builder(object): - def __init__(self, toolchain_type, args): + def __init__(self, toolchain_type, args, obj_ext): self.toolchain_type = toolchain_type self.inputs = args.inputs self.arch = args.arch @@ -219,10 +221,50 @@ self.mode = args.mode self.nodefaultlib = args.nodefaultlib self.verbose = args.verbose + self.obj_ext = obj_ext + + def _exe_file_name(self): + assert self.mode != 'compile' + return self.output + + def _output_name(self, input, extension, with_executable=False): + basename = os.path.splitext(os.path.basename(input))[0] + extension + if with_executable: + exe_basename = os.path.basename(self._exe_file_name()) + basename = exe_basename + '-' + basename + + output = os.path.join(self.outdir, basename) + return os.path.normpath(output) + + def _obj_file_names(self): + if self.mode == 'link': + return self.inputs + + if self.mode == 'compile-and-link': + # Object file names should factor in both the input file (source) + # name and output file (executable) name, to ensure that two tests + # which share a common source file don't race to write the same + # object file. + return [self._output_name(x, self.obj_ext, True) for x in self.inputs] + + if self.mode == 'compile' and self.output: + return [self.output] + + return [self._output_name(x, self.obj_ext) for x in self.inputs] + + def build_commands(self): + commands = [] + if self.mode == 'compile' or self.mode == 'compile-and-link': + for input, output in zip(self.inputs, self._obj_file_names()): + commands.append(self._get_compilation_command(input, output)) + if self.mode == 'link' or self.mode == 'compile-and-link': + commands.append(self._get_link_command()) + return commands + class MsvcBuilder(Builder): def __init__(self, toolchain_type, args): - Builder.__init__(self, toolchain_type, args) + Builder.__init__(self, toolchain_type, args, '.obj') self.msvc_arch_str = 'x86' if self.arch == '32' else 'x64' @@ -486,47 +528,17 @@ linkenv.update(defaultenv) return (compileenv, linkenv) - def _output_name(self, input, extension, with_executable=False): - basename = os.path.splitext(os.path.basename(input))[0] + extension - if with_executable: - exe_basename = os.path.basename(self._exe_file_name()) - basename = exe_basename + '-' + basename - - output = os.path.join(self.outdir, basename) - return os.path.normpath(output) - def _ilk_file_names(self): if self.mode == 'link': return [] return [self._output_name(x, '.ilk') for x in self.inputs] - def _obj_file_names(self): - if self.mode == 'link': - return self.inputs - - if self.mode == 'compile-and-link': - # Object file names should factor in both the input file (source) - # name and output file (executable) name, to ensure that two tests - # which share a common source file don't race to write the same - # object file. - return [self._output_name(x, '.obj', True) for x in self.inputs] - - if self.mode == 'compile' and self.output: - return [self.output] - - return [self._output_name(x, '.obj') for x in self.inputs] - def _pdb_file_name(self): if self.mode == 'compile': return None return os.path.splitext(self.output)[0] + '.pdb' - def _exe_file_name(self): - if self.mode == 'compile': - return None - return self.output - def _get_compilation_command(self, source, obj): args = [] @@ -586,10 +598,6 @@ return commands def output_files(self): - outdir = os.path.dirname(self.output) - file = os.path.basename(self.output) - name, ext = os.path.splitext(file) - outputs = [] if self.mode == 'compile' or self.mode == 'compile-and-link': outputs.extend(self._ilk_file_names()) @@ -602,13 +610,56 @@ class GccBuilder(Builder): def __init__(self, toolchain_type, args): - Builder.__init__(self, toolchain_type, args) + Builder.__init__(self, toolchain_type, args, '.o') + + def _get_compilation_command(self, source, obj): + args = [] + + args.append(self.compiler) + args.append('-m' + self.arch) + + args.append('-g') + if self.opt == 'none': + args.append('-O0') + elif self.opt == 'basic': + args.append('-O2') + elif self.opt == 'lto': + raise NotImplementedError("LTO not implemented in gcc builder") + if self.nodefaultlib: + args.append('-nostdinc') + args.append('-static') + args.append('-c') + + args.extend(['-o', obj]) + args.append(source) + + return ('compiling', [source], obj, {}, args) + + def _get_link_command(self): + args = [] + args.append(self.compiler) + args.append('-m' + self.arch) + if self.nodefaultlib: + args.append('-nostdlib') + args.append('-static') + main_symbol = 'main' + if sys.platform == 'darwin': + main_symbol = '_main' + args.append('-Wl,-e,' + main_symbol) + args.extend(['-o', self._exe_file_name()]) + args.extend(self._obj_file_names()) + + return ('linking', self._obj_file_names(), self._exe_file_name(), {}, args) - def build_commands(self): - pass def output_files(self): - pass + outputs = [] + if self.mode == 'compile' or self.mode == 'compile-and-link': + outputs.extend(self._obj_file_names()) + if self.mode == 'link' or self.mode == 'compile-and-link': + outputs.append(self._exe_file_name()) + + return outputs def indent(text, spaces): def prefixed_lines():