コード例 #1
0
    def test_TempFileNotTooLong(self):
        '''Test that temp files with too-long names are not generated'''
        if not driver_test_utils.CanRunHost() or driver_tools.IsWindowsPython(
        ):
            return

        # This name is chosen such that the .c file has the maximum length. pnacl-ld
        # should not generate any temp names longer than that.
        shortname = os.path.join(self.LongTempDir, 'a' * 12)

        self.WriteCFile(shortname + '.c')
        driver_tools.RunDriver(
            'pnacl-clang', [shortname + '.c', '-c', '-o', shortname + '.o'])

        driver_tools.RunDriver('pnacl-ld', [shortname + '.o', '-o', shortname])

        # If it's impossible to generate a temp file short enough using our scheme
        # (i.e. the directory name is so long that 8 chars will be over the limit),
        # make sure we still fail the right way.
        longerdir = os.path.join(self.LongTempDir, 'a' * 8)
        os.mkdir(longerdir)
        longname = os.path.join(longerdir, 'a' * 3)
        os.rename(shortname + '.o', longname + '.o')

        output = self.AssertRaisesAndReturnOutput(
            driver_test_utils.DriverExitException, driver_tools.RunDriver,
            'pnacl-ld', [longname + '.o', '-o', longname])

        self.assertIn('.pexe is too long', output)
コード例 #2
0
    def test_compile_native_objects(self):
        s = self.getFakeSourceFile()
        with self.getTemp(suffix='.o') as obj:
            # TODO(dschuff): Use something more descriptive instead of -arch
            # (i.e. something that indicates that a translation is requested)
            # and remove pnacl-allow-translate
            driver_tools.RunDriver('clang', [
                s.name, '-c', '-o', obj.name, '--target=x86_64-unknown-nacl',
                '-arch', 'x86-64', '--pnacl-allow-translate'
            ])
            self.assertTrue(filetype.IsNativeObject(obj.name))
            self.assertEqual(elftools.GetELFHeader(obj.name).arch, 'X8664')

            driver_tools.RunDriver('clang', [
                s.name, '-c', '-o', obj.name, '--target=i686-unknown-nacl',
                '-arch', 'x86-32', '--pnacl-allow-translate'
            ])
            self.assertTrue(filetype.IsNativeObject(obj.name))
            self.assertEqual(elftools.GetELFHeader(obj.name).arch, 'X8632')

            driver_tools.RunDriver('clang', [
                s.name, '-c', '-o', obj.name,
                '--target=armv7-unknown-nacl-gnueabi', '-arch', 'arm',
                '--pnacl-allow-translate'
            ])
            self.assertTrue(filetype.IsNativeObject(obj.name))
            self.assertEqual(elftools.GetELFHeader(obj.name).arch, 'ARM')

            # TODO(dschuff): This should be an error.
            driver_tools.RunDriver('clang', [
                s.name, '-c', '-o', obj.name, '--target=x86_64-unknown-nacl',
                '-arch', 'x86-32', '--pnacl-allow-translate'
            ])
            self.assertTrue(filetype.IsNativeObject(obj.name))
            self.assertEqual(elftools.GetELFHeader(obj.name).arch, 'X8632')
コード例 #3
0
def main(argv):
    env.update(EXTRA_ENV)
    driver_tools.ParseArgs(argv, PrepPatterns)

    inputs = env.get('INPUTS')
    output = env.getone('OUTPUT')

    if len(inputs) != 1:
        Log.Fatal('Can only have one input')
    f_input = inputs[0]

    # Allow in-place file changes if output isn't specified..
    if output != '':
        f_output = output
    else:
        f_output = f_input

    if env.getbool('DISABLE_FINALIZE') or filetype.IsPNaClBitcode(f_input):
        # Just copy the input file to the output file.
        if f_input != f_output:
            shutil.copyfile(f_input, f_output)
        return 0

    opt_flags = [
        '-disable-opt', '-strip', '-strip-metadata', '--bitcode-format=pnacl',
        f_input, '-o', f_output
    ]
    # Transform the file, and convert it to a PNaCl bitcode file.
    driver_tools.RunDriver('opt', opt_flags)
    # Compress the result if requested.
    if env.getbool('COMPRESS'):
        driver_tools.RunDriver('compress', [f_output])
    return 0
