def test_ParseCommandArgs(self): # TODO(tvl): add -F and -iframework lines to the tests once we figure # out how we're dealing with them. quote_dirs, angle_dirs, include_files, filepath, _incl_clos_f, _d_opts = ( parse_command.ParseCommandArgs( parse_command.ParseCommandLine( self.mock_compiler + " -isystem system -Imice -iquote/and -I/men a.c " " -include included_A.h " " -includeincluded_B.h " "-Xlinker W,l -L /ignored_by_us -o a.o"), os.getcwd(), self.includepath_map, self.directory_map, self.compiler_defaults)) self.assertEqual( (self._RetrieveDirectoriesExceptSys(quote_dirs), self._RetrieveDirectoriesExceptSys(angle_dirs), [self.includepath_map.String(i) for i in include_files], filepath), (('/and', 'mice', '/men', 'system'), ('mice', '/men', 'system'), ["included_A.h", "included_B.h"], 'a.c')) self.assertRaises( NotCoveredError, parse_command.ParseCommandArgs, parse_command.ParseCommandLine(self.mock_compiler + " -I- -iquote a.c"), os.getcwd(), self.includepath_map, self.directory_map, self.compiler_defaults) quote_dirs, angle_dirs, include_files, filepath, _incl_cls_file, _d_opts = ( parse_command.ParseCommandArgs( parse_command.ParseCommandLine( "/usr/crosstool/v8/gcc-4.1.0-glibc-2.2.2/blah/gcc" + " -fno-exceptions -funsigned-char -D__STDC_FORMAT_MACROS -g0" + " -D_REENTRANT -DCOMPILER_GCC3 -DCOMPILER_GCC4 -DARCH_PIII -DOS_LINUX" + " -fmessage-length=0 -fno-strict-aliasing -fno-tree-vrp -D_REENTRANT" + " -DHAS_vsnprintf" + " -Iobj/gcc-4.1.0-glibc-2.2.2-piii-linux-g0-dbg/genfiles/third_party/libxml/third_party/libxml" + " -Ithird_party/zlib -iquote . -fno-strict-aliasing -c -o" + " obj/gcc-4.1.0-glibc-2.2.2-piii-linux-g0-dbg/bin/third_party/libxml/threads.c.o" + " third_party/libxml/threads.c"), os.getcwd(), self.includepath_map, self.directory_map, self.compiler_defaults)) self.assertEqual(( self._RetrieveDirectoriesExceptSys(quote_dirs), self._RetrieveDirectoriesExceptSys(angle_dirs), filepath ), (( '', 'obj/gcc-4.1.0-glibc-2.2.2-piii-linux-g0-dbg/genfiles/third_party/libxml/third_party/libxml', 'third_party/zlib' ), ('obj/gcc-4.1.0-glibc-2.2.2-piii-linux-g0-dbg/genfiles/third_party/libxml/third_party/libxml', 'third_party/zlib'), 'third_party/libxml/threads.c'))
def ProcessCompilationCommandLine(self, cmd, cwd): return (self.include_analyzer.ProcessCompilationCommand( cwd, parse_command.ParseCommandArgs( parse_command.ParseCommandLine(cmd), cwd, self.include_analyzer.includepath_map, self.include_analyzer.directory_map, self.include_analyzer.compiler_defaults)))
def test__CalculateIncludeClosureExceptSystem_on_distcc(self): includepath_map = self.includepath_map canonical_path = self.canonical_path directory_map = self.directory_map realpath_map = self.realpath_map include_analyzer = self.include_analyzer current_dir = os.path.realpath("test_data/distcc") os.chdir(current_dir) src_stem = "distcc" cmd = self._ConstructDistccCommandLine(src_stem) parsed_command = (parse_command.ParseCommandArgs( parse_command.ParseCommandLine(cmd), current_dir, include_analyzer.includepath_map, include_analyzer.directory_map, include_analyzer.compiler_defaults)) (include_analyzer.quote_dirs, include_analyzer.angle_dirs, include_analyzer.include_files, translation_unit, include_analyzer.result_file_prefix, _) = parsed_command self.assertEqual(translation_unit, "src/%s.c" % src_stem) expected_suffixes = [ "src/include_me.h", "src/implicit.h", "src/distcc.c", "src/config.h", "src/distcc.h", "src/state.h", "src/compile.h", "src/trace.h", "src/exitcode.h", "src/util.h", "src/hosts.h", "src/bulk.h", "src/emaillog.h" ] include_closure = (include_analyzer.ProcessCompilationCommand( current_dir, parsed_command)) expected_prefix = os.getcwd() + '/' expected = set([ expected_prefix + expected_suffix for expected_suffix in expected_suffixes ]) self.assertEqual( set([realpath_map.string[key] for key in include_closure.keys()]), expected) for rp_idx in include_closure: self.assertEqual(len(include_closure[rp_idx]), 0)
def DoCompilationCommand(self, cmd, currdir, client_root_keeper): """Parse and and process the command; then gather files and links.""" self.translation_unit = "unknown translation unit" # don't know yet # Any relative paths in the globs in the --stat_reset_trigger argument # must be evaluated relative to the include server's original working # directory. os.chdir(self.include_server_cwd) self.DoStatResetTriggers() # Now change to the distcc client's working directory. # That'll let us use os.path.join etc without including currdir explicitly. os.chdir(currdir) parsed_command = (parse_command.ParseCommandArgs( cmd, currdir, self.includepath_map, self.directory_map, self.compiler_defaults, self.timer)) (unused_quote_dirs, unused_angle_dirs, unused_include_files, source_file, result_file_prefix, unused_Dopts) = parsed_command # Do the real work. include_closure = (self.ProcessCompilationCommand( currdir, parsed_command)) # Cancel timer before I/O in compress_files. if self.timer: # timer may not always exist when testing self.timer.Cancel() # Get name of the initial source file translation_unit = self.translation_unit # Links are accumulated intra-build (across different compilations in a # build). We send all of 'em every time. This will potentially lead to # performance degradation for large link farms. We expect at most a # handful. We add put the system links first, because there should be very # few of them. links = self.compiler_defaults.system_links + self.mirror_path.Links() files = self.compress_files.Compress(include_closure, client_root_keeper, self.currdir_idx) files_and_links = files + links # Note that the performance degradation comment above applies especially # to forced include directories, unless disabled with --no_force_dirs if basics.opt_no_force_dirs == False: files_and_links += self._ForceDirectoriesToExist() realpath_map = self.realpath_map if basics.opt_verify: # Invoke the real preprocessor. exact_no_system_header_dependency_set = (ExactDependencies( " ".join(cmd), realpath_map, self.systemdir_prefix_cache, translation_unit)) if basics.opt_write_include_closure: WriteDependencies(exact_no_system_header_dependency_set, self.result_file_prefix + '.d_exact', realpath_map) VerifyExactDependencies(include_closure, exact_no_system_header_dependency_set, realpath_map, translation_unit) if basics.opt_write_include_closure: WriteDependencies(include_closure, self.result_file_prefix + '.d_approx', realpath_map) return files_and_links
def DoCompilationCommand(self, cmd, currdir, client_root_keeper): """Parse and and process the command; then gather files and links.""" self.translation_unit = "unknown translation unit" # don't know yet # Any relative paths in the globs in the --stat_reset_trigger argument # must be evaluated relative to the include server's original working # directory. os.chdir(self.include_server_cwd) self.DoStatResetTriggers() # Now change to the distcc client's working directory. # That'll let us use os.path.join etc without including currdir explicitly. os.chdir(currdir) parsed_command = (parse_command.ParseCommandArgs( cmd, currdir, self.includepath_map, self.directory_map, self.compiler_defaults, self.timer)) (quote_dirs, unused_angle_dirs, unused_include_files, source_file, result_file_prefix, unused_Dopts) = parsed_command realpath_map = self.realpath_map # Do the real work. include_closure = (self.ProcessCompilationCommand( currdir, parsed_command)) # Look for header maps that are also used during the compilation. Apple # gcc is instructed to use header maps by being given an -I or -iquote # referencing a header map file instead of a directory, so look through # the set of known include directories for header maps. Use quote_dirs # because it contains all of the angle dirs as well. hmap_closure is not # a proper closure, but it's faked up to be compatible with the # include_closure format expected by self.compress_files.Compress. hmap_closure = {} for dir_idx in quote_dirs: dir_str = self.directory_map.string[dir_idx] if dir_str.endswith('.hmap/'): hmap_closure[realpath_map.Index(os.path.abspath(dir_str))] = [] # Cancel timer before I/O in compress_files. if self.timer: # timer may not always exist when testing self.timer.Cancel() # Get name of the initial source file translation_unit = self.translation_unit # Links are accumulated intra-build (across different compilations in a # build). We send all of 'em every time. This will potentially lead to # performance degradation for large link farms. We expect at most a # handful. We add put the system links first, because there should be very # few of them. links = self.compiler_defaults.system_links + self.mirror_path.Links() files = self.compress_files.Compress(include_closure, client_root_keeper, self.currdir_idx) hmaps = self.compress_files.Compress(hmap_closure, client_root_keeper, self.currdir_idx) forcing_files = self._ForceDirectoriesToExist() files_and_links = files + hmaps + links + forcing_files if basics.opt_verify: # Invoke the real preprocessor. exact_no_system_header_dependency_set = (ExactDependencies( " ".join(cmd), realpath_map, self.systemdir_prefix_cache, translation_unit)) if basics.opt_write_include_closure: WriteDependencies(exact_no_system_header_dependency_set, self.result_file_prefix + '.d_exact', realpath_map) VerifyExactDependencies(include_closure, exact_no_system_header_dependency_set, realpath_map, translation_unit) if basics.opt_write_include_closure: WriteDependencies(include_closure, self.result_file_prefix + '.d_approx', realpath_map) return files_and_links