95
95
"two libraries. C++ symbols in the appropriate namespaces will be renamed "
96
96
"even if they are external. Otherwise, only symbols defined in the library "
97
97
"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." )
98
102
99
103
# Never rename 'std::' by default when --auto_hide_cpp_namespaces is enabled.
100
104
IMPLICIT_CPP_NAMESPACES_TO_IGNORE = {"std" }
101
105
102
106
DEFAULT_ENCODING = "ascii"
103
107
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
+
104
112
105
113
class Demangler (object ):
106
114
"""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):
258
266
Empty list if there are no errors, or error text if there was an error.
259
267
"""
260
268
errors = []
261
- if old_archive :
269
+ if old_archive and FLAGS . platform != "windows" :
262
270
# Copy the old archive to the new archive, then clear the files from it.
263
271
# This preserves the file format of the old archive file.
272
+ # On Windows, we'll always create a new archive.
264
273
shutil .copy (old_archive , output_archive_file )
265
274
(old_contents , errors ) = list_objects_in_archive (output_archive_file )
266
- run_command (
275
+ run_binutils_command (
267
276
[FLAGS .binutils_ar_cmd , "d" , output_archive_file ] + old_contents ,
268
277
errors )
269
- run_command (
278
+ run_binutils_command (
270
279
[FLAGS .binutils_ar_cmd , "rs" , output_archive_file ] + object_files ,
271
280
errors )
272
281
else :
273
- run_command (
282
+ run_binutils_command (
274
283
[FLAGS .binutils_ar_cmd , "rcs" , output_archive_file ] + object_files ,
275
284
errors )
276
285
@@ -738,7 +747,17 @@ def run_binutils_command(cmdline, error_output=None, ignore_errors=False):
738
747
Returns:
739
748
A list of lines of text of the command's stdout.
740
749
"""
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 )
742
761
if error_output and not output :
743
762
# There are some expected errors: "Bad value" or "File format is ambiguous".
744
763
#
@@ -748,20 +767,22 @@ def run_binutils_command(cmdline, error_output=None, ignore_errors=False):
748
767
# depending on whether the file is 32-bit or 64-bit.
749
768
#
750
769
# 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 ]:
752
771
# Workaround for MIPS, force elf32-little and/or elf64-little.
753
772
error_output = []
754
773
logging .debug ("Bad value when running %s %s" ,
755
774
os .path .basename (cmdline [0 ]), " " .join (cmdline [1 :]))
756
775
logging .debug ("Retrying with --target=elf32-little" )
757
776
output = run_command ([cmdline [0 ]] + ["--target=elf32-little" ] +
758
777
cmdline [1 :], error_output , True )
778
+ binutils_force_target_format = 'elf32-little'
759
779
if error_output :
760
780
# Oops, it wasn't 32-bit, try 64-bit instead.
761
781
error_output = []
762
782
logging .debug ("Retrying with --target=elf64-little" )
763
783
output = run_command ([cmdline [0 ]] + ["--target=elf64-little" ] +
764
784
cmdline [1 :], error_output , ignore_errors )
785
+ binutils_force_target_format = 'elf64-little'
765
786
# In other cases, we sometimes get an expected error about ambiguous file
766
787
# format, which also includes a list of matching formats:
767
788
#
@@ -770,7 +791,7 @@ def run_binutils_command(cmdline, error_output=None, ignore_errors=False):
770
791
#
771
792
# If this occurs, we will run the command again, passing in the
772
793
# 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
774
795
"ile format is ambiguous" in error_output [0 ]):
775
796
m = re .search ("Matching formats: (.+)" , error_output [1 ])
776
797
if m :
@@ -783,14 +804,14 @@ def run_binutils_command(cmdline, error_output=None, ignore_errors=False):
783
804
BINUTILS_PREFERRED_FORMAT_PREFIX_IF_AMBIGUOUS [FLAGS .platform ])
784
805
]
785
806
# 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 ])
789
810
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 :],
794
815
error_output , ignore_errors )
795
816
if error_output and not ignore_errors :
796
817
# If we failed any other way, or if the second run failed, bail.
@@ -1014,8 +1035,17 @@ def main(argv):
1014
1035
if os .path .isfile (output_path ):
1015
1036
os .remove (output_path )
1016
1037
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 ])
1019
1049
1020
1050
shutdown_cache ()
1021
1051
0 commit comments