コード例 #4
0
    def test_bc_objects(self):
        s = self.getFakeSourceFile()
        with self.getTemp(suffix='.o') as obj:
            # Test that clang with "normal" args results in a portable bitcode object
            driver_tools.RunDriver('clang', [s.name, '-c', '-o', obj.name])
            self.assertTrue(filetype.IsLLVMBitcode(obj.name))
            self.assertEqual(self.getBitcodeArch(obj.name), 'le32')

            # Test that the --target flag produces biased bitcode objects
            driver_tools.RunDriver(
                'clang',
                [s.name, '--target=x86_64-unknown-nacl', '-c', '-o', obj.name])
            self.assertTrue(filetype.IsLLVMBitcode(obj.name))
            self.assertEqual(self.getBitcodeArch(obj.name), 'X8664')

            driver_tools.RunDriver(
                'clang',
                [s.name, '--target=i686-unknown-nacl', '-c', '-o', obj.name])
            self.assertTrue(filetype.IsLLVMBitcode(obj.name))
            self.assertEqual(self.getBitcodeArch(obj.name), 'X8632')

            driver_tools.RunDriver('clang', [
                s.name, '--target=armv7a-unknown-nacl-gnueabi',
                '-mfloat-abi=hard', '-c', '-o', obj.name
            ])
            self.assertTrue(filetype.IsLLVMBitcode(obj.name))
            self.assertEqual(self.getBitcodeArch(obj.name), 'ARM')
コード例 #5
0
 def test_multiple_compresses(self):
     pexe = self.getFakePexe()
     init_size = pathtools.getsize(pexe.name)
     driver_tools.RunDriver('pnacl-compress', [pexe.name])
     shrunk_size = pathtools.getsize(pexe.name)
     self.assertTrue(init_size >= shrunk_size)
     driver_tools.RunDriver('pnacl-compress', [pexe.name])
     self.assertTrue(pathtools.getsize(pexe.name) == shrunk_size)
コード例 #6
0
 def stripFileAndCheck(self, f):
   f_stripped = self.getTemp()
   driver_tools.RunDriver('strip',
       ['--strip-all', f.name, '-o', f_stripped.name])
   self.assertTrue(self.getFileSize(f_stripped.name) <
                   self.getFileSize(f.name))
   driver_tools.RunDriver('strip',
       ['--strip-debug', f.name, '-o', f_stripped.name])
   self.assertTrue(self.getFileSize(f_stripped.name) <
                   self.getFileSize(f.name))
コード例 #7
0
def BuildDynamicExecutable():
  inputs = Env.get('INPUTS')
  if len(inputs) != 1:
    Log.Fatal('You must specify exactly on input for a dynamic executable.')

  pexe_command = ProcessBuildCommand(BUILD_COMMAND_PEXE_FROM_BC)
  DumpCommand("@bc->pexe", pexe_command)
  driver_tools.RunDriver('clang', pexe_command, suppress_arch=True)

  nexe_command = ProcessBuildCommand(BUILD_COMMAND_NEXE_FROM_PEXE)
  DumpCommand("@pexe->nexe", nexe_command)
  driver_tools.RunDriver('translate', nexe_command)
コード例 #8
0
    def getFakePexe(self):
        with self.getTemp(suffix='.ll', close=False) as t:
            with self.getTemp(suffix='.pexe') as p:
                t.write('''
define i32 @foo() {
  %1 = add i32 1, 1
  %2 = add i32 %1, %1
  %3 = add i32 %2, %2
  %4 = add i32 %3, %3
  %5 = add i32 %4, %4
  %6 = add i32 %5, %5
  %7 = add i32 %6, %6
  %8 = add i32 %7, %7
  %9 = add i32 %8, %8
  %10 = add i32 %9, %9
  %11 = add i32 %10, %10
  %12 = add i32 %11, %11
  %13 = add i32 %12, %12
  %14 = add i32 %13, %13
  %15 = add i32 %14, %14
  %16 = add i32 %15, %15
  ret i32 %16
}

define i32 @main() {
  %1 = add i32 1, 1
  %2 = add i32 %1, %1
  %3 = add i32 %2, %2
  %4 = add i32 %3, %3
  %5 = add i32 %4, %4
  %6 = add i32 %5, %5
  %7 = add i32 %6, %6
  %8 = add i32 %7, %7
  %9 = add i32 %8, %8
  %10 = add i32 %9, %9
  %11 = add i32 %10, %10
  %12 = add i32 %11, %11
  %13 = add i32 %12, %12
  %14 = add i32 %13, %13
  %15 = add i32 %14, %14
  %16 = add i32 %15, %15
  %17 = call i32 @foo()
  %18 = add i32 %16, %17
  ret i32 %18
}
''')
                t.close()
                driver_tools.RunDriver('pnacl-as', [t.name, '-o', p.name])
                driver_tools.RunDriver('pnacl-finalize', [p.name])
                return p
