From f9dead5624c63b009fc04229c1e5f660436b747b Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Wed, 18 Mar 2015 15:16:29 -0300 Subject: [PATCH] Install shared libraries to bin/ in Windows under MSVC Since commit cb4a3b04 we were already doing this for the Cygwin/mingw toolchains, but MSVC had not been updated to do it. At Install.pm time, the Makefile (or GNUmakefile) is inspected, and if a line matching SO_MAJOR_VERSION is found (indicating a shared library is being built), then files with the .dll extension are set to be installed in bin/ rather than lib/, while files with .lib extension are installed in lib/. This makes the MSVC toolchain up to date with cygwin/mingw. This removes ad-hoc hacks that were copying files into bin/ or lib/ manually (libpq.dll in particular was already being copied into bin). So while this is a rather ugly kludge, it's still cleaner than what was there before. Author: Michael Paquier Reviewed by: Asif Naeem --- src/tools/msvc/Install.pm | 81 +++++++++++++++++++++++++++------------ 1 file changed, 57 insertions(+), 24 deletions(-) diff --git a/src/tools/msvc/Install.pm b/src/tools/msvc/Install.pm index eba9aa08f1b..93a672498ab 100644 --- a/src/tools/msvc/Install.pm +++ b/src/tools/msvc/Install.pm @@ -91,7 +91,6 @@ sub Install } CopySolutionOutput($conf, $target); - lcopy($target . '/lib/libpq.dll', $target . '/bin/libpq.dll'); my $sample_files = []; my @top_dir = ("src"); @top_dir = ("src\\bin", "src\\interfaces") if ($insttype eq "client"); @@ -106,14 +105,8 @@ sub Install CopyFiles( 'Import libraries', $target . '/lib/', - "$conf\\", - "postgres\\postgres.lib", - "libpq\\libpq.lib", - "libecpg\\libecpg.lib", - "libpgcommon\\libpgcommon.lib", - "libpgport\\libpgport.lib", - "libpgtypes\\libpgtypes.lib", - "libecpg_compat\\libecpg_compat.lib"); + "$conf\\", "postgres\\postgres.lib", "libpgcommon\\libpgcommon.lib", + "libpgport\\libpgport.lib"); CopyContribFiles($config, $target); CopyIncludeFiles($target); @@ -236,8 +229,14 @@ sub CopySolutionOutput while ($sln =~ $rem) { my $pf = $1; - my $dir; - my $ext; + + # Hash-of-arrays listing where to install things. For each + # subdirectory there's a hash key, and the value is an array + # of file extensions to install in that subdirectory. Example: + # { 'bin' => [ 'dll', 'lib' ], + # 'lib' => [ 'lib' ] } + my %install_list; + my $is_sharedlib = 0; $sln =~ s/$rem//; @@ -247,22 +246,45 @@ sub CopySolutionOutput my $proj = read_file("$pf.$vcproj") || croak "Could not open $pf.$vcproj\n"; + + # Check if this project uses a shared library by looking if + # SO_MAJOR_VERSION is defined in its Makefile, whose path + # can be found using the resource file of this project. + if (( $vcproj eq 'vcxproj' + && $proj =~ qr{ResourceCompile\s*Include="([^"]+)"}) + || ( $vcproj eq 'vcproj' + && $proj =~ qr{File\s*RelativePath="([^\"]+)\.rc"})) + { + my $projpath = dirname($1); + my $mfname = + -e "$projpath/GNUmakefile" + ? "$projpath/GNUmakefile" + : "$projpath/Makefile"; + my $mf = read_file($mfname) || croak "Could not open $mfname\n"; + + $is_sharedlib = 1 if ($mf =~ /^SO_MAJOR_VERSION\s*=\s*(.*)$/mg); + } + if ($vcproj eq 'vcproj' && $proj =~ qr{ConfigurationType="([^"]+)"}) { if ($1 == 1) { - $dir = "bin"; - $ext = "exe"; + push(@{ $install_list{'bin'} }, "exe"); } elsif ($1 == 2) { - $dir = "lib"; - $ext = "dll"; + push(@{ $install_list{'lib'} }, "dll"); + if ($is_sharedlib) + { + push(@{ $install_list{'bin'} }, "dll"); + push(@{ $install_list{'lib'} }, "lib"); + } } else { -# Static lib, such as libpgport, only used internally during build, don't install + # Static libraries, such as libpgport, only used internally + # during build, don't install. next; } } @@ -271,18 +293,21 @@ sub CopySolutionOutput { if ($1 eq 'Application') { - $dir = "bin"; - $ext = "exe"; + push(@{ $install_list{'bin'} }, "exe"); } elsif ($1 eq 'DynamicLibrary') { - $dir = "lib"; - $ext = "dll"; + push(@{ $install_list{'lib'} }, "dll"); + if ($is_sharedlib) + { + push(@{ $install_list{'bin'} }, "dll"); + push(@{ $install_list{'lib'} }, "lib"); + } } else # 'StaticLibrary' { - -# Static lib, such as libpgport, only used internally during build, don't install + # Static lib, such as libpgport, only used internally + # during build, don't install. next; } } @@ -290,8 +315,16 @@ sub CopySolutionOutput { croak "Could not parse $pf.$vcproj\n"; } - lcopy("$conf\\$pf\\$pf.$ext", "$target\\$dir\\$pf.$ext") - || croak "Could not copy $pf.$ext\n"; + + # Install each element + foreach my $dir (keys %install_list) + { + foreach my $ext (@{ $install_list{$dir} }) + { + lcopy("$conf\\$pf\\$pf.$ext", "$target\\$dir\\$pf.$ext") + || croak "Could not copy $pf.$ext\n"; + } + } lcopy("$conf\\$pf\\$pf.pdb", "$target\\symbols\\$pf.pdb") || croak "Could not copy $pf.pdb\n"; print ".";