lh3
10/7/2016 - 6:55 PM

pexe.pl

#!/usr/bin/env perl

use strict;
use warnings;
use Getopt::Std;

my %opts = ();
getopts('fd:', \%opts);

die("Usage: pexe.pl [options] <exe1> [exe2 [...]]
Options:
  -d DIR     library directory name [exe1]
  -f         force overwirte
") if @ARGV == 0;

my $dir;
if (defined $opts{d}) {
	$dir = $opts{d};
} else {
	$dir = "$1.lib" if $ARGV[0] =~ /([^\/]+)$/;
}
die "ERROR: failed to determine the output directory.\n" unless defined($dir);

open(FH, join(" ", "ldd", @ARGV, "|")) || die;
my $fn = $ARGV[0];
my (%libs, %ld_so);
while (<FH>) {
	chomp;
	if (/^(\S+):/) {
		$fn = $1;
	} elsif (/^\s+\S+ => (\/\S+)/) {
		$libs{$1} = 1;
	} elsif (/^\s+(\/\S+ld\S*\.so\S*)/) {
		$ld_so{$1} = 1;
	}
}
close(FH);

my @ld_so = keys(%ld_so);
die "ERROR: failed to determine the 'ld.so' helper.\n" if scalar(@ld_so) != 1;
my $exes = join(" ", @ARGV);
my $libs = join(" ", sort(keys %libs));
system("mkdir -p $dir && cp $libs $exes $dir && cp $ld_so[0] $dir/ld.so");

for my $exe (@ARGV) {
	my $fn;
	if ($exe =~ /([^\/]+)$/) {
		$fn = $1;
	}
	next unless defined($fn);
	unless (defined $opts{f}) {
		die "ERROR: file '$fn' exists.\n" if (-f $fn);
	}
	open(FH, ">$fn") || die;
	print FH q(#!/bin/sh), "\n";
	print FH q(root=`dirname $0`/), "$dir\n";
	print FH q($root/ld.so --library-path $root $root/), $fn, ' $*', "\n";
	close(FH);
	chmod 0755, $fn;
}