コード例 #9
0
    def getFakePexe(self):
        # Even --dry-run requires a file to exist, so make a fake pexe.
        # It even cares that the file is really bitcode.
        with self.getTemp(suffix='.ll', close=False) as t:
            with self.getTemp(suffix='.pexe') as p:
                t.write('''
define i32 @main() {
  ret i32 0
}
''')
                t.close()
                driver_tools.RunDriver('as', [t.name, '-o', p.name])
                driver_tools.RunDriver('finalize', [p.name])
                return p
コード例 #10
0
 def test_relocatable_header(self):
     """Tests that the driver accepts --relocatable-header."""
     h = self.getFirstTestHeader(suffix='.h')
     h2 = self.getSecondTestHeader(h.name, suffix='.h')
     driver_tools.RunDriver('pnacl-clang', [
         '-x', 'c-header', '--relocatable-pch', '-isysroot', self.temp_dir,
         h2.name
     ])
コード例 #11
0
ファイル: strip_test.py プロジェクト: sbc100/native_client
 def generateArchive(self, objs):
     a = self.getTemp(suffix='.a')
     # Archive file must be a valid archive (non-empty), or non-existent,
     # so remove it before running.
     os.remove(a.name)
     obj_names = [obj.name for obj in objs]
     args = ['rcs', a.name] + obj_names
     driver_tools.RunDriver('pnacl-ar', args)
     return a
コード例 #12
0
    def getFakePexe(self, finalized=True):
        # Even --dry-run requires a file to exist, so make a fake pexe.
        # It even cares that the file is really bitcode.
        with self.getTemp(suffix='.ll', close=False) as t:
            with self.getTemp(suffix='.pexe') as p:
                t.write('''
define i32 @_start() {
  ret i32 0
}
''')
                t.close()
                driver_tools.RunDriver('as', [t.name, '-o', p.name])
                if finalized:
                    driver_tools.RunDriver('finalize', [p.name])
                    self.assertTrue(filetype.IsPNaClBitcode(p.name))
                else:
                    self.assertTrue(filetype.IsLLVMBitcode(p.name))
                return p
コード例 #13
0
    def test_ExpandedPathTooLong(self):
        '''Test that the expanded path is checked with a short relative path'''
        if not driver_test_utils.CanRunHost() or driver_tools.IsWindowsPython(
        ):
            return

        os.chdir(self.LongTempDir)

        shortname = 'a' * 10
        longname = 'a' * 32

        # Now we are in a state where the file can be referred to by a relative
        # path or a normalized absolute path. For 'shortname', both are short
        # enough
        assert len(os.path.join(self.LongTempDir, shortname)) + 2 < 255
        assert len(os.path.join(self.LongTempDir, longname)) + 2 > 255
        self.WriteCFile(shortname + '.c')

        # Test that using a relative almost-too-long path works
        driver_tools.RunDriver(
            'pnacl-clang', [shortname + '.c', '-c', '-o', shortname + '.o'])

        driver_tools.RunDriver('pnacl-ld', [shortname + '.o'])

        # This name has a short-enough relative path and a short-enough normalized
        # final path, but the intermediate concatenation of pwd + rel path is too
        # long
        name_with_traversals = os.path.join('..',
                                            os.path.basename(self.LongTempDir),
                                            shortname)

        output = self.AssertRaisesAndReturnOutput(
            driver_test_utils.DriverExitException, driver_tools.RunDriver,
            'pnacl-clang',
            [name_with_traversals + '.c', '-c', '-o', shortname + '.o'])
        self.assertIn('expanded', output)

        # The previous test only gives a long input name. Also test that the output
        # name is checked.
        output = self.AssertRaisesAndReturnOutput(
            driver_test_utils.DriverExitException, driver_tools.RunDriver,
            'pnacl-clang',
            [shortname + '.c', '-c', '-o', name_with_traversals + '.o'])
        self.assertIn('expanded', output)
