#!/usr/bin/env perl # #//===----------------------------------------------------------------------===// #// #// The LLVM Compiler Infrastructure #// #// This file is dual licensed under the MIT and the University of Illinois Open #// Source Licenses. See LICENSE.txt for details. #// #//===----------------------------------------------------------------------===// # use strict; use warnings; use File::Glob ":glob"; use File::Temp; use Cwd; use FindBin; use lib "$FindBin::Bin/lib"; use tools; use Uname; use Platform ":vars"; our $VERSION = "0.005"; # -------------------------------------------------------------------------------------------------- # Subroutines. # -------------------------------------------------------------------------------------------------- sub windows { my ( $arch, $output, @args ) = @_; my %files; # TODO: Check the archives are of specified architecture. foreach my $arg ( @args ) { foreach my $archive ( bsd_glob( $arg ) ) { info( "Processing \"$archive\"..." ); my $bulk; execute( [ "lib.exe", "/nologo", "/list", $archive ], -stdout => \$bulk ); my @members = split( "\n", $bulk ); foreach my $member ( @members ) { my $file = get_file( $member ); my $path = cat_file( $output, $file ); if ( exists( $files{ $file } ) ) { runtime_error( "Extraction \"$file\" member from \"$archive\" archive failed:", "\"$file\" member has already been extracted from \"$files{ $file }\" archive" ); }; # if $files{ $file } = $archive; info( " Writing \"$path\"..." ); execute( [ "lib.exe", "/nologo", "/extract:" . $member, "/out:" . $path, $archive ] ); }; # foreach $member }; # foreach $archive }; # foreach $arg }; # sub windows sub linux { my ( $arch, $output, @archives ) = @_; # TODO: Check the archives are of specified architecture. my $cwd = Cwd::cwd(); change_dir( $output ); foreach my $archive ( @archives ) { info( "Processing \"$archive\"..." ); my $path = abs_path( $archive, $cwd ); execute( [ "ar", "xo", $path ] ); }; # foreach $archive change_dir( $cwd ); }; # sub linux my %mac_arch = ( "32" => "i386", "32e" => "x86_64" ); sub darwin { my ( $arch, $output, @archives ) = @_; my $cwd = getcwd(); change_dir( $output ); if ( defined( $arch ) ) { if ( not defined( $mac_arch{ $arch } ) ) { runtime_error( "Architecture \"$arch\" is not a valid one for OS X*" ); }; # if $arch = $mac_arch{ $arch }; }; # if foreach my $archive ( @archives ) { info( "Processing \"$archive\"..." ); my $path = abs_path( $archive, $cwd ); my $temp; # Whether archive is a fat or thin? my $bulk; execute( [ "file", $path ], -stdout => \$bulk ); if ( $bulk =~ m{Mach-O universal binary} ) { # Archive is fat, extracy thin archive first. if ( not defined( $arch ) ) { runtime_error( "\"$archive\" archive is universal binary, " . "please specify architecture to work with" ); }; # if ( undef, $temp ) = File::Temp::tempfile(); execute( [ "libtool", "-static", "-arch_only", $arch, "-o", $temp, $path ] ); $path = $temp; }; # if execute( [ "ar", "xo", $path ] ); # Extract members. if ( defined( $temp ) ) { # Delete temp file, if any. del_file( $temp ); }; # if }; # foreach $archive change_dir( $cwd ); }; # sub darwin # -------------------------------------------------------------------------------------------------- # Main. # -------------------------------------------------------------------------------------------------- # Parse command line. my $output = "."; my @args; get_options( Platform::target_options(), "o|output-directory=s" => \$output, ); @args = @ARGV; if ( not -e $output ) { runtime_error( "Output directory \"$output\" does not exist" ); }; # if if ( not -d $output ) { runtime_error( "\"$output\" is not a directory" ); }; # if if ( not -w $output ) { runtime_error( "Output directory \"$output\" is not writable" ); }; # if if ( $target_os eq "win" ) { *process = \&windows; } elsif ( $target_os eq "lin" or $target_os eq "lrb" ) { *process = \&linux; } elsif ( $target_os eq "mac" ) { *process = \&darwin; } else { runtime_error( "OS \"$target_os\" not supported" ); }; # if # Do the work. process( $target_arch, $output, @args ); exit( 0 ); __END__ =pod =head1 NAME B -- Extract all object files from static library. =head1 SYNOPSIS B I