mirror of
https://github.com/postgres/postgres.git
synced 2025-08-21 10:42:50 +03:00
Add a line to the project file setting the target SDK. Otherwise, in for example VS2017, if the default but optional 8.1 SDK is not installed the build will fail. Patch from Peifeng Qiu, slightly edited by me. Discussion: https://postgr.es/m/CABmtVJhw1boP_bd4=b3Qv5YnqEdL696NtHFi2ruiyQ6mFHkeQQ@mail.gmail.com Backpatch to all live branches.
509 lines
14 KiB
Perl
509 lines
14 KiB
Perl
package MSBuildProject;
|
|
|
|
#
|
|
# Package that encapsulates a MSBuild project file (Visual C++ 2013 or greater)
|
|
#
|
|
# src/tools/msvc/MSBuildProject.pm
|
|
#
|
|
|
|
use Carp;
|
|
use strict;
|
|
use warnings;
|
|
use base qw(Project);
|
|
|
|
no warnings qw(redefine); ## no critic
|
|
|
|
sub _new
|
|
{
|
|
my $classname = shift;
|
|
my $self = $classname->SUPER::_new(@_);
|
|
bless($self, $classname);
|
|
|
|
$self->{filenameExtension} = '.vcxproj';
|
|
$self->{ToolsVersion} = '4.0';
|
|
|
|
return $self;
|
|
}
|
|
|
|
sub WriteHeader
|
|
{
|
|
my ($self, $f) = @_;
|
|
|
|
print $f <<EOF;
|
|
<?xml version="1.0" encoding="Windows-1252"?>
|
|
<Project DefaultTargets="Build" ToolsVersion="$self->{ToolsVersion}" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
<ItemGroup Label="ProjectConfigurations">
|
|
EOF
|
|
$self->WriteConfigurationHeader($f, 'Debug');
|
|
$self->WriteConfigurationHeader($f, 'Release');
|
|
print $f <<EOF;
|
|
</ItemGroup>
|
|
<PropertyGroup Label="Globals">
|
|
<ProjectGuid>$self->{guid}</ProjectGuid>
|
|
EOF
|
|
# Check whether WindowsSDKVersion env variable is present.
|
|
# Add WindowsTargetPlatformVersion node if so.
|
|
my $sdkVersion = $ENV{'WindowsSDKVersion'};
|
|
if (defined($sdkVersion))
|
|
{
|
|
# remove trailing backslash if necessary.
|
|
$sdkVersion, =~ s/\\$//;
|
|
print $f <<EOF
|
|
<WindowsTargetPlatformVersion>$sdkVersion</WindowsTargetPlatformVersion>
|
|
EOF
|
|
}
|
|
print $f <<EOF;
|
|
</PropertyGroup>
|
|
<Import Project="\$(VCTargetsPath)\\Microsoft.Cpp.Default.props" />
|
|
EOF
|
|
$self->WriteConfigurationPropertyGroup($f, 'Release',
|
|
{ wholeopt => 'false' });
|
|
$self->WriteConfigurationPropertyGroup($f, 'Debug',
|
|
{ wholeopt => 'false' });
|
|
print $f <<EOF;
|
|
<Import Project="\$(VCTargetsPath)\\Microsoft.Cpp.props" />
|
|
<ImportGroup Label="ExtensionSettings">
|
|
</ImportGroup>
|
|
EOF
|
|
$self->WritePropertySheetsPropertyGroup($f, 'Release');
|
|
$self->WritePropertySheetsPropertyGroup($f, 'Debug');
|
|
print $f <<EOF;
|
|
<PropertyGroup Label="UserMacros" />
|
|
<PropertyGroup>
|
|
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
|
EOF
|
|
$self->WriteAdditionalProperties($f, 'Debug');
|
|
$self->WriteAdditionalProperties($f, 'Release');
|
|
print $f <<EOF;
|
|
</PropertyGroup>
|
|
EOF
|
|
|
|
$self->WriteItemDefinitionGroup(
|
|
$f, 'Debug',
|
|
{
|
|
defs => "_DEBUG;DEBUG=1",
|
|
opt => 'Disabled',
|
|
strpool => 'false',
|
|
runtime => 'MultiThreadedDebugDLL'
|
|
});
|
|
$self->WriteItemDefinitionGroup(
|
|
$f,
|
|
'Release',
|
|
{
|
|
defs => "",
|
|
opt => 'Full',
|
|
strpool => 'true',
|
|
runtime => 'MultiThreadedDLL'
|
|
});
|
|
return;
|
|
}
|
|
|
|
sub AddDefine
|
|
{
|
|
my ($self, $def) = @_;
|
|
|
|
$self->{defines} .= $def . ';';
|
|
return;
|
|
}
|
|
|
|
sub WriteReferences
|
|
{
|
|
my ($self, $f) = @_;
|
|
|
|
my @references = @{ $self->{references} };
|
|
|
|
if (scalar(@references))
|
|
{
|
|
print $f <<EOF;
|
|
<ItemGroup>
|
|
EOF
|
|
foreach my $ref (@references)
|
|
{
|
|
print $f <<EOF;
|
|
<ProjectReference Include="$ref->{name}$ref->{filenameExtension}">
|
|
<Project>$ref->{guid}</Project>
|
|
</ProjectReference>
|
|
EOF
|
|
}
|
|
print $f <<EOF;
|
|
</ItemGroup>
|
|
EOF
|
|
}
|
|
return;
|
|
}
|
|
|
|
sub WriteFiles
|
|
{
|
|
my ($self, $f) = @_;
|
|
print $f <<EOF;
|
|
<ItemGroup>
|
|
EOF
|
|
my @grammarFiles = ();
|
|
my @resourceFiles = ();
|
|
my %uniquefiles;
|
|
foreach my $fileNameWithPath (sort keys %{ $self->{files} })
|
|
{
|
|
confess "Bad format filename '$fileNameWithPath'\n"
|
|
unless ($fileNameWithPath =~ m!^(.*)/([^/]+)\.(c|cpp|y|l|rc)$!);
|
|
my $dir = $1;
|
|
my $fileName = $2;
|
|
if ($fileNameWithPath =~ /\.y$/ or $fileNameWithPath =~ /\.l$/)
|
|
{
|
|
push @grammarFiles, $fileNameWithPath;
|
|
}
|
|
elsif ($fileNameWithPath =~ /\.rc$/)
|
|
{
|
|
push @resourceFiles, $fileNameWithPath;
|
|
}
|
|
elsif (defined($uniquefiles{$fileName}))
|
|
{
|
|
|
|
# File already exists, so fake a new name
|
|
my $obj = $dir;
|
|
$obj =~ s!/!_!g;
|
|
|
|
print $f <<EOF;
|
|
<ClCompile Include="$fileNameWithPath">
|
|
<ObjectFileName Condition="'\$(Configuration)|\$(Platform)'=='Debug|$self->{platform}'">.\\debug\\$self->{name}\\${obj}_$fileName.obj</ObjectFileName>
|
|
<ObjectFileName Condition="'\$(Configuration)|\$(Platform)'=='Release|$self->{platform}'">.\\release\\$self->{name}\\${obj}_$fileName.obj</ObjectFileName>
|
|
</ClCompile>
|
|
EOF
|
|
}
|
|
else
|
|
{
|
|
$uniquefiles{$fileName} = 1;
|
|
print $f <<EOF;
|
|
<ClCompile Include="$fileNameWithPath" />
|
|
EOF
|
|
}
|
|
|
|
}
|
|
print $f <<EOF;
|
|
</ItemGroup>
|
|
EOF
|
|
if (scalar(@grammarFiles))
|
|
{
|
|
print $f <<EOF;
|
|
<ItemGroup>
|
|
EOF
|
|
foreach my $grammarFile (@grammarFiles)
|
|
{
|
|
(my $outputFile = $grammarFile) =~ s/\.(y|l)$/.c/;
|
|
if ($grammarFile =~ /\.y$/)
|
|
{
|
|
$outputFile =~
|
|
s{^src\\pl\\plpgsql\\src\\gram.c$}{src\\pl\\plpgsql\\src\\pl_gram.c};
|
|
print $f <<EOF;
|
|
<CustomBuild Include="$grammarFile">
|
|
<Message Condition="'\$(Configuration)|\$(Platform)'=='Debug|$self->{platform}'">Running bison on $grammarFile</Message>
|
|
<Command Condition="'\$(Configuration)|\$(Platform)'=='Debug|$self->{platform}'">perl "src\\tools\\msvc\\pgbison.pl" "$grammarFile"</Command>
|
|
<AdditionalInputs Condition="'\$(Configuration)|\$(Platform)'=='Debug|$self->{platform}'">%(AdditionalInputs)</AdditionalInputs>
|
|
<Outputs Condition="'\$(Configuration)|\$(Platform)'=='Debug|$self->{platform}'">$outputFile;%(Outputs)</Outputs>
|
|
<Message Condition="'\$(Configuration)|\$(Platform)'=='Release|$self->{platform}'">Running bison on $grammarFile</Message>
|
|
<Command Condition="'\$(Configuration)|\$(Platform)'=='Release|$self->{platform}'">perl "src\\tools\\msvc\\pgbison.pl" "$grammarFile"</Command>
|
|
<AdditionalInputs Condition="'\$(Configuration)|\$(Platform)'=='Release|$self->{platform}'">%(AdditionalInputs)</AdditionalInputs>
|
|
<Outputs Condition="'\$(Configuration)|\$(Platform)'=='Release|$self->{platform}'">$outputFile;%(Outputs)</Outputs>
|
|
</CustomBuild>
|
|
EOF
|
|
}
|
|
else #if ($grammarFile =~ /\.l$/)
|
|
{
|
|
print $f <<EOF;
|
|
<CustomBuild Include="$grammarFile">
|
|
<Message Condition="'\$(Configuration)|\$(Platform)'=='Debug|$self->{platform}'">Running flex on $grammarFile</Message>
|
|
<Command Condition="'\$(Configuration)|\$(Platform)'=='Debug|$self->{platform}'">perl "src\\tools\\msvc\\pgflex.pl" "$grammarFile"</Command>
|
|
<AdditionalInputs Condition="'\$(Configuration)|\$(Platform)'=='Debug|$self->{platform}'">%(AdditionalInputs)</AdditionalInputs>
|
|
<Outputs Condition="'\$(Configuration)|\$(Platform)'=='Debug|$self->{platform}'">$outputFile;%(Outputs)</Outputs>
|
|
<Message Condition="'\$(Configuration)|\$(Platform)'=='Release|$self->{platform}'">Running flex on $grammarFile</Message>
|
|
<Command Condition="'\$(Configuration)|\$(Platform)'=='Release|$self->{platform}'">perl "src\\tools\\msvc\\pgflex.pl" "$grammarFile"</Command>
|
|
<AdditionalInputs Condition="'\$(Configuration)|\$(Platform)'=='Release|$self->{platform}'">%(AdditionalInputs)</AdditionalInputs>
|
|
<Outputs Condition="'\$(Configuration)|\$(Platform)'=='Release|$self->{platform}'">$outputFile;%(Outputs)</Outputs>
|
|
</CustomBuild>
|
|
EOF
|
|
}
|
|
}
|
|
print $f <<EOF;
|
|
</ItemGroup>
|
|
EOF
|
|
}
|
|
if (scalar(@resourceFiles))
|
|
{
|
|
print $f <<EOF;
|
|
<ItemGroup>
|
|
EOF
|
|
foreach my $rcFile (@resourceFiles)
|
|
{
|
|
print $f <<EOF;
|
|
<ResourceCompile Include="$rcFile" />
|
|
EOF
|
|
}
|
|
print $f <<EOF;
|
|
</ItemGroup>
|
|
EOF
|
|
}
|
|
return;
|
|
}
|
|
|
|
sub WriteConfigurationHeader
|
|
{
|
|
my ($self, $f, $cfgname) = @_;
|
|
print $f <<EOF;
|
|
<ProjectConfiguration Include="$cfgname|$self->{platform}">
|
|
<Configuration>$cfgname</Configuration>
|
|
<Platform>$self->{platform}</Platform>
|
|
</ProjectConfiguration>
|
|
EOF
|
|
return;
|
|
}
|
|
|
|
sub WriteConfigurationPropertyGroup
|
|
{
|
|
my ($self, $f, $cfgname, $p) = @_;
|
|
my $cfgtype =
|
|
($self->{type} eq "exe")
|
|
? 'Application'
|
|
: ($self->{type} eq "dll" ? 'DynamicLibrary' : 'StaticLibrary');
|
|
|
|
print $f <<EOF;
|
|
<PropertyGroup Condition="'\$(Configuration)|\$(Platform)'=='$cfgname|$self->{platform}'" Label="Configuration">
|
|
<ConfigurationType>$cfgtype</ConfigurationType>
|
|
<UseOfMfc>false</UseOfMfc>
|
|
<CharacterSet>MultiByte</CharacterSet>
|
|
<WholeProgramOptimization>$p->{wholeopt}</WholeProgramOptimization>
|
|
<PlatformToolset>$self->{PlatformToolset}</PlatformToolset>
|
|
</PropertyGroup>
|
|
EOF
|
|
return;
|
|
}
|
|
|
|
sub WritePropertySheetsPropertyGroup
|
|
{
|
|
my ($self, $f, $cfgname) = @_;
|
|
print $f <<EOF;
|
|
<ImportGroup Condition="'\$(Configuration)|\$(Platform)'=='$cfgname|$self->{platform}'" Label="PropertySheets">
|
|
<Import Project="\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props" Condition="exists('\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
</ImportGroup>
|
|
EOF
|
|
return;
|
|
}
|
|
|
|
sub WriteAdditionalProperties
|
|
{
|
|
my ($self, $f, $cfgname) = @_;
|
|
print $f <<EOF;
|
|
<OutDir Condition="'\$(Configuration)|\$(Platform)'=='$cfgname|$self->{platform}'">.\\$cfgname\\$self->{name}\\</OutDir>
|
|
<IntDir Condition="'\$(Configuration)|\$(Platform)'=='$cfgname|$self->{platform}'">.\\$cfgname\\$self->{name}\\</IntDir>
|
|
<LinkIncremental Condition="'\$(Configuration)|\$(Platform)'=='$cfgname|$self->{platform}'">false</LinkIncremental>
|
|
EOF
|
|
return;
|
|
}
|
|
|
|
sub WriteItemDefinitionGroup
|
|
{
|
|
my ($self, $f, $cfgname, $p) = @_;
|
|
my $cfgtype =
|
|
($self->{type} eq "exe")
|
|
? 'Application'
|
|
: ($self->{type} eq "dll" ? 'DynamicLibrary' : 'StaticLibrary');
|
|
my $libs = $self->GetAdditionalLinkerDependencies($cfgname, ';');
|
|
|
|
my $targetmachine =
|
|
$self->{platform} eq 'Win32' ? 'MachineX86' : 'MachineX64';
|
|
|
|
my $includes = $self->{includes};
|
|
unless ($includes eq '' or $includes =~ /;$/)
|
|
{
|
|
$includes .= ';';
|
|
}
|
|
print $f <<EOF;
|
|
<ItemDefinitionGroup Condition="'\$(Configuration)|\$(Platform)'=='$cfgname|$self->{platform}'">
|
|
<ClCompile>
|
|
<Optimization>$p->{opt}</Optimization>
|
|
<AdditionalIncludeDirectories>$self->{prefixincludes}src/include;src/include/port/win32;src/include/port/win32_msvc;$includes\%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
<PreprocessorDefinitions>WIN32;_WINDOWS;__WINDOWS__;__WIN32__;EXEC_BACKEND;WIN32_STACK_RLIMIT=4194304;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE$self->{defines}$p->{defs}\%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
<StringPooling>$p->{strpool}</StringPooling>
|
|
<RuntimeLibrary>$p->{runtime}</RuntimeLibrary>
|
|
<DisableSpecificWarnings>$self->{disablewarnings};\%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
|
<AdditionalOptions>/MP \%(AdditionalOptions)</AdditionalOptions>
|
|
<AssemblerOutput>
|
|
</AssemblerOutput>
|
|
<AssemblerListingLocation>.\\$cfgname\\$self->{name}\\</AssemblerListingLocation>
|
|
<ObjectFileName>.\\$cfgname\\$self->{name}\\</ObjectFileName>
|
|
<ProgramDataBaseFileName>.\\$cfgname\\$self->{name}\\</ProgramDataBaseFileName>
|
|
<BrowseInformation>false</BrowseInformation>
|
|
<WarningLevel>Level3</WarningLevel>
|
|
<SuppressStartupBanner>true</SuppressStartupBanner>
|
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
|
<CompileAs>Default</CompileAs>
|
|
</ClCompile>
|
|
<Link>
|
|
<OutputFile>.\\$cfgname\\$self->{name}\\$self->{name}.$self->{type}</OutputFile>
|
|
<AdditionalDependencies>$libs;\%(AdditionalDependencies)</AdditionalDependencies>
|
|
<SuppressStartupBanner>true</SuppressStartupBanner>
|
|
<AdditionalLibraryDirectories>\%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
|
<IgnoreSpecificDefaultLibraries>libc;\%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
|
<StackReserveSize>4194304</StackReserveSize>
|
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
<ProgramDatabaseFile>.\\$cfgname\\$self->{name}\\$self->{name}.pdb</ProgramDatabaseFile>
|
|
<GenerateMapFile>false</GenerateMapFile>
|
|
<MapFileName>.\\$cfgname\\$self->{name}\\$self->{name}.map</MapFileName>
|
|
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
|
<!-- Permit links to MinGW-built, 32-bit DLLs (default before VS2012). -->
|
|
<ImageHasSafeExceptionHandlers/>
|
|
<SubSystem>Console</SubSystem>
|
|
<TargetMachine>$targetmachine</TargetMachine>
|
|
EOF
|
|
if ($self->{disablelinkerwarnings})
|
|
{
|
|
print $f
|
|
" <AdditionalOptions>/ignore:$self->{disablelinkerwarnings} \%(AdditionalOptions)</AdditionalOptions>\n";
|
|
}
|
|
if ($self->{implib})
|
|
{
|
|
my $l = $self->{implib};
|
|
$l =~ s/__CFGNAME__/$cfgname/g;
|
|
print $f " <ImportLibrary>$l</ImportLibrary>\n";
|
|
}
|
|
if ($self->{def})
|
|
{
|
|
my $d = $self->{def};
|
|
$d =~ s/__CFGNAME__/$cfgname/g;
|
|
print $f " <ModuleDefinitionFile>$d</ModuleDefinitionFile>\n";
|
|
}
|
|
print $f <<EOF;
|
|
</Link>
|
|
<ResourceCompile>
|
|
<AdditionalIncludeDirectories>src\\include;\%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
</ResourceCompile>
|
|
EOF
|
|
if ($self->{builddef})
|
|
{
|
|
print $f <<EOF;
|
|
<PreLinkEvent>
|
|
<Message>Generate DEF file</Message>
|
|
<Command>perl src\\tools\\msvc\\gendef.pl $cfgname\\$self->{name} $self->{platform}</Command>
|
|
</PreLinkEvent>
|
|
EOF
|
|
}
|
|
print $f <<EOF;
|
|
</ItemDefinitionGroup>
|
|
EOF
|
|
return;
|
|
}
|
|
|
|
sub Footer
|
|
{
|
|
my ($self, $f) = @_;
|
|
$self->WriteReferences($f);
|
|
|
|
print $f <<EOF;
|
|
<Import Project="\$(VCTargetsPath)\\Microsoft.Cpp.targets" />
|
|
<ImportGroup Label="ExtensionTargets">
|
|
</ImportGroup>
|
|
</Project>
|
|
EOF
|
|
return;
|
|
}
|
|
|
|
package VC2013Project;
|
|
|
|
#
|
|
# Package that encapsulates a Visual C++ 2013 project file
|
|
#
|
|
|
|
use strict;
|
|
use warnings;
|
|
use base qw(MSBuildProject);
|
|
|
|
no warnings qw(redefine); ## no critic
|
|
|
|
sub new
|
|
{
|
|
my $classname = shift;
|
|
my $self = $classname->SUPER::_new(@_);
|
|
bless($self, $classname);
|
|
|
|
$self->{vcver} = '12.00';
|
|
$self->{PlatformToolset} = 'v120';
|
|
$self->{ToolsVersion} = '12.0';
|
|
|
|
return $self;
|
|
}
|
|
|
|
package VC2015Project;
|
|
|
|
#
|
|
# Package that encapsulates a Visual C++ 2015 project file
|
|
#
|
|
|
|
use strict;
|
|
use warnings;
|
|
use base qw(MSBuildProject);
|
|
|
|
no warnings qw(redefine); ## no critic
|
|
|
|
sub new
|
|
{
|
|
my $classname = shift;
|
|
my $self = $classname->SUPER::_new(@_);
|
|
bless($self, $classname);
|
|
|
|
$self->{vcver} = '14.00';
|
|
$self->{PlatformToolset} = 'v140';
|
|
$self->{ToolsVersion} = '14.0';
|
|
|
|
return $self;
|
|
}
|
|
|
|
package VC2017Project;
|
|
|
|
#
|
|
# Package that encapsulates a Visual C++ 2017 project file
|
|
#
|
|
|
|
use strict;
|
|
use warnings;
|
|
use base qw(MSBuildProject);
|
|
|
|
no warnings qw(redefine); ## no critic
|
|
|
|
sub new
|
|
{
|
|
my $classname = shift;
|
|
my $self = $classname->SUPER::_new(@_);
|
|
bless($self, $classname);
|
|
|
|
$self->{vcver} = '15.00';
|
|
$self->{PlatformToolset} = 'v141';
|
|
$self->{ToolsVersion} = '15.0';
|
|
|
|
return $self;
|
|
}
|
|
|
|
package VC2019Project;
|
|
|
|
#
|
|
# Package that encapsulates a Visual C++ 2019 project file
|
|
#
|
|
|
|
use strict;
|
|
use warnings;
|
|
use base qw(MSBuildProject);
|
|
|
|
no warnings qw(redefine); ## no critic
|
|
|
|
sub new
|
|
{
|
|
my $classname = shift;
|
|
my $self = $classname->SUPER::_new(@_);
|
|
bless($self, $classname);
|
|
|
|
$self->{vcver} = '16.00';
|
|
$self->{PlatformToolset} = 'v142';
|
|
$self->{ToolsVersion} = '16.0';
|
|
|
|
return $self;
|
|
}
|
|
|
|
1;
|