コード例 #14
0
 def test_finalize(self):
   """ Test that pnacl-ld will finalize the pexe when requested"""
   if not driver_test_utils.CanRunHost():
     return
   bitcode = self.getBitcode()
   with self.getTemp(suffix='.pexe') as temp_output:
     driver_tools.RunDriver(
       'pnacl-ld', ['--finalize', bitcode.name, '-o', temp_output.name])
     self.assertFalse(filetype.IsLLVMBitcode(temp_output.name))
     self.assertTrue(filetype.IsPNaClBitcode(temp_output.name))
コード例 #15
0
ファイル: strip_test.py プロジェクト: sbc100/native_client
 def generateObjWithDebug(self, src, is_native):
     s = '.bc'
     if is_native:
         s = '.o'
     obj = self.getTemp(suffix=s)
     args = ['-c', '-g', src.name, '-o', obj.name]
     if is_native:
         args += ['-arch', 'x86-32', '--pnacl-allow-translate']
     driver_tools.RunDriver('pnacl-clang', args)
     return obj
コード例 #16
0
    def test_PathWithSpaces(self):
        '''Test that the driver correctly handles paths containing spaces'''
        if not driver_test_utils.CanRunHost():
            return

        name = os.path.join(self.ShorterTempDir, 'a file')
        self.WriteCFile(name + '.c')
        driver_tools.RunDriver('pnacl-clang',
                               [name + '.c', '-c', '-o', name + '.o'])
        self.assertEqual('po', filetype.FileType(name + '.o'))
コード例 #17
0
 def getBitcodeArch(self, filename):
     with self.getTemp(suffix='.ll') as ll:
         driver_tools.RunDriver('dis', [filename, '-o', ll.name])
         with open(ll.name) as f:
             disassembly = f.read()
             match = re.search(r'target triple = "(.+)"', disassembly)
             if not match:
                 return None
             triple = match.group(1)
             return driver_tools.ParseTriple(triple)
コード例 #18
0
 def test_inplace_finalize(self):
   if not driver_test_utils.CanRunHost():
     return
   ll, bc = self.getFakeLLAndBitcodeFile()
   self.assertTrue(filetype.FileType(bc.name) == 'po')
   self.assertTrue(filetype.IsLLVMBitcode(bc.name))
   self.assertFalse(filetype.IsPNaClBitcode(bc.name))
   driver_tools.RunDriver('finalize', [bc.name])
   self.assertFalse(filetype.IsLLVMBitcode(bc.name))
   self.assertTrue(filetype.IsPNaClBitcode(bc.name))
   self.assertTrue(filetype.FileType(bc.name) == 'pexe')
コード例 #19
0
def BuildSharedLib():
  # Shared libs must be built PIC
  Env.set('GENERATE_PIC', '1')
  inputs = Env.get('INPUTS')
  if len(inputs) == 0:
    Log.Fatal('No input specified.')
  if not Env.getbool('GENERATE_PIC'):
    Log.Fatal('Shared libs must be build in pic mode. Use -fPIC')
  if Env.getone('SONAME_FLAG') == '':
    Log.Fatal('Shared libs must be given a soname.')

  pso_command = ProcessBuildCommand(BUILD_COMMAND_PSO_FROM_BC)
  DumpCommand("@bc->pso", pso_command)
  # suppress_arch is needed to prevent clang to inherit the
  # -arch argument
  driver_tools.RunDriver('clang', pso_command, suppress_arch=True)

  so_command = ProcessBuildCommand(BUILD_COMMAND_SO_FROM_PSO)
  DumpCommand("@pso->so", so_command)
  driver_tools.RunDriver('translate', so_command)
コード例 #20
0
  def getFakeLLAndBitcodeFile(self):
    with self.getTemp(suffix='.ll', close=False) as t:
      t.write('''
define i32 @main() {
  ret i32 0
}
''')
      t.close()
      with self.getTemp(suffix='.bc') as b:
        driver_tools.RunDriver('as', [t.name, '-o', b.name])
        return t, b
コード例 #21
0
def RunLD(infile, outfile):
    inputs = env.get('INPUTS')
    if infile:
        inputs = ListReplace(inputs, '__BITCODE__',
                             '--llc-translated-file=' + infile)
    ToggleDefaultCommandlineLD(inputs, infile)
    env.set('ld_inputs', *inputs)
    args = env.get('LD_ARGS') + ['-o', outfile]
    if not env.getbool('SHARED') and env.getbool('STDLIB'):
        args += env.get('LD_ARGS_ENTRY')
    args += env.get('LD_FLAGS')
    driver_tools.RunDriver('nativeld', args)
