def test_analyze_expanded_args_params(self): with FakeFs(bitcode_files=['foo.o']): result = goma_ld.GomaLinkUnix().analyze_expanded_args([ 'clang', '-O2', '-flto=thin', '-fsplit-lto-unit', '-fwhole-program-vtables', '-fsanitize=cfi', '-g', '-gsplit-dwarf', '-mllvm', '-generate-type-units', 'foo.o', '-o', 'foo' ], 'foo', 'clang', 'lto.foo', 'common', False) self.assertIsNotNone(result) self.assertIn('-Wl,-plugin-opt=obj-path=lto.foo/foo.split.o', result.index_params) self.assertIn('-O2', result.index_params) self.assertIn('-g', result.index_params) self.assertIn('-gsplit-dwarf', result.index_params) self.assertIn('-mllvm -generate-type-units', ' '.join(result.index_params)) self.assertIn('-flto=thin', result.index_params) self.assertIn('-fwhole-program-vtables', result.index_params) self.assertIn('-fsanitize=cfi', result.index_params) self.assertIn('-O2', result.codegen_params) self.assertIn('-g', result.codegen_params) self.assertIn('-gsplit-dwarf', result.codegen_params) self.assertIn('-mllvm -generate-type-units', ' '.join(result.codegen_params)) self.assertNotIn('-flto=thin', result.codegen_params) self.assertNotIn('-fwhole-program-vtables', result.codegen_params) self.assertNotIn('-fsanitize=cfi', result.codegen_params) self.assertIn('-flto=thin', result.final_params)
def test_codegen_params_no_function_sections(self): with FakeFs(bitcode_files=['foo.o'], other_files=['bar.o']): result = goma_ld.GomaLinkUnix().analyze_expanded_args( ['clang', '-fno-function-sections', 'foo.o', 'bar.o', '-o', 'foo'], 'foo', 'clang', 'lto.foo', 'common', False) self.assertIn('-fdata-sections', result.codegen_params) self.assertNotIn('-ffunction-sections', result.codegen_params)
def test_fallback_lto(self): with NamedDirectory() as d, WorkingDirectory(d): _create_inputs(d) subprocess.check_call([ self.clangxx(), '-c', '-Os', '-flto=thin', 'main.cpp', '-o', 'main.o' ]) subprocess.check_call([ self.clangxx(), '-c', '-Os', '-flto=thin', 'foo.cpp', '-o', 'foo.o' ]) rc = goma_ld.GomaLinkUnix().main([ 'goma_ld.py', '--gomacc', 'gomacc', '--', self.clangxx(), '-fuse-ld=lld', '-flto=thin', 'main.o', 'foo.o', '-o', 'main' ]) # Should succeed. self.assertEqual(rc, 0) # lto.main directory should not be present. self.assertFalse(os.path.exists(os.path.join(d, 'lto.main'))) # Check that main does not call foo. disasm = subprocess.check_output(['llvm-objdump', '-d', 'main']) main_idx = disasm.index(b' main:\n') after_main_idx = disasm.index(b'\n\n', main_idx) main_disasm = disasm[main_idx:after_main_idx] self.assertNotIn(b'foo', main_disasm)
def test_override_allowlist(self): with named_directory() as d, working_directory(d): _create_inputs(d) subprocess.check_call([ self.clangxx(), '-c', '-Os', '-flto=thin', 'main.cpp', '-o', 'main.o' ]) subprocess.check_call([ self.clangxx(), '-c', '-Os', '-flto=thin', 'foo.cpp', '-o', 'foo.o' ]) rc = goma_ld.GomaLinkUnix().main([ 'goma_ld.py', '--generate', '--allowlist', '--', self.clangxx(), '-fuse-ld=lld', '-flto=thin', 'main.o', 'foo.o', '-o', 'main' ]) # Should succeed. self.assertEqual(rc, 0) # build.ninja file should have rules for main and foo. ninjafile = os.path.join(d, 'lto.main', 'build.ninja') self.assertTrue(os.path.exists(ninjafile)) with open(ninjafile) as f: buildrules = f.read() self.assertIn('build lto.main/main.o.stamp : codegen ', buildrules) self.assertIn('build lto.main/foo.o.stamp : codegen ', buildrules)
def test_transform_codegen_param_on_mllvm(self): # Regression test for crbug.com/1135234 link = goma_ld.GomaLinkUnix() self.assertEqual( link.transform_codegen_param_common( '-mllvm,-import-instr-limit=20'), ['-mllvm', '-import-instr-limit=20'])
def test_codegen_params_default(self): with FakeFs(bitcode_files=['foo.o'], other_files=['bar.o']): result = goma_ld.GomaLinkUnix().analyze_expanded_args( ['clang', 'foo.o', 'bar.o', '-o', 'foo'], 'foo', 'clang', 'lto.foo', 'common', False) # Codegen optimization level should default to 2. self.assertIn('-O2', result.codegen_params) # -fdata-sections and -ffunction-sections default to on to match the # behavior of local linking. self.assertIn('-fdata-sections', result.codegen_params) self.assertIn('-ffunction-sections', result.codegen_params)
def test_analyze_expanded_args_one_codegen(self): with FakeFs(bitcode_files=['foo.o'], other_files=['bar.o']): result = goma_ld.GomaLinkUnix().analyze_expanded_args( ['clang', 'foo.o', 'bar.o', '-o', 'foo'], 'foo', 'clang', 'lto.foo', 'common', False) self.assertIsNotNone(result) self.assertNotEqual(len(result.codegen), 0) self.assertEqual(result.codegen[0][1], 'foo.o') self.assertEqual(len(result.codegen), 1) self.assertIn('foo.o', result.index_params) self.assertIn('bar.o', result.index_params) self.assertIn('bar.o', result.final_params) # foo.o should not be in final_params because it will be added via # the used object file. self.assertNotIn('foo.o', result.final_params)
def test_analyze_expanded_args_nocodegen(self): with FakeFs(other_files=['foo.o', 'bar.o']): self.assertIsNone(goma_ld.GomaLinkUnix().analyze_expanded_args( ['clang', 'foo.o', 'bar.o', '-o', 'foo'], 'foo', 'clang', 'lto.foo', 'common', False))