Index: lldb/trunk/lit/BuildScript/modes.test =================================================================== --- lldb/trunk/lit/BuildScript/modes.test +++ lldb/trunk/lit/BuildScript/modes.test @@ -0,0 +1,35 @@ +RUN: %build -n --verbose --arch=32 --mode=compile --compiler=any -o %t/foo.out foobar.c \ +RUN: | FileCheck --check-prefix=COMPILE %s + +RUN: %build -n --verbose --arch=32 --mode=compile --compiler=any --outdir %t foo.c bar.c \ +RUN: | FileCheck --check-prefix=COMPILE-MULTI %s + +RUN: %build -n --verbose --arch=32 --mode=link --compiler=any -o %t/foo.exe foobar.obj \ +RUN: | FileCheck --check-prefix=LINK %s + +RUN: %build -n --verbose --arch=32 --mode=link --compiler=any -o %t/foobar.exe foo.obj bar.obj \ +RUN: | FileCheck --check-prefix=LINK-MULTI %s + +RUN: %build -n --verbose --arch=32 --mode=compile-and-link --compiler=any -o %t/foobar.exe foobar.c \ +RUN: | FileCheck --check-prefix=BOTH %s + +RUN: %build -n --verbose --arch=32 --mode=compile-and-link --compiler=any -o %t/foobar.exe foo.c bar.c \ +RUN: | FileCheck --check-prefix=BOTH-MULTI %s + + +COMPILE: compiling foobar.c -> foo.out + +COMPILE-MULTI: compiling foo.c -> foo.obj +COMPILE-MULTI: compiling bar.c -> bar.obj + + +LINK: linking foobar.obj -> foo.exe + +LINK-MULTI: linking foo.obj+bar.obj -> foobar.exe + +BOTH: compiling foobar.c -> foobar.obj +BOTH: linking foobar.obj -> foobar.exe + +BOTH-MULTI: compiling foo.c -> foo.obj +BOTH-MULTI: compiling bar.c -> bar.obj +BOTH-MULTI: linking foo.obj+bar.obj -> foobar.exe Index: lldb/trunk/lit/BuildScript/script-args.test =================================================================== --- lldb/trunk/lit/BuildScript/script-args.test +++ lldb/trunk/lit/BuildScript/script-args.test @@ -0,0 +1,32 @@ +RUN: %build -n --verbose --arch=32 --mode=compile --compiler=any -o %t/foo.out foobar.c \ +RUN: | FileCheck %s +RUN: %build -n --verbose --arch=32 --mode=compile --compiler=any --outdir %t foo.c bar.c \ +RUN: | FileCheck --check-prefix=MULTI-INPUT %s + + +CHECK: Script Arguments: +CHECK-NEXT: Arch: 32 +CHECK: Compiler: any +CHECK: Outdir: {{.*}}script-args.test.tmp +CHECK: Output: {{.*}}script-args.test.tmp{{.}}foo.out +CHECK: Nodefaultlib: False +CHECK: Opt: none +CHECK: Mode: compile +CHECK: Clean: True +CHECK: Verbose: True +CHECK: Dryrun: True +CHECK: Inputs: foobar.c + +MULTI-INPUT: Script Arguments: +MULTI-INPUT-NEXT: Arch: 32 +MULTI-INPUT-NEXT: Compiler: any +MULTI-INPUT-NEXT: Outdir: {{.*}}script-args.test.tmp +MULTI-INPUT-NEXT: Output: +MULTI-INPUT-NEXT: Nodefaultlib: False +MULTI-INPUT-NEXT: Opt: none +MULTI-INPUT-NEXT: Mode: compile +MULTI-INPUT-NEXT: Clean: True +MULTI-INPUT-NEXT: Verbose: True +MULTI-INPUT-NEXT: Dryrun: True +MULTI-INPUT-NEXT: Inputs: foo.c +MULTI-INPUT-NEXT: bar.c \ No newline at end of file Index: lldb/trunk/lit/BuildScript/toolchain-clang-cl.test =================================================================== --- lldb/trunk/lit/BuildScript/toolchain-clang-cl.test +++ lldb/trunk/lit/BuildScript/toolchain-clang-cl.test @@ -0,0 +1,49 @@ +REQUIRES: lld + +RUN: %build -n --verbose --arch=32 --compiler=clang-cl --mode=compile-and-link -o %t/foo.exe foobar.c \ +RUN: | FileCheck --check-prefix=CHECK-32 %s + +RUN: %build -n --verbose --arch=64 --compiler=clang-cl --mode=compile-and-link -o %t/foo.exe foobar.c \ +RUN: | FileCheck --check-prefix=CHECK-64 %s + +CHECK-32: Script Arguments: +CHECK-32: Arch: 32 +CHECK-32: Compiler: clang-cl +CHECK-32: Outdir: {{.*}} +CHECK-32: Output: {{.*}}toolchain-clang-cl.test.tmp\foo.exe +CHECK-32: Nodefaultlib: False +CHECK-32: Opt: none +CHECK-32: Mode: compile +CHECK-32: Clean: True +CHECK-32: Verbose: True +CHECK-32: Dryrun: True +CHECK-32: Inputs: foobar.c +CHECK-32: Cleaning {{.*}}toolchain-clang-cl.test.tmp{{.}}foobar.ilk +CHECK-32: Cleaning {{.*}}toolchain-clang-cl.test.tmp{{.}}foobar.obj +CHECK-32: Cleaning {{.*}}toolchain-clang-cl.test.tmp{{.}}foo.pdb +CHECK-32: Cleaning {{.*}}toolchain-clang-cl.test.tmp{{.}}foo.exe +CHECK-32: compiling foobar.c -> foobar.obj +CHECK-32: {{.*}}clang-cl{{(.exe)?}} -m32 +CHECK-32: linking foobar.obj -> foo.exe +CHECK-32: {{.*}}lld-link + +CHECK-64: Script Arguments: +CHECK-64: Arch: 64 +CHECK-64: Compiler: clang-cl +CHECK-64: Outdir: {{.*}} +CHECK-64: Output: {{.*}}toolchain-clang-cl.test.tmp\foo.exe +CHECK-64: Nodefaultlib: False +CHECK-64: Opt: none +CHECK-64: Mode: compile +CHECK-64: Clean: True +CHECK-64: Verbose: True +CHECK-64: Dryrun: True +CHECK-64: Inputs: foobar.c +CHECK-64: Cleaning {{.*}}toolchain-clang-cl.test.tmp{{.}}foobar.ilk +CHECK-64: Cleaning {{.*}}toolchain-clang-cl.test.tmp{{.}}foobar.obj +CHECK-64: Cleaning {{.*}}toolchain-clang-cl.test.tmp{{.}}foo.pdb +CHECK-64: Cleaning {{.*}}toolchain-clang-cl.test.tmp{{.}}foo.exe +CHECK-64: compiling foobar.c -> foobar.obj +CHECK-64: {{.*}}clang-cl{{(.exe)?}} -m64 +CHECK-64: linking foobar.obj -> foo.exe +CHECK-64: {{.*}}lld-link{{(.exe)?}} Index: lldb/trunk/lit/BuildScript/toolchain-msvc.test =================================================================== --- lldb/trunk/lit/BuildScript/toolchain-msvc.test +++ lldb/trunk/lit/BuildScript/toolchain-msvc.test @@ -0,0 +1,62 @@ +REQUIRES: system-windows, msvc + +RUN: %build -n --verbose --arch=32 --compiler=msvc --mode=compile-and-link -o %t/foo.exe foobar.c \ +RUN: | FileCheck --check-prefix=X86 %s + +RUN: %build -n --verbose --arch=64 --compiler=msvc --mode=compile-and-link -o %t/foo.exe foobar.c \ +RUN: | FileCheck --check-prefix=X64 %s + +X86: Script Arguments: +X86: Arch: 32 +X86: Compiler: msvc +X86: Outdir: {{.*}} +X86: Output: {{.*}}toolchain-msvc.test.tmp\foo.exe +X86: Nodefaultlib: False +X86: Opt: none +X86: Mode: compile +X86: Clean: True +X86: Verbose: True +X86: Dryrun: True +X86: Inputs: foobar.c +X86: Cleaning {{.*}}toolchain-msvc.test.tmp\foobar.ilk +X86: Cleaning {{.*}}toolchain-msvc.test.tmp\foobar.obj +X86: Cleaning {{.*}}toolchain-msvc.test.tmp\foo.pdb +X86: Cleaning {{.*}}toolchain-msvc.test.tmp\foo.exe +X86: compiling foobar.c -> foobar.obj +X86: Command Line: {{.*}}\{{[Hh]ost[Xx]64}}\x86\cl.exe +X86: linking foobar.obj -> foo.exe +X86: Command Line: {{.*}}\{{[Hh]ost[Xx]64}}\x86\link.exe +X86: Env +X86: LIB = {{.*}}\ATLMFC\lib\x86 +X86: {{.*}}\lib\x86 +X86: {{.*}}\ucrt\x86 +X86: {{.*}}\um\x86 +X86: PATH = {{.*}}\bin\{{[Hh]ost[Xx]64}}\x64 + + +X64: Script Arguments: +X64: Arch: 64 +X64: Compiler: msvc +X64: Outdir: {{.*}} +X64: Output: {{.*}}toolchain-msvc.test.tmp\foo.exe +X64: Nodefaultlib: False +X64: Opt: none +X64: Mode: compile +X64: Clean: True +X64: Verbose: True +X64: Dryrun: True +X64: Inputs: foobar.c +X64: Cleaning {{.*}}toolchain-msvc.test.tmp\foobar.ilk +X64: Cleaning {{.*}}toolchain-msvc.test.tmp\foobar.obj +X64: Cleaning {{.*}}toolchain-msvc.test.tmp\foo.pdb +X64: Cleaning {{.*}}toolchain-msvc.test.tmp\foo.exe +X64: compiling foobar.c -> foobar.obj +X64: Command Line: {{.*}}\{{[Hh]ost[Xx]64}}\x64\cl.exe +X64: linking foobar.obj -> foo.exe +X64: Command Line: {{.*}}\{{[Hh]ost[Xx]64}}\x64\link.exe +X64: Env +X64: LIB = {{.*}}\ATLMFC\lib\x64 +X64: {{.*}}\lib\x64 +X64: {{.*}}\ucrt\x64 +X64: {{.*}}\um\x64 +X64: PATH = {{.*}}\bin\{{[Hh]ost[Xx]64}}\x64 Index: lldb/trunk/lit/CMakeLists.txt =================================================================== --- lldb/trunk/lit/CMakeLists.txt +++ lldb/trunk/lit/CMakeLists.txt @@ -7,6 +7,10 @@ set(LLVM_BUILD_MODE "%(build_mode)s") endif () +if (CMAKE_SIZEOF_VOID_P EQUAL 8) + set(LLDB_IS_64_BITS 1) +endif() + if (NOT LLDB_TEST_USE_CUSTOM_C_COMPILER) string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_TEST_C_COMPILER ${LLDB_TEST_C_COMPILER}) endif () @@ -49,7 +53,8 @@ # the value is not canonicalized within LLVM llvm_canonicalize_cmake_booleans( LLDB_DISABLE_PYTHON - LLVM_ENABLE_ZLIB) + LLVM_ENABLE_ZLIB + LLDB_IS_64_BITS) configure_lit_site_cfg( ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in Index: lldb/trunk/lit/helper/build.py =================================================================== --- lldb/trunk/lit/helper/build.py +++ lldb/trunk/lit/helper/build.py @@ -23,7 +23,9 @@ metavar='arch', dest='arch', required=True, - help='Specify the architecture to target. Valid values=[32,64]') + default='host', + choices=['32', '64', 'host'], + help='Specify the architecture to target.') parser.add_argument('--compiler', metavar='compiler', @@ -48,9 +50,16 @@ parser.add_argument('--output', '-o', dest='output', metavar='file', - required=True, + required=False, + default='', help='Path to output file') +parser.add_argument('--outdir', '-d', + dest='outdir', + metavar='directory', + required=False, + help='Directory for output files') + parser.add_argument('--nodefaultlib', dest='nodefaultlib', action='store_true', @@ -81,9 +90,16 @@ default=False, help='Print verbose output') -parser.add_argument('input', +parser.add_argument('-n', '--dry-run', + dest='dry', + action='store_true', + default=False, + help='Print the commands that would run, but dont actually run them') + +parser.add_argument('inputs', metavar='file', - help='Source file to compile / object file to link') + nargs='+', + help='Source file(s) to compile / object file(s) to link') args = parser.parse_args(args=sys.argv[1:]) @@ -128,14 +144,18 @@ except AttributeError: raise TypeError('not sure how to convert %s to %s' % (type(b), str)) +def format_text(lines, indent_0, indent_n): + result = ' ' * indent_0 + lines[0] + for next in lines[1:]: + result = result + '\n{0}{1}'.format(' ' * indent_n, next) + return result + def print_environment(env): for e in env: value = env[e] - split = value.split(os.pathsep) - print(' {0} = {1}'.format(e, split[0])) - prefix_width = 3 + len(e) - for next in split[1:]: - print(' {0}{1}'.format(' ' * prefix_width, next)) + lines = value.split(os.pathsep) + formatted_value = format_text(lines, 0, 7 + len(e)) + print(' {0} = {1}'.format(e, formatted_value)) def find_executable(binary_name, search_paths): if sys.platform == 'win32': @@ -189,9 +209,10 @@ class Builder(object): def __init__(self, toolchain_type, args): self.toolchain_type = toolchain_type - self.input = args.input + self.inputs = args.inputs self.arch = args.arch self.opt = args.opt + self.outdir = args.outdir self.compiler = args.compiler self.clean = args.clean self.output = args.output @@ -465,15 +486,26 @@ linkenv.update(defaultenv) return (compileenv, linkenv) - def _ilk_file_name(self): + def _output_name(self, input, extension): + basename = os.path.basename(input) + basename = os.path.splitext(basename)[0] + extension + output = os.path.join(self.outdir, basename) + return os.path.normpath(output) + + def _ilk_file_names(self): if self.mode == 'link': - return None - return os.path.splitext(self.output)[0] + '.ilk' + return [] - def _obj_file_name(self): - if self.mode == 'compile': - return self.output - return os.path.splitext(self.output)[0] + '.obj' + 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 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': @@ -485,7 +517,7 @@ return None return self.output - def _get_compilation_command(self): + def _get_compilation_command(self, source, obj): args = [] args.append(self.compiler) @@ -511,11 +543,10 @@ args.append('-fkeep-static-consts') args.append('/c') - args.append('/Fo' + self._obj_file_name()) - args.append(self.input) - input = os.path.basename(self.input) - output = os.path.basename(self._obj_file_name()) - return ('compiling {0} -> {1}'.format(input, output), + args.append('/Fo' + obj) + args.append(source) + + return ('compiling', [source], obj, self.compile_env, args) @@ -529,18 +560,17 @@ args.append('/entry:main') args.append('/PDB:' + self._pdb_file_name()) args.append('/OUT:' + self._exe_file_name()) - args.append(self._obj_file_name()) + args.extend(self._obj_file_names()) - input = os.path.basename(self._obj_file_name()) - output = os.path.basename(self._exe_file_name()) - return ('linking {0} -> {1}'.format(input, output), + return ('linking', self._obj_file_names(), self._exe_file_name(), self.link_env, args) def build_commands(self): commands = [] if self.mode == 'compile' or self.mode == 'compile-and-link': - commands.append(self._get_compilation_command()) + 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 @@ -552,8 +582,8 @@ outputs = [] if self.mode == 'compile' or self.mode == 'compile-and-link': - outputs.append(self._ilk_file_name()) - outputs.append(self._obj_file_name()) + outputs.extend(self._ilk_file_names()) + outputs.extend(self._obj_file_names()) if self.mode == 'link' or self.mode == 'compile-and-link': outputs.append(self._pdb_file_name()) outputs.append(self._exe_file_name()) @@ -579,13 +609,20 @@ def build(commands): global args - for (status, env, child_args) in commands: + for (status, inputs, output, env, child_args) in commands: print('\n\n') - print(status) + if not args.verbose: + inputs = [os.path.basename(x) for x in inputs] + output = os.path.basename(output) + print(status + ' {0} -> {1}'.format('+'.join(inputs), output)) + if args.verbose: print(' Command Line: ' + ' '.join(child_args)) print(' Env:') print_environment(env) + if args.dry: + continue + popen = subprocess.Popen(child_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, @@ -609,7 +646,8 @@ print('Cleaning {0}'.format(file)) try: if os.path.exists(o): - os.remove(o) + if not args.dry: + os.remove(o) if args.verbose: print(' The file was successfully cleaned.') elif args.verbose: @@ -618,17 +656,57 @@ if args.verbose: print(' The file could not be removed.') +def fix_arguments(args): + if not args.inputs: + raise ValueError('No input files specified') + + if args.output and args.mode == 'compile' and len(args.inputs) > 1: + raise ValueError('Cannot specify -o with mode=compile and multiple source files. Use --outdir instead.') + + if not args.dry: + args.inputs = [os.path.abspath(x) for x in args.inputs] + + # If user didn't specify the outdir, use the directory of the first input. + if not args.outdir: + if args.output: + args.outdir = os.path.dirname(args.output) + else: + args.outdir = os.path.dirname(args.inputs[0]) + args.outdir = os.path.abspath(args.outdir) + args.outdir = os.path.normpath(args.outdir) + + # If user specified a non-absolute path for the output file, append the + # output directory to it. + if args.output: + if not os.path.isabs(args.output): + args.output = os.path.join(args.outdir, args.output) + args.output = os.path.normpath(args.output) + +fix_arguments(args) + (toolchain_type, toolchain_path) = find_toolchain(args.compiler, args.tools_dir) if not toolchain_path or not toolchain_type: print('Unable to find toolchain {0}'.format(args.compiler)) sys.exit(1) if args.verbose: - print("Script Environment:") + print('Script Arguments:') + print(' Arch: ' + args.arch) + print(' Compiler: ' + args.compiler) + print(' Outdir: ' + args.outdir) + print(' Output: ' + args.output) + print(' Nodefaultlib: ' + str(args.nodefaultlib)) + print(' Opt: ' + args.opt) + print(' Mode: ' + args.mode) + print(' Clean: ' + str(args.clean)) + print(' Verbose: ' + str(args.verbose)) + print(' Dryrun: ' + str(args.dry)) + print(' Inputs: ' + format_text(args.inputs, 0, 10)) + print('Script Environment:') print_environment(os.environ) args.compiler = toolchain_path -if not os.path.exists(args.compiler): +if not os.path.exists(args.compiler) and not args.dry: raise ValueError('The toolchain {} does not exist.'.format(args.compiler)) if toolchain_type == 'msvc' or toolchain_type=='clang-cl': Index: lldb/trunk/lit/helper/toolchain.py =================================================================== --- lldb/trunk/lit/helper/toolchain.py +++ lldb/trunk/lit/helper/toolchain.py @@ -20,15 +20,18 @@ command=FindTool('lldb-mi'), extra_args=['--synchronous'], unresolved='ignore') + + build_script = os.path.dirname(__file__) build_script = os.path.join(build_script, 'build.py') build_script_args = [build_script, '--compiler=any', # Default to best compiler - '--arch=64'] # Default to 64-bit, user can override + '--arch=' + str(config.lldb_bitness)] if config.lldb_lit_tools_dir: build_script_args.append('--tools-dir={0}'.format(config.lldb_lit_tools_dir)) if config.lldb_tools_dir: build_script_args.append('--tools-dir={0}'.format(config.lldb_tools_dir)) + primary_tools = [ ToolSubst('%lldb', command=FindTool('lldb'), Index: lldb/trunk/lit/lit.site.cfg.py.in =================================================================== --- lldb/trunk/lit/lit.site.cfg.py.in +++ lldb/trunk/lit/lit.site.cfg.py.in @@ -16,6 +16,7 @@ config.python_executable = "@PYTHON_EXECUTABLE@" config.have_zlib = @LLVM_ENABLE_ZLIB@ config.host_triple = "@LLVM_HOST_TRIPLE@" +config.lldb_bitness = 64 if @LLDB_IS_64_BITS@ else 32 # Support substitution of the tools and libs dirs with user parameters. This is # used when we can't determine the tool dir at configuration time.