コード例 #22
0
 def checkXFlagOutput(self, flags, expected):
   ''' Given |flags| for pnacl-clang, check that clang outputs the |expected|.
   '''
   if not driver_test_utils.CanRunHost():
     return
   temp_out = pathtools.normalize(tempfile.NamedTemporaryFile().name)
   driver_temps.TempFiles.add(temp_out)
   driver_tools.RunDriver('pnacl-clang', flags + ['-o', temp_out])
   output = open(temp_out, 'r').read()
   for e in expected:
     self.assertTrue(re.search(e, output),
                     msg='Searching for regex %s in %s' % (e, output))
コード例 #23
0
 def test_finalize_keep_syms(self):
     """Test that finalize is still able to create a pexe w/ -no-strip-syms."""
     if not driver_test_utils.CanRunHost():
         return
     bc = self.getBCWithDebug()
     self.assertTrue(filetype.FileType(bc.name) == 'po')
     self.assertTrue(filetype.IsLLVMBitcode(bc.name))
     self.assertFalse(filetype.IsPNaClBitcode(bc.name))
     driver_tools.RunDriver('pnacl-finalize', [bc.name, '--no-strip-syms'])
     self.assertFalse(filetype.IsLLVMBitcode(bc.name))
     self.assertTrue(filetype.IsPNaClBitcode(bc.name))
     self.assertTrue(filetype.FileType(bc.name) == 'pexe')
     # Use pnacl-dis instead of llvm-nm, since llvm-nm won't know how to
     # handle finalized bitcode for now:
     # https://code.google.com/p/nativeclient/issues/detail?id=3993
     with self.getTemp(suffix='.ll') as temp_ll:
         driver_tools.RunDriver('pnacl-dis', [bc.name, '-o', temp_ll.name])
         with open(temp_ll.name, 'r') as dis_file:
             file_contents = dis_file.read()
             self.assertTrue(re.search(r'define .*@baz', file_contents))
             self.assertTrue(re.search(r'define .*@foo', file_contents))
コード例 #24
0
  def getBitcode(self, finalized=True):
    # Even --dry-run requires a file to exist, so make a fake bitcode file.
    # It even cares that the file is really bitcode.
    with self.getTemp(suffix='.ll', close=False) as t:
      with self.getTemp(suffix='.o') as o:
        t.write('''
define i32 @_start() {
  ret i32 0
}
''')
        t.close()
        driver_tools.RunDriver('pnacl-as', [t.name, '-o', o.name])
        return o
コード例 #25
0
    def test_InputPathTooLong(self):
        '''Test that clang and ld reject input paths that are too long

     Test that compiling and linking paths shorter than 255 succeeds and paths
     longer than 255 fails.
     Operations in python (e.g. rename) on long paths don't work on Windows,
     so just run the tests on Linux/Mac (the checks are enabled in unittest
     mode)
     '''
        if not driver_test_utils.CanRunHost() or driver_tools.IsWindowsPython(
        ):
            return

        shortname = os.path.join(self.LongTempDir, 'a' * 10)
        longname = os.path.join(self.LongTempDir, 'a' * 32)

        assert len(shortname) + 2 < 255
        assert len(longname) + 2 > 255
        self.WriteCFile(shortname + '.c')

        driver_tools.RunDriver(
            'pnacl-clang', [shortname + '.c', '-c', '-o', shortname + '.o'])

        driver_tools.RunDriver('pnacl-ld', [shortname + '.o'])

        os.rename(shortname + '.c', longname + '.c')
        os.rename(shortname + '.o', longname + '.o')

        output = self.AssertRaisesAndReturnOutput(
            driver_test_utils.DriverExitException, driver_tools.RunDriver,
            'pnacl-clang', [longname + '.c', '-c', '-o', longname + '.o'])

        self.assertIn('too long', output)

        output = self.AssertRaisesAndReturnOutput(
            driver_test_utils.DriverExitException, driver_tools.RunDriver,
            'pnacl-ld', [longname + '.o'])

        self.assertIn('too long', output)
