9595 "two libraries. C++ symbols in the appropriate namespaces will be renamed "
9696 "even if they are external. Otherwise, only symbols defined in the library "
9797 "are renamed." )
98+ flags .DEFINE_bool (
99+ "skip_creating_archives" , False ,
100+ "Skip creating archive files (.a or .lib) and instead just leave the object "
101+ "files (.o or .obj) in the output directory." )
98102
99103# Never rename 'std::' by default when --auto_hide_cpp_namespaces is enabled.
100104IMPLICIT_CPP_NAMESPACES_TO_IGNORE = {"std" }
101105
102106DEFAULT_ENCODING = "ascii"
103107
108+ # Once a binutils command fails due to an ambiguous target, use this explicit target
109+ # when running all subsequent binutils commands.
110+ binutils_force_target_format = None
111+
104112
105113class Demangler (object ):
106114 """Spins up a C++ demangler and pipes symboles to/from it to demangle them.
@@ -258,19 +266,20 @@ def create_archive(output_archive_file, object_files, old_archive=None):
258266 Empty list if there are no errors, or error text if there was an error.
259267 """
260268 errors = []
261- if old_archive :
269+ if old_archive and FLAGS . platform != "windows" :
262270 # Copy the old archive to the new archive, then clear the files from it.
263271 # This preserves the file format of the old archive file.
272+ # On Windows, we'll always create a new archive.
264273 shutil .copy (old_archive , output_archive_file )
265274 (old_contents , errors ) = list_objects_in_archive (output_archive_file )
266- run_command (
275+ run_binutils_command (
267276 [FLAGS .binutils_ar_cmd , "d" , output_archive_file ] + old_contents ,
268277 errors )
269- run_command (
278+ run_binutils_command (
270279 [FLAGS .binutils_ar_cmd , "rs" , output_archive_file ] + object_files ,
271280 errors )
272281 else :
273- run_command (
282+ run_binutils_command (
274283 [FLAGS .binutils_ar_cmd , "rcs" , output_archive_file ] + object_files ,
275284 errors )
276285
@@ -738,7 +747,17 @@ def run_binutils_command(cmdline, error_output=None, ignore_errors=False):
738747 Returns:
739748 A list of lines of text of the command's stdout.
740749 """
741- output = run_command (cmdline , error_output , True )
750+ global binutils_force_target_format
751+ if binutils_force_target_format :
752+ # Once we've had to force the format once, assume all subsequent
753+ # files use the same format. Also we will need to explicitly specify this
754+ # format when creating an archive with "ar".
755+ # If we've never had to force a format, let binutils autodetect.
756+ output = run_command ([cmdline [0 ]] + ["--target=%s" % binutils_force_target_format ] + cmdline [1 :],
757+ error_output , ignore_errors )
758+ else :
759+ # Otherwise, if we've never had to force a format, use the default.
760+ output = run_command (cmdline , error_output , True )
742761 if error_output and not output :
743762 # There are some expected errors: "Bad value" or "File format is ambiguous".
744763 #
@@ -748,20 +767,22 @@ def run_binutils_command(cmdline, error_output=None, ignore_errors=False):
748767 # depending on whether the file is 32-bit or 64-bit.
749768 #
750769 # Line 0: filename.o: Bad value
751- if error_output and "Bad value" in error_output [0 ]:
770+ if not binutils_force_target_format and error_output and "Bad value" in error_output [0 ]:
752771 # Workaround for MIPS, force elf32-little and/or elf64-little.
753772 error_output = []
754773 logging .debug ("Bad value when running %s %s" ,
755774 os .path .basename (cmdline [0 ]), " " .join (cmdline [1 :]))
756775 logging .debug ("Retrying with --target=elf32-little" )
757776 output = run_command ([cmdline [0 ]] + ["--target=elf32-little" ] +
758777 cmdline [1 :], error_output , True )
778+ binutils_force_target_format = 'elf32-little'
759779 if error_output :
760780 # Oops, it wasn't 32-bit, try 64-bit instead.
761781 error_output = []
762782 logging .debug ("Retrying with --target=elf64-little" )
763783 output = run_command ([cmdline [0 ]] + ["--target=elf64-little" ] +
764784 cmdline [1 :], error_output , ignore_errors )
785+ binutils_force_target_format = 'elf64-little'
765786 # In other cases, we sometimes get an expected error about ambiguous file
766787 # format, which also includes a list of matching formats:
767788 #
@@ -770,7 +791,7 @@ def run_binutils_command(cmdline, error_output=None, ignore_errors=False):
770791 #
771792 # If this occurs, we will run the command again, passing in the
772793 # target format that we believe we should use instead.
773- elif (len (error_output ) >= 2 and
794+ elif not binutils_force_target_format and (len (error_output ) >= 2 and
774795 "ile format is ambiguous" in error_output [0 ]):
775796 m = re .search ("Matching formats: (.+)" , error_output [1 ])
776797 if m :
@@ -783,14 +804,14 @@ def run_binutils_command(cmdline, error_output=None, ignore_errors=False):
783804 BINUTILS_PREFERRED_FORMAT_PREFIX_IF_AMBIGUOUS [FLAGS .platform ])
784805 ]
785806 # Or if for some reason none was found, just take the default (first).
786- retry_format = (preferred_formats [0 ]
787- if len (preferred_formats ) > 0
788- else all_formats [0 ])
807+ binutils_force_target_format = (preferred_formats [0 ]
808+ if len (preferred_formats ) > 0
809+ else all_formats [0 ])
789810 error_output = []
790- logging .debug ("Ambiguous file format when running %s %s" ,
791- os .path .basename (cmdline [0 ]), " " .join (cmdline [1 :]))
792- logging .debug ("Retrying with --target=%s" , retry_format )
793- output = run_command ([cmdline [0 ]] + ["--target=%s" % retry_format ] + cmdline [1 :],
811+ logging .debug ("Ambiguous file format when running %s %s (%s) " ,
812+ os .path .basename (cmdline [0 ]), " " .join (cmdline [1 :]), ", " . join ( all_formats ) )
813+ logging .debug ("Retrying with --target=%s" , binutils_force_target_format )
814+ output = run_command ([cmdline [0 ]] + ["--target=%s" % binutils_force_target_format ] + cmdline [1 :],
794815 error_output , ignore_errors )
795816 if error_output and not ignore_errors :
796817 # If we failed any other way, or if the second run failed, bail.
@@ -1014,8 +1035,17 @@ def main(argv):
10141035 if os .path .isfile (output_path ):
10151036 os .remove (output_path )
10161037
1017- logging .debug ("Creating output archive %s" , output_path )
1018- create_archive (output_path , all_obj_files , input_path [1 ])
1038+ if (FLAGS .skip_creating_archives ):
1039+ output_path_dir = output_path + ".dir"
1040+ logging .debug ("Copying object files to %s" , output_path_dir )
1041+ if not os .path .exists (output_path_dir ):
1042+ os .makedirs (output_path_dir )
1043+ for obj_file in all_obj_files :
1044+ logging .debug ("Copy %s to %s" % (obj_file , os .path .join (output_path_dir , os .path .basename (obj_file ))))
1045+ shutil .copyfile (obj_file , os .path .join (output_path_dir , os .path .basename (obj_file )))
1046+ else :
1047+ logging .debug ("Creating output archive %s" , output_path )
1048+ create_archive (output_path , all_obj_files , input_path [1 ])
10191049
10201050 shutdown_cache ()
10211051
0 commit comments