c8fb25f22e
A followup to the incomplete previous commit.
438 lines
14 KiB
Perl
Executable file
438 lines
14 KiB
Perl
Executable file
#!/usr/bin/perl -w
|
|
# -*- tab-width: 4; cperl-indent-level: 4; indent-tabs-mode: nil -*-
|
|
|
|
use File::Copy;
|
|
use File::Glob;
|
|
|
|
my $output_format = 'u';
|
|
|
|
sub reg_get_value($)
|
|
{
|
|
# it is believed that the registry moves keys around
|
|
# depending on OS version, this will de-mangle that
|
|
my $key = shift;
|
|
my $fhandle;
|
|
my $value;
|
|
|
|
open ($fhandle, "/proc/registry/$key") || return;
|
|
# reg keys have 0x00 0x5c at the end
|
|
$value = (split /\0/, <$fhandle>)[0];
|
|
close ($fhandle);
|
|
|
|
if ( defined $value ) {
|
|
chomp ($value);
|
|
$value =~ s|\r\n||;
|
|
# print "Value '$value' at '$key'\n";
|
|
}
|
|
|
|
return $value;
|
|
}
|
|
|
|
sub print_syntax()
|
|
{
|
|
print "oowintool [option] ...\n";
|
|
print " encoding options\n";
|
|
print " -w - windows form\n";
|
|
print " -u - unix form (default)\n";
|
|
print " commands:\n";
|
|
print " --msvc-ver - print version of MSVC eg. 6.0\n";
|
|
print " --msvc-copy-dlls <dest> - copy msvc[pr]??.dlls into <dest>/msvcp??/\n";
|
|
print " --msvc-copy-dlls-64 <dest> - copy x64 msvc[pr]??.dlls into <dest>/msvcp??/\n";
|
|
print " --msvc-copy-msms <dest> - copy mscrt merge modules to <dest>/msm90/\n";
|
|
print " --msvc-copy-msms-64 <ds> - copy the x64 mscrt merge modules to <ds>/msm90/\n";
|
|
print " --msvc-productdir - print productdir\n";
|
|
print " --msvs-productdir - print productdir\n";
|
|
print " --dotnetsdk-dir - print .NET SDK path\n";
|
|
print " --csc-compilerdir - print .NET SDK compiler path\n";
|
|
print " --al-home - print AL.exe install dir\n";
|
|
print " --windows-sdk-home - print Windows SDK install dir\n";
|
|
print " --jdk-home - print the jdk install dir\n";
|
|
print " --help - print this message\n";
|
|
}
|
|
|
|
sub cygpath($$$)
|
|
{
|
|
my ($path, $input_format, $format) = @_;
|
|
|
|
return $path if ( ! defined $path );
|
|
# Strip trailing path separators
|
|
if ($input_format eq 'u') {
|
|
$path =~ s|/*\s*$||;
|
|
} else {
|
|
$path =~ s|\\*\s*$||;
|
|
}
|
|
|
|
# 'Unterminated quoted string errors' from 'ash' when
|
|
# forking cygpath so - reimplement cygpath in perl [ gack ]
|
|
if ($format eq 'u' && $input_format eq 'w') {
|
|
$path =~ s|\\|/|g;
|
|
$path =~ s|([a-zA-Z]):/|/cygdrive/$1/|g;
|
|
}
|
|
elsif ($format eq 'w' && $input_format eq 'u') {
|
|
$path =~ s|/cygdrive/([a-zA-Z])/|/$1/|g;
|
|
$path =~ s|/|\\|g;
|
|
}
|
|
|
|
return $path;
|
|
}
|
|
|
|
sub print_path($$)
|
|
{
|
|
my ($path, $unix) = @_;
|
|
|
|
$path = cygpath ($path, $unix, $output_format);
|
|
|
|
print $path;
|
|
}
|
|
|
|
sub print_windows_sdk_home()
|
|
{
|
|
my ($value, $key);
|
|
|
|
# This is for the Windows SDK 8 distributed with MSVS 2012
|
|
$value = reg_get_value ('HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows Kits/Installed Roots/KitsRoot');
|
|
|
|
if (!defined $value) {
|
|
$value = reg_get_value ('HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Microsoft SDKs/Windows/CurrentInstallFolder');
|
|
}
|
|
if (!defined $value) {
|
|
$value = reg_get_value ('HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/MicrosoftSDK/Directories/Install Dir');
|
|
}
|
|
|
|
if (!defined $value) {
|
|
# Unclear whether we ever get here, don't the above match any
|
|
# recent Windows SDK?
|
|
foreach $key (File::Glob::bsd_glob('/proc/registry/HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/MicrosoftSDK/InstalledSDKs/*/Install Dir')) {
|
|
$value = reg_get_value ($key);
|
|
last if defined $value;
|
|
}
|
|
}
|
|
|
|
defined $value || die "Windows SDK not found";
|
|
|
|
print cygpath ($value, 'w', $output_format);
|
|
}
|
|
|
|
sub print_al_home()
|
|
{
|
|
# Called by configure only if al.exe is not in the Windows SDK's
|
|
# bin folder, where it AFAIK always is in any recent Windows SDK,
|
|
# so whether this will ever be called is unclear...
|
|
|
|
my ($value, $key);
|
|
|
|
foreach $key (File::Glob::bsd_glob('/proc/registry/HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Microsoft SDKs/Windows/*/WinSDK-NetFx40Tools/InstallationFolder')) {
|
|
$key =~ s!^/proc/registry/!!;
|
|
$value = reg_get_value ($key);
|
|
|
|
# Sigh, the same test that configure does for al.exe
|
|
# being either directly in it, or in a "bin" subdir... But on
|
|
# the other hand we don't want to be mislead by a registry key
|
|
# that matches the above but points to a directory that does
|
|
# in fact not contain an al.exe. For me,
|
|
# HKLM/SOFTWARE/Microsoft/Microsoft SDKs/Windows/v7.0A/WinSDK-NetFx40Tools/InstallationFolder
|
|
# contains
|
|
# c:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\NETFX 4.0 Tools\
|
|
# but that then does not contain any al.exe.
|
|
|
|
if (-f "$value/bin/al.exe" || -f "$value/al.exe") {
|
|
print cygpath ($value, 'w', $output_format);
|
|
return;
|
|
}
|
|
}
|
|
die "Can't find al.exe";
|
|
}
|
|
|
|
my %msvs_2008 = (
|
|
'ver' => '9.0',
|
|
'key' => 'Microsoft/VisualStudio/9.0/Setup/VS/ProductDir',
|
|
'dll_path' => 'VC/redist/x86/Microsoft.VC90.CRT',
|
|
'dll_suffix' => '90'
|
|
);
|
|
my %msvc_2008 = (
|
|
'ver' => '9.0',
|
|
'key' => 'Microsoft/VisualStudio/9.0/Setup/VC/ProductDir',
|
|
'dll_path' => 'redist/x86/Microsoft.VC90.CRT',
|
|
'dll_suffix' => '90'
|
|
);
|
|
my %msvs_express_2008 = (
|
|
'ver' => '9.0',
|
|
'key' => 'Microsoft/VCExpress/9.0/Setup/VS/ProductDir',
|
|
'dll_path' => 'VC/redist/x86/Microsoft.VC90.CRT',
|
|
'dll_suffix' => '90'
|
|
);
|
|
my %msvc_express_2008 = (
|
|
'ver' => '9.0',
|
|
'key' => 'Microsoft/VCExpress/9.0/Setup/VC/ProductDir',
|
|
'dll_path' => 'redist/x86/Microsoft.VC90.CRT',
|
|
'dll_suffix' => '90'
|
|
);
|
|
my %msvs_2010 = (
|
|
'ver' => '10.0',
|
|
'key' => 'Microsoft/VisualStudio/10.0/Setup/VS/ProductDir',
|
|
'dll_path' => 'VC/redist/x86/Microsoft.VC100.CRT',
|
|
'dll_suffix' => '100'
|
|
);
|
|
my %msvc_2010 = (
|
|
'ver' => '10.0',
|
|
'key' => 'Microsoft/VisualStudio/10.0/Setup/VC/ProductDir',
|
|
'dll_path' => 'redist/x86/Microsoft.VC100.CRT',
|
|
'dll_suffix' => '100'
|
|
);
|
|
my %msvs_2012 = (
|
|
'ver' => '11.0',
|
|
'key' => 'Microsoft/VisualStudio/11.0/Setup/VS/ProductDir',
|
|
'dll_path' => 'VC/redist/x86/Microsoft.VC110.CRT',
|
|
'dll_suffix' => '110'
|
|
);
|
|
my %msvc_2012 = (
|
|
'ver' => '11.0',
|
|
'key' => 'Microsoft/VisualStudio/11.0/Setup/VC/ProductDir',
|
|
'dll_path' => 'redist/x86/Microsoft.VC110.CRT',
|
|
'dll_suffix' => '110'
|
|
);
|
|
|
|
sub find_msvs()
|
|
{
|
|
my @ms_versions = ( \%msvs_2010, \%msvs_2012, \%msvs_2008, \%msvs_express_2008 );
|
|
|
|
for $ver (@ms_versions) {
|
|
my $install = reg_get_value ("HKEY_LOCAL_MACHINE/SOFTWARE/" . $ver->{'key'});
|
|
if (defined $install && $install ne '') {
|
|
$ver->{'product_dir'} = $install;
|
|
return $ver;
|
|
}
|
|
}
|
|
die "Can't find MS Visual Studio / VC++";
|
|
}
|
|
|
|
sub find_msvc()
|
|
{
|
|
my @ms_versions = ( \%msvc_2010, \%msvc_2012, \%msvc_2008, \%msvc_express_2008 );
|
|
|
|
for $ver (@ms_versions) {
|
|
my $install = reg_get_value ("HKEY_LOCAL_MACHINE/SOFTWARE/" . $ver->{'key'});
|
|
if (defined $install && $install ne '') {
|
|
$ver->{'product_dir'} = $install;
|
|
return $ver;
|
|
}
|
|
}
|
|
die "Can't find MS Visual Studio / VC++";
|
|
}
|
|
|
|
sub print_msvc_ver()
|
|
{
|
|
my $ver = find_msvc();
|
|
print $ver->{'ver'};
|
|
}
|
|
|
|
sub print_msvc_product_dir()
|
|
{
|
|
my $ver = find_msvc();
|
|
print cygpath ($ver->{'product_dir'}, 'w', $output_format);
|
|
}
|
|
|
|
sub print_msvs_productdir()
|
|
{
|
|
my $ver = find_msvs();
|
|
print cygpath ($ver->{'product_dir'}, 'w', $output_format);
|
|
}
|
|
|
|
sub print_csc_compiler_dir()
|
|
{
|
|
my $csc_exe;
|
|
my $ver = find_msvc();
|
|
if ($ver->{'ver'} == "9.0") {
|
|
# We need to compile C# with the 3.5 or 2.0 compiler in order
|
|
# for the assemblies to be loadable by managed C++ code
|
|
# compiled with MSVC 2008.
|
|
$csc_exe =
|
|
reg_get_value ("HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/NET Framework Setup/NDP/v3.5/InstallPath") ||
|
|
reg_get_value ("HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/.NETFramework/InstallRoot") . "v2.0.50727";
|
|
} else {
|
|
# Is it enough to look for the 4.0 compiler?
|
|
$csc_exe =
|
|
reg_get_value ("HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/NET Framework Setup/NDP/v4/Client/InstallPath");
|
|
}
|
|
print cygpath ($csc_exe, 'w', $output_format);
|
|
}
|
|
|
|
sub print_dotnetsdk_dir()
|
|
{
|
|
my $dir =
|
|
reg_get_value ("HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/.NETFramework/sdkInstallRootv1.1") ||
|
|
reg_get_value ("HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/.NETFramework/sdkInstallRootv2.0");
|
|
if ($dir) {
|
|
print cygpath ($dir, 'w', $output_format);
|
|
}
|
|
}
|
|
|
|
sub print_jdk_dir()
|
|
{
|
|
my $dir =
|
|
reg_get_value ("HKEY_LOCAL_MACHINE/SOFTWARE/JavaSoft/Java\ Development\ Kit/1.7/JavaHome") ||
|
|
reg_get_value ("HKEY_LOCAL_MACHINE/SOFTWARE/JavaSoft/Java\ Development\ Kit/1.6/JavaHome") ||
|
|
reg_get_value ("HKEY_LOCAL_MACHINE/SOFTWARE/JavaSoft/Java\ Development\ Kit/1.5/JavaHome") ||
|
|
reg_get_value ("HKEY_LOCAL_MACHINE/SOFTWARE/JavaSoft/Java\ Development\ Kit/1.4/JavaHome") ||
|
|
reg_get_value ("HKEY_LOCAL_MACHINE/SOFTWARE/JavaSoft/Java\ Development\ Kit/1.3/JavaHome");
|
|
print cygpath($dir, 'w', $output_format);
|
|
}
|
|
|
|
sub copy_dll($$$)
|
|
{
|
|
my ($src, $fname, $dest) = @_;
|
|
|
|
-f "$src/$fname" || die "can't find $src";
|
|
-d $dest || die "no directory $dest";
|
|
|
|
print STDERR "Copying $src/$fname to $dest\n";
|
|
copy ("$src/$fname", $dest) || die "copy failed: $!";
|
|
chmod (0755, "$dest/$fname") || die "failed to set dll executable: $!";
|
|
}
|
|
|
|
sub msvc_find_version($)
|
|
{
|
|
my $checkpath = shift;
|
|
my $ver = find_msvc();
|
|
my $srcdir = (cygpath ($ver->{'product_dir'}, 'w', 'u') . '/' .
|
|
$ver->{$checkpath});
|
|
-d $srcdir && return $ver;
|
|
$ver = find_msvs();
|
|
$srcdir = (cygpath ($ver->{'product_dir'}, 'w', 'u') . '/' .
|
|
$ver->{$checkpath});
|
|
-d $srcdir && return $ver;
|
|
return undef;
|
|
}
|
|
|
|
sub msvc_copy_dlls($$)
|
|
{
|
|
my $dest = shift;
|
|
my $arch = shift;
|
|
my $ver = msvc_find_version('dll_path');
|
|
defined $ver || return;
|
|
my $srcdir = (cygpath ($ver->{'product_dir'}, 'w', 'u') . '/' .
|
|
$ver->{'dll_path'});
|
|
|
|
$srcdir =~ s/x86/amd64/ if ($arch eq 'amd64');
|
|
|
|
copy_dll ($srcdir, "msvcp" . $ver->{'dll_suffix'} . ".dll",
|
|
$dest . $ver->{'dll_suffix'});
|
|
copy_dll ($srcdir, "msvcr" . $ver->{'dll_suffix'} . ".dll",
|
|
$dest . $ver->{'dll_suffix'});
|
|
if ($ver->{'dll_suffix'} == 90) {
|
|
copy_dll ($srcdir, "msvcm" . $ver->{'dll_suffix'} . ".dll",
|
|
$dest . $ver->{'dll_suffix'});
|
|
copy_dll ($srcdir, "Microsoft.VC90.CRT.manifest", $dest . $ver->{'dll_suffix'});
|
|
}
|
|
}
|
|
|
|
sub msvc_find_msms()
|
|
{
|
|
my $ver = find_msvc();
|
|
my $msm_path = (cygpath reg_get_value ("HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/VisualStudio/9.0/Setup/VS/MSMDir"), 'w', $output_format) ||
|
|
(cygpath reg_get_value ("HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/VisualStudio/10.0/Setup/VS/MSMDir"), 'w', $output_format) ||
|
|
(cygpath reg_get_value ("HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/VisualStudio/11.0/Setup/VS/MSMDir"), 'w', $output_format);
|
|
defined $msm_path || die "MSMDir not found";
|
|
return -e "$msm_path/Microsoft_VC".$ver->{'dll_suffix'}."_CRT_x86.msm" ? 0 : 1;
|
|
}
|
|
|
|
sub msvc_copy_msms($$)
|
|
{
|
|
# $postfix is empty for x86, and '_x64' for x64
|
|
my ($dest, $postfix) = @_;
|
|
|
|
my $ver = find_msvc();
|
|
defined $ver || return;
|
|
|
|
my $msm_path = (cygpath reg_get_value ("HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/VisualStudio/9.0/Setup/VS/MSMDir"), 'w', $output_format) ||
|
|
(cygpath reg_get_value ("HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/VisualStudio/10.0/Setup/VS/MSMDir"), 'w', $output_format) ||
|
|
(cygpath reg_get_value ("HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/VisualStudio/11.0/Setup/VS/MSMDir"), 'w', $output_format);
|
|
defined $msm_path || die "MSMDir not found";
|
|
if ($ver->{'dll_suffix'} == 90) {
|
|
if ( $postfix eq "_x86" ) {
|
|
$postfix = ""
|
|
}
|
|
foreach $fname ("Microsoft_VC90_CRT_x86$postfix.msm", "policy_9_0_Microsoft_VC90_CRT_x86$postfix.msm") {
|
|
print STDERR "Copying $msm_path/$fname to $dest\n";
|
|
copy ("$msm_path/$fname", $dest) || die "copy failed: $!";
|
|
}
|
|
}
|
|
elsif ($ver->{'dll_suffix'} == 100) {
|
|
foreach $fname ("Microsoft_VC100_CRT$postfix.msm") {
|
|
print STDERR "Copying $msm_path/$fname to $dest\n";
|
|
copy ("$msm_path/$fname", $dest) || print "copy failed: $!\n";
|
|
}
|
|
}
|
|
else {
|
|
foreach $fname ("Microsoft_VC110_CRT$postfix.msm") {
|
|
print STDERR "Copying $msm_path/$fname to $dest\n";
|
|
copy ("$msm_path/$fname", $dest) || print "copy failed: $!\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!@ARGV) {
|
|
print_syntax();
|
|
exit 1;
|
|
}
|
|
|
|
my @commands = ();
|
|
my $opt;
|
|
while (@ARGV) {
|
|
$opt = shift @ARGV;
|
|
|
|
if ($opt eq '-w' || $opt eq '-u') {
|
|
$output_format = substr($opt, 1, 1);
|
|
} else {
|
|
push @commands, $opt;
|
|
}
|
|
}
|
|
|
|
while (@commands) {
|
|
$opt = shift @commands;
|
|
|
|
if (0) {
|
|
} elsif ($opt eq '--msvc-ver') {
|
|
print_msvc_ver();
|
|
} elsif ($opt eq '--msvc-copy-dlls') {
|
|
my $dest = shift @commands;
|
|
defined $dest || die "copy-dlls requires a destination directory";
|
|
msvc_copy_dlls( $dest, 'x86' );
|
|
} elsif ($opt eq '--msvc-copy-dlls-64') {
|
|
my $dest = shift @commands;
|
|
defined $dest || die "copy-dlls requires a destination directory";
|
|
msvc_copy_dlls( $dest, 'amd64' );
|
|
} elsif ($opt eq '--msvc-find-msms') {
|
|
exit msvc_find_msms();
|
|
} elsif ($opt eq '--msvc-copy-msms') {
|
|
my $dest = shift @commands;
|
|
defined $dest || die "copy-msms requires a destination directory";
|
|
msvc_copy_msms( $dest, '_x86' );
|
|
} elsif ($opt eq '--msvc-copy-msms-64') {
|
|
my $dest = shift @commands;
|
|
defined $dest || die "copy-msms-64 requires a destination directory";
|
|
msvc_copy_msms( $dest, '_x64' );
|
|
} elsif ($opt eq '--msvs-productdir') {
|
|
print_msvs_productdir();
|
|
} elsif ($opt eq '--msvc-productdir') {
|
|
print_msvc_product_dir();
|
|
} elsif ($opt eq '--dotnetsdk-dir') {
|
|
print_dotnetsdk_dir();
|
|
} elsif ($opt eq '--csc-compilerdir') {
|
|
print_csc_compiler_dir();
|
|
} elsif ($opt eq '--windows-sdk-home') {
|
|
print_windows_sdk_home();
|
|
} elsif ($opt eq '--al-home') {
|
|
print_al_home();
|
|
} elsif ($opt eq '--jdk-home') {
|
|
print_jdk_dir();
|
|
} elsif ($opt eq '--help' || $opt eq '/?') {
|
|
print_syntax();
|
|
} else {
|
|
print "Unknown option '$opt'\n";
|
|
print_syntax();
|
|
exit 1;
|
|
}
|
|
}
|
|
|
|
# vim:set shiftwidth=4 softtabstop=4 expandtab:
|