コード例 #26
0
    def test_bc_objects(self):
        s = self.getFakeSourceFile()
        with self.getTemp(suffix='.o') as obj:
            # Test that clang with "normal" args results in a portable bitcode object
            driver_tools.RunDriver('clang', [s.name, '-c', '-o', obj.name])
            self.assertTrue(filetype.IsLLVMBitcode(obj.name))
            self.assertEqual(self.getBitcodeArch(obj.name), 'le32')

            # Test that the --target flag produces biased bitcode objects
            test_args = [
                ('armv7', 'ARM', '-gnueabihf', ['-mfloat-abi=hard']),
                ('i686', 'X8632', '', []),
                ('x86_64', 'X8664', '', []),
                ('mips', 'MIPS32', '', []),
            ]
            for (target, arch, target_extra, cmd_extra) in test_args:
                target_arg = '--target=%s-unknown-nacl%s' % (target,
                                                             target_extra)
                driver_tools.RunDriver(
                    'clang',
                    [s.name, target_arg, '-c', '-o', obj.name] + cmd_extra)
                self.assertTrue(filetype.IsLLVMBitcode(obj.name))
                self.assertEqual(self.getBitcodeArch(obj.name), arch)
コード例 #27
0
def RunLD(infile, outfile):
  inputs = env.get('INPUTS')
  if infile:
    # Put llc-translated-file at the beginning of the inputs so that it will
    # pull in all needed symbols from any native archives that may also be
    # in the input list. This is in case there are any mixed groups of bitcode
    # and native archives in the link (as is the case with irt_browser_lib)
    inputs.remove('__BITCODE__')
    inputs = ['--llc-translated-file=' + infile] + inputs
  env.set('ld_inputs', *inputs)
  args = env.get('LD_ARGS') + ['-o', outfile]
  if env.getbool('USE_STDLIB'):
    args += env.get('LD_ARGS_ENTRY')
  args += env.get('LD_FLAGS')
  driver_tools.RunDriver('nativeld', args)
コード例 #28
0
    def check_flags(self, flags, pnacl_flag):
        """ Check that pnacl_flag doesn't get passed to clang.

    It should only be in the 'Driver invocation:' part that we print out.
    """
        capture_out = cStringIO.StringIO()
        driver_log.Log.CaptureToStream(capture_out)
        driver_tools.RunDriver('clang', flags + [pnacl_flag])
        driver_log.Log.ResetStreams()
        out = capture_out.getvalue()
        lines = out.splitlines()
        self.assertTrue('Driver invocation:' in lines[0])
        self.assertTrue(pnacl_flag in lines[0])
        for line in lines[1:]:
            self.assertTrue(pnacl_flag not in line)
        for flag in flags:
            self.assertTrue(exists(flag, lines[1:]))
コード例 #29
0
    def getBCWithDebug(self):
        with self.getTemp(suffix='.c', close=False) as t:
            t.write('''
int __attribute__((noinline)) baz(int x, int y) {
  return x + y;
}

int foo(int a, int b) {
  return baz(a, b);
}
''')
            t.close()
            with self.getTemp(suffix='.bc') as b:
                # Compile w/ optimization to avoid allocas from local
                # variables/parameters, since this isn't running the ABI
                # simplification passes.
                driver_tools.RunDriver(
                    'pnacl-clang', [t.name, '-o', b.name, '-c', '-g', '-O1'])
                return b
コード例 #30
0
 def checkLDOptNumRuns(self, bitcode, flags, num_runs):
   """ Given a |bitcode| file the |arch| and additional pnacl-ld |flags|,
   check that opt will only be run |num_runs| times. """
   # TODO(jvoung): Get rid of INHERITED_DRIVER_ARGS, which leaks across runs.
   env.set('INHERITED_DRIVER_ARGS', '')
   temp_output = self.getTemp()
   capture_out = cStringIO.StringIO()
   driver_log.Log.CaptureToStream(capture_out)
   driver_tools.RunDriver('pnacl-ld',
                          ['--pnacl-driver-verbose',
                           '--dry-run',
                           bitcode.name,
                           '-o', temp_output.name] + flags)
   driver_log.Log.ResetStreams()
   out = capture_out.getvalue()
   split_out = out.splitlines()
   count = 0
   for line in split_out:
     if re.search('Running: .*opt( |\.exe)', line):
       count += 1
   self.assertEqual(num_runs, count)