def test_lib_flags_lib(self): lib = self.Path('/path/to/lib/foo.lib') self.assertEqual( self.linker.lib_flags( opts.option_list(opts.lib(SharedLibrary(lib, 'native')))), [lib]) self.assertEqual( self.linker.lib_flags(opts.option_list( opts.lib(SharedLibrary(lib, 'native'))), mode='pkg-config'), ['-lfoo']) self.assertEqual( self.linker.lib_flags( opts.option_list( opts.lib(WholeArchive(SharedLibrary(lib, 'native'))))), ['/WHOLEARCHIVE:' + lib]) version = ('Microsoft (R) C/C++ Optimizing Compiler Version ' + '18.00.25831 for x86') with mock.patch('bfg9000.shell.which', mock_which): linker = MsvcBuilder(self.env, known_langs['c++'], ['cl'], version).linker('executable') with self.assertRaises(TypeError): linker.lib_flags( opts.option_list( opts.lib(WholeArchive(StaticLibrary(lib, 'native'))))) with self.assertRaises(TypeError): self.linker.lib_flags( opts.option_list(opts.lib(Framework('cocoa'))))
class TestMsvcLinker(CrossPlatformTestCase): def __init__(self, *args, **kwargs): CrossPlatformTestCase.__init__(self, clear_variables=True, *args, **kwargs) def setUp(self): version = ('Microsoft (R) C/C++ Optimizing Compiler Version ' + '19.12.25831 for x86') with mock.patch('bfg9000.shell.which', mock_which): self.linker = MsvcBuilder(self.env, known_langs['c++'], ['cl'], version).linker('executable') def test_call(self): extra = self.linker._always_flags self.assertEqual(self.linker(['in'], 'out'), [self.linker] + extra + ['in', '/OUT:out']) self.assertEqual(self.linker(['in'], 'out', flags=['flags']), [self.linker] + extra + ['flags', 'in', '/OUT:out']) self.assertEqual(self.linker(['in'], 'out', ['lib']), [self.linker] + extra + ['in', 'lib', '/OUT:out']) self.assertEqual(self.linker(['in'], 'out', ['lib'], ['flags']), [self.linker] + extra + ['flags', 'in', 'lib', '/OUT:out']) def test_output_file(self): fmt = self.env.target_platform.object_format ext = self.env.target_platform.executable_ext self.assertEqual(self.linker.output_file('prog', None), file_types.Executable(Path('prog' + ext), fmt, 'c++')) def test_flags_empty(self): self.assertEqual(self.linker.flags(opts.option_list()), []) def test_flags_lib_dir(self): libdir = self.Path('/path/to/lib') lib = self.Path('/path/to/lib/foo.so') # Lib dir self.assertEqual( self.linker.flags( opts.option_list(opts.lib_dir(file_types.Directory(libdir)))), ['/LIBPATH:' + libdir]) self.assertEqual( self.linker.flags(opts.option_list( opts.lib_dir(file_types.Directory(libdir))), mode='pkg-config'), ['-L' + libdir]) # Shared library self.assertEqual( self.linker.flags( opts.option_list( opts.lib(file_types.SharedLibrary(lib, 'native')))), []) # Static library self.assertEqual( self.linker.flags( opts.option_list( opts.lib(file_types.StaticLibrary(lib, 'native')))), []) # Mixed self.assertEqual( self.linker.flags( opts.option_list( opts.lib_dir(file_types.Directory(libdir)), opts.lib(file_types.SharedLibrary(lib, 'native')))), ['/LIBPATH:' + libdir]) def test_flags_module_def(self): path = self.Path('/path/to/module.def') self.assertEqual( self.linker.flags( opts.option_list( opts.module_def(file_types.ModuleDefFile(path)))), ['/DEF:' + path]) def test_flags_debug(self): self.assertEqual(self.linker.flags(opts.option_list(opts.debug())), ['/DEBUG']) def test_flags_optimize(self): self.assertEqual( self.linker.flags(opts.option_list(opts.optimize('disable'))), []) self.assertEqual( self.linker.flags(opts.option_list(opts.optimize('size'))), []) self.assertEqual( self.linker.flags(opts.option_list(opts.optimize('speed'))), []) self.assertEqual( self.linker.flags(opts.option_list(opts.optimize('linktime'))), ['/LTCG']) self.assertEqual( self.linker.flags( opts.option_list(opts.optimize('speed', 'linktime'))), ['/LTCG']) def test_flags_string(self): self.assertEqual(self.linker.flags(opts.option_list('-v')), ['-v']) def test_flags_lib_literal(self): self.assertEqual( self.linker.flags(opts.option_list(opts.lib_literal('-lfoo'))), []) def test_flags_invalid(self): with self.assertRaises(TypeError): self.linker.flags(opts.option_list(123)) def test_lib_flags_empty(self): self.assertEqual(self.linker.lib_flags(opts.option_list()), []) def test_lib_flags_lib(self): lib = self.Path('/path/to/lib/foo.lib') self.assertEqual( self.linker.lib_flags( opts.option_list( opts.lib(file_types.SharedLibrary(lib, 'native')))), [lib]) self.assertEqual( self.linker.lib_flags(opts.option_list( opts.lib(file_types.SharedLibrary(lib, 'native'))), mode='pkg-config'), ['-lfoo']) self.assertEqual( self.linker.lib_flags( opts.option_list( opts.lib( file_types.WholeArchive( file_types.SharedLibrary(lib, 'native'))))), ['/WHOLEARCHIVE:' + lib]) version = ('Microsoft (R) C/C++ Optimizing Compiler Version ' + '18.00.25831 for x86') with mock.patch('bfg9000.shell.which', mock_which): linker = MsvcBuilder(self.env, known_langs['c++'], ['cl'], version).linker('executable') with self.assertRaises(TypeError): linker.lib_flags( opts.option_list( opts.lib( file_types.WholeArchive( file_types.StaticLibrary(lib, 'native'))))) with self.assertRaises(TypeError): self.linker.lib_flags( opts.option_list(opts.lib(Framework('cocoa')))) def test_lib_flags_lib_literal(self): self.assertEqual( self.linker.lib_flags(opts.option_list(opts.lib_literal('/?'))), ['/?']) def test_lib_flags_ignored(self): self.assertEqual(self.linker.lib_flags(opts.option_list('-Lfoo')), []) def test_parse_flags(self): default = { 'extra': [], 'libs': [], 'nologo': None, } def assertFlags(flags, libflags, extra={}): self.assertEqual(self.linker.parse_flags(flags, libflags), merge_dicts(default, extra)) assertFlags([], []) assertFlags(['/foo', 'bar'], ['/baz', 'quux'], { 'libs': ['quux'], 'extra': ['/foo', 'bar', '/baz'] }) assertFlags(['/nologo'], [], {'nologo': True}) assertFlags([], ['/nologo'], {'nologo': True}) assertFlags(['/nologo'], ['/nologo'], {'nologo': True})
class TestMsvcLinker(unittest.TestCase): def setUp(self): self.env = make_env() version = ('Microsoft (R) C/C++ Optimizing Compiler Version ' + '19.12.25831 for x86') with mock.patch('bfg9000.shell.which', mock_which): self.linker = MsvcBuilder(self.env, known_langs['c++'], ['cl'], version).linker('executable') def test_flags_empty(self): self.assertEqual(self.linker.flags(opts.option_list()), []) def test_flags_lib_dir(self): libdir = Path('/path/to/lib') lib = Path('/path/to/lib/foo.so') # Lib dir self.assertEqual( self.linker.flags( opts.option_list(opts.lib_dir(file_types.Directory(libdir)))), ['/LIBPATH:' + libdir]) self.assertEqual( self.linker.flags(opts.option_list( opts.lib_dir(file_types.Directory(libdir))), mode='pkg-config'), ['-L' + libdir]) # Shared library self.assertEqual( self.linker.flags( opts.option_list( opts.lib(file_types.SharedLibrary(lib, 'native')))), ['/LIBPATH:' + libdir]) # Static library self.assertEqual( self.linker.flags( opts.option_list( opts.lib(file_types.StaticLibrary(lib, 'native')))), ['/LIBPATH:' + libdir]) # Mixed self.assertEqual( self.linker.flags( opts.option_list( opts.lib_dir(file_types.Directory(libdir)), opts.lib(file_types.SharedLibrary(lib, 'native')))), ['/LIBPATH:' + libdir]) def test_flags_string(self): self.assertEqual(self.linker.flags(opts.option_list('-v')), ['-v']) def test_flags_lib_literal(self): self.assertEqual( self.linker.flags(opts.option_list(opts.lib_literal('-lfoo'))), []) def test_flags_invalid(self): with self.assertRaises(TypeError): self.linker.flags(opts.option_list(123)) def test_lib_flags_empty(self): self.assertEqual(self.linker.lib_flags(opts.option_list()), []) def test_lib_flags_lib(self): lib = Path('/path/to/lib/foo.lib') self.assertEqual( self.linker.lib_flags( opts.option_list( opts.lib(file_types.SharedLibrary(lib, 'native')))), [lib.basename()]) self.assertEqual( self.linker.lib_flags(opts.option_list( opts.lib(file_types.SharedLibrary(lib, 'native'))), mode='pkg-config'), ['-lfoo']) self.assertEqual( self.linker.lib_flags( opts.option_list( opts.lib( file_types.WholeArchive( file_types.SharedLibrary(lib, 'native'))))), ['/WHOLEARCHIVE:' + lib.basename()]) version = ('Microsoft (R) C/C++ Optimizing Compiler Version ' + '18.00.25831 for x86') with mock.patch('bfg9000.shell.which', mock_which): linker = MsvcBuilder(self.env, known_langs['c++'], ['cl'], version).linker('executable') with self.assertRaises(TypeError): linker.lib_flags( opts.option_list( opts.lib( file_types.WholeArchive( file_types.StaticLibrary(lib, 'native'))))) with self.assertRaises(TypeError): self.linker.lib_flags( opts.option_list(opts.lib(Framework('cocoa')))) def test_lib_flags_lib_literal(self): self.assertEqual( self.linker.lib_flags(opts.option_list(opts.lib_literal('/?'))), ['/?']) def test_lib_flags_ignored(self): self.assertEqual(self.linker.lib_flags(opts.option_list('-Lfoo')), [])